mfplat/tests: Test locking flags for D3D9 buffers.
[wine.git] / dlls / mfplat / tests / mfplat.c
blob0487a7db5ce44fa29603926186ca1f023f4fc4a8
1 /*
2 * Unit test suite for mfplat.
4 * Copyright 2015 Michael Müller
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <string.h>
23 #include <limits.h>
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "ole2.h"
32 #include "ks.h"
33 #include "ksmedia.h"
34 #include "amvideo.h"
35 #include "mfapi.h"
36 #include "mfidl.h"
37 #include "mferror.h"
38 #include "mfreadwrite.h"
39 #include "propvarutil.h"
40 #include "strsafe.h"
41 #include "uuids.h"
42 #include "evr.h"
43 #include "mfmediaengine.h"
45 #include "wine/test.h"
47 #define D3D11_INIT_GUID
48 #include "initguid.h"
49 #include "d3d11_4.h"
50 #include "d3d9.h"
51 #include "d3d9types.h"
52 #include "ks.h"
53 #include "ksmedia.h"
54 #include "dxva2api.h"
55 #include "d3d12.h"
56 #undef EXTERN_GUID
57 #define EXTERN_GUID DEFINE_GUID
58 #include "mfd3d12.h"
59 #include "wmcodecdsp.h"
61 DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
62 DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
63 DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
64 DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
66 extern const CLSID CLSID_FileSchemePlugin;
68 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1'));
69 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2'));
70 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3'));
71 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4'));
73 static BOOL is_win8_plus;
75 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
76 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
78 ULONG rc;
79 IUnknown_AddRef(obj);
80 rc = IUnknown_Release(obj);
81 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %ld, expected %ld.\n", rc, ref);
84 static ULONG get_refcount(void *iface)
86 IUnknown *unknown = iface;
87 IUnknown_AddRef(unknown);
88 return IUnknown_Release(unknown);
91 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
92 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
94 IUnknown *iface = iface_ptr;
95 HRESULT hr, expected_hr;
96 IUnknown *unk;
98 expected_hr = supported ? S_OK : E_NOINTERFACE;
100 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
101 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
102 if (SUCCEEDED(hr))
103 IUnknown_Release(unk);
106 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
107 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
109 IUnknown *iface = iface_ptr;
110 HRESULT hr, expected_hr;
111 IMFGetService *gs;
112 IUnknown *unk;
114 expected_hr = supported ? S_OK : E_NOINTERFACE;
116 if (SUCCEEDED(hr = IUnknown_QueryInterface(iface, &IID_IMFGetService, (void **)&gs)))
118 hr = IMFGetService_GetService(gs, service, iid, (void **)&unk);
119 IMFGetService_Release(gs);
121 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
122 if (SUCCEEDED(hr))
123 IUnknown_Release(unk);
126 struct d3d11_resource_readback
128 ID3D11Resource *resource;
129 D3D11_MAPPED_SUBRESOURCE map_desc;
130 ID3D11DeviceContext *immediate_context;
131 unsigned int width, height, depth, sub_resource_idx;
134 static void init_d3d11_resource_readback(ID3D11Resource *resource, ID3D11Resource *readback_resource,
135 unsigned int width, unsigned int height, unsigned int depth, unsigned int sub_resource_idx,
136 ID3D11Device *device, struct d3d11_resource_readback *rb)
138 HRESULT hr;
140 rb->resource = readback_resource;
141 rb->width = width;
142 rb->height = height;
143 rb->depth = depth;
144 rb->sub_resource_idx = sub_resource_idx;
146 ID3D11Device_GetImmediateContext(device, &rb->immediate_context);
148 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->resource, resource);
149 if (FAILED(hr = ID3D11DeviceContext_Map(rb->immediate_context,
150 rb->resource, sub_resource_idx, D3D11_MAP_READ, 0, &rb->map_desc)))
152 trace("Failed to map resource, hr %#lx.\n", hr);
153 ID3D11Resource_Release(rb->resource);
154 rb->resource = NULL;
155 ID3D11DeviceContext_Release(rb->immediate_context);
156 rb->immediate_context = NULL;
160 static void get_d3d11_texture2d_readback(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
161 struct d3d11_resource_readback *rb)
163 D3D11_TEXTURE2D_DESC texture_desc;
164 ID3D11Resource *rb_texture;
165 unsigned int miplevel;
166 ID3D11Device *device;
167 HRESULT hr;
169 memset(rb, 0, sizeof(*rb));
171 ID3D11Texture2D_GetDevice(texture, &device);
173 ID3D11Texture2D_GetDesc(texture, &texture_desc);
174 texture_desc.Usage = D3D11_USAGE_STAGING;
175 texture_desc.BindFlags = 0;
176 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
177 texture_desc.MiscFlags = 0;
178 if (FAILED(hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture)))
180 trace("Failed to create texture, hr %#lx.\n", hr);
181 ID3D11Device_Release(device);
182 return;
185 miplevel = sub_resource_idx % texture_desc.MipLevels;
186 init_d3d11_resource_readback((ID3D11Resource *)texture, rb_texture,
187 max(1, texture_desc.Width >> miplevel),
188 max(1, texture_desc.Height >> miplevel),
189 1, sub_resource_idx, device, rb);
191 ID3D11Device_Release(device);
194 static void release_d3d11_resource_readback(struct d3d11_resource_readback *rb)
196 ID3D11DeviceContext_Unmap(rb->immediate_context, rb->resource, rb->sub_resource_idx);
197 ID3D11Resource_Release(rb->resource);
198 ID3D11DeviceContext_Release(rb->immediate_context);
201 static void *get_d3d11_readback_data(struct d3d11_resource_readback *rb,
202 unsigned int x, unsigned int y, unsigned int z, unsigned byte_width)
204 return (BYTE *)rb->map_desc.pData + z * rb->map_desc.DepthPitch + y * rb->map_desc.RowPitch + x * byte_width;
207 static DWORD get_d3d11_readback_u32(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
209 return *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD));
212 static DWORD get_d3d11_readback_color(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
214 return get_d3d11_readback_u32(rb, x, y, z);
217 static DWORD get_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y)
219 struct d3d11_resource_readback rb;
220 DWORD color;
222 get_d3d11_texture2d_readback(texture, 0, &rb);
223 color = get_d3d11_readback_color(&rb, x, y, 0);
224 release_d3d11_resource_readback(&rb);
226 return color;
229 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
230 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
231 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
232 static HRESULT (WINAPI *pD3D12CreateDevice)(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level,
233 REFIID iid, void **device);
235 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
237 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
238 DWORD width, DWORD lines);
239 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
240 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
241 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
242 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
243 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
244 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
245 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
246 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
247 IMFActivate *activate);
248 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
249 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
250 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
251 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
252 const MFT_REGISTER_TYPE_INFO* output_types);
253 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
254 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
255 const MFT_REGISTER_TYPE_INFO *output_types);
256 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
257 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
258 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
259 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
260 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
261 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
262 static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
263 static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
264 IMFMediaBuffer **buffer);
265 static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
266 DWORD min_alignment, IMFMediaBuffer **buffer);
267 static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
268 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
269 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
270 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
271 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
272 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
273 IMFMediaBuffer **buffer);
274 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
275 static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
276 static HRESULT (WINAPI *pMFLockDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
277 static HRESULT (WINAPI *pMFUnlockDXGIDeviceManager)(void);
278 static HRESULT (WINAPI *pMFInitVideoFormat_RGB)(MFVIDEOFORMAT *format, DWORD width, DWORD height, DWORD d3dformat);
280 static HWND create_window(void)
282 RECT r = {0, 0, 640, 480};
284 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
286 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
287 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
290 static IDirect3DDevice9 *create_d3d9_device(IDirect3D9 *d3d9, HWND focus_window)
292 D3DPRESENT_PARAMETERS present_parameters = {0};
293 IDirect3DDevice9 *device = NULL;
295 present_parameters.BackBufferWidth = 640;
296 present_parameters.BackBufferHeight = 480;
297 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
298 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
299 present_parameters.hDeviceWindow = focus_window;
300 present_parameters.Windowed = TRUE;
301 present_parameters.EnableAutoDepthStencil = TRUE;
302 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
303 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
305 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
306 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
308 return device;
311 static const WCHAR fileschemeW[] = L"file://";
313 static WCHAR *load_resource(const WCHAR *name)
315 static WCHAR pathW[MAX_PATH];
316 DWORD written;
317 HANDLE file;
318 HRSRC res;
319 void *ptr;
321 GetTempPathW(ARRAY_SIZE(pathW), pathW);
322 lstrcatW(pathW, name);
324 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
325 NULL, CREATE_ALWAYS, 0, 0);
326 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n",
327 wine_dbgstr_w(pathW), GetLastError());
329 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
330 ok(res != 0, "couldn't find resource\n");
331 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
332 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
333 &written, NULL);
334 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
335 "couldn't write resource\n" );
336 CloseHandle(file);
338 return pathW;
341 static BOOL is_MEDIASUBTYPE_RGB(const GUID *subtype)
343 return IsEqualGUID(subtype, &MEDIASUBTYPE_RGB8)
344 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB555)
345 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB565)
346 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB24)
347 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB32);
350 struct test_callback
352 IMFAsyncCallback IMFAsyncCallback_iface;
353 LONG refcount;
354 HANDLE event;
355 DWORD param;
356 IMFMediaEvent *media_event;
359 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
361 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
364 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
366 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
367 IsEqualIID(riid, &IID_IUnknown))
369 *obj = iface;
370 IMFAsyncCallback_AddRef(iface);
371 return S_OK;
374 *obj = NULL;
375 return E_NOINTERFACE;
378 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
380 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
381 return InterlockedIncrement(&callback->refcount);
384 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
386 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
387 ULONG refcount = InterlockedDecrement(&callback->refcount);
389 if (!refcount)
390 free(callback);
392 return refcount;
395 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
397 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
398 return E_NOTIMPL;
401 static BOOL check_clsid(CLSID *clsids, UINT32 count)
403 int i;
404 for (i = 0; i < count; i++)
406 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
407 return TRUE;
409 return FALSE;
412 static void test_register(void)
414 MFT_REGISTER_TYPE_INFO *in_types, *out_types;
415 WCHAR name[] = L"Wine test";
416 MFT_REGISTER_TYPE_INFO input[] =
418 { DUMMY_CLSID, DUMMY_GUID1 }
420 MFT_REGISTER_TYPE_INFO output[] =
422 { DUMMY_CLSID, DUMMY_GUID2 }
424 UINT32 count, in_count, out_count;
425 IMFAttributes *attributes;
426 WCHAR *mft_name;
427 CLSID *clsids;
428 HRESULT hr, ret;
430 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
431 if (ret == E_ACCESSDENIED)
433 win_skip("Not enough permissions to register a transform.\n");
434 return;
436 ok(ret == S_OK, "Failed to register dummy transform, hr %#lx.\n", ret);
438 if(0)
440 /* NULL name crashes on windows */
441 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
442 ok(ret == E_INVALIDARG, "Unexpected hr %#lx.\n", ret);
445 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
446 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
448 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
449 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
451 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
452 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
454 if(0)
456 /* NULL clsids/count crashes on windows (vista) */
457 count = 0;
458 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
459 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
460 ok(count == 0, "Expected count == 0\n");
462 clsids = NULL;
463 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
464 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
466 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, NULL, NULL, NULL, NULL, NULL);
467 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
468 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
469 CoTaskMemFree(mft_name);
471 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, NULL);
472 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
474 in_count = out_count = 1;
475 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, &in_count, NULL, &out_count, NULL);
476 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
477 ok(!in_count, "Unexpected count %u.\n", in_count);
478 ok(!out_count, "Unexpected count %u.\n", out_count);
480 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, &attributes);
481 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
482 ok(!!attributes, "Unexpected attributes.\n");
483 IMFAttributes_Release(attributes);
485 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, &in_types, &in_count, &out_types, &out_count, &attributes);
486 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
487 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
488 ok(!!in_types, "Unexpected pointer.\n");
489 ok(!!out_types, "Unexpected pointer.\n");
490 ok(in_count == 1, "Unexpected count %u.\n", in_count);
491 ok(out_count == 1, "Unexpected count %u.\n", out_count);
492 ok(IsEqualGUID(&in_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
493 wine_dbgstr_guid(&in_types->guidMajorType));
494 ok(IsEqualGUID(&in_types->guidSubtype, &DUMMY_GUID1), "Unexpected type guid %s.\n",
495 wine_dbgstr_guid(&in_types->guidSubtype));
496 ok(IsEqualGUID(&out_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
497 wine_dbgstr_guid(&out_types->guidMajorType));
498 ok(IsEqualGUID(&out_types->guidSubtype, &DUMMY_GUID2), "Unexpected type guid %s.\n",
499 wine_dbgstr_guid(&out_types->guidSubtype));
500 ok(!!attributes, "Unexpected attributes.\n");
501 count = 1;
502 hr = IMFAttributes_GetCount(attributes, &count);
503 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
504 ok(!count, "Unexpected count %u.\n", count);
505 CoTaskMemFree(mft_name);
506 CoTaskMemFree(in_types);
507 CoTaskMemFree(out_types);
508 IMFAttributes_Release(attributes);
510 count = 0;
511 clsids = NULL;
512 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
513 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
514 ok(count > 0, "Expected count > 0\n");
515 ok(clsids != NULL, "Expected clsids != NULL\n");
516 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
517 CoTaskMemFree(clsids);
519 count = 0;
520 clsids = NULL;
521 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
522 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
523 ok(count > 0, "Expected count > 0\n");
524 ok(clsids != NULL, "Expected clsids != NULL\n");
525 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
526 CoTaskMemFree(clsids);
528 count = 0;
529 clsids = NULL;
530 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
531 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
532 ok(count > 0, "Expected count > 0\n");
533 ok(clsids != NULL, "Expected clsids != NULL\n");
534 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
535 CoTaskMemFree(clsids);
537 count = 0;
538 clsids = NULL;
539 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
540 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
541 ok(count > 0, "Expected count > 0\n");
542 ok(clsids != NULL, "Expected clsids != NULL\n");
543 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
544 CoTaskMemFree(clsids);
546 /* exchange input and output */
547 count = 0;
548 clsids = NULL;
549 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
550 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
551 ok(!count, "got %d\n", count);
552 ok(clsids == NULL, "Expected clsids == NULL\n");
554 ret = MFTUnregister(DUMMY_CLSID);
555 ok(ret == S_OK ||
556 /* w7pro64 */
557 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
559 ret = MFTUnregister(DUMMY_CLSID);
560 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
563 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
565 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
566 IMFSourceResolver *resolver;
567 IUnknown *object, *object2;
568 MF_OBJECT_TYPE obj_type;
569 HRESULT hr;
571 ok(!!result, "Unexpected result object.\n");
573 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
575 object = NULL;
576 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
577 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
579 hr = IMFAsyncResult_GetObject(result, &object2);
580 ok(hr == S_OK, "Failed to get result object, hr %#lx.\n", hr);
581 ok(object2 == object, "Unexpected object.\n");
583 if (object)
584 IUnknown_Release(object);
585 IUnknown_Release(object2);
587 SetEvent(callback->event);
589 return S_OK;
592 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
594 testcallback_QueryInterface,
595 testcallback_AddRef,
596 testcallback_Release,
597 testcallback_GetParameters,
598 test_create_from_url_callback_Invoke,
601 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
603 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
604 IMFSchemeHandler *handler;
605 IUnknown *object, *object2;
606 MF_OBJECT_TYPE obj_type;
607 HRESULT hr;
609 ok(!!result, "Unexpected result object.\n");
611 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
613 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
614 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
616 if (SUCCEEDED(hr))
618 hr = IMFAsyncResult_GetObject(result, &object2);
619 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
621 IUnknown_Release(object);
624 SetEvent(callback->event);
626 return S_OK;
629 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
631 testcallback_QueryInterface,
632 testcallback_AddRef,
633 testcallback_Release,
634 testcallback_GetParameters,
635 test_create_from_file_handler_callback_Invoke,
638 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
640 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
641 IMFMediaEventGenerator *generator;
642 HRESULT hr;
644 ok(!!result, "Unexpected result object.\n");
646 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
648 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
649 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
651 SetEvent(callback->event);
653 return S_OK;
656 static const IMFAsyncCallbackVtbl events_callback_vtbl =
658 testcallback_QueryInterface,
659 testcallback_AddRef,
660 testcallback_Release,
661 testcallback_GetParameters,
662 source_events_callback_Invoke,
665 static const IMFAsyncCallbackVtbl testcallbackvtbl;
667 static struct test_callback * create_test_callback(const IMFAsyncCallbackVtbl *vtbl)
669 struct test_callback *callback = calloc(1, sizeof(*callback));
671 callback->IMFAsyncCallback_iface.lpVtbl = vtbl ? vtbl : &testcallbackvtbl;
672 callback->refcount = 1;
674 return callback;
677 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
679 struct test_callback *callback;
680 MediaEventType event_type;
681 BOOL ret = FALSE;
682 HRESULT hr;
684 callback = create_test_callback(&events_callback_vtbl);
685 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
687 for (;;)
689 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback->IMFAsyncCallback_iface,
690 (IUnknown *)generator);
691 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
693 if (WaitForSingleObject(callback->event, 1000) == WAIT_TIMEOUT)
695 ok(0, "timeout\n");
696 break;
699 Sleep(10);
701 hr = IMFMediaEvent_GetType(callback->media_event, &event_type);
702 ok(hr == S_OK, "Failed to event type, hr %#lx.\n", hr);
704 if ((ret = (event_type == expected_event_type)))
706 if (value)
708 hr = IMFMediaEvent_GetValue(callback->media_event, value);
709 ok(hr == S_OK, "Failed to get value of event, hr %#lx.\n", hr);
712 break;
716 CloseHandle(callback->event);
717 if (callback->media_event)
718 IMFMediaEvent_Release(callback->media_event);
719 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
721 return ret;
724 static const IMFByteStreamVtbl *bytestream_vtbl_orig;
726 static int bytestream_closed = 0;
727 static HRESULT WINAPI bytestream_wrapper_Close(IMFByteStream *iface)
729 bytestream_closed = 1;
730 return bytestream_vtbl_orig->Close(iface);
733 static void test_source_resolver(void)
735 struct test_callback *callback, *callback2;
736 IMFByteStreamVtbl bytestream_vtbl_wrapper;
737 IMFSourceResolver *resolver, *resolver2;
738 IMFPresentationDescriptor *descriptor;
739 IMFSchemeHandler *scheme_handler;
740 IMFMediaStream *video_stream;
741 IMFAttributes *attributes;
742 IMFMediaSource *mediasource;
743 IMFMediaTypeHandler *handler;
744 IMFMediaType *media_type;
745 BOOL selected, do_uninit;
746 MF_OBJECT_TYPE obj_type;
747 IMFStreamDescriptor *sd;
748 IUnknown *cancel_cookie;
749 IMFByteStream *stream;
750 IMFGetService *get_service;
751 IMFRateSupport *rate_support;
752 WCHAR pathW[MAX_PATH];
753 int i, sample_count;
754 WCHAR *filename;
755 PROPVARIANT var;
756 HRESULT hr;
757 GUID guid;
758 float rate;
759 UINT32 rotation;
761 if (!pMFCreateSourceResolver)
763 win_skip("MFCreateSourceResolver() not found\n");
764 return;
767 callback = create_test_callback(&test_create_from_url_callback_vtbl);
768 callback2 = create_test_callback(&test_create_from_file_handler_callback_vtbl);
770 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
773 hr = pMFCreateSourceResolver(NULL);
774 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
776 hr = pMFCreateSourceResolver(&resolver);
777 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
779 hr = pMFCreateSourceResolver(&resolver2);
780 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
781 ok(resolver != resolver2, "Expected new instance\n");
783 IMFSourceResolver_Release(resolver2);
785 filename = load_resource(L"test.mp4");
787 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
788 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
790 hr = IMFSourceResolver_CreateObjectFromByteStream(
791 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
792 &obj_type, (IUnknown **)&mediasource);
793 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
795 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
796 NULL, (IUnknown **)&mediasource);
797 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
799 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
800 &obj_type, NULL);
801 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
803 IMFByteStream_Release(stream);
805 /* Create from URL. */
806 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
808 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
809 (IUnknown **)&stream);
810 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
812 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
813 (IUnknown **)&stream);
814 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
815 IMFByteStream_Release(stream);
817 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
818 &cancel_cookie, &callback->IMFAsyncCallback_iface, (IUnknown *)resolver);
819 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
820 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
821 IUnknown_Release(cancel_cookie);
823 if (SUCCEEDED(hr))
824 WaitForSingleObject(callback->event, INFINITE);
826 /* With explicit scheme. */
827 lstrcpyW(pathW, fileschemeW);
828 lstrcatW(pathW, filename);
830 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
831 (IUnknown **)&stream);
832 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
833 IMFByteStream_Release(stream);
835 /* We have to create a new bytestream here, because all following
836 * calls to CreateObjectFromByteStream will fail. */
837 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
838 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
840 /* Wrap ::Close to test when the media source calls it */
841 bytestream_vtbl_orig = stream->lpVtbl;
842 bytestream_vtbl_wrapper = *bytestream_vtbl_orig;
843 bytestream_vtbl_wrapper.Close = bytestream_wrapper_Close;
844 stream->lpVtbl = &bytestream_vtbl_wrapper;
846 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
847 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
848 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
849 ok(hr == S_OK, "Failed to set string value, hr %#lx.\n", hr);
850 IMFAttributes_Release(attributes);
852 /* Start of gstreamer dependent tests */
854 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
855 &obj_type, (IUnknown **)&mediasource);
856 if (strcmp(winetest_platform, "wine"))
857 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
858 if (FAILED(hr))
860 IMFByteStream_Release(stream);
861 IMFSourceResolver_Release(resolver);
863 hr = MFShutdown();
864 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
866 DeleteFileW(filename);
867 return;
869 ok(mediasource != NULL, "got %p\n", mediasource);
870 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
872 check_interface(mediasource, &IID_IMFGetService, TRUE);
873 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
875 hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service);
876 ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
878 hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support);
879 ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
881 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
882 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
883 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
884 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
885 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
886 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
887 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
888 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
889 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
890 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
891 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
892 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
894 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
895 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
896 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
897 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
898 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
899 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
900 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
901 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
902 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
903 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
904 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
905 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
907 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, NULL);
908 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
909 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, &rate);
910 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
911 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
913 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1.0f, &rate);
914 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
915 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
916 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1.0f, &rate);
917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
918 ok(rate == -1.0f, "Unexpected rate %f.\n", rate);
919 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1e6f + 1.0f, &rate);
920 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
921 ok(rate == 1e6f + 1.0f || broken(rate == 1e6f) /* Win7 */, "Unexpected %f.\n", rate);
922 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f, &rate);
923 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
924 ok(rate == -1e6f, "Unexpected rate %f.\n", rate);
926 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f - 1.0f, &rate);
927 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
928 ok(rate == -1e6f - 1.0f || broken(rate == -1e6f) /* Win7 */, "Unexpected rate %f.\n", rate);
930 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
931 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
932 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#lx.\n", hr);
933 ok(descriptor != NULL, "got %p\n", descriptor);
935 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
936 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
938 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
939 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
940 IMFStreamDescriptor_Release(sd);
942 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
943 ok(hr == S_OK, "Failed to get stream major type, hr %#lx.\n", hr);
945 /* Check major/minor type for the test media. */
946 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
948 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
949 ok(hr == S_OK, "Failed to get current media type, hr %#lx.\n", hr);
950 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
951 ok(hr == S_OK, "Failed to get media sub type, hr %#lx.\n", hr);
952 todo_wine
953 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
955 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_ROTATION, &rotation);
956 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Win7 */, "Failed to get rotation, hr %#lx.\n", hr);
957 if (hr == S_OK)
958 ok(rotation == MFVideoRotationFormat_0, "Got wrong rotation %u.\n", rotation);
960 IMFMediaType_Release(media_type);
962 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
963 ok(hr == S_OK, "Failed to select video stream, hr %#lx.\n", hr);
965 var.vt = VT_EMPTY;
966 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
967 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
969 video_stream = NULL;
970 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
972 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
973 video_stream = (IMFMediaStream *)var.punkVal;
976 hr = IMFMediaSource_Pause(mediasource);
977 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
978 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
979 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
981 var.vt = VT_EMPTY;
982 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
983 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
985 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
986 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
988 hr = IMFMediaSource_Pause(mediasource);
989 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
990 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
991 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
993 var.vt = VT_I8;
994 var.uhVal.QuadPart = 0;
995 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
996 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
998 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceSeeked, &var))
999 ok(var.vt == VT_I8, "Unexpected value type.\n");
1001 hr = IMFMediaSource_Stop(mediasource);
1002 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1003 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStopped, &var))
1004 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1006 var.vt = VT_I8;
1007 var.uhVal.QuadPart = 0;
1008 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1009 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1011 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
1012 ok(var.vt == VT_I8, "Unexpected value type.\n");
1014 sample_count = 10;
1016 for (i = 0; i < sample_count; ++i)
1018 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1019 ok(hr == S_OK, "Failed to request sample %u, hr %#lx.\n", i + 1, hr);
1020 if (hr != S_OK)
1021 break;
1024 for (i = 0; i < sample_count; ++i)
1026 static const LONGLONG MILLI_TO_100_NANO = 10000;
1027 LONGLONG duration, time;
1028 DWORD buffer_count;
1029 IMFSample *sample;
1030 BOOL ret;
1032 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
1033 ok(ret, "Sample %u not received.\n", i + 1);
1034 if (!ret)
1035 break;
1037 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
1038 sample = (IMFSample *)var.punkVal;
1040 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1041 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1042 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
1044 hr = IMFSample_GetSampleDuration(sample, &duration);
1045 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
1046 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
1048 hr = IMFSample_GetSampleTime(sample, &time);
1049 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
1050 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
1052 IMFSample_Release(sample);
1055 if (i == sample_count)
1057 IMFMediaEvent *event;
1059 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
1060 Sleep(100);
1061 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
1062 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
1064 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1065 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1066 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
1070 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1071 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1073 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
1075 IMFMediaStream_Release(video_stream);
1076 IMFMediaTypeHandler_Release(handler);
1077 IMFPresentationDescriptor_Release(descriptor);
1079 ok(!bytestream_closed, "IMFByteStream::Close called unexpectedly\n");
1081 hr = IMFMediaSource_Shutdown(mediasource);
1082 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1084 ok(bytestream_closed, "Missing IMFByteStream::Close call\n");
1086 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
1087 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
1089 IMFRateSupport_Release(rate_support);
1090 IMFGetService_Release(get_service);
1091 IMFMediaSource_Release(mediasource);
1092 IMFByteStream_Release(stream);
1094 /* Create directly through scheme handler. */
1095 hr = CoInitialize(NULL);
1096 ok(SUCCEEDED(hr), "Failed to initialize, hr %#lx.\n", hr);
1097 do_uninit = hr == S_OK;
1099 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
1100 (void **)&scheme_handler);
1101 ok(hr == S_OK, "Failed to create handler object, hr %#lx.\n", hr);
1103 callback2->event = callback->event;
1104 cancel_cookie = NULL;
1105 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
1106 &callback2->IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
1107 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
1108 ok(!!cancel_cookie, "Unexpected cancel object.\n");
1109 IUnknown_Release(cancel_cookie);
1111 WaitForSingleObject(callback2->event, INFINITE);
1113 IMFSchemeHandler_Release(scheme_handler);
1115 if (do_uninit)
1116 CoUninitialize();
1118 CloseHandle(callback->event);
1120 IMFSourceResolver_Release(resolver);
1122 hr = MFShutdown();
1123 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
1125 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
1126 IMFAsyncCallback_Release(&callback2->IMFAsyncCallback_iface);
1128 DeleteFileW(filename);
1131 static void init_functions(void)
1133 HMODULE mod = GetModuleHandleA("mfplat.dll");
1135 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
1136 X(MFAddPeriodicCallback);
1137 X(MFAllocateSerialWorkQueue);
1138 X(MFAllocateWorkQueueEx);
1139 X(MFCopyImage);
1140 X(MFCreate2DMediaBuffer);
1141 X(MFCreateDXGIDeviceManager);
1142 X(MFCreateDXGISurfaceBuffer);
1143 X(MFCreateDXSurfaceBuffer);
1144 X(MFCreateSourceResolver);
1145 X(MFCreateMediaBufferFromMediaType);
1146 X(MFCreateMFByteStreamOnStream);
1147 X(MFCreateTrackedSample);
1148 X(MFCreateTransformActivate);
1149 X(MFCreateVideoMediaTypeFromSubtype);
1150 X(MFCreateVideoSampleAllocatorEx);
1151 X(MFGetPlaneSize);
1152 X(MFGetStrideForBitmapInfoHeader);
1153 X(MFInitVideoFormat_RGB);
1154 X(MFLockDXGIDeviceManager);
1155 X(MFLockSharedWorkQueue);
1156 X(MFMapDX9FormatToDXGIFormat);
1157 X(MFMapDXGIFormatToDX9Format);
1158 X(MFPutWaitingWorkItem);
1159 X(MFRegisterLocalByteStreamHandler);
1160 X(MFRegisterLocalSchemeHandler);
1161 X(MFRemovePeriodicCallback);
1162 X(MFTEnumEx);
1163 X(MFTRegisterLocal);
1164 X(MFTRegisterLocalByCLSID);
1165 X(MFTUnregisterLocal);
1166 X(MFTUnregisterLocalByCLSID);
1167 X(MFUnlockDXGIDeviceManager);
1169 if ((mod = LoadLibraryA("d3d11.dll")))
1171 X(D3D11CreateDevice);
1174 if ((mod = LoadLibraryA("d3d12.dll")))
1176 X(D3D12CreateDevice);
1179 mod = GetModuleHandleA("ole32.dll");
1181 X(CoGetApartmentType);
1182 #undef X
1184 is_win8_plus = pMFPutWaitingWorkItem != NULL;
1187 static void test_media_type(void)
1189 IMFMediaType *mediatype, *mediatype2;
1190 IMFVideoMediaType *video_type;
1191 IUnknown *unk, *unk2;
1192 BOOL compressed;
1193 DWORD flags;
1194 UINT count;
1195 HRESULT hr;
1196 GUID guid;
1198 if(0)
1200 /* Crash on Windows Vista/7 */
1201 hr = MFCreateMediaType(NULL);
1202 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1205 hr = MFCreateMediaType(&mediatype);
1206 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1208 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1209 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1211 compressed = FALSE;
1212 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1213 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1214 ok(compressed, "Unexpected value %d.\n", compressed);
1216 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
1217 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1219 compressed = FALSE;
1220 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1221 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1222 ok(compressed, "Unexpected value %d.\n", compressed);
1224 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 0);
1225 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1227 compressed = FALSE;
1228 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1229 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1230 ok(compressed, "Unexpected value %d.\n", compressed);
1232 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
1233 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1235 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 1);
1236 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1238 compressed = TRUE;
1239 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1240 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1241 ok(!compressed, "Unexpected value %d.\n", compressed);
1243 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_COMPRESSED);
1244 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1246 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1247 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1249 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1250 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
1251 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
1253 /* IsEqual() */
1254 hr = MFCreateMediaType(&mediatype2);
1255 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
1257 flags = 0xdeadbeef;
1258 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1259 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1260 ok(flags == 0, "Unexpected flags %#lx.\n", flags);
1262 /* Different major types. */
1263 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1264 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
1266 flags = 0;
1267 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1268 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1269 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1270 "Unexpected flags %#lx.\n", flags);
1272 /* Same major types, different subtypes. */
1273 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1274 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
1276 flags = 0;
1277 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1278 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1279 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
1280 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#lx.\n", flags);
1282 /* Different user data. */
1283 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
1284 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1286 flags = 0;
1287 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1288 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1289 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
1290 "Unexpected flags %#lx.\n", flags);
1292 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
1293 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1295 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1296 ok(hr == S_OK, "Failed to set subtype, hr %#lx.\n", hr);
1298 flags = 0;
1299 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1300 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1301 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1302 "Unexpected flags %#lx.\n", flags);
1304 IMFMediaType_Release(mediatype2);
1305 IMFMediaType_Release(mediatype);
1307 /* IMFVideoMediaType */
1308 hr = MFCreateMediaType(&mediatype);
1309 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1311 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
1313 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1314 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1315 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1316 IUnknown_Release(unk);
1318 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1319 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1321 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
1322 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1324 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1326 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1327 IUnknown_Release(unk2);
1329 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1330 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1331 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1332 IUnknown_Release(unk2);
1334 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1335 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1336 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1337 IUnknown_Release(unk2);
1339 IUnknown_Release(unk);
1340 IMFMediaType_Release(mediatype);
1342 if (pMFCreateVideoMediaTypeFromSubtype)
1344 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
1345 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1347 check_interface(video_type, &IID_IMFMediaType, TRUE);
1348 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
1350 /* Major and subtype are set on creation. */
1351 hr = IMFVideoMediaType_GetCount(video_type, &count);
1352 ok(count == 2, "Unexpected attribute count %#lx.\n", hr);
1354 hr = IMFVideoMediaType_DeleteAllItems(video_type);
1355 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1357 hr = IMFVideoMediaType_GetCount(video_type, &count);
1358 ok(!count, "Unexpected attribute count %#lx.\n", hr);
1360 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
1362 IMFVideoMediaType_Release(video_type);
1364 else
1365 win_skip("MFCreateVideoMediaTypeFromSubtype() is not available.\n");
1367 /* IMFAudioMediaType */
1368 hr = MFCreateMediaType(&mediatype);
1369 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1371 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
1373 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1374 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1375 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1376 IUnknown_Release(unk);
1378 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1379 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1381 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1382 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1384 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1385 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1386 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1387 IUnknown_Release(unk2);
1389 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1390 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1391 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1392 IUnknown_Release(unk2);
1394 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1395 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1396 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1397 IUnknown_Release(unk2);
1399 IUnknown_Release(unk);
1401 IMFMediaType_Release(mediatype);
1404 static void test_MFCreateMediaEvent(void)
1406 HRESULT hr;
1407 IMFMediaEvent *mediaevent;
1409 MediaEventType type;
1410 GUID extended_type;
1411 HRESULT status;
1412 PROPVARIANT value;
1414 PropVariantInit(&value);
1415 value.vt = VT_UNKNOWN;
1417 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1418 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1420 PropVariantClear(&value);
1422 hr = IMFMediaEvent_GetType(mediaevent, &type);
1423 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1424 ok(type == MEError, "got %#lx\n", type);
1426 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1427 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1428 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1429 wine_dbgstr_guid(&extended_type));
1431 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1432 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1433 ok(status == E_FAIL, "Unexpected hr %#lx.\n", status);
1435 PropVariantInit(&value);
1436 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1437 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1438 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1439 PropVariantClear(&value);
1441 IMFMediaEvent_Release(mediaevent);
1443 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1444 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1446 hr = IMFMediaEvent_GetType(mediaevent, &type);
1447 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1448 ok(type == MEUnknown, "got %#lx\n", type);
1450 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1451 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1452 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1453 wine_dbgstr_guid(&extended_type));
1455 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1456 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1457 ok(status == S_OK, "Unexpected hr %#lx.\n", status);
1459 PropVariantInit(&value);
1460 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1461 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1462 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1463 PropVariantClear(&value);
1465 IMFMediaEvent_Release(mediaevent);
1468 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1469 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1471 UINT32 count = expected + 1;
1472 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1473 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
1474 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1477 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1478 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1480 MF_ATTRIBUTE_TYPE type;
1481 HRESULT hr;
1483 hr = IMFAttributes_GetItemType(obj, key, &type);
1484 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
1485 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1488 static void test_attributes(void)
1490 static const WCHAR stringW[] = L"Wine";
1491 static const UINT8 blob[] = {0,1,2,3,4,5};
1492 IMFAttributes *attributes, *attributes1;
1493 UINT8 blob_value[256], *blob_buf = NULL;
1494 MF_ATTRIBUTES_MATCH_TYPE match_type;
1495 UINT32 value, string_length, size;
1496 PROPVARIANT propvar, ret_propvar;
1497 MF_ATTRIBUTE_TYPE type;
1498 double double_value;
1499 IUnknown *unk_value;
1500 WCHAR bufferW[256];
1501 UINT64 value64;
1502 WCHAR *string;
1503 BOOL result;
1504 HRESULT hr;
1505 GUID key;
1507 hr = MFCreateAttributes( &attributes, 3 );
1508 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1510 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1511 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1513 CHECK_ATTR_COUNT(attributes, 0);
1514 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1515 ok(hr == S_OK, "Failed to set UINT32 value, hr %#lx.\n", hr);
1516 CHECK_ATTR_COUNT(attributes, 1);
1517 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1519 value = 0xdeadbeef;
1520 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1521 ok(hr == S_OK, "Failed to get UINT32 value, hr %#lx.\n", hr);
1522 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1524 value64 = 0xdeadbeef;
1525 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1526 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1527 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1529 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1530 ok(hr == S_OK, "Failed to set UINT64 value, hr %#lx.\n", hr);
1531 CHECK_ATTR_COUNT(attributes, 1);
1532 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1534 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1535 ok(hr == S_OK, "Failed to get UINT64 value, hr %#lx.\n", hr);
1536 ok(value64 == 65536, "Unexpected value.\n");
1538 value = 0xdeadbeef;
1539 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1540 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1541 ok(value == 0xdeadbeef, "Unexpected value.\n");
1543 IMFAttributes_Release(attributes);
1545 hr = MFCreateAttributes(&attributes, 0);
1546 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1548 PropVariantInit(&propvar);
1549 propvar.vt = MF_ATTRIBUTE_UINT32;
1550 U(propvar).ulVal = 123;
1551 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1552 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1553 PropVariantInit(&ret_propvar);
1554 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1555 U(ret_propvar).ulVal = 0xdeadbeef;
1556 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1557 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1558 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1559 PropVariantClear(&ret_propvar);
1560 CHECK_ATTR_COUNT(attributes, 1);
1562 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1563 ok(hr == S_OK, "Item check failed, hr %#lx.\n", hr);
1565 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1566 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1568 PropVariantInit(&ret_propvar);
1569 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1570 U(ret_propvar).pwszVal = NULL;
1571 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1572 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1573 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1574 PropVariantClear(&ret_propvar);
1576 PropVariantClear(&propvar);
1578 PropVariantInit(&propvar);
1579 propvar.vt = MF_ATTRIBUTE_UINT64;
1580 U(propvar).uhVal.QuadPart = 65536;
1581 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1582 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1583 PropVariantInit(&ret_propvar);
1584 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1585 U(ret_propvar).ulVal = 0xdeadbeef;
1586 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1587 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1588 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1589 PropVariantClear(&ret_propvar);
1590 PropVariantClear(&propvar);
1591 CHECK_ATTR_COUNT(attributes, 1);
1593 PropVariantInit(&propvar);
1594 propvar.vt = VT_I4;
1595 U(propvar).lVal = 123;
1596 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1597 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#lx.\n", hr);
1598 PropVariantInit(&ret_propvar);
1599 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1600 U(ret_propvar).lVal = 0xdeadbeef;
1601 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1602 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1603 PropVariantClear(&propvar);
1604 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1605 PropVariantClear(&ret_propvar);
1607 PropVariantInit(&propvar);
1608 propvar.vt = MF_ATTRIBUTE_UINT32;
1609 U(propvar).ulVal = 123;
1610 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1611 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1613 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1614 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1615 CHECK_ATTR_COUNT(attributes, 2);
1617 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1618 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1619 CHECK_ATTR_COUNT(attributes, 2);
1621 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1622 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1623 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1624 PropVariantClear(&ret_propvar);
1625 PropVariantClear(&propvar);
1627 propvar.vt = MF_ATTRIBUTE_UINT64;
1628 U(propvar).uhVal.QuadPart = 65536;
1630 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1631 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1632 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1633 PropVariantClear(&ret_propvar);
1634 PropVariantClear(&propvar);
1636 /* Item ordering is not consistent across Windows version. */
1637 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1638 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1639 PropVariantClear(&ret_propvar);
1641 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1642 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1643 PropVariantClear(&ret_propvar);
1645 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1646 ok(hr == S_OK, "Failed to set double value, hr %#lx.\n", hr);
1647 CHECK_ATTR_COUNT(attributes, 3);
1648 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1650 double_value = 0xdeadbeef;
1651 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1652 ok(hr == S_OK, "Failed to get double value, hr %#lx.\n", hr);
1653 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1655 propvar.vt = MF_ATTRIBUTE_UINT64;
1656 U(propvar).uhVal.QuadPart = 22;
1657 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1658 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1659 ok(!result, "Unexpected result.\n");
1661 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1662 U(propvar).dblVal = 22.0;
1663 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1664 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1665 ok(result, "Unexpected result.\n");
1667 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1668 ok(hr == S_OK, "Failed to set string attribute, hr %#lx.\n", hr);
1669 CHECK_ATTR_COUNT(attributes, 3);
1670 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1672 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1673 ok(hr == S_OK, "Failed to get string length, hr %#lx.\n", hr);
1674 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1676 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, NULL);
1677 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1678 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1679 CoTaskMemFree(string);
1681 string_length = 0xdeadbeef;
1682 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1683 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1684 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1685 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1686 CoTaskMemFree(string);
1688 string_length = 0xdeadbeef;
1689 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1690 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1691 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1692 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1693 memset(bufferW, 0, sizeof(bufferW));
1695 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1696 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1697 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1698 memset(bufferW, 0, sizeof(bufferW));
1700 string_length = 0;
1701 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1702 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1703 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1704 ok(string_length, "Unexpected length.\n");
1706 string_length = 0xdeadbeef;
1707 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1708 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1709 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1711 /* VT_UNKNOWN */
1712 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1713 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1714 CHECK_ATTR_COUNT(attributes, 4);
1715 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1717 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1718 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1719 IUnknown_Release(unk_value);
1721 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1722 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1723 IUnknown_Release(unk_value);
1725 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1726 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1728 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1729 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1730 CHECK_ATTR_COUNT(attributes, 5);
1732 unk_value = NULL;
1733 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1734 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1736 /* CopyAllItems() */
1737 hr = MFCreateAttributes(&attributes1, 0);
1738 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1739 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1740 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1741 CHECK_ATTR_COUNT(attributes, 5);
1742 CHECK_ATTR_COUNT(attributes1, 5);
1744 hr = IMFAttributes_DeleteAllItems(attributes1);
1745 ok(hr == S_OK, "Failed to delete items, hr %#lx.\n", hr);
1746 CHECK_ATTR_COUNT(attributes1, 0);
1748 propvar.vt = MF_ATTRIBUTE_UINT64;
1749 U(propvar).uhVal.QuadPart = 22;
1750 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1751 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1752 ok(!result, "Unexpected result.\n");
1754 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1755 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1756 CHECK_ATTR_COUNT(attributes, 0);
1758 /* Blob */
1759 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1760 ok(hr == S_OK, "Failed to set blob attribute, hr %#lx.\n", hr);
1761 CHECK_ATTR_COUNT(attributes, 1);
1762 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1763 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1764 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
1765 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1767 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1768 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1770 size = 0;
1771 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1772 ok(hr == S_OK, "Failed to get blob, hr %#lx.\n", hr);
1773 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1774 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1776 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1777 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1779 memset(blob_value, 0, sizeof(blob_value));
1780 size = 0;
1781 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1782 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1783 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1784 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1785 CoTaskMemFree(blob_buf);
1787 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, NULL);
1788 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1789 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1790 CoTaskMemFree(blob_buf);
1792 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1793 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1795 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1796 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1798 IMFAttributes_Release(attributes);
1799 IMFAttributes_Release(attributes1);
1801 /* Compare() */
1802 hr = MFCreateAttributes(&attributes, 0);
1803 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1804 hr = MFCreateAttributes(&attributes1, 0);
1805 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1807 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1808 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1810 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1812 result = FALSE;
1813 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1814 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1815 ok(result, "Unexpected result %d.\n", result);
1817 result = FALSE;
1818 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1819 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1820 ok(result, "Unexpected result %d.\n", result);
1823 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1824 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1826 result = TRUE;
1827 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1828 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1829 ok(!result, "Unexpected result %d.\n", result);
1831 result = TRUE;
1832 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1833 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1834 ok(!result, "Unexpected result %d.\n", result);
1836 result = FALSE;
1837 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1838 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1839 ok(result, "Unexpected result %d.\n", result);
1841 result = FALSE;
1842 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1843 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1844 ok(result, "Unexpected result %d.\n", result);
1846 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1847 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1849 result = TRUE;
1850 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1851 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1852 ok(!result, "Unexpected result %d.\n", result);
1854 result = TRUE;
1855 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1856 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1857 ok(!result, "Unexpected result %d.\n", result);
1859 result = TRUE;
1860 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1861 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1862 ok(!result, "Unexpected result %d.\n", result);
1864 result = TRUE;
1865 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1866 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1867 ok(!result, "Unexpected result %d.\n", result);
1869 result = TRUE;
1870 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1871 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1872 ok(!result, "Unexpected result %d.\n", result);
1874 result = TRUE;
1875 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1876 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1877 ok(!result, "Unexpected result %d.\n", result);
1879 result = TRUE;
1880 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1881 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1882 ok(!result, "Unexpected result %d.\n", result);
1884 result = TRUE;
1885 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1886 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1887 ok(!result, "Unexpected result %d.\n", result);
1889 result = TRUE;
1890 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1891 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1892 ok(!result, "Unexpected result %d.\n", result);
1894 result = TRUE;
1895 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1896 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1897 ok(!result, "Unexpected result %d.\n", result);
1899 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1900 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1902 result = FALSE;
1903 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1904 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1905 ok(result, "Unexpected result %d.\n", result);
1907 result = FALSE;
1908 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1909 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1910 ok(result, "Unexpected result %d.\n", result);
1912 result = FALSE;
1913 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1914 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1915 ok(result, "Unexpected result %d.\n", result);
1917 result = FALSE;
1918 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1919 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1920 ok(result, "Unexpected result %d.\n", result);
1922 result = FALSE;
1923 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1924 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1925 ok(result, "Unexpected result %d.\n", result);
1927 result = FALSE;
1928 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1929 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1930 ok(result, "Unexpected result %d.\n", result);
1932 result = FALSE;
1933 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1934 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1935 ok(result, "Unexpected result %d.\n", result);
1937 result = FALSE;
1938 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1939 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1940 ok(result, "Unexpected result %d.\n", result);
1942 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1943 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1945 result = TRUE;
1946 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1947 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1948 ok(!result, "Unexpected result %d.\n", result);
1950 result = TRUE;
1951 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1952 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1953 ok(!result, "Unexpected result %d.\n", result);
1955 result = FALSE;
1956 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1957 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1958 ok(result, "Unexpected result %d.\n", result);
1960 result = FALSE;
1961 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1962 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1963 ok(result, "Unexpected result %d.\n", result);
1965 result = FALSE;
1966 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1967 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1968 ok(result, "Unexpected result %d.\n", result);
1970 result = TRUE;
1971 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1972 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1973 ok(!result, "Unexpected result %d.\n", result);
1975 result = FALSE;
1976 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1977 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1978 ok(result, "Unexpected result %d.\n", result);
1980 result = TRUE;
1981 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1982 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1983 ok(!result, "Unexpected result %d.\n", result);
1985 result = FALSE;
1986 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1987 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1988 ok(result, "Unexpected result %d.\n", result);
1990 result = FALSE;
1991 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1992 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1993 ok(result, "Unexpected result %d.\n", result);
1995 IMFAttributes_Release(attributes);
1996 IMFAttributes_Release(attributes1);
1999 static void test_MFCreateMFByteStreamOnStream(void)
2001 IMFByteStream *bytestream;
2002 IMFByteStream *bytestream2;
2003 IStream *stream;
2004 IMFAttributes *attributes = NULL;
2005 DWORD caps, written;
2006 IUnknown *unknown;
2007 ULONG ref, size;
2008 HRESULT hr;
2009 UINT count;
2010 QWORD to;
2012 if(!pMFCreateMFByteStreamOnStream)
2014 win_skip("MFCreateMFByteStreamOnStream() not found\n");
2015 return;
2018 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2019 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2021 caps = 0xffff0000;
2022 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
2023 ok(hr == S_OK, "Failed to write, hr %#lx.\n", hr);
2025 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
2026 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2028 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
2029 (void **)&unknown);
2030 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2031 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2032 ref = IUnknown_Release(unknown);
2033 ok(ref == 1, "got %lu\n", ref);
2035 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
2036 (void **)&bytestream2);
2037 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2038 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2039 ref = IMFByteStream_Release(bytestream2);
2040 ok(ref == 1, "got %lu\n", ref);
2042 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2043 (void **)&attributes);
2044 ok(hr == S_OK ||
2045 /* w7pro64 */
2046 broken(hr == E_NOINTERFACE), "Unexpected hr %#lx.\n", hr);
2048 if (hr != S_OK)
2050 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
2051 IStream_Release(stream);
2052 IMFByteStream_Release(bytestream);
2053 return;
2056 ok(attributes != NULL, "got NULL\n");
2057 hr = IMFAttributes_GetCount(attributes, &count);
2058 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2059 ok(count == 0, "Unexpected attributes count %u.\n", count);
2061 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
2062 (void **)&unknown);
2063 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2064 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2065 ref = IUnknown_Release(unknown);
2066 ok(ref == 2, "got %lu\n", ref);
2068 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
2069 (void **)&bytestream2);
2070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2071 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2072 ref = IMFByteStream_Release(bytestream2);
2073 ok(ref == 2, "got %lu\n", ref);
2075 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2076 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2077 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2078 check_interface(bytestream, &IID_IMFGetService, FALSE);
2080 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2081 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2082 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2084 hr = IMFByteStream_Close(bytestream);
2085 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2087 hr = IMFByteStream_Close(bytestream);
2088 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2090 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2091 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2092 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2094 /* IMFByteStream maintains position separately from IStream */
2095 caps = 0;
2096 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2097 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2098 ok(size == 4, "Unexpected size.\n");
2099 ok(caps == 0xffff0000, "Unexpected content.\n");
2101 caps = 0;
2102 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2103 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2104 ok(size == 4, "Unexpected size.\n");
2105 ok(caps == 0xffff0000, "Unexpected content.\n");
2107 caps = 0;
2108 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2109 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2110 ok(size == 0, "Unexpected size.\n");
2111 ok(caps == 0, "Unexpected content.\n");
2113 hr = IMFByteStream_Seek(bytestream, msoBegin, 0, 0, &to);
2114 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2116 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2117 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2118 ok(size == 0, "Unexpected size.\n");
2119 ok(caps == 0, "Unexpected content.\n");
2121 caps = 0;
2122 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2123 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2124 ok(size == 4, "Unexpected size.\n");
2125 ok(caps == 0xffff0000, "Unexpected content.\n");
2127 caps = 0;
2128 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2129 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2130 ok(size == 0, "Unexpected size.\n");
2131 ok(caps == 0, "Unexpected content.\n");
2133 IMFAttributes_Release(attributes);
2134 IMFByteStream_Release(bytestream);
2135 IStream_Release(stream);
2138 static void test_file_stream(void)
2140 static const WCHAR newfilename[] = L"new.mp4";
2141 IMFByteStream *bytestream, *bytestream2;
2142 QWORD bytestream_length, position;
2143 IMFAttributes *attributes = NULL;
2144 MF_ATTRIBUTE_TYPE item_type;
2145 WCHAR pathW[MAX_PATH];
2146 WCHAR *filename;
2147 HRESULT hr;
2148 WCHAR *str;
2149 DWORD caps;
2150 UINT count;
2151 BOOL eos;
2153 filename = load_resource(L"test.mp4");
2155 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2156 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2158 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2159 MF_FILEFLAGS_NONE, filename, &bytestream);
2160 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2162 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2163 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2164 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2165 check_interface(bytestream, &IID_IMFGetService, TRUE);
2167 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2168 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2169 if (is_win8_plus)
2171 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
2172 "Unexpected caps %#lx.\n", caps);
2174 else
2175 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2177 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2178 (void **)&attributes);
2179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2180 ok(attributes != NULL, "got NULL\n");
2182 hr = IMFAttributes_GetCount(attributes, &count);
2183 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2184 ok(count == 2, "Unexpected attributes count %u.\n", count);
2186 /* Original file name. */
2187 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
2188 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
2189 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
2190 CoTaskMemFree(str);
2192 /* Modification time. */
2193 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
2194 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
2195 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
2197 IMFAttributes_Release(attributes);
2199 /* Length. */
2200 hr = IMFByteStream_GetLength(bytestream, NULL);
2201 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2203 bytestream_length = 0;
2204 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
2205 ok(hr == S_OK, "Failed to get bytestream length, hr %#lx.\n", hr);
2206 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
2208 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
2209 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2211 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
2212 ok(hr == S_OK, "Failed query end of stream, hr %#lx.\n", hr);
2213 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
2215 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
2216 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2218 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
2219 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2221 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
2222 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2223 ok(position == 2 * bytestream_length, "Unexpected position.\n");
2225 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2226 MF_FILEFLAGS_NONE, filename, &bytestream2);
2227 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2228 IMFByteStream_Release(bytestream2);
2230 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2231 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2233 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2234 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2236 IMFByteStream_Release(bytestream);
2238 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2239 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2240 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
2242 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2243 MF_FILEFLAGS_NONE, filename, &bytestream);
2244 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "Unexpected hr %#lx.\n", hr);
2246 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2247 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2248 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2250 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2251 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2253 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2254 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2256 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2257 newfilename, &bytestream2);
2258 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2260 IMFByteStream_Release(bytestream);
2262 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2263 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
2264 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2266 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
2267 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2268 newfilename, &bytestream2);
2269 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2271 IMFByteStream_Release(bytestream);
2273 /* Explicit file: scheme */
2274 lstrcpyW(pathW, fileschemeW);
2275 lstrcatW(pathW, filename);
2276 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
2277 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2279 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream);
2280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2281 ok(DeleteFileW(filename), "failed to delete file\n");
2282 IMFByteStream_Release(bytestream);
2284 hr = MFShutdown();
2285 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2287 DeleteFileW(newfilename);
2290 static void test_system_memory_buffer(void)
2292 IMFMediaBuffer *buffer;
2293 HRESULT hr;
2294 DWORD length, max;
2295 BYTE *data, *data2;
2297 hr = MFCreateMemoryBuffer(1024, NULL);
2298 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2300 hr = MFCreateMemoryBuffer(0, &buffer);
2301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2302 if(buffer)
2304 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2305 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2306 ok(length == 0, "got %lu\n", length);
2308 IMFMediaBuffer_Release(buffer);
2311 hr = MFCreateMemoryBuffer(1024, &buffer);
2312 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2314 check_interface(buffer, &IID_IMFGetService, FALSE);
2316 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
2317 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2319 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2320 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2321 ok(length == 1024, "got %lu\n", length);
2323 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2324 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2326 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2327 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2329 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2330 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2332 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2333 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2334 ok(length == 10, "got %lu\n", length);
2336 length = 0;
2337 max = 0;
2338 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2339 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2340 ok(length == 0, "got %lu\n", length);
2341 ok(max == 0, "got %lu\n", length);
2343 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2344 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2345 ok(length == 10, "got %lu\n", length);
2346 ok(max == 1024, "got %lu\n", max);
2348 /* Attempt to lock the buffer twice */
2349 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2350 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2351 ok(data == data2, "Unexpected hr %#lx.\n", hr);
2353 hr = IMFMediaBuffer_Unlock(buffer);
2354 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2356 hr = IMFMediaBuffer_Unlock(buffer);
2357 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2359 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2360 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2362 hr = IMFMediaBuffer_Unlock(buffer);
2363 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2365 /* Extra Unlock */
2366 hr = IMFMediaBuffer_Unlock(buffer);
2367 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2369 IMFMediaBuffer_Release(buffer);
2372 static void test_system_memory_aligned_buffer(void)
2374 static const DWORD alignments[] =
2376 MF_16_BYTE_ALIGNMENT,
2377 MF_32_BYTE_ALIGNMENT,
2378 MF_64_BYTE_ALIGNMENT,
2379 MF_128_BYTE_ALIGNMENT,
2380 MF_256_BYTE_ALIGNMENT,
2381 MF_512_BYTE_ALIGNMENT,
2383 IMFMediaBuffer *buffer;
2384 DWORD length, max;
2385 unsigned int i;
2386 BYTE *data;
2387 HRESULT hr;
2389 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2390 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2392 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2393 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2395 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2396 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2397 ok(length == 0, "Unexpected current length %lu.\n", length);
2399 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2400 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2401 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2402 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2403 ok(length == 1, "Unexpected current length %lu.\n", length);
2405 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2406 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2407 ok(length == 201, "Unexpected max length %lu.\n", length);
2409 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2410 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2411 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2412 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2413 ok(length == 201, "Unexpected max length %lu.\n", length);
2414 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2415 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2417 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2418 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2419 ok(max == 201 && length == 10, "Unexpected length.\n");
2420 hr = IMFMediaBuffer_Unlock(buffer);
2421 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2423 IMFMediaBuffer_Release(buffer);
2425 for (i = 0; i < ARRAY_SIZE(alignments); ++i)
2427 hr = MFCreateAlignedMemoryBuffer(200, alignments[i], &buffer);
2428 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2430 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2431 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2432 ok(max == 200 && !length, "Unexpected length.\n");
2433 ok(!((uintptr_t)data & alignments[i]), "Data at %p is misaligned.\n", data);
2434 hr = IMFMediaBuffer_Unlock(buffer);
2435 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2437 IMFMediaBuffer_Release(buffer);
2440 hr = MFCreateAlignedMemoryBuffer(200, 0, &buffer);
2441 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2442 IMFMediaBuffer_Release(buffer);
2445 static void test_sample(void)
2447 static const DWORD test_pattern = 0x22222222;
2448 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2449 DWORD count, flags, length;
2450 IMFAttributes *attributes;
2451 IMFSample *sample;
2452 LONGLONG time;
2453 HRESULT hr;
2454 BYTE *data;
2456 hr = MFCreateSample( &sample );
2457 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2459 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2460 ok(hr == S_OK, "Failed to get attributes interface, hr %#lx.\n", hr);
2462 CHECK_ATTR_COUNT(attributes, 0);
2464 hr = IMFSample_GetBufferCount(sample, NULL);
2465 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2467 hr = IMFSample_GetBufferCount(sample, &count);
2468 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2469 ok(count == 0, "got %ld\n", count);
2471 hr = IMFSample_GetSampleFlags(sample, &flags);
2472 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2473 ok(!flags, "Unexpected flags %#lx.\n", flags);
2475 hr = IMFSample_SetSampleFlags(sample, 0x123);
2476 ok(hr == S_OK, "Failed to set sample flags, hr %#lx.\n", hr);
2477 hr = IMFSample_GetSampleFlags(sample, &flags);
2478 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2479 ok(flags == 0x123, "Unexpected flags %#lx.\n", flags);
2481 hr = IMFSample_GetSampleTime(sample, &time);
2482 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
2484 hr = IMFSample_GetSampleDuration(sample, &time);
2485 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
2487 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2488 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2490 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2491 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2493 hr = IMFSample_RemoveAllBuffers(sample);
2494 ok(hr == S_OK, "Failed to remove all, hr %#lx.\n", hr);
2496 hr = IMFSample_GetTotalLength(sample, &length);
2497 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2498 ok(!length, "Unexpected total length %lu.\n", length);
2500 hr = MFCreateMemoryBuffer(16, &buffer);
2501 ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr);
2503 hr = IMFSample_AddBuffer(sample, buffer);
2504 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2506 hr = IMFSample_AddBuffer(sample, buffer);
2507 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2509 hr = IMFSample_GetBufferCount(sample, &count);
2510 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2511 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2513 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2514 ok(hr == S_OK, "Failed to get buffer, hr %#lx.\n", hr);
2515 ok(buffer2 == buffer, "Unexpected object.\n");
2516 IMFMediaBuffer_Release(buffer2);
2518 hr = IMFSample_GetTotalLength(sample, &length);
2519 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2520 ok(!length, "Unexpected total length %lu.\n", length);
2522 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2523 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2525 hr = IMFSample_GetTotalLength(sample, &length);
2526 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2527 ok(length == 4, "Unexpected total length %lu.\n", length);
2529 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2530 ok(hr == S_OK, "Failed to remove buffer, hr %#lx.\n", hr);
2532 hr = IMFSample_GetTotalLength(sample, &length);
2533 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2534 ok(length == 2, "Unexpected total length %lu.\n", length);
2536 IMFMediaBuffer_Release(buffer);
2538 /* Duration */
2539 hr = IMFSample_SetSampleDuration(sample, 10);
2540 ok(hr == S_OK, "Failed to set duration, hr %#lx.\n", hr);
2541 CHECK_ATTR_COUNT(attributes, 0);
2542 hr = IMFSample_GetSampleDuration(sample, &time);
2543 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
2544 ok(time == 10, "Unexpected duration.\n");
2546 /* Timestamp */
2547 hr = IMFSample_SetSampleTime(sample, 1);
2548 ok(hr == S_OK, "Failed to set timestamp, hr %#lx.\n", hr);
2549 CHECK_ATTR_COUNT(attributes, 0);
2550 hr = IMFSample_GetSampleTime(sample, &time);
2551 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
2552 ok(time == 1, "Unexpected timestamp.\n");
2554 IMFAttributes_Release(attributes);
2555 IMFSample_Release(sample);
2557 /* CopyToBuffer() */
2558 hr = MFCreateSample(&sample);
2559 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2561 hr = MFCreateMemoryBuffer(16, &buffer2);
2562 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2564 /* Sample with no buffers. */
2565 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2566 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2567 hr = IMFSample_CopyToBuffer(sample, buffer2);
2568 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2569 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2570 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2571 ok(!length, "Unexpected length %lu.\n", length);
2573 /* Single buffer, larger destination. */
2574 hr = MFCreateMemoryBuffer(8, &buffer);
2575 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2577 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2578 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2579 *(DWORD *)data = 0x11111111;
2580 hr = IMFMediaBuffer_Unlock(buffer);
2581 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2582 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2583 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2585 hr = IMFSample_AddBuffer(sample, buffer);
2586 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2588 /* Existing content is overwritten. */
2589 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2590 ok(hr == S_OK, "Failed to set length, hr %#lx.\n", hr);
2592 hr = IMFSample_CopyToBuffer(sample, buffer2);
2593 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2595 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2596 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2597 ok(length == 4, "Unexpected buffer length %lu.\n", length);
2599 /* Multiple buffers, matching total size. */
2600 hr = IMFSample_AddBuffer(sample, buffer);
2601 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2603 hr = IMFSample_GetBufferCount(sample, &count);
2604 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2605 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2607 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2608 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2610 hr = IMFSample_CopyToBuffer(sample, buffer2);
2611 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2613 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2614 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2615 ok(length == 16, "Unexpected buffer length %lu.\n", length);
2617 hr = IMFSample_AddBuffer(sample, buffer);
2618 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2620 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2621 ok(hr == S_OK, "Failed to set buffer length, hr %#lx.\n", hr);
2623 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2624 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2625 *(DWORD *)data = test_pattern;
2626 hr = IMFMediaBuffer_Unlock(buffer2);
2627 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2629 hr = IMFSample_CopyToBuffer(sample, buffer2);
2630 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
2632 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2633 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2634 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#lx\n", *(DWORD *)data);
2635 hr = IMFMediaBuffer_Unlock(buffer2);
2636 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2638 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2639 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2640 ok(!length, "Unexpected buffer length %lu.\n", length);
2642 IMFMediaBuffer_Release(buffer2);
2643 IMFSample_Release(sample);
2645 /* ConvertToContiguousBuffer() */
2646 hr = MFCreateSample(&sample);
2647 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2649 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2650 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2652 hr = MFCreateMemoryBuffer(16, &buffer);
2653 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2655 hr = IMFSample_AddBuffer(sample, buffer);
2656 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2658 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2659 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2660 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2661 IMFMediaBuffer_Release(buffer2);
2663 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2664 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2666 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2667 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2668 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2669 IMFMediaBuffer_Release(buffer2);
2671 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2674 hr = MFCreateMemoryBuffer(16, &buffer2);
2675 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2677 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2678 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2680 hr = IMFSample_AddBuffer(sample, buffer2);
2681 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2682 IMFMediaBuffer_Release(buffer2);
2684 hr = IMFSample_GetBufferCount(sample, &count);
2685 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2686 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2688 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2689 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2691 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2692 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2693 ok(length == 7, "Unexpected length %lu.\n", length);
2695 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2696 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2697 ok(length == 7, "Unexpected length %lu.\n", length);
2699 IMFMediaBuffer_Release(buffer3);
2701 hr = IMFSample_GetBufferCount(sample, &count);
2702 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2703 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2705 hr = IMFSample_AddBuffer(sample, buffer);
2706 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2708 hr = IMFSample_GetBufferCount(sample, &count);
2709 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2710 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2712 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2713 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2715 hr = IMFSample_GetBufferCount(sample, &count);
2716 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2717 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2719 IMFMediaBuffer_Release(buffer);
2721 IMFSample_Release(sample);
2724 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2726 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2727 IMFMediaEventQueue *queue;
2728 IUnknown *state, *obj;
2729 HRESULT hr;
2731 ok(result != NULL, "Unexpected result object.\n");
2733 state = IMFAsyncResult_GetStateNoAddRef(result);
2734 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2736 IMFMediaEvent *event = NULL, *event2;
2738 if (is_win8_plus)
2740 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2741 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2743 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2744 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2746 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2747 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#lx.\n", hr);
2749 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2750 ok(hr == E_FAIL, "Unexpected result, hr %#lx.\n", hr);
2752 if (event)
2753 IMFMediaEvent_Release(event);
2756 hr = IMFAsyncResult_GetObject(result, &obj);
2757 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2759 IMFMediaEventQueue_Release(queue);
2761 SetEvent(callback->event);
2764 return E_NOTIMPL;
2767 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2769 testcallback_QueryInterface,
2770 testcallback_AddRef,
2771 testcallback_Release,
2772 testcallback_GetParameters,
2773 testcallback_Invoke,
2776 static void test_MFCreateAsyncResult(void)
2778 IMFAsyncResult *result, *result2;
2779 struct test_callback *callback;
2780 IUnknown *state, *object;
2781 MFASYNCRESULT *data;
2782 ULONG refcount;
2783 HANDLE event;
2784 DWORD flags;
2785 HRESULT hr;
2786 BOOL ret;
2788 callback = create_test_callback(NULL);
2790 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2791 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2793 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2794 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2796 data = (MFASYNCRESULT *)result;
2797 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2798 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2799 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2800 ok(data->hEvent == NULL, "Unexpected event.\n");
2802 hr = IMFAsyncResult_GetState(result, NULL);
2803 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2805 state = (void *)0xdeadbeef;
2806 hr = IMFAsyncResult_GetState(result, &state);
2807 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2808 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2810 hr = IMFAsyncResult_GetStatus(result);
2811 ok(hr == S_OK, "Unexpected status %#lx.\n", hr);
2813 data->hrStatusResult = 123;
2814 hr = IMFAsyncResult_GetStatus(result);
2815 ok(hr == 123, "Unexpected status %#lx.\n", hr);
2817 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2818 ok(hr == S_OK, "Failed to set status, hr %#lx.\n", hr);
2819 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#lx.\n", hr);
2821 hr = IMFAsyncResult_GetObject(result, NULL);
2822 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2824 object = (void *)0xdeadbeef;
2825 hr = IMFAsyncResult_GetObject(result, &object);
2826 ok(hr == E_POINTER, "Failed to get object, hr %#lx.\n", hr);
2827 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2829 state = IMFAsyncResult_GetStateNoAddRef(result);
2830 ok(state == NULL, "Unexpected state.\n");
2832 /* Object. */
2833 hr = MFCreateAsyncResult((IUnknown *)result, &callback->IMFAsyncCallback_iface, NULL, &result2);
2834 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2836 data = (MFASYNCRESULT *)result2;
2837 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2838 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2839 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2840 ok(data->hEvent == NULL, "Unexpected event.\n");
2842 object = NULL;
2843 hr = IMFAsyncResult_GetObject(result2, &object);
2844 ok(hr == S_OK, "Failed to get object, hr %#lx.\n", hr);
2845 ok(object == (IUnknown *)result, "Unexpected object.\n");
2846 IUnknown_Release(object);
2848 IMFAsyncResult_Release(result2);
2850 /* State object. */
2851 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2852 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2854 data = (MFASYNCRESULT *)result2;
2855 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2856 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2857 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2858 ok(data->hEvent == NULL, "Unexpected event.\n");
2860 state = NULL;
2861 hr = IMFAsyncResult_GetState(result2, &state);
2862 ok(hr == S_OK, "Failed to get state object, hr %#lx.\n", hr);
2863 ok(state == (IUnknown *)result, "Unexpected state.\n");
2864 IUnknown_Release(state);
2866 state = IMFAsyncResult_GetStateNoAddRef(result2);
2867 ok(state == (IUnknown *)result, "Unexpected state.\n");
2869 refcount = IMFAsyncResult_Release(result2);
2870 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2871 refcount = IMFAsyncResult_Release(result);
2872 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2874 /* Event handle is closed on release. */
2875 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2876 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2878 data = (MFASYNCRESULT *)result;
2879 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2880 ok(data->hEvent != NULL, "Failed to create event.\n");
2881 ret = GetHandleInformation(event, &flags);
2882 ok(ret, "Failed to get handle info.\n");
2884 refcount = IMFAsyncResult_Release(result);
2885 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2886 ret = GetHandleInformation(event, &flags);
2887 ok(!ret, "Expected handle to be closed.\n");
2889 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
2890 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2892 data = (MFASYNCRESULT *)result;
2893 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2894 ok(data->hEvent != NULL, "Failed to create event.\n");
2895 ret = GetHandleInformation(event, &flags);
2896 ok(ret, "Failed to get handle info.\n");
2898 refcount = IMFAsyncResult_Release(result);
2899 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2900 ret = GetHandleInformation(event, &flags);
2901 ok(!ret, "Expected handle to be closed.\n");
2903 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
2906 static void test_startup(void)
2908 DWORD queue;
2909 HRESULT hr;
2911 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2912 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#lx.\n", hr);
2914 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2915 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2917 hr = MFAllocateWorkQueue(&queue);
2918 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2919 hr = MFUnlockWorkQueue(queue);
2920 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2922 hr = MFShutdown();
2923 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2925 hr = MFAllocateWorkQueue(&queue);
2926 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2928 /* Already shut down, has no effect. */
2929 hr = MFShutdown();
2930 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2932 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2933 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2935 hr = MFAllocateWorkQueue(&queue);
2936 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2937 hr = MFUnlockWorkQueue(queue);
2938 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2940 hr = MFShutdown();
2941 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2943 /* Platform lock. */
2944 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2945 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2947 hr = MFAllocateWorkQueue(&queue);
2948 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2949 hr = MFUnlockWorkQueue(queue);
2950 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2952 /* Unlocking implies shutdown. */
2953 hr = MFUnlockPlatform();
2954 ok(hr == S_OK, "Failed to unlock, %#lx.\n", hr);
2956 hr = MFAllocateWorkQueue(&queue);
2957 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2959 hr = MFLockPlatform();
2960 ok(hr == S_OK, "Failed to lock, %#lx.\n", hr);
2962 hr = MFAllocateWorkQueue(&queue);
2963 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2964 hr = MFUnlockWorkQueue(queue);
2965 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2967 hr = MFShutdown();
2968 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2971 static void test_allocate_queue(void)
2973 DWORD queue, queue2;
2974 HRESULT hr;
2976 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2977 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2979 hr = MFAllocateWorkQueue(&queue);
2980 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2981 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2983 hr = MFUnlockWorkQueue(queue);
2984 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2986 hr = MFUnlockWorkQueue(queue);
2987 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2989 hr = MFAllocateWorkQueue(&queue2);
2990 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2991 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2993 hr = MFUnlockWorkQueue(queue2);
2994 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2996 /* Unlock in system queue range. */
2997 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2998 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3000 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
3001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3003 hr = MFUnlockWorkQueue(0x20);
3004 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3006 hr = MFShutdown();
3007 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3010 static void test_MFCopyImage(void)
3012 BYTE dest[16], src[16];
3013 HRESULT hr;
3015 if (!pMFCopyImage)
3017 win_skip("MFCopyImage() is not available.\n");
3018 return;
3021 memset(dest, 0xaa, sizeof(dest));
3022 memset(src, 0x11, sizeof(src));
3024 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
3025 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3026 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
3028 memset(dest, 0xaa, sizeof(dest));
3029 memset(src, 0x11, sizeof(src));
3031 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
3032 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3033 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3035 memset(dest, 0xaa, sizeof(dest));
3036 memset(src, 0x11, sizeof(src));
3038 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
3039 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3040 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3043 static void test_MFCreateCollection(void)
3045 IMFCollection *collection;
3046 IUnknown *element;
3047 DWORD count;
3048 HRESULT hr;
3050 hr = MFCreateCollection(NULL);
3051 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3053 hr = MFCreateCollection(&collection);
3054 ok(hr == S_OK, "Failed to create collection, hr %#lx.\n", hr);
3056 hr = IMFCollection_GetElementCount(collection, NULL);
3057 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3059 count = 1;
3060 hr = IMFCollection_GetElementCount(collection, &count);
3061 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3062 ok(count == 0, "Unexpected count %lu.\n", count);
3064 hr = IMFCollection_GetElement(collection, 0, NULL);
3065 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3067 element = (void *)0xdeadbeef;
3068 hr = IMFCollection_GetElement(collection, 0, &element);
3069 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3070 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3072 hr = IMFCollection_RemoveElement(collection, 0, NULL);
3073 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3075 element = (void *)0xdeadbeef;
3076 hr = IMFCollection_RemoveElement(collection, 0, &element);
3077 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#lx.\n", hr);
3078 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3080 hr = IMFCollection_RemoveAllElements(collection);
3081 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3083 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
3084 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3086 count = 0;
3087 hr = IMFCollection_GetElementCount(collection, &count);
3088 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3089 ok(count == 1, "Unexpected count %lu.\n", count);
3091 hr = IMFCollection_AddElement(collection, NULL);
3092 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3094 count = 0;
3095 hr = IMFCollection_GetElementCount(collection, &count);
3096 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3097 ok(count == 2, "Unexpected count %lu.\n", count);
3099 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
3100 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3102 count = 0;
3103 hr = IMFCollection_GetElementCount(collection, &count);
3104 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3105 ok(count == 11, "Unexpected count %lu.\n", count);
3107 hr = IMFCollection_GetElement(collection, 0, &element);
3108 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3109 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3110 IUnknown_Release(element);
3112 hr = IMFCollection_GetElement(collection, 1, &element);
3113 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3114 ok(!element, "Unexpected element.\n");
3116 hr = IMFCollection_GetElement(collection, 2, &element);
3117 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3118 ok(!element, "Unexpected element.\n");
3120 hr = IMFCollection_GetElement(collection, 10, &element);
3121 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3122 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3123 IUnknown_Release(element);
3125 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3126 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3128 hr = IMFCollection_GetElement(collection, 0, &element);
3129 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3131 hr = IMFCollection_RemoveAllElements(collection);
3132 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3134 count = 1;
3135 hr = IMFCollection_GetElementCount(collection, &count);
3136 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3137 ok(count == 0, "Unexpected count %lu.\n", count);
3139 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3140 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3142 IMFCollection_Release(collection);
3145 static void test_MFHeapAlloc(void)
3147 void *res;
3149 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
3150 ok(res != NULL, "MFHeapAlloc failed.\n");
3152 MFHeapFree(res);
3155 static void test_scheduled_items(void)
3157 struct test_callback *callback;
3158 IMFAsyncResult *result;
3159 MFWORKITEM_KEY key, key2;
3160 HRESULT hr;
3162 callback = create_test_callback(NULL);
3164 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3165 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3167 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3168 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3170 hr = MFCancelWorkItem(key);
3171 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3173 hr = MFCancelWorkItem(key);
3174 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#lx.\n", hr);
3176 if (!pMFPutWaitingWorkItem)
3178 win_skip("Waiting items are not supported.\n");
3179 return;
3182 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3183 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3185 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
3186 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3188 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
3189 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3191 hr = MFCancelWorkItem(key);
3192 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3194 hr = MFCancelWorkItem(key2);
3195 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3197 IMFAsyncResult_Release(result);
3199 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3200 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3202 hr = MFCancelWorkItem(key);
3203 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3205 hr = MFShutdown();
3206 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3208 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3211 static void test_serial_queue(void)
3213 static const DWORD queue_ids[] =
3215 MFASYNC_CALLBACK_QUEUE_STANDARD,
3216 MFASYNC_CALLBACK_QUEUE_RT,
3217 MFASYNC_CALLBACK_QUEUE_IO,
3218 MFASYNC_CALLBACK_QUEUE_TIMER,
3219 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
3220 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
3222 DWORD queue, serial_queue;
3223 unsigned int i;
3224 HRESULT hr;
3226 if (!pMFAllocateSerialWorkQueue)
3228 win_skip("Serial queues are not supported.\n");
3229 return;
3232 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3233 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3235 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
3237 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
3238 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
3240 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
3241 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
3242 "%u: failed to allocate a queue, hr %#lx.\n", i, hr);
3244 if (SUCCEEDED(hr))
3246 hr = MFUnlockWorkQueue(serial_queue);
3247 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#lx.\n", i, hr);
3251 /* Chain them together. */
3252 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
3253 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3255 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
3256 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3258 hr = MFUnlockWorkQueue(serial_queue);
3259 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3261 hr = MFUnlockWorkQueue(queue);
3262 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3264 hr = MFShutdown();
3265 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3268 static LONG periodic_counter;
3269 static void CALLBACK periodic_callback(IUnknown *context)
3271 InterlockedIncrement(&periodic_counter);
3274 static void test_periodic_callback(void)
3276 DWORD period, key;
3277 HRESULT hr;
3279 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3280 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3282 period = 0;
3283 hr = MFGetTimerPeriodicity(&period);
3284 ok(hr == S_OK, "Failed to get timer perdiod, hr %#lx.\n", hr);
3285 ok(period == 10, "Unexpected period %lu.\n", period);
3287 if (!pMFAddPeriodicCallback)
3289 win_skip("Periodic callbacks are not supported.\n");
3290 hr = MFShutdown();
3291 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3292 return;
3295 ok(periodic_counter == 0, "Unexpected counter value %lu.\n", periodic_counter);
3297 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
3298 ok(hr == S_OK, "Failed to add periodic callback, hr %#lx.\n", hr);
3299 ok(key != 0, "Unexpected key %#lx.\n", key);
3301 Sleep(10 * period);
3303 hr = pMFRemovePeriodicCallback(key);
3304 ok(hr == S_OK, "Failed to remove callback, hr %#lx.\n", hr);
3306 ok(periodic_counter > 0, "Unexpected counter value %lu.\n", periodic_counter);
3308 hr = MFShutdown();
3309 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3312 static void test_event_queue(void)
3314 struct test_callback *callback, *callback2;
3315 IMFMediaEvent *event, *event2;
3316 IMFMediaEventQueue *queue;
3317 IMFAsyncResult *result;
3318 HRESULT hr;
3319 DWORD ret;
3321 callback = create_test_callback(NULL);
3322 callback2 = create_test_callback(NULL);
3324 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3325 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3327 hr = MFCreateEventQueue(&queue);
3328 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3330 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3331 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
3333 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3334 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3336 if (is_win8_plus)
3338 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3339 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3341 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3342 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3343 ok(event2 == event, "Unexpected event object.\n");
3344 IMFMediaEvent_Release(event2);
3346 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3347 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3349 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3350 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3351 IMFMediaEvent_Release(event2);
3354 /* Async case. */
3355 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3356 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3358 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3359 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3361 /* Same callback, same state. */
3362 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3363 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3365 /* Same callback, different state. */
3366 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3367 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3369 /* Different callback, same state. */
3370 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)queue);
3371 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3373 /* Different callback, different state. */
3374 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3375 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3377 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
3379 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3380 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3382 ret = WaitForSingleObject(callback->event, 500);
3383 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#lx.\n", ret);
3385 CloseHandle(callback->event);
3387 IMFMediaEvent_Release(event);
3389 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3390 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3392 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3393 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3395 /* Shutdown behavior. */
3396 hr = IMFMediaEventQueue_Shutdown(queue);
3397 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3399 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3400 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3402 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3403 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3404 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3405 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3406 IMFMediaEvent_Release(event);
3408 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3409 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3411 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3412 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3414 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3415 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3417 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3418 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3420 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3421 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3422 IMFAsyncResult_Release(result);
3424 /* Already shut down. */
3425 hr = IMFMediaEventQueue_Shutdown(queue);
3426 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3428 IMFMediaEventQueue_Release(queue);
3429 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3431 /* Release while subscribed. */
3432 callback = create_test_callback(NULL);
3434 hr = MFCreateEventQueue(&queue);
3435 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3437 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3438 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3439 EXPECT_REF(&callback->IMFAsyncCallback_iface, 2);
3441 IMFMediaEventQueue_Release(queue);
3442 ret = get_refcount(&callback->IMFAsyncCallback_iface);
3443 ok(ret == 1 || broken(ret == 2) /* Vista */,
3444 "Unexpected refcount %ld, expected 1.\n", ret);
3445 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3447 hr = MFShutdown();
3448 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3451 static void test_presentation_descriptor(void)
3453 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3454 IMFPresentationDescriptor *pd, *pd2;
3455 IMFMediaType *media_type;
3456 unsigned int i;
3457 BOOL selected;
3458 UINT64 value;
3459 DWORD count;
3460 HRESULT hr;
3462 hr = MFCreateMediaType(&media_type);
3463 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
3465 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3467 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3468 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3471 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3472 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr);
3474 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3475 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %lu.\n", count);
3477 for (i = 0; i < count; ++i)
3479 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3480 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3481 ok(!selected, "Unexpected selected state.\n");
3482 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3483 IMFStreamDescriptor_Release(stream_desc2);
3486 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3487 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3489 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3490 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3492 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3493 ok(hr == S_OK, "Failed to select a stream, hr %#lx.\n", hr);
3495 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3496 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3497 ok(!!selected, "Unexpected selected state.\n");
3498 IMFStreamDescriptor_Release(stream_desc2);
3500 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3501 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
3503 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3504 ok(hr == S_OK, "Failed to clone, hr %#lx.\n", hr);
3506 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3507 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3508 ok(!!selected, "Unexpected selected state.\n");
3509 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3510 IMFStreamDescriptor_Release(stream_desc2);
3512 value = 0;
3513 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3514 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
3515 ok(value == 1, "Unexpected attribute value.\n");
3517 IMFPresentationDescriptor_Release(pd2);
3518 IMFPresentationDescriptor_Release(pd);
3520 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3522 IMFStreamDescriptor_Release(stream_desc[i]);
3525 /* Partially initialized array. */
3526 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3527 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3528 stream_desc[0] = NULL;
3530 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3531 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3533 IMFStreamDescriptor_Release(stream_desc[1]);
3534 IMFMediaType_Release(media_type);
3537 enum clock_action
3539 CLOCK_START,
3540 CLOCK_STOP,
3541 CLOCK_PAUSE,
3542 CLOCK_RESTART,
3545 static void test_system_time_source(void)
3547 static const struct clock_state_test
3549 enum clock_action action;
3550 MFCLOCK_STATE state;
3551 BOOL is_invalid;
3553 clock_state_change[] =
3555 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3556 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3557 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3558 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3559 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3560 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3561 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3562 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3563 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3564 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3565 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3566 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3567 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3568 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3569 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3570 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3571 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3573 IMFPresentationTimeSource *time_source, *time_source2;
3574 IMFClockStateSink *statesink;
3575 IMFClock *clock, *clock2;
3576 MFCLOCK_PROPERTIES props;
3577 MFCLOCK_STATE state;
3578 unsigned int i;
3579 MFTIME systime;
3580 LONGLONG time;
3581 DWORD value;
3582 HRESULT hr;
3584 hr = MFCreateSystemTimeSource(&time_source);
3585 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3587 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3588 ok(hr == S_OK, "Failed to get flags, hr %#lx.\n", hr);
3589 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3590 "Unexpected flags %#lx.\n", value);
3592 value = 1;
3593 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3594 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3595 ok(value == 0, "Unexpected value %lu.\n", value);
3597 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3598 ok(hr == S_OK, "Failed to get state, hr %#lx.\n", hr);
3599 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3601 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3602 ok(hr == S_OK, "Failed to get state sink, hr %#lx.\n", hr);
3604 /* State changes. */
3605 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3607 switch (clock_state_change[i].action)
3609 case CLOCK_STOP:
3610 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3611 break;
3612 case CLOCK_RESTART:
3613 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3614 break;
3615 case CLOCK_PAUSE:
3616 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3617 break;
3618 case CLOCK_START:
3619 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3620 break;
3621 default:
3624 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#lx.\n", i, hr);
3625 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3626 ok(hr == S_OK, "%u: failed to get state, hr %#lx.\n", i, hr);
3627 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3630 IMFClockStateSink_Release(statesink);
3632 /* Properties. */
3633 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3634 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3636 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3637 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3639 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3640 wine_dbgstr_longlong(props.qwCorrelationRate));
3641 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3642 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3643 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3644 wine_dbgstr_longlong(props.qwClockFrequency));
3645 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3646 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3648 /* Underlying clock. */
3649 hr = MFCreateSystemTimeSource(&time_source2);
3650 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3651 EXPECT_REF(time_source2, 1);
3652 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3653 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3654 EXPECT_REF(time_source2, 1);
3655 EXPECT_REF(clock2, 2);
3657 EXPECT_REF(time_source, 1);
3658 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3659 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3660 EXPECT_REF(time_source, 1);
3661 EXPECT_REF(clock, 2);
3663 ok(clock != clock2, "Unexpected clock instance.\n");
3665 IMFPresentationTimeSource_Release(time_source2);
3666 IMFClock_Release(clock2);
3668 hr = IMFClock_GetClockCharacteristics(clock, &value);
3669 ok(hr == S_OK, "Failed to get clock flags, hr %#lx.\n", hr);
3670 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3671 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#lx.\n", value);
3673 hr = IMFClock_GetContinuityKey(clock, &value);
3674 ok(hr == S_OK, "Failed to get clock key, hr %#lx.\n", hr);
3675 ok(value == 0, "Unexpected key value %lu.\n", value);
3677 hr = IMFClock_GetState(clock, 0, &state);
3678 ok(hr == S_OK, "Failed to get clock state, hr %#lx.\n", hr);
3679 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3681 hr = IMFClock_GetProperties(clock, &props);
3682 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3684 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3685 wine_dbgstr_longlong(props.qwCorrelationRate));
3686 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3687 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3688 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3689 wine_dbgstr_longlong(props.qwClockFrequency));
3690 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3691 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3693 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3694 ok(hr == S_OK, "Failed to get clock time, hr %#lx.\n", hr);
3695 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3697 IMFClock_Release(clock);
3699 /* Test returned time regarding specified rate and offset. */
3700 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3701 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3703 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3704 ok(hr == S_OK, "Failed to get state %#lx.\n", hr);
3705 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3707 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3708 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3709 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3711 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3712 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3714 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3715 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3716 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3718 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3719 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3721 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3722 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3723 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3724 wine_dbgstr_longlong(systime));
3726 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3727 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3729 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3730 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3731 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3733 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3734 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3736 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3737 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3738 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3739 wine_dbgstr_longlong(systime));
3741 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3742 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3744 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3745 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3746 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3747 wine_dbgstr_longlong(systime));
3749 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3750 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3752 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3753 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3754 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3756 /* Increased rate. */
3757 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3758 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3760 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3761 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3763 hr = IMFClockStateSink_OnClockSetRate(statesink, 5, 2.0f);
3764 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3766 hr = IMFClockStateSink_OnClockPause(statesink, 6);
3767 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3769 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3770 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3771 ok(time == 12 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3772 wine_dbgstr_longlong(systime));
3774 hr = IMFClockStateSink_OnClockRestart(statesink, 7);
3775 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3777 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3778 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3780 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3781 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3782 ok(time == 14 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3783 wine_dbgstr_longlong(systime));
3785 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3786 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3788 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3789 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3790 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3791 wine_dbgstr_longlong(2 * systime));
3793 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3794 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3796 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3797 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3798 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3799 wine_dbgstr_longlong(2 * systime));
3801 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3802 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3804 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3805 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3806 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3807 wine_dbgstr_longlong(systime));
3809 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3810 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3812 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3813 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3814 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3815 wine_dbgstr_longlong(systime));
3817 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3818 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3820 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3821 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3822 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3823 wine_dbgstr_longlong(systime));
3825 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3826 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3828 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3829 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3830 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3832 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3833 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3835 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3836 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3837 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3838 wine_dbgstr_longlong(2 * systime));
3840 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3841 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3843 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3844 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3846 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3847 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3848 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3849 wine_dbgstr_longlong(2 * systime));
3851 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3852 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3854 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3855 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3856 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3857 wine_dbgstr_longlong(systime));
3859 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3860 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3862 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3863 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3864 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3865 wine_dbgstr_longlong(systime));
3867 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3868 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3870 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3871 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3872 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3873 wine_dbgstr_longlong(systime));
3875 IMFClockStateSink_Release(statesink);
3876 IMFPresentationTimeSource_Release(time_source);
3878 /* PRESENTATION_CURRENT_POSITION */
3879 hr = MFCreateSystemTimeSource(&time_source);
3880 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3882 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3883 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3885 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3886 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3887 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3888 wine_dbgstr_longlong(systime));
3890 /* INVALID -> RUNNING */
3891 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
3892 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3894 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3895 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3896 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3897 wine_dbgstr_longlong(systime));
3899 /* RUNNING -> RUNNING */
3900 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
3901 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3903 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3904 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3905 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3906 wine_dbgstr_longlong(systime));
3908 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
3909 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3911 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3912 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3913 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3914 wine_dbgstr_longlong(systime));
3916 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3917 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3919 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3920 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3921 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3922 wine_dbgstr_longlong(systime));
3924 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3925 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3927 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3928 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3929 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3930 wine_dbgstr_longlong(systime));
3932 /* STOPPED -> RUNNING */
3933 hr = IMFClockStateSink_OnClockStop(statesink, 567);
3934 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3936 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3937 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3938 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3939 wine_dbgstr_longlong(systime));
3941 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3942 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3944 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3945 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3946 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3947 wine_dbgstr_longlong(systime));
3949 /* PAUSED -> RUNNING */
3950 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3951 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3953 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3954 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3955 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3956 wine_dbgstr_longlong(systime));
3958 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
3959 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3961 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3962 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3963 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3964 wine_dbgstr_longlong(systime));
3966 hr = IMFClockStateSink_OnClockPause(statesink, 7);
3967 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3969 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3970 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3971 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3972 wine_dbgstr_longlong(systime));
3974 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
3975 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3977 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3978 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3979 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3980 wine_dbgstr_longlong(systime));
3982 IMFClockStateSink_Release(statesink);
3983 IMFPresentationTimeSource_Release(time_source);
3986 static void test_MFInvokeCallback(void)
3988 struct test_callback *callback;
3989 IMFAsyncResult *result;
3990 MFASYNCRESULT *data;
3991 ULONG refcount;
3992 HRESULT hr;
3993 DWORD ret;
3995 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3996 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3998 callback = create_test_callback(NULL);
4000 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
4001 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4003 data = (MFASYNCRESULT *)result;
4004 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
4005 ok(data->hEvent != NULL, "Failed to create event.\n");
4007 hr = MFInvokeCallback(result);
4008 ok(hr == S_OK, "Failed to invoke, hr %#lx.\n", hr);
4010 ret = WaitForSingleObject(data->hEvent, 100);
4011 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#lx.\n", ret);
4013 refcount = IMFAsyncResult_Release(result);
4014 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
4016 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4018 hr = MFShutdown();
4019 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4022 static void test_stream_descriptor(void)
4024 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
4025 IMFMediaTypeHandler *type_handler;
4026 IMFStreamDescriptor *stream_desc;
4027 GUID major_type;
4028 DWORD id, count;
4029 unsigned int i;
4030 HRESULT hr;
4032 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
4033 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4035 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4037 hr = MFCreateMediaType(&media_types[i]);
4038 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4041 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
4042 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4044 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4045 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4047 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
4048 ok(hr == S_OK, "Failed to get descriptor id, hr %#lx.\n", hr);
4049 ok(id == 123, "Unexpected id %#lx.\n", id);
4051 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4052 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4054 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4055 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4056 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4058 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
4059 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
4061 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4062 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4064 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4066 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
4067 ok(hr == S_OK, "Failed to get media type, hr %#lx.\n", hr);
4068 ok(media_type == media_types[i], "Unexpected object.\n");
4070 if (SUCCEEDED(hr))
4071 IMFMediaType_Release(media_type);
4074 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
4075 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#lx.\n", hr);
4077 /* IsMediaTypeSupported() */
4079 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
4080 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4082 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
4083 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4085 hr = MFCreateMediaType(&media_type);
4086 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4088 hr = MFCreateMediaType(&media_type3);
4089 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4091 media_type2 = (void *)0xdeadbeef;
4092 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4093 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4094 ok(!media_type2, "Unexpected pointer.\n");
4096 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
4097 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4099 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
4100 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4102 media_type2 = (void *)0xdeadbeef;
4103 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4104 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4105 ok(!media_type2, "Unexpected pointer.\n");
4107 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4108 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4110 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4111 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4113 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4114 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4115 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
4117 /* Mismatching major types. */
4118 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4119 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4121 media_type2 = (void *)0xdeadbeef;
4122 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4123 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4124 ok(!media_type2, "Unexpected pointer.\n");
4126 /* Subtype missing. */
4127 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4128 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4130 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4131 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4133 media_type2 = (void *)0xdeadbeef;
4134 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4135 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4136 ok(!media_type2, "Unexpected pointer.\n");
4138 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4139 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4141 media_type2 = (void *)0xdeadbeef;
4142 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4143 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4144 ok(!media_type2, "Unexpected pointer.\n");
4146 /* Mismatching subtype. */
4147 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4148 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4150 media_type2 = (void *)0xdeadbeef;
4151 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4152 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4153 ok(!media_type2, "Unexpected pointer.\n");
4155 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4156 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4157 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4159 IMFMediaTypeHandler_Release(type_handler);
4160 IMFStreamDescriptor_Release(stream_desc);
4162 /* IsMediaTypeSupported() for unset current type. */
4163 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4166 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4167 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4169 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
4170 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4172 /* Initialize one from initial type set. */
4173 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
4174 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4176 media_type2 = (void *)0xdeadbeef;
4177 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4179 ok(!media_type2, "Unexpected pointer.\n");
4181 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4182 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4184 media_type2 = (void *)0xdeadbeef;
4185 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4186 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4187 ok(!media_type2, "Unexpected pointer.\n");
4189 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4190 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4192 media_type2 = (void *)0xdeadbeef;
4193 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4194 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4195 ok(!media_type2, "Unexpected pointer.\n");
4197 /* Now set current type that's not compatible. */
4198 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4199 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4201 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4202 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4204 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
4205 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4207 media_type2 = (void *)0xdeadbeef;
4208 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4209 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4210 ok(!media_type2, "Unexpected pointer.\n");
4212 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
4213 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4215 media_type2 = (void *)0xdeadbeef;
4216 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4217 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4218 ok(!media_type2, "Unexpected pointer.\n");
4220 IMFMediaType_Release(media_type);
4221 IMFMediaType_Release(media_type3);
4223 IMFMediaTypeHandler_Release(type_handler);
4225 IMFStreamDescriptor_Release(stream_desc);
4227 /* Major type is returned for first entry. */
4228 hr = MFCreateMediaType(&media_types[0]);
4229 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4230 hr = MFCreateMediaType(&media_types[1]);
4231 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4233 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4234 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4235 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4236 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4238 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
4239 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4241 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4242 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4244 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4245 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4246 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4248 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4249 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4250 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4251 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4253 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4254 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4255 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4257 IMFMediaType_Release(media_types[0]);
4258 IMFMediaType_Release(media_types[1]);
4260 IMFMediaTypeHandler_Release(type_handler);
4261 IMFStreamDescriptor_Release(stream_desc);
4264 static const struct image_size_test
4266 const GUID *subtype;
4267 UINT32 width;
4268 UINT32 height;
4269 UINT32 size;
4270 UINT32 plane_size; /* Matches image size when 0. */
4271 UINT32 max_length;
4272 UINT32 contiguous_length;
4273 UINT32 pitch;
4275 image_size_tests[] =
4277 /* RGB */
4278 { &MFVideoFormat_RGB8, 3, 5, 20, 0, 320, 20, 64 },
4279 { &MFVideoFormat_RGB8, 1, 1, 4, 0, 64, 4, 64 },
4280 { &MFVideoFormat_RGB555, 3, 5, 40, 0, 320, 40, 64 },
4281 { &MFVideoFormat_RGB555, 1, 1, 4, 0, 64, 4, 64 },
4282 { &MFVideoFormat_RGB565, 3, 5, 40, 0, 320, 40, 64 },
4283 { &MFVideoFormat_RGB565, 1, 1, 4, 0, 64, 4, 64 },
4284 { &MFVideoFormat_RGB24, 3, 5, 60, 0, 320, 60, 64 },
4285 { &MFVideoFormat_RGB24, 1, 1, 4, 0, 64, 4, 64 },
4286 { &MFVideoFormat_RGB24, 4, 3, 36, 0, 192, 36, 64 },
4287 { &MFVideoFormat_RGB32, 3, 5, 60, 0, 320, 60, 64 },
4288 { &MFVideoFormat_RGB32, 1, 1, 4, 0, 64, 4, 64 },
4289 { &MFVideoFormat_ARGB32, 3, 5, 60, 0, 320, 60, 64 },
4290 { &MFVideoFormat_ARGB32, 1, 1, 4, 0, 64, 4, 64 },
4291 { &MFVideoFormat_A2R10G10B10, 3, 5, 60, 0, 320, 60, 64 },
4292 { &MFVideoFormat_A2R10G10B10, 1, 1, 4, 0, 64, 4, 64 },
4293 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120, 0, 320, 120, 64 },
4294 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8, 0, 64, 8, 64 },
4295 { &MEDIASUBTYPE_RGB8, 3, 5, 20 },
4296 { &MEDIASUBTYPE_RGB8, 1, 1, 4 },
4297 { &MEDIASUBTYPE_RGB555, 3, 5, 40 },
4298 { &MEDIASUBTYPE_RGB555, 1, 1, 4 },
4299 { &MEDIASUBTYPE_RGB565, 3, 5, 40 },
4300 { &MEDIASUBTYPE_RGB565, 1, 1, 4 },
4301 { &MEDIASUBTYPE_RGB24, 3, 5, 60 },
4302 { &MEDIASUBTYPE_RGB24, 1, 1, 4 },
4303 { &MEDIASUBTYPE_RGB24, 4, 3, 36 },
4304 { &MEDIASUBTYPE_RGB32, 3, 5, 60 },
4305 { &MEDIASUBTYPE_RGB32, 1, 1, 4 },
4307 /* YUV 4:4:4, 32 bpp, packed */
4308 { &MFVideoFormat_AYUV, 1, 1, 4, 0, 64, 4, 64 },
4309 { &MFVideoFormat_AYUV, 2, 1, 8, 0, 64, 8, 64 },
4310 { &MFVideoFormat_AYUV, 1, 2, 8, 0, 128, 8, 64 },
4311 { &MFVideoFormat_AYUV, 4, 3, 48, 0, 192, 48, 64 },
4312 { &MFVideoFormat_AYUV, 320, 240, 307200, 0, 307200, 307200, 1280 },
4314 /* YUV 4:2:2, 16 bpp, packed */
4315 { &MFVideoFormat_YUY2, 2, 1, 4, 0, 64, 4, 64 },
4316 { &MFVideoFormat_YUY2, 4, 3, 24, 0, 192, 24, 64 },
4317 { &MFVideoFormat_YUY2, 128, 128, 32768, 0, 32768, 32768, 256 },
4318 { &MFVideoFormat_YUY2, 320, 240, 153600, 0, 153600, 153600, 640 },
4320 { &MFVideoFormat_UYVY, 2, 1, 4, 0, 64, 4, 64 },
4321 { &MFVideoFormat_UYVY, 4, 3, 24, 0, 192, 24, 64 },
4322 { &MFVideoFormat_UYVY, 128, 128, 32768, 0, 32768, 32768, 256 },
4323 { &MFVideoFormat_UYVY, 320, 240, 153600, 0, 153600, 153600, 640 },
4325 /* YUV 4:2:0, 16 bpp, planar (the secondary plane has the same
4326 * height, half the width and the same stride as the primary
4327 * one) */
4328 { &MFVideoFormat_IMC1, 1, 1, 4, 0, 256, 8, 128 },
4329 { &MFVideoFormat_IMC1, 2, 1, 4, 0, 256, 8, 128 },
4330 { &MFVideoFormat_IMC1, 1, 2, 8, 0, 512, 16, 128 },
4331 { &MFVideoFormat_IMC1, 2, 2, 8, 0, 512, 16, 128 },
4332 { &MFVideoFormat_IMC1, 2, 4, 16, 0, 1024, 32, 128 },
4333 { &MFVideoFormat_IMC1, 4, 2, 16, 0, 512, 32, 128 },
4334 { &MFVideoFormat_IMC1, 4, 3, 24, 0, 768, 48, 128 },
4335 { &MFVideoFormat_IMC1, 320, 240, 153600, 0, 307200, 307200, 640 },
4337 { &MFVideoFormat_IMC3, 1, 1, 4, 0, 256, 8, 128 },
4338 { &MFVideoFormat_IMC3, 2, 1, 4, 0, 256, 8, 128 },
4339 { &MFVideoFormat_IMC3, 1, 2, 8, 0, 512, 16, 128 },
4340 { &MFVideoFormat_IMC3, 2, 2, 8, 0, 512, 16, 128 },
4341 { &MFVideoFormat_IMC3, 2, 4, 16, 0, 1024, 32, 128 },
4342 { &MFVideoFormat_IMC3, 4, 2, 16, 0, 512, 32, 128 },
4343 { &MFVideoFormat_IMC3, 4, 3, 24, 0, 768, 48, 128 },
4344 { &MFVideoFormat_IMC3, 320, 240, 153600, 0, 307200, 307200, 640 },
4346 /* YUV 4:2:0, 12 bpp, planar, full stride (the secondary plane has
4347 * half the height, the same width and the same stride as the
4348 * primary one) */
4349 { &MFVideoFormat_NV12, 1, 3, 9, 4, 288, 4, 64 },
4350 { &MFVideoFormat_NV12, 1, 2, 6, 3, 192, 3, 64 },
4351 { &MFVideoFormat_NV12, 2, 2, 6, 6, 192, 6, 64 },
4352 { &MFVideoFormat_NV12, 2, 4, 12, 0, 384, 12, 64 },
4353 { &MFVideoFormat_NV12, 3, 2, 12, 9, 192, 9, 64 },
4354 { &MFVideoFormat_NV12, 4, 2, 12, 0, 192, 12, 64 },
4355 { &MFVideoFormat_NV12, 320, 240, 115200, 0, 115200, 115200, 320 },
4357 /* YUV 4:2:0, 12 bpp, planar, half stride (the secondary plane has
4358 * the same height, half the width and half the stride of the
4359 * primary one) */
4360 { &MFVideoFormat_IMC2, 1, 1, 3, 1, 192, 1, 128 },
4361 { &MFVideoFormat_IMC2, 1, 2, 6, 3, 384, 2, 128 },
4362 { &MFVideoFormat_IMC2, 1, 3, 9, 4, 576, 3, 128 },
4363 { &MFVideoFormat_IMC2, 2, 1, 3, 0, 192, 3, 128 },
4364 { &MFVideoFormat_IMC2, 2, 2, 6, 6, 384, 6, 128 },
4365 { &MFVideoFormat_IMC2, 2, 4, 12, 0, 768, 12, 128 },
4366 { &MFVideoFormat_IMC2, 3, 2, 12, 9, 384, 8, 128 },
4367 { &MFVideoFormat_IMC2, 3, 5, 30, 22, 960, 20, 128 },
4368 { &MFVideoFormat_IMC2, 4, 2, 12, 0, 384, 12, 128 },
4369 { &MFVideoFormat_IMC2, 4, 3, 18, 0, 576, 18, 128 },
4370 { &MFVideoFormat_IMC2, 320, 240, 115200, 0, 138240, 115200, 384 },
4372 { &MFVideoFormat_IMC4, 1, 1, 3, 1, 192, 1, 128 },
4373 { &MFVideoFormat_IMC4, 1, 2, 6, 3, 384, 2, 128 },
4374 { &MFVideoFormat_IMC4, 1, 3, 9, 4, 576, 3, 128 },
4375 { &MFVideoFormat_IMC4, 2, 1, 3, 0, 192, 3, 128 },
4376 { &MFVideoFormat_IMC4, 2, 2, 6, 6, 384, 6, 128 },
4377 { &MFVideoFormat_IMC4, 2, 4, 12, 0, 768, 12, 128 },
4378 { &MFVideoFormat_IMC4, 3, 2, 12, 9, 384, 8, 128 },
4379 { &MFVideoFormat_IMC4, 3, 5, 30, 22, 960, 20, 128 },
4380 { &MFVideoFormat_IMC4, 4, 2, 12, 0, 384, 12, 128 },
4381 { &MFVideoFormat_IMC4, 4, 3, 18, 0, 576, 18, 128 },
4382 { &MFVideoFormat_IMC4, 320, 240, 115200, 0, 138240, 115200, 384 },
4384 /* YUV 4:1:1, 12 bpp, semi-planar */
4385 { &MFVideoFormat_NV11, 1, 3, 18, 4, 576, 3, 128 },
4386 { &MFVideoFormat_NV11, 1, 2, 12, 3, 384, 2, 128 },
4387 { &MFVideoFormat_NV11, 2, 2, 12, 6, 384, 6, 128 },
4388 { &MFVideoFormat_NV11, 2, 4, 24, 12, 768, 12, 128 },
4389 { &MFVideoFormat_NV11, 3, 2, 12, 9, 384, 8, 128 },
4390 { &MFVideoFormat_NV11, 4, 2, 12, 0, 384, 12, 128 },
4391 { &MFVideoFormat_NV11, 320, 240, 115200, 0, 138240, 115200, 384 },
4394 static void test_MFCalculateImageSize(void)
4396 unsigned int i;
4397 UINT32 size;
4398 HRESULT hr;
4400 size = 1;
4401 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
4402 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#lx.\n", hr);
4403 ok(size == 0, "Unexpected size %u.\n", size);
4405 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4407 const struct image_size_test *ptr = &image_size_tests[i];
4409 /* Those are supported since Win10. */
4410 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
4411 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
4413 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4414 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr);
4415 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4416 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4420 static void test_MFGetPlaneSize(void)
4422 unsigned int i;
4423 DWORD size;
4424 HRESULT hr;
4426 if (!pMFGetPlaneSize)
4428 win_skip("MFGetPlaneSize() is not available.\n");
4429 return;
4432 size = 1;
4433 hr = pMFGetPlaneSize(0xdeadbeef, 64, 64, &size);
4434 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4435 ok(size == 0, "Unexpected size %lu.\n", size);
4437 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4439 const struct image_size_test *ptr = &image_size_tests[i];
4440 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4441 if ((is_MEDIASUBTYPE_RGB(ptr->subtype)))
4442 continue;
4444 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4445 ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr);
4446 ok(size == plane_size, "%u: unexpected plane size %lu, expected %u. Size %u x %u, format %s.\n", i, size, plane_size,
4447 ptr->width, ptr->height, wine_dbgstr_an((char*)&ptr->subtype->Data1, 4));
4451 static void test_MFCompareFullToPartialMediaType(void)
4453 IMFMediaType *full_type, *partial_type;
4454 HRESULT hr;
4455 BOOL ret;
4457 hr = MFCreateMediaType(&full_type);
4458 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4460 hr = MFCreateMediaType(&partial_type);
4461 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4463 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4464 ok(!ret, "Unexpected result %d.\n", ret);
4466 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4467 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4469 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4470 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4472 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4473 ok(ret, "Unexpected result %d.\n", ret);
4475 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4476 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4478 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4479 ok(ret, "Unexpected result %d.\n", ret);
4481 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4482 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4484 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4485 ok(!ret, "Unexpected result %d.\n", ret);
4487 IMFMediaType_Release(full_type);
4488 IMFMediaType_Release(partial_type);
4491 static void test_attributes_serialization(void)
4493 static const UINT8 blob[] = {1,2,3};
4494 IMFAttributes *attributes, *dest;
4495 UINT32 size, count, value32;
4496 double value_dbl;
4497 UINT64 value64;
4498 UINT8 *buffer;
4499 IUnknown *obj;
4500 HRESULT hr;
4501 WCHAR *str;
4502 GUID guid;
4504 hr = MFCreateAttributes(&attributes, 0);
4505 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4507 hr = MFCreateAttributes(&dest, 0);
4508 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4510 hr = MFGetAttributesAsBlobSize(attributes, &size);
4511 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4512 ok(size == 8, "Got size %u.\n", size);
4514 buffer = malloc(size);
4516 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4517 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4519 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4520 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
4522 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4523 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4525 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4526 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4528 hr = MFInitAttributesFromBlob(dest, buffer, size);
4529 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4531 /* Previous items are cleared. */
4532 hr = IMFAttributes_GetCount(dest, &count);
4533 ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr);
4534 ok(count == 0, "Unexpected count %u.\n", count);
4536 free(buffer);
4538 /* Set some attributes of various types. */
4539 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4540 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4541 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4542 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4543 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4544 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4545 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4547 hr = MFGetAttributesAsBlobSize(attributes, &size);
4548 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4549 ok(size > 8, "Got unexpected size %u.\n", size);
4551 buffer = malloc(size);
4552 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4553 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4554 hr = MFInitAttributesFromBlob(dest, buffer, size);
4555 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4556 free(buffer);
4558 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4559 ok(hr == S_OK, "Failed to get get uint32 value, hr %#lx.\n", hr);
4560 ok(value32 == 456, "Unexpected value %u.\n", value32);
4561 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4562 ok(hr == S_OK, "Failed to get get uint64 value, hr %#lx.\n", hr);
4563 ok(value64 == 123, "Unexpected value.\n");
4564 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4565 ok(hr == S_OK, "Failed to get get double value, hr %#lx.\n", hr);
4566 ok(value_dbl == 0.5, "Unexpected value.\n");
4567 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4568 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4569 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4570 ok(hr == S_OK, "Failed to get guid value, hr %#lx.\n", hr);
4571 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4572 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4573 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
4574 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4575 CoTaskMemFree(str);
4576 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4577 ok(hr == S_OK, "Failed to get blob value, hr %#lx.\n", hr);
4578 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4579 CoTaskMemFree(buffer);
4581 IMFAttributes_Release(attributes);
4582 IMFAttributes_Release(dest);
4585 static void test_wrapped_media_type(void)
4587 IMFMediaType *mediatype, *mediatype2;
4588 UINT32 count, type;
4589 HRESULT hr;
4590 GUID guid;
4592 hr = MFCreateMediaType(&mediatype);
4593 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4595 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4596 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4598 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4599 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4600 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4601 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4603 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4604 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
4606 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4607 ok(hr == S_OK, "Failed to create wrapped media type, hr %#lx.\n", hr);
4609 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4610 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4611 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4613 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4614 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
4615 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4617 hr = IMFMediaType_GetCount(mediatype2, &count);
4618 ok(hr == S_OK, "Failed to get item count, hr %#lx.\n", hr);
4619 ok(count == 3, "Unexpected count %u.\n", count);
4621 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4622 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
4623 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4625 IMFMediaType_Release(mediatype);
4627 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4628 ok(hr == S_OK, "Failed to unwrap, hr %#lx.\n", hr);
4630 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4631 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4632 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4634 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4635 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4637 IMFMediaType_Release(mediatype);
4638 IMFMediaType_Release(mediatype2);
4641 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4643 static const struct wave_fmt_test
4645 const GUID *subtype;
4646 WORD format_tag;
4648 wave_fmt_tests[] =
4650 { &MFAudioFormat_PCM, WAVE_FORMAT_PCM, },
4651 { &MFAudioFormat_Float, WAVE_FORMAT_IEEE_FLOAT, },
4653 WAVEFORMATEXTENSIBLE *format_ext;
4654 IMFMediaType *mediatype;
4655 WAVEFORMATEX *format;
4656 UINT32 size, i;
4657 HRESULT hr;
4659 hr = MFCreateMediaType(&mediatype);
4660 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4662 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4663 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4665 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4666 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4668 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4669 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4671 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4672 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4674 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4675 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4677 for (i = 0; i < ARRAY_SIZE(wave_fmt_tests); ++i)
4679 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, wave_fmt_tests[i].subtype);
4680 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4682 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4683 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4684 ok(format != NULL, "Expected format structure.\n");
4685 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4686 ok(format->wFormatTag == wave_fmt_tests[i].format_tag, "Expected tag %u, got %u.\n", wave_fmt_tests[i].format_tag, format->wFormatTag);
4687 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4688 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format->nSamplesPerSec);
4689 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n", format->nAvgBytesPerSec);
4690 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4691 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4692 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4693 CoTaskMemFree(format);
4695 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4696 MFWaveFormatExConvertFlag_ForceExtensible);
4697 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4698 ok(format_ext != NULL, "Expected format structure.\n");
4699 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4700 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4701 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4702 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format_ext->Format.nSamplesPerSec);
4703 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n",
4704 format_ext->Format.nAvgBytesPerSec);
4705 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4706 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4707 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4708 format_ext->Format.cbSize);
4709 CoTaskMemFree(format_ext);
4711 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4712 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4713 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4714 CoTaskMemFree(format);
4717 IMFMediaType_Release(mediatype);
4720 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4722 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4723 IMFByteStream *stream;
4724 IUnknown *object;
4725 HRESULT hr;
4727 ok(!!result, "Unexpected result object.\n");
4729 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4731 hr = IMFAsyncResult_GetObject(result, &object);
4732 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4734 hr = MFEndCreateFile(result, &stream);
4735 ok(hr == S_OK, "Failed to get file stream, hr %#lx.\n", hr);
4736 IMFByteStream_Release(stream);
4738 SetEvent(callback->event);
4740 return S_OK;
4743 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4745 testcallback_QueryInterface,
4746 testcallback_AddRef,
4747 testcallback_Release,
4748 testcallback_GetParameters,
4749 test_create_file_callback_Invoke,
4752 static void test_async_create_file(void)
4754 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4755 struct test_callback *callback;
4756 IUnknown *cancel_cookie;
4757 HRESULT hr;
4758 BOOL ret;
4760 callback = create_test_callback(&test_create_file_callback_vtbl);
4762 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4763 ok(hr == S_OK, "Fail to start up, hr %#lx.\n", hr);
4765 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
4767 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4768 GetTempFileNameW(pathW, NULL, 0, fileW);
4770 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4771 &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface, &cancel_cookie);
4772 ok(hr == S_OK, "Async create request failed, hr %#lx.\n", hr);
4773 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4775 WaitForSingleObject(callback->event, INFINITE);
4777 IUnknown_Release(cancel_cookie);
4779 CloseHandle(callback->event);
4781 hr = MFShutdown();
4782 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4784 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4786 ret = DeleteFileW(fileW);
4787 ok(ret, "Failed to delete test file.\n");
4790 struct activate_object
4792 IMFActivate IMFActivate_iface;
4793 LONG refcount;
4796 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4798 if (IsEqualIID(riid, &IID_IMFActivate) ||
4799 IsEqualIID(riid, &IID_IMFAttributes) ||
4800 IsEqualIID(riid, &IID_IUnknown))
4802 *obj = iface;
4803 IMFActivate_AddRef(iface);
4804 return S_OK;
4807 *obj = NULL;
4808 return E_NOINTERFACE;
4811 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4813 return 2;
4816 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4818 return 1;
4821 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
4823 return E_NOTIMPL;
4826 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
4828 return E_NOTIMPL;
4831 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
4833 return E_NOTIMPL;
4836 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
4837 BOOL *result)
4839 return E_NOTIMPL;
4842 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
4844 return E_NOTIMPL;
4847 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
4849 return E_NOTIMPL;
4852 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
4854 return E_NOTIMPL;
4857 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
4859 return E_NOTIMPL;
4862 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
4864 return E_NOTIMPL;
4867 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
4868 UINT32 size, UINT32 *length)
4870 return E_NOTIMPL;
4873 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
4874 WCHAR **value, UINT32 *length)
4876 return E_NOTIMPL;
4879 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
4881 return E_NOTIMPL;
4884 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
4885 UINT32 bufsize, UINT32 *blobsize)
4887 return E_NOTIMPL;
4890 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
4892 return E_NOTIMPL;
4895 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
4897 return E_NOTIMPL;
4900 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
4902 return E_NOTIMPL;
4905 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
4907 return E_NOTIMPL;
4910 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
4912 return E_NOTIMPL;
4915 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
4917 return E_NOTIMPL;
4920 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
4922 return E_NOTIMPL;
4925 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
4927 return E_NOTIMPL;
4930 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
4932 return E_NOTIMPL;
4935 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
4937 return E_NOTIMPL;
4940 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
4942 return E_NOTIMPL;
4945 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
4947 return E_NOTIMPL;
4950 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
4952 return E_NOTIMPL;
4955 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
4957 return E_NOTIMPL;
4960 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
4962 return E_NOTIMPL;
4965 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
4967 return E_NOTIMPL;
4970 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
4972 return E_NOTIMPL;
4975 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
4977 return E_NOTIMPL;
4980 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
4982 return E_NOTIMPL;
4985 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
4987 return E_NOTIMPL;
4990 static const IMFActivateVtbl activate_object_vtbl =
4992 activate_object_QueryInterface,
4993 activate_object_AddRef,
4994 activate_object_Release,
4995 activate_object_GetItem,
4996 activate_object_GetItemType,
4997 activate_object_CompareItem,
4998 activate_object_Compare,
4999 activate_object_GetUINT32,
5000 activate_object_GetUINT64,
5001 activate_object_GetDouble,
5002 activate_object_GetGUID,
5003 activate_object_GetStringLength,
5004 activate_object_GetString,
5005 activate_object_GetAllocatedString,
5006 activate_object_GetBlobSize,
5007 activate_object_GetBlob,
5008 activate_object_GetAllocatedBlob,
5009 activate_object_GetUnknown,
5010 activate_object_SetItem,
5011 activate_object_DeleteItem,
5012 activate_object_DeleteAllItems,
5013 activate_object_SetUINT32,
5014 activate_object_SetUINT64,
5015 activate_object_SetDouble,
5016 activate_object_SetGUID,
5017 activate_object_SetString,
5018 activate_object_SetBlob,
5019 activate_object_SetUnknown,
5020 activate_object_LockStore,
5021 activate_object_UnlockStore,
5022 activate_object_GetCount,
5023 activate_object_GetItemByIndex,
5024 activate_object_CopyAllItems,
5025 activate_object_ActivateObject,
5026 activate_object_ShutdownObject,
5027 activate_object_DetachObject,
5030 static void test_local_handlers(void)
5032 IMFActivate local_activate = { &activate_object_vtbl };
5033 static const WCHAR localW[] = L"local";
5034 HRESULT hr;
5036 if (!pMFRegisterLocalSchemeHandler)
5038 win_skip("Local handlers are not supported.\n");
5039 return;
5042 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
5043 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5045 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
5046 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5048 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
5049 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5051 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5052 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5054 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5055 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5057 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
5058 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5060 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
5061 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5063 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
5064 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5066 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
5067 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5069 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
5070 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5073 static void test_create_property_store(void)
5075 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
5076 IPropertyStore *store, *store2;
5077 PROPVARIANT value = {0};
5078 PROPERTYKEY key;
5079 ULONG refcount;
5080 DWORD count;
5081 HRESULT hr;
5083 hr = CreatePropertyStore(NULL);
5084 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5086 hr = CreatePropertyStore(&store);
5087 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5089 hr = CreatePropertyStore(&store2);
5090 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5091 ok(store2 != store, "Expected different store objects.\n");
5092 IPropertyStore_Release(store2);
5094 check_interface(store, &IID_IPropertyStoreCache, FALSE);
5095 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
5097 hr = IPropertyStore_GetCount(store, NULL);
5098 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5100 count = 0xdeadbeef;
5101 hr = IPropertyStore_GetCount(store, &count);
5102 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5103 ok(!count, "Unexpected count %lu.\n", count);
5105 hr = IPropertyStore_Commit(store);
5106 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5108 hr = IPropertyStore_GetAt(store, 0, &key);
5109 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5111 hr = IPropertyStore_GetValue(store, NULL, &value);
5112 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5114 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
5115 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5117 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5118 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5120 memset(&value, 0, sizeof(PROPVARIANT));
5121 value.vt = VT_I4;
5122 value.lVal = 0xdeadbeef;
5123 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5126 if (0)
5128 /* crashes on Windows */
5129 hr = IPropertyStore_SetValue(store, NULL, &value);
5130 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5133 hr = IPropertyStore_GetCount(store, &count);
5134 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5135 ok(count == 1, "Unexpected count %lu.\n", count);
5137 hr = IPropertyStore_Commit(store);
5138 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5140 hr = IPropertyStore_GetAt(store, 0, &key);
5141 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5142 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
5144 hr = IPropertyStore_GetAt(store, 1, &key);
5145 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5147 memset(&value, 0xcc, sizeof(PROPVARIANT));
5148 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5149 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5150 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
5151 ok(value.lVal == 0xdeadbeef, "Unexpected value %#lx.\n", value.lVal);
5153 memset(&value, 0, sizeof(PROPVARIANT));
5154 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5155 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5157 hr = IPropertyStore_GetCount(store, &count);
5158 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5159 ok(count == 1, "Unexpected count %lu.\n", count);
5161 memset(&value, 0xcc, sizeof(PROPVARIANT));
5162 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5163 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5164 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
5165 ok(!value.lVal, "Unexpected value %#lx.\n", value.lVal);
5167 refcount = IPropertyStore_Release(store);
5168 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
5171 struct test_thread_param
5173 IMFDXGIDeviceManager *manager;
5174 HANDLE handle;
5175 BOOL lock;
5178 static DWORD WINAPI test_device_manager_thread(void *arg)
5180 struct test_thread_param *param = arg;
5181 ID3D11Device *device;
5182 HRESULT hr;
5184 if (param->lock)
5186 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
5187 (void **)&device, FALSE);
5188 if (SUCCEEDED(hr))
5189 ID3D11Device_Release(device);
5191 else
5192 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
5194 return hr;
5197 static void test_dxgi_device_manager(void)
5199 IMFDXGIDeviceManager *manager, *manager2;
5200 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
5201 struct test_thread_param param;
5202 HANDLE handle1, handle, thread;
5203 UINT token, token2;
5204 IUnknown *unk;
5205 HRESULT hr;
5207 if (!pMFCreateDXGIDeviceManager)
5209 win_skip("MFCreateDXGIDeviceManager not found.\n");
5210 return;
5213 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
5214 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5216 token = 0;
5217 hr = pMFCreateDXGIDeviceManager(&token, NULL);
5218 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5219 ok(!token, "got wrong token: %u.\n", token);
5221 hr = pMFCreateDXGIDeviceManager(&token, &manager);
5222 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5223 EXPECT_REF(manager, 1);
5224 ok(!!token, "got wrong token: %u.\n", token);
5226 Sleep(50);
5227 token2 = 0;
5228 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
5229 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5230 EXPECT_REF(manager2, 1);
5231 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
5232 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
5233 EXPECT_REF(manager, 1);
5235 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5236 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5238 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5239 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5241 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
5242 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5244 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
5245 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
5246 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5247 EXPECT_REF(d3d11_dev, 1);
5249 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
5250 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5251 EXPECT_REF(d3d11_dev, 1);
5253 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
5254 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5256 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5257 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5258 EXPECT_REF(manager, 1);
5259 EXPECT_REF(d3d11_dev, 2);
5261 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
5262 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5263 EXPECT_REF(manager2, 1);
5264 EXPECT_REF(d3d11_dev, 2);
5266 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5267 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5268 EXPECT_REF(manager, 1);
5269 EXPECT_REF(d3d11_dev, 2);
5271 /* GetVideoService() on device change. */
5272 handle = NULL;
5273 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5274 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5275 ok(!!handle, "Unexpected handle value %p.\n", handle);
5277 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
5278 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
5279 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5280 EXPECT_REF(d3d11_dev2, 1);
5281 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
5282 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5283 EXPECT_REF(manager, 1);
5284 EXPECT_REF(d3d11_dev2, 2);
5285 EXPECT_REF(d3d11_dev, 1);
5287 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5288 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#lx.\n", hr);
5290 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5291 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5293 handle = NULL;
5294 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5296 ok(!!handle, "Unexpected handle value %p.\n", handle);
5298 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5299 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5301 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5302 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5303 IUnknown_Release(unk);
5305 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
5306 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5307 IUnknown_Release(unk);
5309 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
5310 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5311 IUnknown_Release(unk);
5313 handle1 = NULL;
5314 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5315 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5316 ok(handle != handle1, "Unexpected handle.\n");
5318 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5319 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5321 /* Already closed. */
5322 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5323 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5325 handle = NULL;
5326 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5327 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5329 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5330 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5332 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
5333 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5335 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5336 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5337 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
5338 ID3D11Device_Release(device);
5340 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5343 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5344 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5346 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
5347 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5349 /* Locked with one handle, unlock with another. */
5350 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5351 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5353 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5354 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5356 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5357 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5359 ID3D11Device_Release(device);
5361 /* Closing unlocks the device. */
5362 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5363 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5365 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5366 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5367 ID3D11Device_Release(device);
5369 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5370 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5372 /* Open two handles. */
5373 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5374 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5376 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5379 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5380 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5381 ID3D11Device_Release(device);
5383 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5384 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5385 ID3D11Device_Release(device);
5387 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5388 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5390 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5391 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5393 param.manager = manager;
5394 param.handle = handle;
5395 param.lock = TRUE;
5396 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5397 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5398 GetExitCodeThread(thread, (DWORD *)&hr);
5399 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#lx.\n", hr);
5400 CloseHandle(thread);
5402 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5403 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5405 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5406 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5408 /* Lock on main thread, unlock on another. */
5409 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5410 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5411 ID3D11Device_Release(device);
5413 param.manager = manager;
5414 param.handle = handle;
5415 param.lock = FALSE;
5416 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5417 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5418 GetExitCodeThread(thread, (DWORD *)&hr);
5419 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5420 CloseHandle(thread);
5422 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5423 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5425 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5426 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5428 IMFDXGIDeviceManager_Release(manager);
5429 EXPECT_REF(d3d11_dev2, 1);
5430 ID3D11Device_Release(d3d11_dev);
5431 ID3D11Device_Release(d3d11_dev2);
5432 IMFDXGIDeviceManager_Release(manager2);
5435 static void test_MFCreateTransformActivate(void)
5437 IMFActivate *activate;
5438 UINT32 count;
5439 HRESULT hr;
5441 if (!pMFCreateTransformActivate)
5443 win_skip("MFCreateTransformActivate() is not available.\n");
5444 return;
5447 hr = pMFCreateTransformActivate(&activate);
5448 ok(hr == S_OK, "Failed to create activator, hr %#lx.\n", hr);
5450 hr = IMFActivate_GetCount(activate, &count);
5451 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5452 ok(!count, "Unexpected attribute count %u.\n", count);
5454 IMFActivate_Release(activate);
5457 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5459 if (IsEqualIID(riid, &IID_IClassFactory) ||
5460 IsEqualIID(riid, &IID_IUnknown))
5462 *obj = iface;
5463 IClassFactory_AddRef(iface);
5464 return S_OK;
5467 *obj = NULL;
5468 return E_NOINTERFACE;
5471 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5473 return 2;
5476 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5478 return 1;
5481 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5483 ok(0, "Unexpected call.\n");
5484 return E_NOTIMPL;
5487 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5489 return S_OK;
5492 static const IClassFactoryVtbl test_mft_factory_vtbl =
5494 test_mft_factory_QueryInterface,
5495 test_mft_factory_AddRef,
5496 test_mft_factory_Release,
5497 test_mft_factory_CreateInstance,
5498 test_mft_factory_LockServer,
5501 static void test_MFTRegisterLocal(void)
5503 IClassFactory test_factory = { &test_mft_factory_vtbl };
5504 MFT_REGISTER_TYPE_INFO input_types[1], *in_types, *out_types;
5505 IMFAttributes *attributes;
5506 IMFActivate **activate;
5507 UINT32 count, count2;
5508 WCHAR *name;
5509 HRESULT hr;
5511 if (!pMFTRegisterLocal)
5513 win_skip("MFTRegisterLocal() is not available.\n");
5514 return;
5517 input_types[0].guidMajorType = MFMediaType_Audio;
5518 input_types[0].guidSubtype = MFAudioFormat_PCM;
5519 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5520 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5522 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5523 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5525 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5527 ok(count > 0, "Unexpected count %u.\n", count);
5528 CoTaskMemFree(activate);
5530 hr = pMFTUnregisterLocal(&test_factory);
5531 ok(hr == S_OK, "Failed to unregister MFT, hr %#lx.\n", hr);
5533 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5534 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5535 ok(count2 < count, "Unexpected count %u.\n", count2);
5536 CoTaskMemFree(activate);
5538 hr = pMFTUnregisterLocal(&test_factory);
5539 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5541 hr = pMFTUnregisterLocal(NULL);
5542 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5544 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5545 0, NULL);
5546 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5548 hr = MFTGetInfo(MFT_CATEGORY_OTHER, &name, &in_types, &count, &out_types, &count2, &attributes);
5549 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5551 hr = pMFTUnregisterLocal(NULL);
5552 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5554 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5555 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5557 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5558 0, NULL);
5559 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5561 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5565 static void test_queue_com(void)
5567 static int system_queues[] =
5569 MFASYNC_CALLBACK_QUEUE_STANDARD,
5570 MFASYNC_CALLBACK_QUEUE_RT,
5571 MFASYNC_CALLBACK_QUEUE_IO,
5572 MFASYNC_CALLBACK_QUEUE_TIMER,
5573 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5574 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5577 static int user_queues[] =
5579 MF_STANDARD_WORKQUEUE,
5580 MF_WINDOW_WORKQUEUE,
5581 MF_MULTITHREADED_WORKQUEUE,
5584 char path_name[MAX_PATH];
5585 PROCESS_INFORMATION info;
5586 STARTUPINFOA startup;
5587 char **argv;
5588 int i;
5590 if (!pCoGetApartmentType)
5592 win_skip("CoGetApartmentType() is not available.\n");
5593 return;
5596 winetest_get_mainargs(&argv);
5598 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5600 memset(&startup, 0, sizeof(startup));
5601 startup.cb = sizeof(startup);
5602 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5603 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5604 "CreateProcess failed.\n" );
5605 wait_child_process(info.hProcess);
5606 CloseHandle(info.hProcess);
5607 CloseHandle(info.hThread);
5610 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5612 memset(&startup, 0, sizeof(startup));
5613 startup.cb = sizeof(startup);
5614 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5615 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5616 "CreateProcess failed.\n" );
5617 wait_child_process(info.hProcess);
5618 CloseHandle(info.hProcess);
5619 CloseHandle(info.hThread);
5623 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5625 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5626 APTTYPEQUALIFIER qualifier;
5627 APTTYPE com_type;
5628 HRESULT hr;
5630 hr = pCoGetApartmentType(&com_type, &qualifier);
5631 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#lx.\n", hr);
5632 if (SUCCEEDED(hr))
5634 todo_wine {
5635 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5636 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5637 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5638 else
5639 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5640 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5644 SetEvent(callback->event);
5645 return S_OK;
5648 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5650 testcallback_QueryInterface,
5651 testcallback_AddRef,
5652 testcallback_Release,
5653 testcallback_GetParameters,
5654 test_queue_com_state_callback_Invoke,
5657 static void test_queue_com_state(const char *name)
5659 struct test_callback *callback;
5660 DWORD queue, queue_type;
5661 HRESULT hr;
5663 callback = create_test_callback(&test_queue_com_state_callback_vtbl);
5664 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
5666 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5667 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
5669 if (name[0] == 's')
5671 callback->param = name[1] - '0';
5672 hr = MFPutWorkItem(callback->param, &callback->IMFAsyncCallback_iface, NULL);
5673 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5674 WaitForSingleObject(callback->event, INFINITE);
5676 else if (name[0] == 'u')
5678 queue_type = name[1] - '0';
5680 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5681 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5682 "Failed to allocate a queue of type %lu, hr %#lx.\n", queue_type, hr);
5684 if (SUCCEEDED(hr))
5686 callback->param = queue;
5687 hr = MFPutWorkItem(queue, &callback->IMFAsyncCallback_iface, NULL);
5688 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5689 WaitForSingleObject(callback->event, INFINITE);
5691 hr = MFUnlockWorkQueue(queue);
5692 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
5696 CloseHandle(callback->event);
5698 hr = MFShutdown();
5699 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
5701 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
5704 static void test_MFGetStrideForBitmapInfoHeader(void)
5706 static const struct stride_test
5708 const GUID *subtype;
5709 unsigned int width;
5710 LONG stride;
5712 stride_tests[] =
5714 { &MFVideoFormat_RGB8, 3, -4 },
5715 { &MFVideoFormat_RGB8, 1, -4 },
5716 { &MFVideoFormat_RGB555, 3, -8 },
5717 { &MFVideoFormat_RGB555, 1, -4 },
5718 { &MFVideoFormat_RGB565, 3, -8 },
5719 { &MFVideoFormat_RGB565, 1, -4 },
5720 { &MFVideoFormat_RGB24, 3, -12 },
5721 { &MFVideoFormat_RGB24, 1, -4 },
5722 { &MFVideoFormat_RGB32, 3, -12 },
5723 { &MFVideoFormat_RGB32, 1, -4 },
5724 { &MFVideoFormat_ARGB32, 3, -12 },
5725 { &MFVideoFormat_ARGB32, 1, -4 },
5726 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5727 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5728 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5729 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5731 /* YUV */
5732 { &MFVideoFormat_NV12, 1, 1 },
5733 { &MFVideoFormat_NV12, 2, 2 },
5734 { &MFVideoFormat_NV12, 3, 3 },
5735 { &MFVideoFormat_AYUV, 1, 4 },
5736 { &MFVideoFormat_AYUV, 4, 16 },
5737 { &MFVideoFormat_AYUV, 5, 20 },
5738 { &MFVideoFormat_IMC1, 1, 4 },
5739 { &MFVideoFormat_IMC1, 2, 4 },
5740 { &MFVideoFormat_IMC1, 3, 8 },
5741 { &MFVideoFormat_IMC3, 1, 4 },
5742 { &MFVideoFormat_IMC3, 2, 4 },
5743 { &MFVideoFormat_IMC3, 3, 8 },
5744 { &MFVideoFormat_IMC2, 1, 1 },
5745 { &MFVideoFormat_IMC2, 2, 2 },
5746 { &MFVideoFormat_IMC2, 3, 3 },
5747 { &MFVideoFormat_IMC4, 1, 1 },
5748 { &MFVideoFormat_IMC4, 2, 2 },
5749 { &MFVideoFormat_IMC4, 3, 3 },
5750 { &MFVideoFormat_YV12, 1, 1 },
5751 { &MFVideoFormat_YV12, 2, 2 },
5752 { &MFVideoFormat_YV12, 3, 3 },
5753 { &MFVideoFormat_YV12, 320, 320 },
5754 { &MFVideoFormat_I420, 1, 1 },
5755 { &MFVideoFormat_I420, 2, 2 },
5756 { &MFVideoFormat_I420, 3, 3 },
5757 { &MFVideoFormat_I420, 320, 320 },
5758 { &MFVideoFormat_IYUV, 1, 1 },
5759 { &MFVideoFormat_IYUV, 2, 2 },
5760 { &MFVideoFormat_IYUV, 3, 3 },
5761 { &MFVideoFormat_IYUV, 320, 320 },
5762 { &MFVideoFormat_NV11, 1, 1 },
5763 { &MFVideoFormat_NV11, 2, 2 },
5764 { &MFVideoFormat_NV11, 3, 3 },
5766 unsigned int i;
5767 LONG stride;
5768 HRESULT hr;
5770 if (!pMFGetStrideForBitmapInfoHeader)
5772 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5773 return;
5776 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5777 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5779 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5781 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5782 ok(hr == S_OK, "%u: failed to get stride, hr %#lx.\n", i, hr);
5783 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %ld, expected %ld.\n", i,
5784 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5788 static void test_MFCreate2DMediaBuffer(void)
5790 static const char two_aas[] = { 0xaa, 0xaa };
5791 static const char eight_bbs[] = { 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb };
5792 DWORD max_length, length, length2;
5793 BYTE *buffer_start, *data, *data2;
5794 LONG pitch, pitch2, stride;
5795 IMF2DBuffer2 *_2dbuffer2;
5796 IMF2DBuffer *_2dbuffer;
5797 IMFMediaBuffer *buffer;
5798 int i, j, k;
5799 HRESULT hr;
5800 BOOL ret;
5802 if (!pMFCreate2DMediaBuffer)
5804 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5805 return;
5808 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5809 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5811 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5812 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5814 /* YUV formats can't be bottom-up. */
5815 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5816 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5818 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5819 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
5821 check_interface(buffer, &IID_IMFGetService, TRUE);
5822 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5824 /* Full backing buffer size, with 64 bytes per row alignment. */
5825 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5826 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5827 ok(max_length > 0, "Unexpected length %lu.\n", max_length);
5829 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5830 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
5831 ok(!length, "Unexpected length.\n");
5833 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
5834 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
5836 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5837 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
5838 ok(length == 10, "Unexpected length.\n");
5840 /* Linear lock/unlock. */
5842 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
5843 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5845 /* Linear locking call returns plane size.*/
5846 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
5847 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5848 ok(max_length == length, "Unexpected length.\n");
5850 memset(data, 0xaa, length);
5852 length = 0;
5853 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
5854 ok(max_length == length && length == 9, "Unexpected length %lu.\n", length);
5856 /* Already locked */
5857 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5858 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5859 ok(data2 == data, "Unexpected pointer.\n");
5861 hr = IMFMediaBuffer_Unlock(buffer);
5862 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5864 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5865 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
5867 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
5868 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5870 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5871 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5872 ok(length == 9, "Unexpected length %lu.\n", length);
5874 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
5875 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5877 /* 2D lock. */
5878 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5879 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
5881 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5882 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5884 hr = IMFMediaBuffer_Unlock(buffer);
5885 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5887 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5888 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5890 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
5891 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5893 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
5894 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5896 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
5897 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5899 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5900 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5901 ok(!!data, "Expected data pointer.\n");
5902 ok(pitch == 64, "Unexpected pitch %ld.\n", pitch);
5904 for (i = 0; i < 4; i++)
5905 ok(memcmp(&data[64 * i], two_aas, sizeof(two_aas)) == 0, "Invalid data instead of 0xaa.\n");
5906 memset(data, 0xbb, 194);
5908 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
5909 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5910 ok(data == data2, "Expected data pointer.\n");
5912 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
5913 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5915 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
5916 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5918 /* Active 2D lock */
5919 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5920 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
5922 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5923 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5925 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5926 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
5928 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5929 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5931 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5932 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5934 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5935 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5937 ok(memcmp(data, eight_bbs, sizeof(eight_bbs)) == 0, "Invalid data instead of 0xbb.\n");
5939 hr = IMFMediaBuffer_Unlock(buffer);
5940 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5942 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5943 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#lx.\n", hr);
5945 if (SUCCEEDED(hr))
5947 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5948 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5950 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5951 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5953 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5954 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5956 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5957 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5959 /* Flags are ignored. */
5960 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5961 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5963 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
5964 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5966 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5967 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5969 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5970 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5972 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
5973 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5975 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
5976 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5978 IMF2DBuffer2_Release(_2dbuffer2);
5980 else
5981 win_skip("IMF2DBuffer2 is not supported.\n");
5983 IMF2DBuffer_Release(_2dbuffer);
5985 IMFMediaBuffer_Release(buffer);
5987 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
5989 const struct image_size_test *ptr = &image_size_tests[i];
5991 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
5992 continue;
5994 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
5995 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
5997 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5998 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5999 ok(length == ptr->max_length, "%u: unexpected maximum length %lu for %u x %u, format %s.\n",
6000 i, length, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6002 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6003 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6005 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6006 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6007 ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %lu for %u x %u, format %s.\n",
6008 i, length, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6010 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6011 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6012 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6013 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6015 hr = pMFGetStrideForBitmapInfoHeader(ptr->subtype->Data1, ptr->width, &stride);
6016 ok(hr == S_OK, "Failed to get stride, hr %#lx.\n", hr);
6017 stride = abs(stride);
6019 /* primary plane */
6020 ok(ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6021 ptr->height * stride, length2);
6022 for (j = 0; j < ptr->height; j++)
6023 for (k = 0; k < stride; k++)
6024 data[j * stride + k] = ((j % 16) << 4) + (k % 16);
6026 data += ptr->height * stride;
6028 /* secondary planes */
6029 switch (ptr->subtype->Data1)
6031 case MAKEFOURCC('I','M','C','1'):
6032 case MAKEFOURCC('I','M','C','3'):
6033 ok(2 * ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6034 2 * ptr->height * stride, length2);
6035 for (j = 0; j < ptr->height; j++)
6036 for (k = 0; k < stride / 2; k++)
6037 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6038 break;
6040 case MAKEFOURCC('I','M','C','2'):
6041 case MAKEFOURCC('I','M','C','4'):
6042 ok(stride * 3 / 2 * ptr->height <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6043 stride * 3 / 2 * ptr->height, length2);
6044 for (j = 0; j < ptr->height; j++)
6045 for (k = 0; k < stride / 2; k++)
6046 data[j * (stride / 2) + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6047 break;
6049 case MAKEFOURCC('N','V','1','2'):
6050 ok(stride * ptr->height * 3 / 2 <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6051 stride * ptr->height * 3 / 2, length2);
6052 for (j = 0; j < ptr->height / 2; j++)
6053 for (k = 0; k < stride; k++)
6054 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6055 break;
6058 hr = IMFMediaBuffer_Unlock(buffer);
6059 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6061 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6062 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6064 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
6065 ok(hr == S_OK, "Failed to get scanline, hr %#lx.\n", hr);
6066 ok(data2 == data, "Unexpected data pointer.\n");
6067 ok(pitch == pitch2, "Unexpected pitch.\n");
6069 /* primary plane */
6070 for (j = 0; j < ptr->height; j++)
6071 for (k = 0; k < stride; k++)
6072 ok(data[j * pitch + k] == ((j % 16) << 4) + (k % 16),
6073 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6074 data[j * pitch + k], ((j % 16) << 4) + (k % 16), i, j, k);
6076 data += ptr->height * pitch;
6078 /* secondary planes */
6079 switch (ptr->subtype->Data1)
6081 case MAKEFOURCC('I','M','C','1'):
6082 case MAKEFOURCC('I','M','C','3'):
6083 for (j = 0; j < ptr->height; j++)
6084 for (k = 0; k < stride / 2; k++)
6085 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6086 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6087 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), i, j + ptr->height, k);
6088 break;
6090 case MAKEFOURCC('I','M','C','2'):
6091 case MAKEFOURCC('I','M','C','4'):
6092 for (j = 0; j < ptr->height; j++)
6093 for (k = 0; k < stride / 2; k++)
6094 ok(data[j * (pitch / 2) + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6095 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6096 data[j * (pitch / 2) + k], (((j + ptr->height) % 16) << 4) + (k % 16), i, j + ptr->height, k);
6097 break;
6099 case MAKEFOURCC('N','V','1','2'):
6100 for (j = 0; j < ptr->height / 2; j++)
6101 for (k = 0; k < stride; k++)
6102 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6103 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6104 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), i, j + ptr->height, k);
6105 break;
6107 default:
6111 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6112 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6114 ok(pitch == ptr->pitch, "%d: unexpected pitch %ld, expected %d, %u x %u, format %s.\n", i, pitch, ptr->pitch,
6115 ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6117 ret = TRUE;
6118 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
6119 ok(hr == S_OK, "Failed to get format flag, hr %#lx.\n", hr);
6120 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
6122 IMF2DBuffer_Release(_2dbuffer);
6124 IMFMediaBuffer_Release(buffer);
6127 /* Alignment tests */
6128 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
6130 const struct image_size_test *ptr = &image_size_tests[i];
6132 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
6133 continue;
6135 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
6136 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6138 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6139 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6141 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6142 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6143 ok(((uintptr_t)data & MF_64_BYTE_ALIGNMENT) == 0, "Misaligned data at %p.\n", data);
6145 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6146 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6148 IMF2DBuffer_Release(_2dbuffer);
6149 IMFMediaBuffer_Release(buffer);
6153 static void test_MFCreateMediaBufferFromMediaType(void)
6155 static struct audio_buffer_test
6157 unsigned int duration;
6158 unsigned int min_length;
6159 unsigned int min_alignment;
6160 unsigned int block_alignment;
6161 unsigned int bytes_per_second;
6162 unsigned int buffer_length;
6163 } audio_tests[] =
6165 { 0, 0, 0, 4, 0, 20 },
6166 { 0, 16, 0, 4, 0, 20 },
6167 { 0, 0, 32, 4, 0, 36 },
6168 { 0, 64, 32, 4, 0, 64 },
6169 { 1, 0, 0, 4, 16, 36 },
6170 { 2, 0, 0, 4, 16, 52 },
6171 { 2, 0, 64, 4, 16, 68 },
6172 { 2, 0, 128, 4, 16,132 },
6174 IMFMediaType *media_type, *media_type2;
6175 unsigned int i, alignment;
6176 IMFMediaBuffer *buffer;
6177 DWORD length, max;
6178 BYTE *data;
6179 HRESULT hr;
6181 if (!pMFCreateMediaBufferFromMediaType)
6183 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
6184 return;
6187 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
6188 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6190 hr = MFCreateMediaType(&media_type);
6191 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6193 hr = MFCreateMediaType(&media_type2);
6194 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6196 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
6197 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6199 hr = IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)media_type2);
6200 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6202 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
6204 const struct audio_buffer_test *ptr = &audio_tests[i];
6206 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
6207 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6209 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
6210 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6212 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
6213 ptr->min_alignment, &buffer);
6214 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#lx.\n", hr);
6215 if (FAILED(hr))
6216 break;
6218 check_interface(buffer, &IID_IMFGetService, FALSE);
6220 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6221 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6222 ok(ptr->buffer_length == length, "%d: unexpected buffer length %lu, expected %u.\n", i, length, ptr->buffer_length);
6224 alignment = ptr->min_alignment ? ptr->min_alignment - 1 : MF_16_BYTE_ALIGNMENT;
6225 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6226 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6227 ok(ptr->buffer_length == max && !length, "Unexpected length.\n");
6228 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6229 hr = IMFMediaBuffer_Unlock(buffer);
6230 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6232 IMFMediaBuffer_Release(buffer);
6234 /* Only major type is set. */
6235 hr = pMFCreateMediaBufferFromMediaType(media_type2, ptr->duration * 10000000, ptr->min_length,
6236 ptr->min_alignment, &buffer);
6237 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6239 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6240 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6241 ok(ptr->min_length == length, "%u: unexpected buffer length %lu, expected %u.\n", i, length, ptr->min_length);
6243 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6244 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6245 ok(ptr->min_length == max && !length, "Unexpected length.\n");
6246 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6247 hr = IMFMediaBuffer_Unlock(buffer);
6248 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6250 IMFMediaBuffer_Release(buffer);
6253 IMFMediaType_Release(media_type);
6254 IMFMediaType_Release(media_type2);
6257 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
6259 GUID guid, subtype;
6260 UINT32 value;
6261 HRESULT hr;
6263 hr = IMFMediaType_GetMajorType(mediatype, &guid);
6264 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
6265 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
6267 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
6268 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
6270 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
6272 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
6273 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6275 if (fex->dwChannelMask)
6277 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
6278 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6279 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
6282 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
6284 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
6285 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6286 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
6289 else
6291 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
6292 subtype.Data1 = format->wFormatTag;
6293 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6295 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
6296 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6297 ok(value, "Unexpected value.\n");
6300 if (format->nChannels)
6302 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
6303 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6304 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
6307 if (format->nSamplesPerSec)
6309 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
6310 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6311 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
6314 if (format->nAvgBytesPerSec)
6316 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
6317 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6318 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
6321 if (format->nBlockAlign)
6323 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
6324 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6325 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
6328 if (format->wBitsPerSample)
6330 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
6331 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6332 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
6335 /* Only set for uncompressed formats. */
6336 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
6337 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
6338 IsEqualGUID(&guid, &MFAudioFormat_PCM))
6340 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6341 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
6343 else
6344 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
6347 static void test_MFInitMediaTypeFromWaveFormatEx(void)
6349 static const WAVEFORMATEX waveformatex_tests[] =
6351 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
6352 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
6353 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
6354 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
6355 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
6356 { 1234, 0, 0, 0, 0, 0 },
6357 { WAVE_FORMAT_ALAW },
6358 { WAVE_FORMAT_CREATIVE_ADPCM },
6359 { WAVE_FORMAT_MPEGLAYER3 },
6360 { WAVE_FORMAT_MPEG_ADTS_AAC },
6361 { WAVE_FORMAT_ALAC },
6362 { WAVE_FORMAT_AMR_NB },
6363 { WAVE_FORMAT_AMR_WB },
6364 { WAVE_FORMAT_AMR_WP },
6365 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
6366 { WAVE_FORMAT_DRM },
6367 { WAVE_FORMAT_DTS },
6368 { WAVE_FORMAT_FLAC },
6369 { WAVE_FORMAT_MPEG },
6370 { WAVE_FORMAT_WMAVOICE9 },
6371 { WAVE_FORMAT_OPUS },
6372 { WAVE_FORMAT_WMAUDIO2 },
6373 { WAVE_FORMAT_WMAUDIO3 },
6374 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
6375 { WAVE_FORMAT_WMASPDIF },
6378 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
6379 WAVEFORMATEXTENSIBLE waveformatext;
6380 MPEGLAYER3WAVEFORMAT mp3format;
6381 IMFMediaType *mediatype;
6382 unsigned int i, size;
6383 HRESULT hr;
6385 hr = MFCreateMediaType(&mediatype);
6386 ok(hr == S_OK, "Failed to create mediatype, hr %#lx.\n", hr);
6388 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
6390 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
6391 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#lx.\n", i, waveformatex_tests[i].wFormatTag, hr);
6393 validate_media_type(mediatype, &waveformatex_tests[i]);
6395 waveformatext.Format = waveformatex_tests[i];
6396 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
6397 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
6398 waveformatext.Samples.wSamplesPerBlock = 123;
6399 waveformatext.dwChannelMask = 0x8;
6400 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
6401 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
6403 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
6404 ok(hr == S_OK, "Failed to initialize media type, hr %#lx.\n", hr);
6406 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
6407 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
6409 validate_media_type(mediatype, &waveformatext.Format);
6412 /* MPEGLAYER3WAVEFORMAT */
6413 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
6414 mp3format.wfx.nChannels = 2;
6415 mp3format.wfx.nSamplesPerSec = 44100;
6416 mp3format.wfx.nAvgBytesPerSec = 16000;
6417 mp3format.wfx.nBlockAlign = 1;
6418 mp3format.wfx.wBitsPerSample = 0;
6419 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
6420 mp3format.wID = MPEGLAYER3_ID_MPEG;
6421 mp3format.fdwFlags = 0;
6422 mp3format.nBlockSize = 417;
6423 mp3format.nFramesPerBlock = 0;
6424 mp3format.nCodecDelay = 0;
6426 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
6427 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6429 validate_media_type(mediatype, &mp3format.wfx);
6430 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
6431 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6432 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
6433 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
6435 IMFMediaType_Release(mediatype);
6438 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
6440 MFVIDEOFORMAT *video_format;
6441 IMFMediaType *media_type;
6442 UINT32 size;
6443 HRESULT hr;
6445 hr = MFCreateMediaType(&media_type);
6446 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6448 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
6449 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6450 ok(!!video_format, "Unexpected format.\n");
6451 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
6452 CoTaskMemFree(video_format);
6454 IMFMediaType_Release(media_type);
6457 static void test_MFCreateDXSurfaceBuffer(void)
6459 IDirect3DSurface9 *backbuffer = NULL, *surface;
6460 IDirect3DSwapChain9 *swapchain;
6461 D3DLOCKED_RECT locked_rect;
6462 DWORD length, max_length;
6463 IDirect3DDevice9 *device;
6464 IMF2DBuffer2 *_2dbuffer2;
6465 BOOL value, broken_test;
6466 IMFMediaBuffer *buffer;
6467 IMF2DBuffer *_2dbuffer;
6468 BYTE *data, *data2;
6469 IMFGetService *gs;
6470 IDirect3D9 *d3d;
6471 HWND window;
6472 HRESULT hr;
6473 LONG pitch;
6475 if (!pMFCreateDXSurfaceBuffer)
6477 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
6478 return;
6481 window = create_window();
6482 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6483 ok(!!d3d, "Failed to create a D3D object.\n");
6484 if (!(device = create_d3d9_device(d3d, window)))
6486 skip("Failed to create a D3D device, skipping tests.\n");
6487 goto done;
6490 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
6491 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08lx)\n", hr);
6493 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6494 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08lx)\n", hr);
6495 ok(backbuffer != NULL, "The back buffer is NULL\n");
6497 IDirect3DSwapChain9_Release(swapchain);
6499 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
6500 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6502 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
6503 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6505 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6506 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6507 check_interface(buffer, &IID_IMFGetService, TRUE);
6509 /* Surface is accessible. */
6510 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
6511 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6512 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
6513 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6514 ok(surface == backbuffer, "Unexpected surface pointer.\n");
6515 IDirect3DSurface9_Release(surface);
6516 IMFGetService_Release(gs);
6518 max_length = 0;
6519 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6521 ok(!!max_length, "Unexpected length %lu.\n", max_length);
6523 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6524 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6525 ok(!length, "Unexpected length %lu.\n", length);
6527 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6528 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6530 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6531 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6532 ok(length == 2 * max_length, "Unexpected length %lu.\n", length);
6534 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6535 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6537 /* Cannot lock while the surface is locked. */
6538 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6539 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6541 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6542 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6544 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6545 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6546 /* Broken on Windows 8 and 10 v1507 */
6547 broken_test = length == 0;
6548 ok(length == max_length || broken(broken_test), "Unexpected length %lu instead of %lu.\n", length, max_length);
6550 /* You can lock the surface while the media buffer is locked. */
6551 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6552 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6554 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6557 hr = IMFMediaBuffer_Unlock(buffer);
6558 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6560 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6561 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6563 /* Unlock twice. */
6564 hr = IMFMediaBuffer_Unlock(buffer);
6565 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6567 hr = IMFMediaBuffer_Unlock(buffer);
6568 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6570 /* Lock twice. */
6571 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6574 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6575 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6576 ok(data == data2, "Unexpected pointer.\n");
6578 hr = IMFMediaBuffer_Unlock(buffer);
6579 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6581 hr = IMFMediaBuffer_Unlock(buffer);
6582 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6584 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6585 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6587 /* Unlocked. */
6588 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6589 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6591 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6592 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6594 /* Cannot lock the buffer while the surface is locked. */
6595 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6596 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6598 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6599 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6601 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6604 /* Cannot lock the surface once the buffer is locked. */
6605 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6606 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6608 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6609 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6611 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6612 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6614 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6615 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6617 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6618 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6620 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6621 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6623 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6624 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6626 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6627 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6629 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6630 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
6632 hr = IMFMediaBuffer_Unlock(buffer);
6633 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6635 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
6636 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6637 ok(!value, "Unexpected return value %d.\n", value);
6639 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6640 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6641 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6642 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6643 ok(length == max_length, "Unexpected length %lu.\n", length);
6645 IMF2DBuffer_Release(_2dbuffer);
6647 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6648 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6650 /* Lock flags are ignored, so writing is allowed when locking for
6651 * reading and viceversa. */
6652 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6653 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6654 ok(data == data2, "Unexpected scanline pointer.\n");
6655 memset(data, 0xab, 4);
6656 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6658 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6659 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6660 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6661 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6663 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6664 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6665 ok(data[0] == 0xab || broken(broken_test), "Unexpected leading byte.\n");
6666 hr = IMFMediaBuffer_Unlock(buffer);
6667 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6669 /* Also, flags incompatibilities are not taken into account even
6670 * if a buffer is already locked. */
6671 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6673 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6674 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6675 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6676 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6677 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6678 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6679 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6680 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6681 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6682 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6683 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6684 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6685 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6686 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6687 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6688 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6689 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6690 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6692 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6693 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6694 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6695 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6696 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6697 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6698 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6699 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6700 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6701 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6702 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6703 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6704 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6705 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6706 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6707 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6708 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6709 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6710 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6713 /* Except when originally locking for writing. */
6714 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6716 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6717 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6718 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6719 todo_wine
6720 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
6721 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6722 todo_wine
6723 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
6724 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6725 todo_wine
6726 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
6727 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6728 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6729 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6730 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6732 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6733 todo_wine
6734 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6736 IMF2DBuffer2_Release(_2dbuffer2);
6738 IMFMediaBuffer_Release(buffer);
6739 IDirect3DDevice9_Release(device);
6741 done:
6742 if (backbuffer)
6743 IDirect3DSurface9_Release(backbuffer);
6744 ok(!IDirect3D9_Release(d3d), "Unexpected refcount.\n");
6745 DestroyWindow(window);
6748 static void test_MFCreateTrackedSample(void)
6750 IMFTrackedSample *tracked_sample;
6751 IMFSample *sample;
6752 IUnknown *unk;
6753 HRESULT hr;
6755 if (!pMFCreateTrackedSample)
6757 win_skip("MFCreateTrackedSample() is not available.\n");
6758 return;
6761 hr = pMFCreateTrackedSample(&tracked_sample);
6762 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6764 /* It's actually a sample. */
6765 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
6766 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6768 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
6769 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6770 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
6771 IUnknown_Release(unk);
6773 IMFSample_Release(sample);
6775 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
6777 IMFTrackedSample_Release(tracked_sample);
6780 static void test_MFFrameRateToAverageTimePerFrame(void)
6782 static const struct frame_rate_test
6784 unsigned int numerator;
6785 unsigned int denominator;
6786 UINT64 avgtime;
6787 } frame_rate_tests[] =
6789 { 60000, 1001, 166833 },
6790 { 30000, 1001, 333667 },
6791 { 24000, 1001, 417188 },
6792 { 60, 1, 166667 },
6793 { 30, 1, 333333 },
6794 { 50, 1, 200000 },
6795 { 25, 1, 400000 },
6796 { 24, 1, 416667 },
6798 { 39, 1, 256410 },
6799 { 120, 1, 83333 },
6801 unsigned int i;
6802 UINT64 avgtime;
6803 HRESULT hr;
6805 avgtime = 1;
6806 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
6807 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6808 ok(!avgtime, "Unexpected frame time.\n");
6810 avgtime = 1;
6811 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
6812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6813 ok(!avgtime, "Unexpected frame time.\n");
6815 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6817 avgtime = 0;
6818 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
6819 frame_rate_tests[i].denominator, &avgtime);
6820 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6821 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
6822 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
6826 static void test_MFAverageTimePerFrameToFrameRate(void)
6828 static const struct frame_rate_test
6830 unsigned int numerator;
6831 unsigned int denominator;
6832 UINT64 avgtime;
6833 } frame_rate_tests[] =
6835 { 60000, 1001, 166833 },
6836 { 30000, 1001, 333667 },
6837 { 24000, 1001, 417188 },
6838 { 60, 1, 166667 },
6839 { 30, 1, 333333 },
6840 { 50, 1, 200000 },
6841 { 25, 1, 400000 },
6842 { 24, 1, 416667 },
6844 { 1000000, 25641, 256410 },
6845 { 10000000, 83333, 83333 },
6846 { 1, 10, 100000000 },
6847 { 1, 10, 100000001 },
6848 { 1, 10, 200000000 },
6849 { 1, 1, 10000000 },
6850 { 1, 2, 20000000 },
6851 { 5, 1, 2000000 },
6852 { 10, 1, 1000000 },
6854 unsigned int i, numerator, denominator;
6855 HRESULT hr;
6857 numerator = denominator = 1;
6858 hr = MFAverageTimePerFrameToFrameRate(0, &numerator, &denominator);
6859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6860 ok(!numerator && !denominator, "Unexpected output %u/%u.\n", numerator, denominator);
6862 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6864 numerator = denominator = 12345;
6865 hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
6866 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6867 ok(numerator == frame_rate_tests[i].numerator && denominator == frame_rate_tests[i].denominator,
6868 "%u: unexpected %u/%u, expected %u/%u.\n", i, numerator, denominator, frame_rate_tests[i].numerator,
6869 frame_rate_tests[i].denominator);
6873 static void test_MFMapDXGIFormatToDX9Format(void)
6875 static const struct format_pair
6877 DXGI_FORMAT dxgi_format;
6878 DWORD d3d9_format;
6880 formats_map[] =
6882 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6883 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6884 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6885 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6886 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6887 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6888 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6889 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6890 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6891 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6892 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6893 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6894 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6895 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6896 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6897 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6898 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6899 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6900 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6901 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6902 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
6903 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6904 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
6905 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6906 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
6907 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6908 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6909 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6910 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
6911 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6912 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6913 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6914 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6915 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6916 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6917 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6918 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6919 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6920 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6921 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6922 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6923 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6924 { DXGI_FORMAT_P8, D3DFMT_P8 },
6925 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6927 unsigned int i;
6928 DWORD format;
6930 if (!pMFMapDXGIFormatToDX9Format)
6932 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
6933 return;
6936 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6938 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
6939 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
6943 static void test_MFMapDX9FormatToDXGIFormat(void)
6945 static const struct format_pair
6947 DXGI_FORMAT dxgi_format;
6948 DWORD d3d9_format;
6950 formats_map[] =
6952 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6953 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6954 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6955 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6956 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6957 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6958 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6959 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6960 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6961 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6962 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6963 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6964 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6965 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6966 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6967 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6968 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6969 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6970 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6971 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6972 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6973 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6974 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6975 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6976 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6977 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6978 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6979 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6980 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6981 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6982 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6983 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6984 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6985 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6986 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6987 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6988 { DXGI_FORMAT_P8, D3DFMT_P8 },
6989 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6991 DXGI_FORMAT format;
6992 unsigned int i;
6994 if (!pMFMapDX9FormatToDXGIFormat)
6996 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
6997 return;
7000 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
7002 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
7003 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#lx.\n",
7004 format, formats_map[i].d3d9_format);
7008 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
7009 REFIID riid, void **obj)
7011 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
7012 IsEqualIID(riid, &IID_IUnknown))
7014 *obj = iface;
7015 IMFVideoSampleAllocatorNotify_AddRef(iface);
7016 return S_OK;
7019 *obj = NULL;
7020 return E_NOINTERFACE;
7023 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
7025 return 2;
7028 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
7030 return 1;
7033 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
7035 return E_NOTIMPL;
7038 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
7040 test_notify_callback_QueryInterface,
7041 test_notify_callback_AddRef,
7042 test_notify_callback_Release,
7043 test_notify_callback_NotifyRelease,
7046 static IMFMediaType * create_video_type(const GUID *subtype)
7048 IMFMediaType *video_type;
7049 HRESULT hr;
7051 hr = MFCreateMediaType(&video_type);
7052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7054 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
7055 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7057 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
7058 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7060 return video_type;
7063 static ID3D11Device *create_d3d11_device(void)
7065 static const D3D_FEATURE_LEVEL default_feature_level[] =
7067 D3D_FEATURE_LEVEL_11_0,
7068 D3D_FEATURE_LEVEL_10_1,
7069 D3D_FEATURE_LEVEL_10_0,
7071 const D3D_FEATURE_LEVEL *feature_level;
7072 unsigned int feature_level_count;
7073 ID3D11Device *device;
7075 feature_level = default_feature_level;
7076 feature_level_count = ARRAY_SIZE(default_feature_level);
7078 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
7079 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7080 return device;
7081 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
7082 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7083 return device;
7084 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
7085 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7086 return device;
7088 return NULL;
7091 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
7092 const BYTE *data, unsigned int src_pitch)
7094 ID3D11DeviceContext *immediate_context;
7095 ID3D11Device *device;
7097 ID3D11Texture2D_GetDevice(texture, &device);
7098 ID3D11Device_GetImmediateContext(device, &immediate_context);
7100 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
7101 sub_resource_idx, NULL, data, src_pitch, 0);
7103 ID3D11DeviceContext_Release(immediate_context);
7104 ID3D11Device_Release(device);
7107 static ID3D12Device *create_d3d12_device(void)
7109 ID3D12Device *device;
7110 HRESULT hr;
7112 if (!pD3D12CreateDevice) return NULL;
7114 hr = pD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
7115 if (FAILED(hr))
7116 return NULL;
7118 return device;
7121 static void test_d3d11_surface_buffer(void)
7123 DWORD max_length, cur_length, length, color;
7124 IMFDXGIBuffer *dxgi_buffer;
7125 D3D11_TEXTURE2D_DESC desc;
7126 ID3D11Texture2D *texture;
7127 IMF2DBuffer *_2d_buffer;
7128 IMFMediaBuffer *buffer;
7129 ID3D11Device *device;
7130 BYTE buff[64 * 64 * 4];
7131 BYTE *data, *data2;
7132 LONG pitch, pitch2;
7133 UINT index, size;
7134 IUnknown *obj;
7135 HRESULT hr;
7137 if (!pMFCreateDXGISurfaceBuffer)
7139 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
7140 return;
7143 /* d3d11 */
7144 if (!(device = create_d3d11_device()))
7146 skip("Failed to create a D3D11 device, skipping tests.\n");
7147 return;
7150 memset(&desc, 0, sizeof(desc));
7151 desc.Width = 64;
7152 desc.Height = 64;
7153 desc.ArraySize = 1;
7154 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7155 desc.SampleDesc.Count = 1;
7156 desc.SampleDesc.Quality = 0;
7158 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7159 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7161 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
7162 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7164 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7165 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7166 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7167 check_interface(buffer, &IID_IMFGetService, FALSE);
7169 max_length = 0;
7170 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
7171 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7172 ok(!!max_length, "Unexpected length %lu.\n", max_length);
7174 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7175 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7176 ok(!cur_length, "Unexpected length %lu.\n", cur_length);
7178 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
7179 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7181 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7182 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7183 ok(cur_length == 2 * max_length, "Unexpected length %lu.\n", cur_length);
7185 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7186 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7188 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
7189 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7190 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
7191 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7192 ok(length == max_length, "Unexpected length %lu.\n", length);
7193 IMF2DBuffer_Release(_2d_buffer);
7195 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7196 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7198 EXPECT_REF(texture, 2);
7199 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
7200 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7201 EXPECT_REF(texture, 3);
7202 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
7203 IUnknown_Release(obj);
7205 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
7206 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7208 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
7209 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7210 ok(index == 0, "Unexpected subresource index.\n");
7212 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7213 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7215 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7216 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7218 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7219 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#lx.\n", hr);
7221 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
7222 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7224 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
7225 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7226 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
7227 IUnknown_Release(obj);
7229 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7230 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7232 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
7233 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7235 IMFDXGIBuffer_Release(dxgi_buffer);
7237 /* Texture updates. */
7238 color = get_d3d11_texture_color(texture, 0, 0);
7239 ok(!color, "Unexpected texture color %#lx.\n", color);
7241 max_length = cur_length = 0;
7242 data = NULL;
7243 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7244 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7245 ok(max_length && max_length == cur_length, "Unexpected length %lu.\n", max_length);
7246 if (data) *(DWORD *)data = ~0u;
7248 color = get_d3d11_texture_color(texture, 0, 0);
7249 ok(!color, "Unexpected texture color %#lx.\n", color);
7251 hr = IMFMediaBuffer_Unlock(buffer);
7252 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7254 color = get_d3d11_texture_color(texture, 0, 0);
7255 ok(color == ~0u, "Unexpected texture color %#lx.\n", color);
7257 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7258 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7259 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#lx.\n", *(DWORD *)data);
7261 hr = IMFMediaBuffer_Unlock(buffer);
7262 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7264 /* Lock2D()/Unlock2D() */
7265 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7266 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7268 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7269 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7271 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7272 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7273 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7275 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7277 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7279 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7281 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7283 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7284 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
7286 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7287 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7289 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7290 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7292 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7293 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7295 IMF2DBuffer_Release(_2d_buffer);
7296 IMFMediaBuffer_Release(buffer);
7298 /* Bottom up. */
7299 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
7300 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7302 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7303 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7305 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7306 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7307 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7309 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7310 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7311 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7313 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7314 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7316 IMF2DBuffer_Release(_2d_buffer);
7317 IMFMediaBuffer_Release(buffer);
7319 ID3D11Texture2D_Release(texture);
7321 /* Subresource index 1. */
7322 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7323 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7325 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
7326 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7328 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7331 /* Pitch reflects top level. */
7332 memset(buff, 0, sizeof(buff));
7333 *(DWORD *)buff = 0xff00ff00;
7334 update_d3d11_texture(texture, 1, buff, 64 * 4);
7336 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7337 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7338 ok(pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7339 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#lx.\n", *(DWORD *)data);
7341 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7342 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7344 IMF2DBuffer_Release(_2d_buffer);
7345 IMFMediaBuffer_Release(buffer);
7347 ID3D11Texture2D_Release(texture);
7349 ID3D11Device_Release(device);
7352 static void test_d3d12_surface_buffer(void)
7354 IMFDXGIBuffer *dxgi_buffer;
7355 D3D12_HEAP_PROPERTIES heap_props;
7356 D3D12_RESOURCE_DESC desc;
7357 ID3D12Resource *resource;
7358 IMFMediaBuffer *buffer;
7359 unsigned int refcount;
7360 ID3D12Device *device;
7361 IUnknown *obj;
7362 HRESULT hr;
7364 /* d3d12 */
7365 if (!(device = create_d3d12_device()))
7367 skip("Failed to create a D3D12 device, skipping tests.\n");
7368 return;
7371 memset(&heap_props, 0, sizeof(heap_props));
7372 heap_props.Type = D3D12_HEAP_TYPE_DEFAULT;
7374 memset(&desc, 0, sizeof(desc));
7375 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
7376 desc.Alignment = 0;
7377 desc.Width = 32;
7378 desc.Height = 32;
7379 desc.DepthOrArraySize = 1;
7380 desc.MipLevels = 1;
7381 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7382 desc.SampleDesc.Count = 1;
7383 desc.SampleDesc.Quality = 0;
7384 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
7385 desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
7387 hr = ID3D12Device_CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE,
7388 &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&resource);
7389 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7391 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D12Resource, (IUnknown *)resource, 0, FALSE, &buffer);
7392 if (hr == E_INVALIDARG)
7394 todo_wine
7395 win_skip("D3D12 resource buffers are not supported.\n");
7396 goto notsupported;
7398 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7400 if (SUCCEEDED(hr))
7402 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7403 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7404 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7405 check_interface(buffer, &IID_IMFGetService, FALSE);
7407 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7408 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7410 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&obj);
7411 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7412 ok(obj == (IUnknown *)resource, "Unexpected resource pointer.\n");
7413 IUnknown_Release(obj);
7415 IMFDXGIBuffer_Release(dxgi_buffer);
7416 IMFMediaBuffer_Release(buffer);
7419 notsupported:
7420 ID3D12Resource_Release(resource);
7421 refcount = ID3D12Device_Release(device);
7422 ok(!refcount, "Unexpected device refcount %u.\n", refcount);
7425 static void test_sample_allocator_sysmem(void)
7427 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
7428 IMFMediaType *media_type, *video_type, *video_type2;
7429 IMFVideoSampleAllocatorCallback *allocator_cb;
7430 IMFVideoSampleAllocatorEx *allocatorex;
7431 IMFVideoSampleAllocator *allocator;
7432 IMFSample *sample, *sample2;
7433 IMFAttributes *attributes;
7434 IMFMediaBuffer *buffer;
7435 LONG refcount, count;
7436 DWORD buffer_count;
7437 IUnknown *unk;
7438 HRESULT hr;
7440 if (!pMFCreateVideoSampleAllocatorEx)
7441 return;
7443 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
7444 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7446 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
7447 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
7448 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
7450 IUnknown_Release(unk);
7452 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7453 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7455 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7456 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7458 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7459 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7461 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
7462 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7464 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7465 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7467 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
7468 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7470 count = 10;
7471 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7472 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7473 ok(!count, "Unexpected count %ld.\n", count);
7475 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7476 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7478 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7479 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7481 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
7482 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7484 hr = MFCreateMediaType(&media_type);
7485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7487 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
7488 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7490 video_type = create_video_type(&MFVideoFormat_RGB32);
7491 video_type2 = create_video_type(&MFVideoFormat_RGB32);
7493 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7494 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7496 /* Frame size is required. */
7497 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7498 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7500 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7501 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7503 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
7504 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7506 EXPECT_REF(video_type, 1);
7507 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7508 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7509 EXPECT_REF(video_type, 2);
7511 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
7512 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7514 /* Setting identical type does not replace it. */
7515 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7516 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7517 EXPECT_REF(video_type, 2);
7518 EXPECT_REF(video_type2, 1);
7520 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7521 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7523 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7525 EXPECT_REF(video_type2, 2);
7526 EXPECT_REF(video_type, 1);
7528 /* Modify referenced type. */
7529 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
7530 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7532 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7533 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7534 EXPECT_REF(video_type, 2);
7535 EXPECT_REF(video_type2, 1);
7537 count = 0;
7538 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7539 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7540 ok(count == 1, "Unexpected count %ld.\n", count);
7542 sample = NULL;
7543 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7544 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7545 refcount = get_refcount(sample);
7547 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7549 ok(!count, "Unexpected count %ld.\n", count);
7551 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
7552 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
7554 /* Reinitialize with active sample. */
7555 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7556 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7557 ok(refcount == get_refcount(sample), "Unexpected refcount %lu.\n", get_refcount(sample));
7558 EXPECT_REF(video_type, 2);
7560 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7561 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7562 todo_wine
7563 ok(!count, "Unexpected count %ld.\n", count);
7565 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7566 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7568 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7569 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7571 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7572 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7573 check_interface(buffer, &IID_IMFGetService, TRUE);
7574 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7576 IMFMediaBuffer_Release(buffer);
7578 hr = IMFSample_GetBufferCount(sample, &buffer_count);
7579 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7580 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
7582 IMFSample_Release(sample);
7584 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7585 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7586 todo_wine
7587 EXPECT_REF(video_type, 2);
7589 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7591 ok(!count, "Unexpected count %ld.\n", count);
7593 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7594 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7596 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
7597 IMFVideoSampleAllocator_Release(allocator);
7599 /* IMFVideoSampleAllocatorEx */
7600 hr = MFCreateAttributes(&attributes, 0);
7601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7603 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7604 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7606 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7607 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7609 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
7610 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7612 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
7613 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7615 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7616 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7618 EXPECT_REF(attributes, 1);
7619 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7620 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7621 EXPECT_REF(attributes, 2);
7623 count = 0;
7624 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7625 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7626 ok(count == 1, "Unexpected count %ld.\n", count);
7628 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7629 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7631 hr = IMFSample_GetBufferCount(sample, &buffer_count);
7632 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7633 ok(buffer_count == 2, "Unexpected buffer count %lu.\n", buffer_count);
7635 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
7636 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
7638 /* Reinitialize with already allocated samples. */
7639 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
7640 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7641 EXPECT_REF(attributes, 1);
7643 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
7644 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7645 IMFSample_Release(sample2);
7647 IMFSample_Release(sample);
7649 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
7650 IMFVideoSampleAllocatorEx_Release(allocatorex);
7651 IMFAttributes_Release(attributes);
7654 static void test_sample_allocator_d3d9(void)
7656 IDirect3DDeviceManager9 *d3d9_manager;
7657 IMFVideoSampleAllocator *allocator;
7658 IDirect3DDevice9 *d3d9_device;
7659 IMFMediaType *video_type;
7660 IMFMediaBuffer *buffer;
7661 unsigned int token;
7662 IMFSample *sample;
7663 IDirect3D9 *d3d9;
7664 HWND window;
7665 HRESULT hr;
7667 if (!pMFCreateVideoSampleAllocatorEx)
7668 return;
7670 window = create_window();
7671 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7672 ok(!!d3d9, "Failed to create a D3D9 object.\n");
7673 if (!(d3d9_device = create_d3d9_device(d3d9, window)))
7675 skip("Failed to create a D3D9 device, skipping tests.\n");
7676 goto done;
7679 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
7680 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7682 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
7683 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7685 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7686 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7688 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
7689 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7691 video_type = create_video_type(&MFVideoFormat_RGB32);
7693 /* Frame size is required. */
7694 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7695 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7697 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7698 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7700 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7701 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7703 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7704 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7706 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7707 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7709 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7710 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7711 check_interface(buffer, &IID_IMFGetService, TRUE);
7712 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7714 IMFSample_Release(sample);
7715 IMFMediaBuffer_Release(buffer);
7717 IMFVideoSampleAllocator_Release(allocator);
7718 IMFMediaType_Release(video_type);
7719 IDirect3DDeviceManager9_Release(d3d9_manager);
7720 IDirect3DDevice9_Release(d3d9_device);
7722 done:
7723 IDirect3D9_Release(d3d9);
7724 DestroyWindow(window);
7727 static void test_sample_allocator_d3d11(void)
7729 IMFMediaType *video_type;
7730 IMFVideoSampleAllocatorEx *allocatorex;
7731 IMFVideoSampleAllocator *allocator;
7732 unsigned int i, token;
7733 IMFDXGIDeviceManager *manager;
7734 IMFSample *sample;
7735 IMFDXGIBuffer *dxgi_buffer;
7736 IMFAttributes *attributes;
7737 D3D11_TEXTURE2D_DESC desc;
7738 ID3D11Texture2D *texture;
7739 IMFMediaBuffer *buffer;
7740 ID3D11Device *device;
7741 HRESULT hr;
7742 BYTE *data;
7743 static const unsigned int usage[] =
7745 D3D11_USAGE_DEFAULT,
7746 D3D11_USAGE_IMMUTABLE,
7747 D3D11_USAGE_DYNAMIC,
7748 D3D11_USAGE_STAGING,
7749 D3D11_USAGE_STAGING + 1,
7751 static const unsigned int sharing[] =
7753 D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
7754 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
7755 D3D11_RESOURCE_MISC_SHARED,
7758 if (!pMFCreateVideoSampleAllocatorEx)
7759 return;
7761 if (!(device = create_d3d11_device()))
7763 skip("Failed to create a D3D11 device, skipping tests.\n");
7764 return;
7767 hr = pMFCreateDXGIDeviceManager(&token, &manager);
7768 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
7770 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
7771 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
7773 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7774 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7776 EXPECT_REF(manager, 1);
7777 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
7778 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7779 EXPECT_REF(manager, 2);
7781 video_type = create_video_type(&MFVideoFormat_RGB32);
7782 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7783 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7785 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7786 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7788 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7791 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7792 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7794 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7795 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7796 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7797 check_interface(buffer, &IID_IMFGetService, FALSE);
7799 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7800 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7802 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7803 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7805 ID3D11Texture2D_GetDesc(texture, &desc);
7806 ok(desc.Width == 64, "Unexpected width %u.\n", desc.Width);
7807 ok(desc.Height == 64, "Unexpected height %u.\n", desc.Height);
7808 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
7809 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
7810 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
7811 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
7812 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
7813 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
7814 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
7815 desc.BindFlags);
7816 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7817 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
7819 ID3D11Texture2D_Release(texture);
7820 IMFDXGIBuffer_Release(dxgi_buffer);
7822 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7823 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7825 hr = IMFMediaBuffer_Unlock(buffer);
7826 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7828 IMFMediaBuffer_Release(buffer);
7829 IMFSample_Release(sample);
7831 IMFVideoSampleAllocator_Release(allocator);
7833 /* MF_SA_D3D11_USAGE */
7834 hr = MFCreateAttributes(&attributes, 1);
7835 ok(hr == S_OK, "Failed to create attributes, hr %#lx.\n", hr);
7837 for (i = 0; i < ARRAY_SIZE(usage); ++i)
7839 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7842 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
7843 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7845 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
7846 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7848 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7849 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
7851 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7852 IMFVideoSampleAllocatorEx_Release(allocatorex);
7853 continue;
7855 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", usage[i], hr);
7857 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
7858 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7860 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7861 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7863 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7864 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7866 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7867 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7869 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7870 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7872 ID3D11Texture2D_GetDesc(texture, &desc);
7873 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
7874 if (usage[i] == D3D11_USAGE_DEFAULT)
7876 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
7877 desc.BindFlags);
7878 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7880 else if (usage[i] == D3D11_USAGE_DYNAMIC)
7882 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
7883 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7885 else if (usage[i] == D3D11_USAGE_STAGING)
7887 ok(!desc.BindFlags, "Unexpected bind flags %#x.\n", desc.BindFlags);
7888 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
7889 desc.CPUAccessFlags);
7891 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
7893 ID3D11Texture2D_Release(texture);
7894 IMFDXGIBuffer_Release(dxgi_buffer);
7895 IMFMediaBuffer_Release(buffer);
7897 IMFSample_Release(sample);
7899 IMFVideoSampleAllocatorEx_Release(allocatorex);
7902 /* MF_SA_D3D11_SHARED, MF_SA_D3D11_SHARED_WITHOUT_MUTEX */
7903 for (i = 0; i < ARRAY_SIZE(sharing); ++i)
7905 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7906 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7908 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
7909 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7911 hr = IMFAttributes_DeleteAllItems(attributes);
7912 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7914 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
7915 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7917 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
7919 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED, TRUE);
7920 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7923 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED)
7925 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
7926 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7929 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7930 if (sharing[i] == (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED))
7932 todo_wine
7933 ok(hr == E_INVALIDARG, "%u: Unexpected hr %#lx.\n", i, hr);
7934 IMFVideoSampleAllocatorEx_Release(allocatorex);
7935 continue;
7937 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", i, hr);
7939 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7940 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7942 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7943 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7945 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7946 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7948 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7949 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7951 ID3D11Texture2D_GetDesc(texture, &desc);
7952 ok(desc.MiscFlags == sharing[i], "%u: unexpected misc flags %#x.\n", i, desc.MiscFlags);
7954 ID3D11Texture2D_Release(texture);
7955 IMFDXGIBuffer_Release(dxgi_buffer);
7956 IMFMediaBuffer_Release(buffer);
7958 IMFSample_Release(sample);
7960 IMFVideoSampleAllocatorEx_Release(allocatorex);
7963 IMFAttributes_Release(attributes);
7965 IMFDXGIDeviceManager_Release(manager);
7966 ID3D11Device_Release(device);
7969 static void test_sample_allocator_d3d12(void)
7971 IMFVideoSampleAllocator *allocator = NULL;
7972 D3D12_HEAP_PROPERTIES heap_props;
7973 IMFDXGIDeviceManager *manager;
7974 D3D12_HEAP_FLAGS heap_flags;
7975 IMFDXGIBuffer *dxgi_buffer;
7976 IMFMediaType *video_type;
7977 ID3D12Resource *resource;
7978 D3D12_RESOURCE_DESC desc;
7979 IMFMediaBuffer *buffer;
7980 ID3D12Device *device;
7981 unsigned int token;
7982 IMFSample *sample;
7983 HRESULT hr;
7985 if (!(device = create_d3d12_device()))
7987 skip("Failed to create a D3D12 device, skipping tests.\n");
7988 return;
7991 hr = pMFCreateDXGIDeviceManager(&token, &manager);
7992 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
7994 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
7995 if (FAILED(hr))
7997 win_skip("Device manager does not support D3D12 devices.\n");
7998 goto done;
8000 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
8002 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8003 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8005 EXPECT_REF(manager, 1);
8006 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
8007 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8008 EXPECT_REF(manager, 2);
8010 video_type = create_video_type(&MFVideoFormat_RGB32);
8011 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8012 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8013 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_D3D_RESOURCE_VERSION, MF_D3D12_RESOURCE);
8014 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8016 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8017 todo_wine
8018 ok(hr == S_OK || broken(hr == MF_E_UNEXPECTED) /* Some Win10 versions fail. */, "Unexpected hr %#lx.\n", hr);
8019 if (FAILED(hr)) goto done;
8021 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8022 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8024 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8025 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8027 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8028 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8029 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8030 check_interface(buffer, &IID_IMFGetService, FALSE);
8032 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8033 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8035 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&resource);
8036 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8038 resource->lpVtbl->GetDesc(resource, &desc);
8039 ok(desc.Width == 64, "Unexpected width.\n");
8040 ok(desc.Height == 64, "Unexpected height.\n");
8041 ok(desc.DepthOrArraySize == 1, "Unexpected array size %u.\n", desc.DepthOrArraySize);
8042 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
8043 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
8044 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
8045 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
8046 ok(!desc.Layout, "Unexpected layout %u.\n", desc.Layout);
8047 ok(!desc.Flags, "Unexpected flags %#x.\n", desc.Flags);
8049 hr = ID3D12Resource_GetHeapProperties(resource, &heap_props, &heap_flags);
8050 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8051 ok(heap_props.Type == D3D12_HEAP_TYPE_DEFAULT, "Unexpected heap type %u.\n", heap_props.Type);
8052 ok(heap_props.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN, "Unexpected page property %u.\n",
8053 heap_props.CPUPageProperty);
8054 ok(!heap_props.MemoryPoolPreference, "Unexpected pool preference %u.\n", heap_props.MemoryPoolPreference);
8055 ok(heap_flags == D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, "Unexpected heap flags %#x.\n", heap_flags);
8057 ID3D12Resource_Release(resource);
8058 IMFDXGIBuffer_Release(dxgi_buffer);
8059 IMFMediaBuffer_Release(buffer);
8060 IMFSample_Release(sample);
8062 done:
8063 if (allocator)
8064 IMFVideoSampleAllocator_Release(allocator);
8065 IMFDXGIDeviceManager_Release(manager);
8066 ID3D12Device_Release(device);
8069 static void test_MFLockSharedWorkQueue(void)
8071 DWORD taskid, queue, queue2;
8072 HRESULT hr;
8074 if (!pMFLockSharedWorkQueue)
8076 win_skip("MFLockSharedWorkQueue() is not available.\n");
8077 return;
8080 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
8081 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
8083 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
8084 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8086 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
8087 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8089 taskid = 0;
8090 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
8091 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8093 queue = 0;
8094 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
8095 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
8097 queue2 = 0;
8098 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
8099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8100 ok(queue == queue2, "Unexpected queue %#lx.\n", queue2);
8102 hr = MFUnlockWorkQueue(queue2);
8103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8105 hr = MFUnlockWorkQueue(queue);
8106 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8108 hr = MFShutdown();
8109 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
8112 static void test_MFllMulDiv(void)
8114 /* (a * b + d) / c */
8115 static const struct muldivtest
8117 LONGLONG a;
8118 LONGLONG b;
8119 LONGLONG c;
8120 LONGLONG d;
8121 LONGLONG result;
8123 muldivtests[] =
8125 { 0, 0, 0, 0, _I64_MAX },
8126 { 1000000, 1000000, 2, 0, 500000000000 },
8127 { _I64_MAX, 3, _I64_MAX, 0, 3 },
8128 { _I64_MAX, 3, _I64_MAX, 1, 3 },
8129 { -10000, 3, 100, 0, -300 },
8130 { 2, 0, 3, 5, 1 },
8131 { 2, 1, 1, -3, -1 },
8132 /* a * b product does not fit in uint64_t */
8133 { _I64_MAX, 4, 8, 0, _I64_MAX / 2 },
8134 /* Large a * b product, large denominator */
8135 { _I64_MAX, 4, 0x100000000, 0, 0x1ffffffff },
8137 unsigned int i;
8139 for (i = 0; i < ARRAY_SIZE(muldivtests); ++i)
8141 LONGLONG result;
8143 result = MFllMulDiv(muldivtests[i].a, muldivtests[i].b, muldivtests[i].c, muldivtests[i].d);
8144 ok(result == muldivtests[i].result, "%u: unexpected result %s, expected %s.\n", i,
8145 wine_dbgstr_longlong(result), wine_dbgstr_longlong(muldivtests[i].result));
8149 static void test_shared_dxgi_device_manager(void)
8151 IMFDXGIDeviceManager *manager;
8152 HRESULT hr;
8153 UINT token;
8155 if (!pMFLockDXGIDeviceManager)
8157 win_skip("Shared DXGI device manager is not supported.\n");
8158 return;
8161 hr = pMFUnlockDXGIDeviceManager();
8162 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8164 manager = NULL;
8165 hr = pMFLockDXGIDeviceManager(NULL, &manager);
8166 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8167 ok(!!manager, "Unexpected instance.\n");
8169 hr = pMFLockDXGIDeviceManager(&token, &manager);
8170 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8172 EXPECT_REF(manager, 3);
8174 hr = pMFUnlockDXGIDeviceManager();
8175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8177 EXPECT_REF(manager, 2);
8179 hr = pMFUnlockDXGIDeviceManager();
8180 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8183 static void check_video_format(const MFVIDEOFORMAT *format, unsigned int width, unsigned int height,
8184 DWORD d3dformat)
8186 unsigned int transfer_function;
8187 GUID guid;
8189 if (!d3dformat) d3dformat = D3DFMT_X8R8G8B8;
8191 switch (d3dformat)
8193 case D3DFMT_X8R8G8B8:
8194 case D3DFMT_R8G8B8:
8195 case D3DFMT_A8R8G8B8:
8196 case D3DFMT_R5G6B5:
8197 case D3DFMT_X1R5G5B5:
8198 case D3DFMT_A2B10G10R10:
8199 case D3DFMT_P8:
8200 transfer_function = MFVideoTransFunc_sRGB;
8201 break;
8202 default:
8203 transfer_function = MFVideoTransFunc_10;
8206 memcpy(&guid, &MFVideoFormat_Base, sizeof(guid));
8207 guid.Data1 = d3dformat;
8209 ok(format->dwSize == sizeof(*format), "Unexpected format size.\n");
8210 ok(format->videoInfo.dwWidth == width, "Unexpected width %lu.\n", format->videoInfo.dwWidth);
8211 ok(format->videoInfo.dwHeight == height, "Unexpected height %lu.\n", format->videoInfo.dwHeight);
8212 ok(format->videoInfo.PixelAspectRatio.Numerator == 1 &&
8213 format->videoInfo.PixelAspectRatio.Denominator == 1, "Unexpected PAR.\n");
8214 ok(format->videoInfo.SourceChromaSubsampling == MFVideoChromaSubsampling_Unknown, "Unexpected chroma subsampling.\n");
8215 ok(format->videoInfo.InterlaceMode == MFVideoInterlace_Progressive, "Unexpected interlace mode %u.\n",
8216 format->videoInfo.InterlaceMode);
8217 ok(format->videoInfo.TransferFunction == transfer_function, "Unexpected transfer function %u.\n",
8218 format->videoInfo.TransferFunction);
8219 ok(format->videoInfo.ColorPrimaries == MFVideoPrimaries_BT709, "Unexpected color primaries %u.\n",
8220 format->videoInfo.ColorPrimaries);
8221 ok(format->videoInfo.TransferMatrix == MFVideoTransferMatrix_Unknown, "Unexpected transfer matrix.\n");
8222 ok(format->videoInfo.SourceLighting == MFVideoLighting_office, "Unexpected source lighting %u.\n",
8223 format->videoInfo.SourceLighting);
8224 ok(format->videoInfo.FramesPerSecond.Numerator == 60 &&
8225 format->videoInfo.FramesPerSecond.Denominator == 1, "Unexpected frame rate %lu/%lu.\n",
8226 format->videoInfo.FramesPerSecond.Numerator, format->videoInfo.FramesPerSecond.Denominator);
8227 ok(format->videoInfo.NominalRange == MFNominalRange_Normal, "Unexpected nominal range %u.\n",
8228 format->videoInfo.NominalRange);
8229 ok(format->videoInfo.GeometricAperture.Area.cx == width && format->videoInfo.GeometricAperture.Area.cy == height,
8230 "Unexpected geometric aperture.\n");
8231 ok(!memcmp(&format->videoInfo.GeometricAperture, &format->videoInfo.MinimumDisplayAperture, sizeof(MFVideoArea)),
8232 "Unexpected minimum display aperture.\n");
8233 ok(format->videoInfo.PanScanAperture.Area.cx == 0 && format->videoInfo.PanScanAperture.Area.cy == 0,
8234 "Unexpected geometric aperture.\n");
8235 ok(format->videoInfo.VideoFlags == 0, "Unexpected video flags.\n");
8236 ok(IsEqualGUID(&format->guidFormat, &guid), "Unexpected format guid %s.\n", wine_dbgstr_guid(&format->guidFormat));
8237 ok(format->compressedInfo.AvgBitrate == 0, "Unexpected bitrate.\n");
8238 ok(format->compressedInfo.AvgBitErrorRate == 0, "Unexpected error bitrate.\n");
8239 ok(format->compressedInfo.MaxKeyFrameSpacing == 0, "Unexpected MaxKeyFrameSpacing.\n");
8240 ok(format->surfaceInfo.Format == d3dformat, "Unexpected format %lu.\n", format->surfaceInfo.Format);
8241 ok(format->surfaceInfo.PaletteEntries == 0, "Unexpected palette size %lu.\n", format->surfaceInfo.PaletteEntries);
8244 static void test_MFInitVideoFormat_RGB(void)
8246 static const DWORD formats[] =
8248 0, /* same D3DFMT_X8R8G8B8 */
8249 D3DFMT_X8R8G8B8,
8250 D3DFMT_R8G8B8,
8251 D3DFMT_A8R8G8B8,
8252 D3DFMT_R5G6B5,
8253 D3DFMT_X1R5G5B5,
8254 D3DFMT_A2B10G10R10,
8255 D3DFMT_P8,
8256 D3DFMT_L8,
8257 D3DFMT_YUY2,
8258 D3DFMT_DXT1,
8259 D3DFMT_D16,
8260 D3DFMT_L16,
8261 D3DFMT_A16B16G16R16F,
8263 MFVIDEOFORMAT format;
8264 unsigned int i;
8265 HRESULT hr;
8267 if (!pMFInitVideoFormat_RGB)
8269 win_skip("MFInitVideoFormat_RGB is not available.\n");
8270 return;
8273 hr = pMFInitVideoFormat_RGB(NULL, 64, 32, 0);
8274 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8276 for (i = 0; i < ARRAY_SIZE(formats); ++i)
8278 memset(&format, 0, sizeof(format));
8279 hr = pMFInitVideoFormat_RGB(&format, 64, 32, formats[i]);
8280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8281 if (SUCCEEDED(hr))
8282 check_video_format(&format, 64, 32, formats[i]);
8286 static void test_MFCreateVideoMediaTypeFromVideoInfoHeader(void)
8288 IMFVideoMediaType *media_type;
8289 KS_VIDEOINFOHEADER vih;
8290 UINT32 value32;
8291 UINT64 value64;
8292 HRESULT hr;
8293 GUID guid;
8295 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(NULL, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8296 todo_wine
8297 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8299 memset(&vih, 0, sizeof(vih));
8300 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8301 todo_wine
8302 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8303 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8304 todo_wine
8305 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8306 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8307 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8308 todo_wine
8309 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8311 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8312 vih.bmiHeader.biPlanes = 1;
8313 vih.bmiHeader.biWidth = 16;
8314 vih.bmiHeader.biHeight = 32;
8315 vih.bmiHeader.biBitCount = 32;
8317 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8318 MFVideoFlag_AnalogProtected, &GUID_NULL, &media_type);
8319 todo_wine
8320 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8321 if (FAILED(hr)) return;
8322 IMFVideoMediaType_Release(media_type);
8324 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8325 MFVideoFlag_AnalogProtected, NULL, &media_type);
8326 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8328 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8330 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8331 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8332 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8333 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8334 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8335 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8336 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8337 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8338 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8339 ok(value64 == ((UINT64)3 << 32 | 2), "Unexpected value %#I64x.\n", value64);
8340 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DRM_FLAGS, &value32);
8341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8342 ok(value32 == MFVideoDRMFlag_AnalogProtected, "Unexpected value %#x.\n", value32);
8343 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8344 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8345 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8346 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8347 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8348 ok(value32 == 2048, "Unexpected value %u.\n", value32);
8349 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8350 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8351 ok(value32 == -64, "Unexpected value %d.\n", value32);
8352 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8353 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8354 ok(!!value32, "Unexpected value %#x.\n", value32);
8355 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8356 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8357 ok(!!value32, "Unexpected value %#x.\n", value32);
8359 IMFVideoMediaType_Release(media_type);
8361 /* Negative height. */
8362 vih.bmiHeader.biHeight = -32;
8363 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8364 MFVideoFlag_AnalogProtected, NULL, &media_type);
8365 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8366 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8367 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8368 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8369 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8370 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8371 ok(value32 == 64, "Unexpected value %d.\n", value32);
8372 IMFVideoMediaType_Release(media_type);
8375 static void test_MFInitMediaTypeFromVideoInfoHeader(void)
8377 IMFMediaType *media_type;
8378 VIDEOINFOHEADER vih;
8379 UINT32 value32;
8380 UINT64 value64;
8381 HRESULT hr;
8382 GUID guid;
8384 hr = MFCreateMediaType(&media_type);
8385 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8387 memset(&vih, 0, sizeof(vih));
8388 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, 0, NULL);
8389 todo_wine
8390 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8391 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8392 todo_wine
8393 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8395 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8396 vih.bmiHeader.biPlanes = 1;
8397 vih.bmiHeader.biWidth = 16;
8398 vih.bmiHeader.biHeight = 32;
8399 vih.bmiHeader.biBitCount = 32;
8401 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
8402 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8404 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8405 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8406 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8407 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8408 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8409 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
8410 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8412 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8413 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8414 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8415 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8416 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8417 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8418 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8420 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8421 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8422 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8423 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8424 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8425 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8426 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8427 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8429 vih.bmiHeader.biHeight = -32;
8430 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
8431 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8432 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8433 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8434 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8436 vih.bmiHeader.biHeight = 32;
8437 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8438 todo_wine
8439 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8440 if (FAILED(hr)) goto failed;
8442 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8443 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8444 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8445 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8446 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8447 todo_wine
8448 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8449 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8450 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8451 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8452 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8453 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8454 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8455 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8456 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8457 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8458 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8459 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8460 ok(value32 == 2048, "Unexpected value %u.\n", value32);
8461 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8462 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8463 ok(value32 == -64, "Unexpected value %d.\n", value32);
8464 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8465 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8466 ok(!!value32, "Unexpected value %#x.\n", value32);
8467 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8468 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8469 ok(!!value32, "Unexpected value %#x.\n", value32);
8471 /* Negative height. */
8472 vih.bmiHeader.biHeight = -32;
8473 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8475 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8476 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8477 ok(value32 == 64, "Unexpected value %d.\n", value32);
8478 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8479 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8480 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8482 failed:
8483 IMFMediaType_Release(media_type);
8486 static void test_MFInitMediaTypeFromAMMediaType(void)
8488 IMFMediaType *media_type;
8489 AM_MEDIA_TYPE mt;
8490 UINT32 value32;
8491 UINT64 value64;
8492 HRESULT hr;
8493 GUID guid;
8494 VIDEOINFOHEADER vih =
8496 {0}, {0}, 0, 0, 0,
8497 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, 0xdeadbeef}
8499 static const struct guid_type_pair
8501 const GUID *am_type;
8502 const GUID *mf_type;
8503 } guid_types[] =
8505 { &MEDIASUBTYPE_I420, &MFVideoFormat_I420 },
8506 { &MEDIASUBTYPE_AYUV, &MFVideoFormat_AYUV },
8507 { &MEDIASUBTYPE_YV12, &MFVideoFormat_YV12 },
8508 { &MEDIASUBTYPE_YUY2, &MFVideoFormat_YUY2 },
8509 { &MEDIASUBTYPE_UYVY, &MFVideoFormat_UYVY },
8510 { &MEDIASUBTYPE_YVYU, &MFVideoFormat_YVYU },
8511 { &MEDIASUBTYPE_NV12, &MFVideoFormat_NV12 },
8512 { &MEDIASUBTYPE_ARGB32, &MFVideoFormat_ARGB32 },
8514 unsigned int i;
8516 hr = MFCreateMediaType(&media_type);
8517 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8519 memset(&mt, 0, sizeof(mt));
8520 mt.majortype = MEDIATYPE_Video;
8521 mt.formattype = FORMAT_VideoInfo;
8522 mt.cbFormat = sizeof(VIDEOINFOHEADER);
8523 mt.pbFormat = (BYTE *)&vih;
8525 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, 123);
8526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8528 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
8529 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8531 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8532 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8533 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8534 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8535 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8536 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
8537 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8538 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8539 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
8540 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8541 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8542 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8543 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8544 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8545 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8546 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8547 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8548 ok(!!value32, "Unexpected value %#x.\n", value32);
8550 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8551 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8552 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8553 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8554 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8555 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8557 vih.bmiHeader.biHeight = -24;
8559 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
8560 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8561 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8563 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
8565 memcpy(&mt.subtype, &MEDIASUBTYPE_RGB32, sizeof(GUID));
8566 vih.bmiHeader.biHeight = 24;
8568 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
8569 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8571 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8573 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8574 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8575 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8576 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8577 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8578 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8579 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
8580 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8581 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8582 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8583 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8584 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8585 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8586 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8587 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8588 ok(value32 == 3072, "Unexpected value %u.\n", value32);
8589 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8591 ok(!!value32, "Unexpected value %#x.\n", value32);
8592 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8593 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8594 ok(!!value32, "Unexpected value %u.\n", value32);
8595 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8597 ok(value32 == -128, "Unexpected value %d.\n", value32);
8599 /* Negative height. */
8600 vih.bmiHeader.biHeight = -24;
8602 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
8603 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8605 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8606 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8607 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8608 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8609 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8610 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8611 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8612 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8613 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
8614 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8615 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8616 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8617 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8618 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8619 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8620 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8621 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8622 ok(value32 == 3072, "Unexpected value %u.\n", value32);
8623 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8624 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8625 ok(!!value32, "Unexpected value %#x.\n", value32);
8626 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8627 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8628 ok(!!value32, "Unexpected value %u.\n", value32);
8629 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8630 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8631 ok(value32 == 128, "Unexpected value %d.\n", value32);
8633 vih.bmiHeader.biHeight = 24;
8634 for (i = 0; i < ARRAY_SIZE(guid_types); ++i)
8636 memcpy(&mt.subtype, guid_types[i].am_type, sizeof(GUID));
8638 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
8639 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8641 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8642 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8643 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8644 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8645 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8646 ok(IsEqualGUID(&guid, guid_types[i].mf_type), "Unexpected guid %s.\n", debugstr_guid(&guid));
8649 IMFMediaType_Release(media_type);
8652 START_TEST(mfplat)
8654 char **argv;
8655 int argc;
8657 init_functions();
8659 argc = winetest_get_mainargs(&argv);
8660 if (argc >= 3)
8662 test_queue_com_state(argv[2]);
8663 return;
8666 if (!pMFCreateVideoSampleAllocatorEx)
8667 win_skip("MFCreateVideoSampleAllocatorEx() is not available. Some tests will be skipped.\n");
8669 if (!pD3D12CreateDevice)
8670 skip("Missing d3d12 support, some tests will be skipped.\n");
8672 CoInitialize(NULL);
8674 test_startup();
8675 test_register();
8676 test_media_type();
8677 test_MFCreateMediaEvent();
8678 test_attributes();
8679 test_sample();
8680 test_file_stream();
8681 test_MFCreateMFByteStreamOnStream();
8682 test_system_memory_buffer();
8683 test_system_memory_aligned_buffer();
8684 test_source_resolver();
8685 test_MFCreateAsyncResult();
8686 test_allocate_queue();
8687 test_MFLockSharedWorkQueue();
8688 test_MFCopyImage();
8689 test_MFCreateCollection();
8690 test_MFHeapAlloc();
8691 test_scheduled_items();
8692 test_serial_queue();
8693 test_periodic_callback();
8694 test_event_queue();
8695 test_presentation_descriptor();
8696 test_system_time_source();
8697 test_MFInvokeCallback();
8698 test_stream_descriptor();
8699 test_MFCalculateImageSize();
8700 test_MFGetPlaneSize();
8701 test_MFCompareFullToPartialMediaType();
8702 test_attributes_serialization();
8703 test_wrapped_media_type();
8704 test_MFCreateWaveFormatExFromMFMediaType();
8705 test_async_create_file();
8706 test_local_handlers();
8707 test_create_property_store();
8708 test_dxgi_device_manager();
8709 test_MFCreateTransformActivate();
8710 test_MFTRegisterLocal();
8711 test_queue_com();
8712 test_MFGetStrideForBitmapInfoHeader();
8713 test_MFCreate2DMediaBuffer();
8714 test_MFCreateMediaBufferFromMediaType();
8715 test_MFInitMediaTypeFromWaveFormatEx();
8716 test_MFCreateMFVideoFormatFromMFMediaType();
8717 test_MFCreateDXSurfaceBuffer();
8718 test_MFCreateTrackedSample();
8719 test_MFFrameRateToAverageTimePerFrame();
8720 test_MFAverageTimePerFrameToFrameRate();
8721 test_MFMapDXGIFormatToDX9Format();
8722 test_d3d11_surface_buffer();
8723 test_d3d12_surface_buffer();
8724 test_sample_allocator_sysmem();
8725 test_sample_allocator_d3d9();
8726 test_sample_allocator_d3d11();
8727 test_sample_allocator_d3d12();
8728 test_MFMapDX9FormatToDXGIFormat();
8729 test_MFllMulDiv();
8730 test_shared_dxgi_device_manager();
8731 test_MFInitVideoFormat_RGB();
8732 test_MFCreateVideoMediaTypeFromVideoInfoHeader();
8733 test_MFInitMediaTypeFromVideoInfoHeader();
8734 test_MFInitMediaTypeFromAMMediaType();
8736 CoUninitialize();