mfplat/tests: Create the test_callback event in the constructor.
[wine.git] / dlls / mfplat / tests / mfplat.c
blob0f4ae026228c68a65d7be9e7b3ce029cbb66efd8
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 d3d9_surface_readback
128 IDirect3DSurface9 *surface, *readback_surface;
129 D3DLOCKED_RECT map_desc;
130 D3DSURFACE_DESC surf_desc;
133 static void get_d3d9_surface_readback(IDirect3DSurface9 *surface, struct d3d9_surface_readback *rb)
135 IDirect3DDevice9 *device;
136 HRESULT hr;
138 rb->surface = surface;
140 hr = IDirect3DSurface9_GetDevice(surface, &device);
141 ok(hr == D3D_OK, "Failed to get device, hr %#lx.\n", hr);
143 hr = IDirect3DSurface9_GetDesc(surface, &rb->surf_desc);
144 ok(hr == D3D_OK, "Failed to get surface desc, hr %#lx.\n", hr);
145 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, rb->surf_desc.Width, rb->surf_desc.Height,
146 rb->surf_desc.Format, D3DPOOL_SYSTEMMEM, &rb->readback_surface, NULL);
147 ok(hr == D3D_OK, "Failed to create surface, hr %#lx.\n", hr);
149 hr = IDirect3DDevice9Ex_GetRenderTargetData(device, surface, rb->readback_surface);
150 ok(hr == D3D_OK, "Failed to get render target data, hr %#lx.\n", hr);
152 hr = IDirect3DSurface9_LockRect(rb->readback_surface, &rb->map_desc, NULL, 0);
153 ok(hr == D3D_OK, "Failed to lock surface, hr %#lx.\n", hr);
155 IDirect3DDevice9_Release(device);
158 static void release_d3d9_surface_readback(struct d3d9_surface_readback *rb, BOOL upload)
160 ULONG refcount;
161 HRESULT hr;
163 hr = IDirect3DSurface9_UnlockRect(rb->readback_surface);
164 ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr);
166 if (upload)
168 IDirect3DDevice9 *device;
170 IDirect3DSurface9_GetDevice(rb->surface, &device);
171 ok(hr == D3D_OK, "Failed to get device, hr %#lx.\n", hr);
173 hr = IDirect3DDevice9_UpdateSurface(device, rb->readback_surface, NULL, rb->surface, NULL);
174 ok(hr == D3D_OK, "Failed to update surface, hr %#lx.\n", hr);
176 IDirect3DDevice9_Release(device);
179 refcount = IDirect3DSurface9_Release(rb->readback_surface);
180 ok(refcount == 0, "Readback surface still has references.\n");
183 static void *get_d3d9_readback_data(struct d3d9_surface_readback *rb,
184 unsigned int x, unsigned int y, unsigned byte_width)
186 return (BYTE *)rb->map_desc.pBits + y * rb->map_desc.Pitch + x * byte_width;
189 static DWORD get_d3d9_readback_u32(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y)
191 return *(DWORD *)get_d3d9_readback_data(rb, x, y, sizeof(DWORD));
194 static DWORD get_d3d9_readback_color(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y)
196 return get_d3d9_readback_u32(rb, x, y);
199 static DWORD get_d3d9_surface_color(IDirect3DSurface9 *surface, unsigned int x, unsigned int y)
201 struct d3d9_surface_readback rb;
202 DWORD color;
204 get_d3d9_surface_readback(surface, &rb);
205 color = get_d3d9_readback_color(&rb, x, y);
206 release_d3d9_surface_readback(&rb, FALSE);
208 return color;
211 static void put_d3d9_readback_u32(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y, DWORD color)
213 *(DWORD *)get_d3d9_readback_data(rb, x, y, sizeof(DWORD)) = color;
216 static void put_d3d9_readback_color(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y, DWORD color)
218 put_d3d9_readback_u32(rb, x, y, color);
221 static void put_d3d9_surface_color(IDirect3DSurface9 *surface,
222 unsigned int x, unsigned int y, DWORD color)
224 struct d3d9_surface_readback rb;
226 get_d3d9_surface_readback(surface, &rb);
227 put_d3d9_readback_color(&rb, x, y, color);
228 release_d3d9_surface_readback(&rb, TRUE);
231 struct d3d11_resource_readback
233 ID3D11Resource *orig_resource, *resource;
234 D3D11_MAPPED_SUBRESOURCE map_desc;
235 ID3D11DeviceContext *immediate_context;
236 unsigned int width, height, depth, sub_resource_idx;
239 static void init_d3d11_resource_readback(ID3D11Resource *resource, ID3D11Resource *readback_resource,
240 unsigned int width, unsigned int height, unsigned int depth, unsigned int sub_resource_idx,
241 ID3D11Device *device, struct d3d11_resource_readback *rb)
243 HRESULT hr;
245 rb->orig_resource = resource;
246 rb->resource = readback_resource;
247 rb->width = width;
248 rb->height = height;
249 rb->depth = depth;
250 rb->sub_resource_idx = sub_resource_idx;
252 ID3D11Device_GetImmediateContext(device, &rb->immediate_context);
254 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->resource, resource);
255 if (FAILED(hr = ID3D11DeviceContext_Map(rb->immediate_context,
256 rb->resource, sub_resource_idx, D3D11_MAP_READ_WRITE, 0, &rb->map_desc)))
258 trace("Failed to map resource, hr %#lx.\n", hr);
259 ID3D11Resource_Release(rb->resource);
260 rb->resource = NULL;
261 ID3D11DeviceContext_Release(rb->immediate_context);
262 rb->immediate_context = NULL;
266 static void get_d3d11_texture2d_readback(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
267 struct d3d11_resource_readback *rb)
269 D3D11_TEXTURE2D_DESC texture_desc;
270 ID3D11Resource *rb_texture;
271 unsigned int miplevel;
272 ID3D11Device *device;
273 HRESULT hr;
275 memset(rb, 0, sizeof(*rb));
277 ID3D11Texture2D_GetDevice(texture, &device);
279 ID3D11Texture2D_GetDesc(texture, &texture_desc);
280 texture_desc.Usage = D3D11_USAGE_STAGING;
281 texture_desc.BindFlags = 0;
282 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
283 texture_desc.MiscFlags = 0;
284 if (FAILED(hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture)))
286 trace("Failed to create texture, hr %#lx.\n", hr);
287 ID3D11Device_Release(device);
288 return;
291 miplevel = sub_resource_idx % texture_desc.MipLevels;
292 init_d3d11_resource_readback((ID3D11Resource *)texture, rb_texture,
293 max(1, texture_desc.Width >> miplevel),
294 max(1, texture_desc.Height >> miplevel),
295 1, sub_resource_idx, device, rb);
297 ID3D11Device_Release(device);
300 static void release_d3d11_resource_readback(struct d3d11_resource_readback *rb, BOOL upload)
302 ID3D11DeviceContext_Unmap(rb->immediate_context, rb->resource, rb->sub_resource_idx);
304 if (upload)
306 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->orig_resource, rb->resource);
309 ID3D11Resource_Release(rb->resource);
310 ID3D11DeviceContext_Release(rb->immediate_context);
313 static void *get_d3d11_readback_data(struct d3d11_resource_readback *rb,
314 unsigned int x, unsigned int y, unsigned int z, unsigned byte_width)
316 return (BYTE *)rb->map_desc.pData + z * rb->map_desc.DepthPitch + y * rb->map_desc.RowPitch + x * byte_width;
319 static DWORD get_d3d11_readback_u32(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
321 return *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD));
324 static DWORD get_d3d11_readback_color(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
326 return get_d3d11_readback_u32(rb, x, y, z);
329 static DWORD get_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y)
331 struct d3d11_resource_readback rb;
332 DWORD color;
334 get_d3d11_texture2d_readback(texture, 0, &rb);
335 color = get_d3d11_readback_color(&rb, x, y, 0);
336 release_d3d11_resource_readback(&rb, FALSE);
338 return color;
341 static void put_d3d11_readback_u32(struct d3d11_resource_readback *rb,
342 unsigned int x, unsigned int y, unsigned int z, DWORD color)
344 *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD)) = color;
347 static void put_d3d11_readback_color(struct d3d11_resource_readback *rb,
348 unsigned int x, unsigned int y, unsigned int z, DWORD color)
350 put_d3d11_readback_u32(rb, x, y, z, color);
353 static void put_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y, DWORD color)
355 struct d3d11_resource_readback rb;
357 get_d3d11_texture2d_readback(texture, 0, &rb);
358 put_d3d11_readback_color(&rb, x, y, 0, color);
359 release_d3d11_resource_readback(&rb, TRUE);
362 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
363 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
364 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
365 static HRESULT (WINAPI *pD3D12CreateDevice)(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level,
366 REFIID iid, void **device);
368 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
370 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
371 DWORD width, DWORD lines);
372 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
373 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
374 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
375 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
376 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
377 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
378 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
379 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
380 IMFActivate *activate);
381 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
382 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
383 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
384 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
385 const MFT_REGISTER_TYPE_INFO* output_types);
386 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
387 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
388 const MFT_REGISTER_TYPE_INFO *output_types);
389 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
390 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
391 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
392 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
393 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
394 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
395 static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
396 static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
397 IMFMediaBuffer **buffer);
398 static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
399 DWORD min_alignment, IMFMediaBuffer **buffer);
400 static HRESULT (WINAPI *pMFCreatePathFromURL)(const WCHAR *url, WCHAR **path);
401 static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
402 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
403 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
404 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
405 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
406 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
407 IMFMediaBuffer **buffer);
408 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
409 static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
410 static HRESULT (WINAPI *pMFLockDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
411 static HRESULT (WINAPI *pMFUnlockDXGIDeviceManager)(void);
412 static HRESULT (WINAPI *pMFInitVideoFormat_RGB)(MFVIDEOFORMAT *format, DWORD width, DWORD height, DWORD d3dformat);
414 static HWND create_window(void)
416 RECT r = {0, 0, 640, 480};
418 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
420 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
421 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
424 static IDirect3DDevice9 *create_d3d9_device(IDirect3D9 *d3d9, HWND focus_window)
426 D3DPRESENT_PARAMETERS present_parameters = {0};
427 IDirect3DDevice9 *device = NULL;
429 present_parameters.BackBufferWidth = 640;
430 present_parameters.BackBufferHeight = 480;
431 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
432 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
433 present_parameters.hDeviceWindow = focus_window;
434 present_parameters.Windowed = TRUE;
435 present_parameters.EnableAutoDepthStencil = TRUE;
436 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
437 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
439 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
440 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
442 return device;
445 static const WCHAR fileschemeW[] = L"file://";
447 static WCHAR *load_resource(const WCHAR *name)
449 static WCHAR pathW[MAX_PATH];
450 DWORD written;
451 HANDLE file;
452 HRSRC res;
453 void *ptr;
455 GetTempPathW(ARRAY_SIZE(pathW), pathW);
456 lstrcatW(pathW, name);
458 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
459 NULL, CREATE_ALWAYS, 0, 0);
460 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n",
461 wine_dbgstr_w(pathW), GetLastError());
463 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
464 ok(res != 0, "couldn't find resource\n");
465 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
466 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
467 &written, NULL);
468 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
469 "couldn't write resource\n" );
470 CloseHandle(file);
472 return pathW;
475 static BOOL is_MEDIASUBTYPE_RGB(const GUID *subtype)
477 return IsEqualGUID(subtype, &MEDIASUBTYPE_RGB8)
478 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB555)
479 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB565)
480 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB24)
481 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB32);
484 struct test_callback
486 IMFAsyncCallback IMFAsyncCallback_iface;
487 LONG refcount;
488 HANDLE event;
489 DWORD param;
490 IMFMediaEvent *media_event;
493 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
495 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
498 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
500 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
501 IsEqualIID(riid, &IID_IUnknown))
503 *obj = iface;
504 IMFAsyncCallback_AddRef(iface);
505 return S_OK;
508 *obj = NULL;
509 return E_NOINTERFACE;
512 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
514 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
515 return InterlockedIncrement(&callback->refcount);
518 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
520 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
521 ULONG refcount = InterlockedDecrement(&callback->refcount);
523 if (!refcount)
525 CloseHandle(callback->event);
526 free(callback);
529 return refcount;
532 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
534 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
535 return E_NOTIMPL;
538 static BOOL check_clsid(CLSID *clsids, UINT32 count)
540 int i;
541 for (i = 0; i < count; i++)
543 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
544 return TRUE;
546 return FALSE;
549 static void test_register(void)
551 MFT_REGISTER_TYPE_INFO *in_types, *out_types;
552 WCHAR name[] = L"Wine test";
553 MFT_REGISTER_TYPE_INFO input[] =
555 { DUMMY_CLSID, DUMMY_GUID1 }
557 MFT_REGISTER_TYPE_INFO output[] =
559 { DUMMY_CLSID, DUMMY_GUID2 }
561 UINT32 count, in_count, out_count;
562 IMFAttributes *attributes;
563 WCHAR *mft_name;
564 CLSID *clsids;
565 HRESULT hr, ret;
567 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
568 if (ret == E_ACCESSDENIED)
570 win_skip("Not enough permissions to register a transform.\n");
571 return;
573 ok(ret == S_OK, "Failed to register dummy transform, hr %#lx.\n", ret);
575 if(0)
577 /* NULL name crashes on windows */
578 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
579 ok(ret == E_INVALIDARG, "Unexpected hr %#lx.\n", ret);
582 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
583 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
585 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
586 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
588 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
589 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
591 if(0)
593 /* NULL clsids/count crashes on windows (vista) */
594 count = 0;
595 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
596 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
597 ok(count == 0, "Expected count == 0\n");
599 clsids = NULL;
600 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
601 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
603 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, NULL, NULL, NULL, NULL, NULL);
604 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
605 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
606 CoTaskMemFree(mft_name);
608 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, NULL);
609 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
611 in_count = out_count = 1;
612 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, &in_count, NULL, &out_count, NULL);
613 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
614 ok(!in_count, "Unexpected count %u.\n", in_count);
615 ok(!out_count, "Unexpected count %u.\n", out_count);
617 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, &attributes);
618 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
619 ok(!!attributes, "Unexpected attributes.\n");
620 IMFAttributes_Release(attributes);
622 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, &in_types, &in_count, &out_types, &out_count, &attributes);
623 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
624 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
625 ok(!!in_types, "Unexpected pointer.\n");
626 ok(!!out_types, "Unexpected pointer.\n");
627 ok(in_count == 1, "Unexpected count %u.\n", in_count);
628 ok(out_count == 1, "Unexpected count %u.\n", out_count);
629 ok(IsEqualGUID(&in_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
630 wine_dbgstr_guid(&in_types->guidMajorType));
631 ok(IsEqualGUID(&in_types->guidSubtype, &DUMMY_GUID1), "Unexpected type guid %s.\n",
632 wine_dbgstr_guid(&in_types->guidSubtype));
633 ok(IsEqualGUID(&out_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
634 wine_dbgstr_guid(&out_types->guidMajorType));
635 ok(IsEqualGUID(&out_types->guidSubtype, &DUMMY_GUID2), "Unexpected type guid %s.\n",
636 wine_dbgstr_guid(&out_types->guidSubtype));
637 ok(!!attributes, "Unexpected attributes.\n");
638 count = 1;
639 hr = IMFAttributes_GetCount(attributes, &count);
640 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
641 ok(!count, "Unexpected count %u.\n", count);
642 CoTaskMemFree(mft_name);
643 CoTaskMemFree(in_types);
644 CoTaskMemFree(out_types);
645 IMFAttributes_Release(attributes);
647 count = 0;
648 clsids = NULL;
649 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
650 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
651 ok(count > 0, "Expected count > 0\n");
652 ok(clsids != NULL, "Expected clsids != NULL\n");
653 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
654 CoTaskMemFree(clsids);
656 count = 0;
657 clsids = NULL;
658 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
659 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
660 ok(count > 0, "Expected count > 0\n");
661 ok(clsids != NULL, "Expected clsids != NULL\n");
662 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
663 CoTaskMemFree(clsids);
665 count = 0;
666 clsids = NULL;
667 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
668 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
669 ok(count > 0, "Expected count > 0\n");
670 ok(clsids != NULL, "Expected clsids != NULL\n");
671 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
672 CoTaskMemFree(clsids);
674 count = 0;
675 clsids = NULL;
676 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
677 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
678 ok(count > 0, "Expected count > 0\n");
679 ok(clsids != NULL, "Expected clsids != NULL\n");
680 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
681 CoTaskMemFree(clsids);
683 /* exchange input and output */
684 count = 0;
685 clsids = NULL;
686 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
687 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
688 ok(!count, "got %d\n", count);
689 ok(clsids == NULL, "Expected clsids == NULL\n");
691 ret = MFTUnregister(DUMMY_CLSID);
692 ok(ret == S_OK ||
693 /* w7pro64 */
694 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
696 ret = MFTUnregister(DUMMY_CLSID);
697 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
700 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
702 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
703 IMFSourceResolver *resolver;
704 IUnknown *object, *object2;
705 MF_OBJECT_TYPE obj_type;
706 HRESULT hr;
708 ok(!!result, "Unexpected result object.\n");
710 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
712 object = NULL;
713 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
714 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
716 hr = IMFAsyncResult_GetObject(result, &object2);
717 ok(hr == S_OK, "Failed to get result object, hr %#lx.\n", hr);
718 ok(object2 == object, "Unexpected object.\n");
720 if (object)
721 IUnknown_Release(object);
722 IUnknown_Release(object2);
724 SetEvent(callback->event);
726 return S_OK;
729 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
731 testcallback_QueryInterface,
732 testcallback_AddRef,
733 testcallback_Release,
734 testcallback_GetParameters,
735 test_create_from_url_callback_Invoke,
738 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
740 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
741 IMFSchemeHandler *handler;
742 IUnknown *object, *object2;
743 MF_OBJECT_TYPE obj_type;
744 HRESULT hr;
746 ok(!!result, "Unexpected result object.\n");
748 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
750 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
751 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
753 if (SUCCEEDED(hr))
755 hr = IMFAsyncResult_GetObject(result, &object2);
756 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
758 IUnknown_Release(object);
761 SetEvent(callback->event);
763 return S_OK;
766 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
768 testcallback_QueryInterface,
769 testcallback_AddRef,
770 testcallback_Release,
771 testcallback_GetParameters,
772 test_create_from_file_handler_callback_Invoke,
775 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
777 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
778 IMFMediaEventGenerator *generator;
779 HRESULT hr;
781 ok(!!result, "Unexpected result object.\n");
783 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
785 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
786 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
788 SetEvent(callback->event);
790 return S_OK;
793 static const IMFAsyncCallbackVtbl events_callback_vtbl =
795 testcallback_QueryInterface,
796 testcallback_AddRef,
797 testcallback_Release,
798 testcallback_GetParameters,
799 source_events_callback_Invoke,
802 static const IMFAsyncCallbackVtbl testcallbackvtbl;
804 static struct test_callback * create_test_callback(const IMFAsyncCallbackVtbl *vtbl)
806 struct test_callback *callback = calloc(1, sizeof(*callback));
808 callback->IMFAsyncCallback_iface.lpVtbl = vtbl ? vtbl : &testcallbackvtbl;
809 callback->refcount = 1;
810 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
812 return callback;
815 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
817 struct test_callback *callback;
818 MediaEventType event_type;
819 BOOL ret = FALSE;
820 HRESULT hr;
822 callback = create_test_callback(&events_callback_vtbl);
824 for (;;)
826 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback->IMFAsyncCallback_iface,
827 (IUnknown *)generator);
828 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
830 if (WaitForSingleObject(callback->event, 1000) == WAIT_TIMEOUT)
832 ok(0, "timeout\n");
833 break;
836 Sleep(10);
838 hr = IMFMediaEvent_GetType(callback->media_event, &event_type);
839 ok(hr == S_OK, "Failed to event type, hr %#lx.\n", hr);
841 if ((ret = (event_type == expected_event_type)))
843 if (value)
845 hr = IMFMediaEvent_GetValue(callback->media_event, value);
846 ok(hr == S_OK, "Failed to get value of event, hr %#lx.\n", hr);
849 break;
853 if (callback->media_event)
854 IMFMediaEvent_Release(callback->media_event);
855 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
857 return ret;
860 static const IMFByteStreamVtbl *bytestream_vtbl_orig;
862 static int bytestream_closed = 0;
863 static HRESULT WINAPI bytestream_wrapper_Close(IMFByteStream *iface)
865 bytestream_closed = 1;
866 return bytestream_vtbl_orig->Close(iface);
869 static void test_source_resolver(void)
871 struct test_callback *callback, *callback2;
872 IMFByteStreamVtbl bytestream_vtbl_wrapper;
873 IMFSourceResolver *resolver, *resolver2;
874 IMFPresentationDescriptor *descriptor;
875 IMFSchemeHandler *scheme_handler;
876 IMFMediaStream *video_stream;
877 IMFAttributes *attributes;
878 IMFMediaSource *mediasource;
879 IMFMediaTypeHandler *handler;
880 IMFMediaType *media_type;
881 BOOL selected, do_uninit;
882 MF_OBJECT_TYPE obj_type;
883 IMFStreamDescriptor *sd;
884 IUnknown *cancel_cookie;
885 IMFByteStream *stream;
886 IMFGetService *get_service;
887 IMFRateSupport *rate_support;
888 WCHAR pathW[MAX_PATH];
889 int i, sample_count;
890 WCHAR *filename;
891 PROPVARIANT var;
892 HRESULT hr;
893 GUID guid;
894 float rate;
895 UINT32 rotation;
897 if (!pMFCreateSourceResolver)
899 win_skip("MFCreateSourceResolver() not found\n");
900 return;
903 callback = create_test_callback(&test_create_from_url_callback_vtbl);
904 callback2 = create_test_callback(&test_create_from_file_handler_callback_vtbl);
906 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
907 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
909 hr = pMFCreateSourceResolver(NULL);
910 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
912 hr = pMFCreateSourceResolver(&resolver);
913 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
915 hr = pMFCreateSourceResolver(&resolver2);
916 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
917 ok(resolver != resolver2, "Expected new instance\n");
919 IMFSourceResolver_Release(resolver2);
921 filename = load_resource(L"test.mp4");
923 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
924 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
926 hr = IMFSourceResolver_CreateObjectFromByteStream(
927 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
928 &obj_type, (IUnknown **)&mediasource);
929 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
931 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
932 NULL, (IUnknown **)&mediasource);
933 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
935 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
936 &obj_type, NULL);
937 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
939 IMFByteStream_Release(stream);
941 /* Create from URL. */
943 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
944 (IUnknown **)&stream);
945 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
947 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
948 (IUnknown **)&stream);
949 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
950 IMFByteStream_Release(stream);
952 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
953 &cancel_cookie, &callback->IMFAsyncCallback_iface, (IUnknown *)resolver);
954 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
955 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
956 IUnknown_Release(cancel_cookie);
958 if (SUCCEEDED(hr))
959 WaitForSingleObject(callback->event, INFINITE);
961 /* With explicit scheme. */
962 lstrcpyW(pathW, fileschemeW);
963 lstrcatW(pathW, filename);
965 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
966 (IUnknown **)&stream);
967 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
968 IMFByteStream_Release(stream);
970 /* We have to create a new bytestream here, because all following
971 * calls to CreateObjectFromByteStream will fail. */
972 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
973 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
975 /* Wrap ::Close to test when the media source calls it */
976 bytestream_vtbl_orig = stream->lpVtbl;
977 bytestream_vtbl_wrapper = *bytestream_vtbl_orig;
978 bytestream_vtbl_wrapper.Close = bytestream_wrapper_Close;
979 stream->lpVtbl = &bytestream_vtbl_wrapper;
981 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
982 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
983 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
984 ok(hr == S_OK, "Failed to set string value, hr %#lx.\n", hr);
985 IMFAttributes_Release(attributes);
987 /* Start of gstreamer dependent tests */
989 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
990 &obj_type, (IUnknown **)&mediasource);
991 if (strcmp(winetest_platform, "wine"))
992 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
993 if (FAILED(hr))
995 IMFByteStream_Release(stream);
996 IMFSourceResolver_Release(resolver);
998 hr = MFShutdown();
999 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
1001 DeleteFileW(filename);
1002 return;
1004 ok(mediasource != NULL, "got %p\n", mediasource);
1005 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
1007 check_interface(mediasource, &IID_IMFGetService, TRUE);
1008 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
1010 hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service);
1011 ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
1013 hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support);
1014 ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
1016 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1017 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1018 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
1019 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1020 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1021 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
1022 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1023 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1024 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
1025 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1026 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1027 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
1029 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1030 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1031 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1032 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1033 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1034 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1035 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1036 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1037 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1038 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1039 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1040 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1042 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, NULL);
1043 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1044 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, &rate);
1045 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1046 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1048 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1.0f, &rate);
1049 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1050 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1051 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1.0f, &rate);
1052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1053 ok(rate == -1.0f, "Unexpected rate %f.\n", rate);
1054 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1e6f + 1.0f, &rate);
1055 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
1056 ok(rate == 1e6f + 1.0f || broken(rate == 1e6f) /* Win7 */, "Unexpected %f.\n", rate);
1057 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f, &rate);
1058 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1059 ok(rate == -1e6f, "Unexpected rate %f.\n", rate);
1061 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f - 1.0f, &rate);
1062 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
1063 ok(rate == -1e6f - 1.0f || broken(rate == -1e6f) /* Win7 */, "Unexpected rate %f.\n", rate);
1065 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
1066 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
1067 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#lx.\n", hr);
1068 ok(descriptor != NULL, "got %p\n", descriptor);
1070 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
1071 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
1073 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
1074 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
1075 IMFStreamDescriptor_Release(sd);
1077 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
1078 ok(hr == S_OK, "Failed to get stream major type, hr %#lx.\n", hr);
1080 /* Check major/minor type for the test media. */
1081 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
1083 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
1084 ok(hr == S_OK, "Failed to get current media type, hr %#lx.\n", hr);
1085 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
1086 ok(hr == S_OK, "Failed to get media sub type, hr %#lx.\n", hr);
1087 todo_wine
1088 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
1090 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_ROTATION, &rotation);
1091 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Win7 */, "Failed to get rotation, hr %#lx.\n", hr);
1092 if (hr == S_OK)
1093 ok(rotation == MFVideoRotationFormat_0, "Got wrong rotation %u.\n", rotation);
1095 IMFMediaType_Release(media_type);
1097 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
1098 ok(hr == S_OK, "Failed to select video stream, hr %#lx.\n", hr);
1100 var.vt = VT_EMPTY;
1101 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1102 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1104 video_stream = NULL;
1105 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
1107 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
1108 video_stream = (IMFMediaStream *)var.punkVal;
1111 hr = IMFMediaSource_Pause(mediasource);
1112 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1113 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
1114 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1116 var.vt = VT_EMPTY;
1117 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1118 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1120 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
1121 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1123 hr = IMFMediaSource_Pause(mediasource);
1124 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1125 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
1126 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1128 var.vt = VT_I8;
1129 var.uhVal.QuadPart = 0;
1130 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1131 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1133 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceSeeked, &var))
1134 ok(var.vt == VT_I8, "Unexpected value type.\n");
1136 hr = IMFMediaSource_Stop(mediasource);
1137 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1138 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStopped, &var))
1139 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1141 var.vt = VT_I8;
1142 var.uhVal.QuadPart = 0;
1143 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1144 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1146 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
1147 ok(var.vt == VT_I8, "Unexpected value type.\n");
1149 sample_count = 10;
1151 for (i = 0; i < sample_count; ++i)
1153 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1154 ok(hr == S_OK, "Failed to request sample %u, hr %#lx.\n", i + 1, hr);
1155 if (hr != S_OK)
1156 break;
1159 for (i = 0; i < sample_count; ++i)
1161 static const LONGLONG MILLI_TO_100_NANO = 10000;
1162 LONGLONG duration, time;
1163 DWORD buffer_count;
1164 IMFSample *sample;
1165 BOOL ret;
1167 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
1168 ok(ret, "Sample %u not received.\n", i + 1);
1169 if (!ret)
1170 break;
1172 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
1173 sample = (IMFSample *)var.punkVal;
1175 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1176 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1177 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
1179 hr = IMFSample_GetSampleDuration(sample, &duration);
1180 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
1181 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
1183 hr = IMFSample_GetSampleTime(sample, &time);
1184 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
1185 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
1187 IMFSample_Release(sample);
1190 if (i == sample_count)
1192 IMFMediaEvent *event;
1194 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
1195 Sleep(100);
1196 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
1197 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
1199 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1200 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1201 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
1205 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1206 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1208 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
1210 IMFMediaStream_Release(video_stream);
1211 IMFMediaTypeHandler_Release(handler);
1212 IMFPresentationDescriptor_Release(descriptor);
1214 ok(!bytestream_closed, "IMFByteStream::Close called unexpectedly\n");
1216 hr = IMFMediaSource_Shutdown(mediasource);
1217 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1219 ok(bytestream_closed, "Missing IMFByteStream::Close call\n");
1221 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
1222 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
1224 IMFRateSupport_Release(rate_support);
1225 IMFGetService_Release(get_service);
1226 IMFMediaSource_Release(mediasource);
1227 IMFByteStream_Release(stream);
1229 /* Create directly through scheme handler. */
1230 hr = CoInitialize(NULL);
1231 ok(SUCCEEDED(hr), "Failed to initialize, hr %#lx.\n", hr);
1232 do_uninit = hr == S_OK;
1234 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
1235 (void **)&scheme_handler);
1236 ok(hr == S_OK, "Failed to create handler object, hr %#lx.\n", hr);
1238 cancel_cookie = NULL;
1239 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
1240 &callback2->IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
1241 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
1242 ok(!!cancel_cookie, "Unexpected cancel object.\n");
1243 IUnknown_Release(cancel_cookie);
1245 WaitForSingleObject(callback2->event, INFINITE);
1247 IMFSchemeHandler_Release(scheme_handler);
1249 if (do_uninit)
1250 CoUninitialize();
1252 IMFSourceResolver_Release(resolver);
1254 hr = MFShutdown();
1255 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
1257 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
1258 IMFAsyncCallback_Release(&callback2->IMFAsyncCallback_iface);
1260 DeleteFileW(filename);
1263 static void init_functions(void)
1265 HMODULE mod = GetModuleHandleA("mfplat.dll");
1267 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
1268 X(MFAddPeriodicCallback);
1269 X(MFAllocateSerialWorkQueue);
1270 X(MFAllocateWorkQueueEx);
1271 X(MFCopyImage);
1272 X(MFCreate2DMediaBuffer);
1273 X(MFCreateDXGIDeviceManager);
1274 X(MFCreateDXGISurfaceBuffer);
1275 X(MFCreateDXSurfaceBuffer);
1276 X(MFCreateSourceResolver);
1277 X(MFCreateMediaBufferFromMediaType);
1278 X(MFCreateMFByteStreamOnStream);
1279 X(MFCreatePathFromURL);
1280 X(MFCreateTrackedSample);
1281 X(MFCreateTransformActivate);
1282 X(MFCreateVideoMediaTypeFromSubtype);
1283 X(MFCreateVideoSampleAllocatorEx);
1284 X(MFGetPlaneSize);
1285 X(MFGetStrideForBitmapInfoHeader);
1286 X(MFInitVideoFormat_RGB);
1287 X(MFLockDXGIDeviceManager);
1288 X(MFLockSharedWorkQueue);
1289 X(MFMapDX9FormatToDXGIFormat);
1290 X(MFMapDXGIFormatToDX9Format);
1291 X(MFPutWaitingWorkItem);
1292 X(MFRegisterLocalByteStreamHandler);
1293 X(MFRegisterLocalSchemeHandler);
1294 X(MFRemovePeriodicCallback);
1295 X(MFTEnumEx);
1296 X(MFTRegisterLocal);
1297 X(MFTRegisterLocalByCLSID);
1298 X(MFTUnregisterLocal);
1299 X(MFTUnregisterLocalByCLSID);
1300 X(MFUnlockDXGIDeviceManager);
1302 if ((mod = LoadLibraryA("d3d11.dll")))
1304 X(D3D11CreateDevice);
1307 if ((mod = LoadLibraryA("d3d12.dll")))
1309 X(D3D12CreateDevice);
1312 mod = GetModuleHandleA("ole32.dll");
1314 X(CoGetApartmentType);
1315 #undef X
1317 is_win8_plus = pMFPutWaitingWorkItem != NULL;
1320 static void test_media_type(void)
1322 IMFMediaType *mediatype, *mediatype2;
1323 IMFVideoMediaType *video_type;
1324 IUnknown *unk, *unk2;
1325 BOOL compressed;
1326 DWORD flags;
1327 UINT count;
1328 HRESULT hr;
1329 GUID guid;
1331 if(0)
1333 /* Crash on Windows Vista/7 */
1334 hr = MFCreateMediaType(NULL);
1335 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1338 hr = MFCreateMediaType(&mediatype);
1339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1341 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1342 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1344 compressed = FALSE;
1345 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1346 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1347 ok(compressed, "Unexpected value %d.\n", compressed);
1349 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
1350 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1352 compressed = FALSE;
1353 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1354 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1355 ok(compressed, "Unexpected value %d.\n", compressed);
1357 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 0);
1358 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1360 compressed = FALSE;
1361 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1362 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1363 ok(compressed, "Unexpected value %d.\n", compressed);
1365 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
1366 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1368 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 1);
1369 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1371 compressed = TRUE;
1372 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1373 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1374 ok(!compressed, "Unexpected value %d.\n", compressed);
1376 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_COMPRESSED);
1377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1379 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1380 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1382 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1383 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
1384 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
1386 /* IsEqual() */
1387 hr = MFCreateMediaType(&mediatype2);
1388 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
1390 flags = 0xdeadbeef;
1391 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1392 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1393 ok(flags == 0, "Unexpected flags %#lx.\n", flags);
1395 /* Different major types. */
1396 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1397 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
1399 flags = 0;
1400 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1401 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1402 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1403 "Unexpected flags %#lx.\n", flags);
1405 /* Same major types, different subtypes. */
1406 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1407 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
1409 flags = 0;
1410 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1412 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
1413 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#lx.\n", flags);
1415 /* Different user data. */
1416 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
1417 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1419 flags = 0;
1420 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1421 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1422 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
1423 "Unexpected flags %#lx.\n", flags);
1425 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
1426 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1428 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1429 ok(hr == S_OK, "Failed to set subtype, hr %#lx.\n", hr);
1431 flags = 0;
1432 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1433 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1434 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1435 "Unexpected flags %#lx.\n", flags);
1437 IMFMediaType_Release(mediatype2);
1438 IMFMediaType_Release(mediatype);
1440 /* IMFVideoMediaType */
1441 hr = MFCreateMediaType(&mediatype);
1442 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1444 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
1446 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1447 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1448 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1449 IUnknown_Release(unk);
1451 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1452 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1454 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
1455 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1457 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1458 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1459 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1460 IUnknown_Release(unk2);
1462 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1463 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1464 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1465 IUnknown_Release(unk2);
1467 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1468 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1469 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1470 IUnknown_Release(unk2);
1472 IUnknown_Release(unk);
1473 IMFMediaType_Release(mediatype);
1475 if (pMFCreateVideoMediaTypeFromSubtype)
1477 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
1478 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1480 check_interface(video_type, &IID_IMFMediaType, TRUE);
1481 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
1483 /* Major and subtype are set on creation. */
1484 hr = IMFVideoMediaType_GetCount(video_type, &count);
1485 ok(count == 2, "Unexpected attribute count %#lx.\n", hr);
1487 hr = IMFVideoMediaType_DeleteAllItems(video_type);
1488 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1490 hr = IMFVideoMediaType_GetCount(video_type, &count);
1491 ok(!count, "Unexpected attribute count %#lx.\n", hr);
1493 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
1495 IMFVideoMediaType_Release(video_type);
1497 else
1498 win_skip("MFCreateVideoMediaTypeFromSubtype() is not available.\n");
1500 /* IMFAudioMediaType */
1501 hr = MFCreateMediaType(&mediatype);
1502 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1504 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
1506 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1507 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1508 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1509 IUnknown_Release(unk);
1511 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1512 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1514 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1517 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1518 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1519 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1520 IUnknown_Release(unk2);
1522 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1523 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1524 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1525 IUnknown_Release(unk2);
1527 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1528 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1529 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1530 IUnknown_Release(unk2);
1532 IUnknown_Release(unk);
1534 IMFMediaType_Release(mediatype);
1537 static void test_MFCreateMediaEvent(void)
1539 HRESULT hr;
1540 IMFMediaEvent *mediaevent;
1542 MediaEventType type;
1543 GUID extended_type;
1544 HRESULT status;
1545 PROPVARIANT value;
1547 PropVariantInit(&value);
1548 value.vt = VT_UNKNOWN;
1550 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1551 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1553 PropVariantClear(&value);
1555 hr = IMFMediaEvent_GetType(mediaevent, &type);
1556 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1557 ok(type == MEError, "got %#lx\n", type);
1559 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1560 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1561 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1562 wine_dbgstr_guid(&extended_type));
1564 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1565 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1566 ok(status == E_FAIL, "Unexpected hr %#lx.\n", status);
1568 PropVariantInit(&value);
1569 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1570 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1571 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1572 PropVariantClear(&value);
1574 IMFMediaEvent_Release(mediaevent);
1576 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1577 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1579 hr = IMFMediaEvent_GetType(mediaevent, &type);
1580 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1581 ok(type == MEUnknown, "got %#lx\n", type);
1583 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1584 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1585 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1586 wine_dbgstr_guid(&extended_type));
1588 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1589 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1590 ok(status == S_OK, "Unexpected hr %#lx.\n", status);
1592 PropVariantInit(&value);
1593 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1594 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1595 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1596 PropVariantClear(&value);
1598 IMFMediaEvent_Release(mediaevent);
1601 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1602 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1604 UINT32 count = expected + 1;
1605 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1606 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
1607 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1610 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1611 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1613 MF_ATTRIBUTE_TYPE type;
1614 HRESULT hr;
1616 hr = IMFAttributes_GetItemType(obj, key, &type);
1617 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
1618 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1621 static void test_attributes(void)
1623 static const WCHAR stringW[] = L"Wine";
1624 static const UINT8 blob[] = {0,1,2,3,4,5};
1625 IMFAttributes *attributes, *attributes1;
1626 UINT8 blob_value[256], *blob_buf = NULL;
1627 MF_ATTRIBUTES_MATCH_TYPE match_type;
1628 UINT32 value, string_length, size;
1629 PROPVARIANT propvar, ret_propvar;
1630 MF_ATTRIBUTE_TYPE type;
1631 double double_value;
1632 IUnknown *unk_value;
1633 WCHAR bufferW[256];
1634 UINT64 value64;
1635 WCHAR *string;
1636 BOOL result;
1637 HRESULT hr;
1638 GUID key;
1640 hr = MFCreateAttributes( &attributes, 3 );
1641 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1643 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1644 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1646 CHECK_ATTR_COUNT(attributes, 0);
1647 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1648 ok(hr == S_OK, "Failed to set UINT32 value, hr %#lx.\n", hr);
1649 CHECK_ATTR_COUNT(attributes, 1);
1650 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1652 value = 0xdeadbeef;
1653 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1654 ok(hr == S_OK, "Failed to get UINT32 value, hr %#lx.\n", hr);
1655 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1657 value64 = 0xdeadbeef;
1658 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1659 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1660 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1662 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1663 ok(hr == S_OK, "Failed to set UINT64 value, hr %#lx.\n", hr);
1664 CHECK_ATTR_COUNT(attributes, 1);
1665 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1667 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1668 ok(hr == S_OK, "Failed to get UINT64 value, hr %#lx.\n", hr);
1669 ok(value64 == 65536, "Unexpected value.\n");
1671 value = 0xdeadbeef;
1672 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1673 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1674 ok(value == 0xdeadbeef, "Unexpected value.\n");
1676 IMFAttributes_Release(attributes);
1678 hr = MFCreateAttributes(&attributes, 0);
1679 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1681 PropVariantInit(&propvar);
1682 propvar.vt = MF_ATTRIBUTE_UINT32;
1683 propvar.ulVal = 123;
1684 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1685 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1686 PropVariantInit(&ret_propvar);
1687 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1688 ret_propvar.ulVal = 0xdeadbeef;
1689 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1690 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1691 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1692 PropVariantClear(&ret_propvar);
1693 CHECK_ATTR_COUNT(attributes, 1);
1695 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1696 ok(hr == S_OK, "Item check failed, hr %#lx.\n", hr);
1698 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1699 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1701 PropVariantInit(&ret_propvar);
1702 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1703 ret_propvar.pwszVal = NULL;
1704 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1705 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1706 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1707 PropVariantClear(&ret_propvar);
1709 PropVariantClear(&propvar);
1711 PropVariantInit(&propvar);
1712 propvar.vt = MF_ATTRIBUTE_UINT64;
1713 propvar.uhVal.QuadPart = 65536;
1714 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1715 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1716 PropVariantInit(&ret_propvar);
1717 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1718 ret_propvar.ulVal = 0xdeadbeef;
1719 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1720 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1721 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1722 PropVariantClear(&ret_propvar);
1723 PropVariantClear(&propvar);
1724 CHECK_ATTR_COUNT(attributes, 1);
1726 PropVariantInit(&propvar);
1727 propvar.vt = VT_I4;
1728 propvar.lVal = 123;
1729 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1730 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#lx.\n", hr);
1731 PropVariantInit(&ret_propvar);
1732 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1733 ret_propvar.lVal = 0xdeadbeef;
1734 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1735 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1736 PropVariantClear(&propvar);
1737 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1738 PropVariantClear(&ret_propvar);
1740 PropVariantInit(&propvar);
1741 propvar.vt = MF_ATTRIBUTE_UINT32;
1742 propvar.ulVal = 123;
1743 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1744 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1746 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1747 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1748 CHECK_ATTR_COUNT(attributes, 2);
1750 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1751 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1752 CHECK_ATTR_COUNT(attributes, 2);
1754 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1755 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1756 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1757 PropVariantClear(&ret_propvar);
1758 PropVariantClear(&propvar);
1760 propvar.vt = MF_ATTRIBUTE_UINT64;
1761 propvar.uhVal.QuadPart = 65536;
1763 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1764 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1765 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1766 PropVariantClear(&ret_propvar);
1767 PropVariantClear(&propvar);
1769 /* Item ordering is not consistent across Windows version. */
1770 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1771 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1772 PropVariantClear(&ret_propvar);
1774 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1775 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1776 PropVariantClear(&ret_propvar);
1778 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1779 ok(hr == S_OK, "Failed to set double value, hr %#lx.\n", hr);
1780 CHECK_ATTR_COUNT(attributes, 3);
1781 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1783 double_value = 0xdeadbeef;
1784 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1785 ok(hr == S_OK, "Failed to get double value, hr %#lx.\n", hr);
1786 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1788 propvar.vt = MF_ATTRIBUTE_UINT64;
1789 propvar.uhVal.QuadPart = 22;
1790 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1791 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1792 ok(!result, "Unexpected result.\n");
1794 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1795 propvar.dblVal = 22.0;
1796 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1797 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1798 ok(result, "Unexpected result.\n");
1800 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1801 ok(hr == S_OK, "Failed to set string attribute, hr %#lx.\n", hr);
1802 CHECK_ATTR_COUNT(attributes, 3);
1803 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1805 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1806 ok(hr == S_OK, "Failed to get string length, hr %#lx.\n", hr);
1807 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1809 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, NULL);
1810 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1811 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1812 CoTaskMemFree(string);
1814 string_length = 0xdeadbeef;
1815 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1816 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1817 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1818 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1819 CoTaskMemFree(string);
1821 string_length = 0xdeadbeef;
1822 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1823 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1824 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1825 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1826 memset(bufferW, 0, sizeof(bufferW));
1828 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1829 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1830 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1831 memset(bufferW, 0, sizeof(bufferW));
1833 string_length = 0;
1834 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1835 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1836 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1837 ok(string_length, "Unexpected length.\n");
1839 string_length = 0xdeadbeef;
1840 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1841 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1842 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1844 /* VT_UNKNOWN */
1845 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1846 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1847 CHECK_ATTR_COUNT(attributes, 4);
1848 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1850 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1851 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1852 IUnknown_Release(unk_value);
1854 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1855 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1856 IUnknown_Release(unk_value);
1858 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1859 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1861 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1862 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1863 CHECK_ATTR_COUNT(attributes, 5);
1865 unk_value = NULL;
1866 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1867 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1869 /* CopyAllItems() */
1870 hr = MFCreateAttributes(&attributes1, 0);
1871 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1872 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1873 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1874 CHECK_ATTR_COUNT(attributes, 5);
1875 CHECK_ATTR_COUNT(attributes1, 5);
1877 hr = IMFAttributes_DeleteAllItems(attributes1);
1878 ok(hr == S_OK, "Failed to delete items, hr %#lx.\n", hr);
1879 CHECK_ATTR_COUNT(attributes1, 0);
1881 propvar.vt = MF_ATTRIBUTE_UINT64;
1882 propvar.uhVal.QuadPart = 22;
1883 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1884 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1885 ok(!result, "Unexpected result.\n");
1887 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1888 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1889 CHECK_ATTR_COUNT(attributes, 0);
1891 /* Blob */
1892 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1893 ok(hr == S_OK, "Failed to set blob attribute, hr %#lx.\n", hr);
1894 CHECK_ATTR_COUNT(attributes, 1);
1895 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1896 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1897 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
1898 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1900 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1901 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1903 size = 0;
1904 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1905 ok(hr == S_OK, "Failed to get blob, hr %#lx.\n", hr);
1906 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1907 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1909 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1910 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1912 memset(blob_value, 0, sizeof(blob_value));
1913 size = 0;
1914 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1915 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1916 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1917 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1918 CoTaskMemFree(blob_buf);
1920 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, NULL);
1921 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1922 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1923 CoTaskMemFree(blob_buf);
1925 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1926 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1928 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1929 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1931 IMFAttributes_Release(attributes);
1932 IMFAttributes_Release(attributes1);
1934 /* Compare() */
1935 hr = MFCreateAttributes(&attributes, 0);
1936 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1937 hr = MFCreateAttributes(&attributes1, 0);
1938 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1940 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1941 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1943 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1945 result = FALSE;
1946 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1947 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1948 ok(result, "Unexpected result %d.\n", result);
1950 result = FALSE;
1951 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1952 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1953 ok(result, "Unexpected result %d.\n", result);
1956 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1957 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1959 result = TRUE;
1960 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1961 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1962 ok(!result, "Unexpected result %d.\n", result);
1964 result = TRUE;
1965 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1966 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1967 ok(!result, "Unexpected result %d.\n", result);
1969 result = FALSE;
1970 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1971 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1972 ok(result, "Unexpected result %d.\n", result);
1974 result = FALSE;
1975 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1976 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1977 ok(result, "Unexpected result %d.\n", result);
1979 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1980 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1982 result = TRUE;
1983 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1984 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1985 ok(!result, "Unexpected result %d.\n", result);
1987 result = TRUE;
1988 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1989 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1990 ok(!result, "Unexpected result %d.\n", result);
1992 result = TRUE;
1993 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1994 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1995 ok(!result, "Unexpected result %d.\n", result);
1997 result = TRUE;
1998 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1999 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2000 ok(!result, "Unexpected result %d.\n", result);
2002 result = TRUE;
2003 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2004 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2005 ok(!result, "Unexpected result %d.\n", result);
2007 result = TRUE;
2008 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2009 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2010 ok(!result, "Unexpected result %d.\n", result);
2012 result = TRUE;
2013 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
2014 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2015 ok(!result, "Unexpected result %d.\n", result);
2017 result = TRUE;
2018 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2019 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2020 ok(!result, "Unexpected result %d.\n", result);
2022 result = TRUE;
2023 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2024 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2025 ok(!result, "Unexpected result %d.\n", result);
2027 result = TRUE;
2028 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2029 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2030 ok(!result, "Unexpected result %d.\n", result);
2032 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
2033 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
2035 result = FALSE;
2036 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2037 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2038 ok(result, "Unexpected result %d.\n", result);
2040 result = FALSE;
2041 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2042 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2043 ok(result, "Unexpected result %d.\n", result);
2045 result = FALSE;
2046 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2047 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2048 ok(result, "Unexpected result %d.\n", result);
2050 result = FALSE;
2051 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2052 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2053 ok(result, "Unexpected result %d.\n", result);
2055 result = FALSE;
2056 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2057 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2058 ok(result, "Unexpected result %d.\n", result);
2060 result = FALSE;
2061 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2062 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2063 ok(result, "Unexpected result %d.\n", result);
2065 result = FALSE;
2066 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2067 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2068 ok(result, "Unexpected result %d.\n", result);
2070 result = FALSE;
2071 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2072 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2073 ok(result, "Unexpected result %d.\n", result);
2075 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
2076 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
2078 result = TRUE;
2079 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2080 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2081 ok(!result, "Unexpected result %d.\n", result);
2083 result = TRUE;
2084 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2085 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2086 ok(!result, "Unexpected result %d.\n", result);
2088 result = FALSE;
2089 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
2090 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2091 ok(result, "Unexpected result %d.\n", result);
2093 result = FALSE;
2094 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2095 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2096 ok(result, "Unexpected result %d.\n", result);
2098 result = FALSE;
2099 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2100 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2101 ok(result, "Unexpected result %d.\n", result);
2103 result = TRUE;
2104 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2105 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2106 ok(!result, "Unexpected result %d.\n", result);
2108 result = FALSE;
2109 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2110 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2111 ok(result, "Unexpected result %d.\n", result);
2113 result = TRUE;
2114 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
2115 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2116 ok(!result, "Unexpected result %d.\n", result);
2118 result = FALSE;
2119 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2120 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2121 ok(result, "Unexpected result %d.\n", result);
2123 result = FALSE;
2124 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2125 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2126 ok(result, "Unexpected result %d.\n", result);
2128 IMFAttributes_Release(attributes);
2129 IMFAttributes_Release(attributes1);
2132 static void test_MFCreateMFByteStreamOnStream(void)
2134 IMFByteStream *bytestream;
2135 IMFByteStream *bytestream2;
2136 IStream *stream;
2137 IMFAttributes *attributes = NULL;
2138 DWORD caps, written;
2139 IUnknown *unknown;
2140 ULONG ref, size;
2141 HRESULT hr;
2142 UINT count;
2143 QWORD to;
2145 if(!pMFCreateMFByteStreamOnStream)
2147 win_skip("MFCreateMFByteStreamOnStream() not found\n");
2148 return;
2151 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2152 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2154 caps = 0xffff0000;
2155 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
2156 ok(hr == S_OK, "Failed to write, hr %#lx.\n", hr);
2158 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
2159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2161 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
2162 (void **)&unknown);
2163 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2164 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2165 ref = IUnknown_Release(unknown);
2166 ok(ref == 1, "got %lu\n", ref);
2168 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
2169 (void **)&bytestream2);
2170 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2171 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2172 ref = IMFByteStream_Release(bytestream2);
2173 ok(ref == 1, "got %lu\n", ref);
2175 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2176 (void **)&attributes);
2177 ok(hr == S_OK ||
2178 /* w7pro64 */
2179 broken(hr == E_NOINTERFACE), "Unexpected hr %#lx.\n", hr);
2181 if (hr != S_OK)
2183 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
2184 IStream_Release(stream);
2185 IMFByteStream_Release(bytestream);
2186 return;
2189 ok(attributes != NULL, "got NULL\n");
2190 hr = IMFAttributes_GetCount(attributes, &count);
2191 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2192 ok(count == 0, "Unexpected attributes count %u.\n", count);
2194 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
2195 (void **)&unknown);
2196 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2197 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2198 ref = IUnknown_Release(unknown);
2199 ok(ref == 2, "got %lu\n", ref);
2201 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
2202 (void **)&bytestream2);
2203 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2204 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2205 ref = IMFByteStream_Release(bytestream2);
2206 ok(ref == 2, "got %lu\n", ref);
2208 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2209 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2210 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2211 check_interface(bytestream, &IID_IMFGetService, FALSE);
2213 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2214 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2215 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2217 hr = IMFByteStream_Close(bytestream);
2218 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2220 hr = IMFByteStream_Close(bytestream);
2221 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2223 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2224 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2225 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2227 /* IMFByteStream maintains position separately from IStream */
2228 caps = 0;
2229 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2230 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2231 ok(size == 4, "Unexpected size.\n");
2232 ok(caps == 0xffff0000, "Unexpected content.\n");
2234 caps = 0;
2235 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2236 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2237 ok(size == 4, "Unexpected size.\n");
2238 ok(caps == 0xffff0000, "Unexpected content.\n");
2240 caps = 0;
2241 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2242 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2243 ok(size == 0, "Unexpected size.\n");
2244 ok(caps == 0, "Unexpected content.\n");
2246 hr = IMFByteStream_Seek(bytestream, msoBegin, 0, 0, &to);
2247 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2249 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2250 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2251 ok(size == 0, "Unexpected size.\n");
2252 ok(caps == 0, "Unexpected content.\n");
2254 caps = 0;
2255 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2256 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2257 ok(size == 4, "Unexpected size.\n");
2258 ok(caps == 0xffff0000, "Unexpected content.\n");
2260 caps = 0;
2261 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2262 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2263 ok(size == 0, "Unexpected size.\n");
2264 ok(caps == 0, "Unexpected content.\n");
2266 IMFAttributes_Release(attributes);
2267 IMFByteStream_Release(bytestream);
2268 IStream_Release(stream);
2271 static void test_file_stream(void)
2273 static const WCHAR newfilename[] = L"new.mp4";
2274 IMFByteStream *bytestream, *bytestream2;
2275 QWORD bytestream_length, position;
2276 IMFAttributes *attributes = NULL;
2277 MF_ATTRIBUTE_TYPE item_type;
2278 WCHAR pathW[MAX_PATH];
2279 WCHAR *filename;
2280 HRESULT hr;
2281 WCHAR *str;
2282 DWORD caps;
2283 UINT count;
2284 BOOL eos;
2286 filename = load_resource(L"test.mp4");
2288 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2289 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2291 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2292 MF_FILEFLAGS_NONE, filename, &bytestream);
2293 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2295 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2296 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2297 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2298 check_interface(bytestream, &IID_IMFGetService, TRUE);
2300 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2301 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2302 if (is_win8_plus)
2304 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
2305 "Unexpected caps %#lx.\n", caps);
2307 else
2308 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2310 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2311 (void **)&attributes);
2312 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2313 ok(attributes != NULL, "got NULL\n");
2315 hr = IMFAttributes_GetCount(attributes, &count);
2316 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2317 ok(count == 2, "Unexpected attributes count %u.\n", count);
2319 /* Original file name. */
2320 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
2321 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
2322 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
2323 CoTaskMemFree(str);
2325 /* Modification time. */
2326 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
2327 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
2328 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
2330 IMFAttributes_Release(attributes);
2332 /* Length. */
2333 hr = IMFByteStream_GetLength(bytestream, NULL);
2334 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2336 bytestream_length = 0;
2337 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
2338 ok(hr == S_OK, "Failed to get bytestream length, hr %#lx.\n", hr);
2339 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
2341 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
2342 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2344 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
2345 ok(hr == S_OK, "Failed query end of stream, hr %#lx.\n", hr);
2346 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
2348 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
2349 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2351 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
2352 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2354 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
2355 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2356 ok(position == 2 * bytestream_length, "Unexpected position.\n");
2358 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2359 MF_FILEFLAGS_NONE, filename, &bytestream2);
2360 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2361 IMFByteStream_Release(bytestream2);
2363 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2364 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2366 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2367 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2369 IMFByteStream_Release(bytestream);
2371 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2372 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2373 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
2375 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2376 MF_FILEFLAGS_NONE, filename, &bytestream);
2377 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "Unexpected hr %#lx.\n", hr);
2379 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2380 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2381 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2383 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2384 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2386 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2387 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2389 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2390 newfilename, &bytestream2);
2391 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2393 IMFByteStream_Release(bytestream);
2395 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2396 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
2397 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2399 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
2400 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2401 newfilename, &bytestream2);
2402 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2404 IMFByteStream_Release(bytestream);
2406 /* Explicit file: scheme */
2407 lstrcpyW(pathW, fileschemeW);
2408 lstrcatW(pathW, filename);
2409 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
2410 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2412 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream);
2413 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2414 ok(DeleteFileW(filename), "failed to delete file\n");
2415 IMFByteStream_Release(bytestream);
2417 hr = MFShutdown();
2418 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2420 DeleteFileW(newfilename);
2423 static void test_system_memory_buffer(void)
2425 IMFMediaBuffer *buffer;
2426 HRESULT hr;
2427 DWORD length, max;
2428 BYTE *data, *data2;
2430 hr = MFCreateMemoryBuffer(1024, NULL);
2431 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2433 hr = MFCreateMemoryBuffer(0, &buffer);
2434 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2435 if(buffer)
2437 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2438 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2439 ok(length == 0, "got %lu\n", length);
2441 IMFMediaBuffer_Release(buffer);
2444 hr = MFCreateMemoryBuffer(1024, &buffer);
2445 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2447 check_interface(buffer, &IID_IMFGetService, FALSE);
2449 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
2450 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2452 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2453 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2454 ok(length == 1024, "got %lu\n", length);
2456 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2457 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2459 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2460 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2462 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2463 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2465 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2466 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2467 ok(length == 10, "got %lu\n", length);
2469 length = 0;
2470 max = 0;
2471 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2472 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2473 ok(length == 0, "got %lu\n", length);
2474 ok(max == 0, "got %lu\n", length);
2476 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2477 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2478 ok(length == 10, "got %lu\n", length);
2479 ok(max == 1024, "got %lu\n", max);
2481 /* Attempt to lock the buffer twice */
2482 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2483 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2484 ok(data == data2, "Unexpected hr %#lx.\n", hr);
2486 hr = IMFMediaBuffer_Unlock(buffer);
2487 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2489 hr = IMFMediaBuffer_Unlock(buffer);
2490 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2492 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2493 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2495 hr = IMFMediaBuffer_Unlock(buffer);
2496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2498 /* Extra Unlock */
2499 hr = IMFMediaBuffer_Unlock(buffer);
2500 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2502 IMFMediaBuffer_Release(buffer);
2505 static void test_system_memory_aligned_buffer(void)
2507 static const DWORD alignments[] =
2509 MF_16_BYTE_ALIGNMENT,
2510 MF_32_BYTE_ALIGNMENT,
2511 MF_64_BYTE_ALIGNMENT,
2512 MF_128_BYTE_ALIGNMENT,
2513 MF_256_BYTE_ALIGNMENT,
2514 MF_512_BYTE_ALIGNMENT,
2516 IMFMediaBuffer *buffer;
2517 DWORD length, max;
2518 unsigned int i;
2519 BYTE *data;
2520 HRESULT hr;
2522 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2523 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2525 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2526 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2528 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2529 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2530 ok(length == 0, "Unexpected current length %lu.\n", length);
2532 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2533 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2534 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2535 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2536 ok(length == 1, "Unexpected current length %lu.\n", length);
2538 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2539 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2540 ok(length == 201, "Unexpected max length %lu.\n", length);
2542 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2543 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2544 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2545 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2546 ok(length == 201, "Unexpected max length %lu.\n", length);
2547 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2548 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2550 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2551 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2552 ok(max == 201 && length == 10, "Unexpected length.\n");
2553 hr = IMFMediaBuffer_Unlock(buffer);
2554 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2556 IMFMediaBuffer_Release(buffer);
2558 for (i = 0; i < ARRAY_SIZE(alignments); ++i)
2560 hr = MFCreateAlignedMemoryBuffer(200, alignments[i], &buffer);
2561 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2563 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2564 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2565 ok(max == 200 && !length, "Unexpected length.\n");
2566 ok(!((uintptr_t)data & alignments[i]), "Data at %p is misaligned.\n", data);
2567 hr = IMFMediaBuffer_Unlock(buffer);
2568 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2570 IMFMediaBuffer_Release(buffer);
2573 hr = MFCreateAlignedMemoryBuffer(200, 0, &buffer);
2574 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2575 IMFMediaBuffer_Release(buffer);
2578 static void test_sample(void)
2580 static const DWORD test_pattern = 0x22222222;
2581 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2582 DWORD count, flags, length;
2583 IMFAttributes *attributes;
2584 IMFSample *sample;
2585 LONGLONG time;
2586 HRESULT hr;
2587 BYTE *data;
2589 hr = MFCreateSample( &sample );
2590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2592 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2593 ok(hr == S_OK, "Failed to get attributes interface, hr %#lx.\n", hr);
2595 CHECK_ATTR_COUNT(attributes, 0);
2597 hr = IMFSample_GetBufferCount(sample, NULL);
2598 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2600 hr = IMFSample_GetBufferCount(sample, &count);
2601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2602 ok(count == 0, "got %ld\n", count);
2604 hr = IMFSample_GetSampleFlags(sample, &flags);
2605 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2606 ok(!flags, "Unexpected flags %#lx.\n", flags);
2608 hr = IMFSample_SetSampleFlags(sample, 0x123);
2609 ok(hr == S_OK, "Failed to set sample flags, hr %#lx.\n", hr);
2610 hr = IMFSample_GetSampleFlags(sample, &flags);
2611 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2612 ok(flags == 0x123, "Unexpected flags %#lx.\n", flags);
2614 hr = IMFSample_GetSampleTime(sample, &time);
2615 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
2617 hr = IMFSample_GetSampleDuration(sample, &time);
2618 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
2620 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2621 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2623 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2624 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2626 hr = IMFSample_RemoveAllBuffers(sample);
2627 ok(hr == S_OK, "Failed to remove all, hr %#lx.\n", hr);
2629 hr = IMFSample_GetTotalLength(sample, &length);
2630 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2631 ok(!length, "Unexpected total length %lu.\n", length);
2633 hr = MFCreateMemoryBuffer(16, &buffer);
2634 ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr);
2636 hr = IMFSample_AddBuffer(sample, buffer);
2637 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2639 hr = IMFSample_AddBuffer(sample, buffer);
2640 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2642 hr = IMFSample_GetBufferCount(sample, &count);
2643 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2644 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2646 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2647 ok(hr == S_OK, "Failed to get buffer, hr %#lx.\n", hr);
2648 ok(buffer2 == buffer, "Unexpected object.\n");
2649 IMFMediaBuffer_Release(buffer2);
2651 hr = IMFSample_GetTotalLength(sample, &length);
2652 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2653 ok(!length, "Unexpected total length %lu.\n", length);
2655 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2656 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2658 hr = IMFSample_GetTotalLength(sample, &length);
2659 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2660 ok(length == 4, "Unexpected total length %lu.\n", length);
2662 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2663 ok(hr == S_OK, "Failed to remove buffer, hr %#lx.\n", hr);
2665 hr = IMFSample_GetTotalLength(sample, &length);
2666 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2667 ok(length == 2, "Unexpected total length %lu.\n", length);
2669 IMFMediaBuffer_Release(buffer);
2671 /* Duration */
2672 hr = IMFSample_SetSampleDuration(sample, 10);
2673 ok(hr == S_OK, "Failed to set duration, hr %#lx.\n", hr);
2674 CHECK_ATTR_COUNT(attributes, 0);
2675 hr = IMFSample_GetSampleDuration(sample, &time);
2676 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
2677 ok(time == 10, "Unexpected duration.\n");
2679 /* Timestamp */
2680 hr = IMFSample_SetSampleTime(sample, 1);
2681 ok(hr == S_OK, "Failed to set timestamp, hr %#lx.\n", hr);
2682 CHECK_ATTR_COUNT(attributes, 0);
2683 hr = IMFSample_GetSampleTime(sample, &time);
2684 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
2685 ok(time == 1, "Unexpected timestamp.\n");
2687 IMFAttributes_Release(attributes);
2688 IMFSample_Release(sample);
2690 /* CopyToBuffer() */
2691 hr = MFCreateSample(&sample);
2692 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2694 hr = MFCreateMemoryBuffer(16, &buffer2);
2695 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2697 /* Sample with no buffers. */
2698 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2699 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2700 hr = IMFSample_CopyToBuffer(sample, buffer2);
2701 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2702 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2703 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2704 ok(!length, "Unexpected length %lu.\n", length);
2706 /* Single buffer, larger destination. */
2707 hr = MFCreateMemoryBuffer(8, &buffer);
2708 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2710 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2711 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2712 *(DWORD *)data = 0x11111111;
2713 hr = IMFMediaBuffer_Unlock(buffer);
2714 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2715 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2716 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2718 hr = IMFSample_AddBuffer(sample, buffer);
2719 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2721 /* Existing content is overwritten. */
2722 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2723 ok(hr == S_OK, "Failed to set length, hr %#lx.\n", hr);
2725 hr = IMFSample_CopyToBuffer(sample, buffer2);
2726 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2728 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2729 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2730 ok(length == 4, "Unexpected buffer length %lu.\n", length);
2732 /* Multiple buffers, matching total size. */
2733 hr = IMFSample_AddBuffer(sample, buffer);
2734 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2736 hr = IMFSample_GetBufferCount(sample, &count);
2737 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2738 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2740 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2741 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2743 hr = IMFSample_CopyToBuffer(sample, buffer2);
2744 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2746 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2747 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2748 ok(length == 16, "Unexpected buffer length %lu.\n", length);
2750 hr = IMFSample_AddBuffer(sample, buffer);
2751 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2753 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2754 ok(hr == S_OK, "Failed to set buffer length, hr %#lx.\n", hr);
2756 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2757 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2758 *(DWORD *)data = test_pattern;
2759 hr = IMFMediaBuffer_Unlock(buffer2);
2760 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2762 hr = IMFSample_CopyToBuffer(sample, buffer2);
2763 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
2765 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2766 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2767 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#lx\n", *(DWORD *)data);
2768 hr = IMFMediaBuffer_Unlock(buffer2);
2769 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2771 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2772 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2773 ok(!length, "Unexpected buffer length %lu.\n", length);
2775 IMFMediaBuffer_Release(buffer2);
2776 IMFSample_Release(sample);
2778 /* ConvertToContiguousBuffer() */
2779 hr = MFCreateSample(&sample);
2780 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2782 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2783 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2785 hr = MFCreateMemoryBuffer(16, &buffer);
2786 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2788 hr = IMFSample_AddBuffer(sample, buffer);
2789 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2791 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2792 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2793 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2794 IMFMediaBuffer_Release(buffer2);
2796 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2797 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2799 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2800 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2801 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2802 IMFMediaBuffer_Release(buffer2);
2804 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2805 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2807 hr = MFCreateMemoryBuffer(16, &buffer2);
2808 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2810 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2811 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2813 hr = IMFSample_AddBuffer(sample, buffer2);
2814 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2815 IMFMediaBuffer_Release(buffer2);
2817 hr = IMFSample_GetBufferCount(sample, &count);
2818 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2819 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2821 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2822 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2824 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2825 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2826 ok(length == 7, "Unexpected length %lu.\n", length);
2828 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2829 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2830 ok(length == 7, "Unexpected length %lu.\n", length);
2832 IMFMediaBuffer_Release(buffer3);
2834 hr = IMFSample_GetBufferCount(sample, &count);
2835 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2836 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2838 hr = IMFSample_AddBuffer(sample, buffer);
2839 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2841 hr = IMFSample_GetBufferCount(sample, &count);
2842 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2843 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2845 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2846 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2848 hr = IMFSample_GetBufferCount(sample, &count);
2849 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2850 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2852 IMFMediaBuffer_Release(buffer);
2854 IMFSample_Release(sample);
2857 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2859 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2860 IMFMediaEventQueue *queue;
2861 IUnknown *state, *obj;
2862 HRESULT hr;
2864 ok(result != NULL, "Unexpected result object.\n");
2866 state = IMFAsyncResult_GetStateNoAddRef(result);
2867 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2869 IMFMediaEvent *event = NULL, *event2;
2871 if (is_win8_plus)
2873 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2874 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2876 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2877 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2879 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2880 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#lx.\n", hr);
2882 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2883 ok(hr == E_FAIL, "Unexpected result, hr %#lx.\n", hr);
2885 if (event)
2886 IMFMediaEvent_Release(event);
2889 hr = IMFAsyncResult_GetObject(result, &obj);
2890 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2892 IMFMediaEventQueue_Release(queue);
2894 SetEvent(callback->event);
2897 return E_NOTIMPL;
2900 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2902 testcallback_QueryInterface,
2903 testcallback_AddRef,
2904 testcallback_Release,
2905 testcallback_GetParameters,
2906 testcallback_Invoke,
2909 static void test_MFCreateAsyncResult(void)
2911 IMFAsyncResult *result, *result2;
2912 struct test_callback *callback;
2913 IUnknown *state, *object;
2914 MFASYNCRESULT *data;
2915 ULONG refcount;
2916 HANDLE event;
2917 DWORD flags;
2918 HRESULT hr;
2919 BOOL ret;
2921 callback = create_test_callback(NULL);
2923 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2924 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2926 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2927 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2929 data = (MFASYNCRESULT *)result;
2930 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2931 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2932 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2933 ok(data->hEvent == NULL, "Unexpected event.\n");
2935 hr = IMFAsyncResult_GetState(result, NULL);
2936 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2938 state = (void *)0xdeadbeef;
2939 hr = IMFAsyncResult_GetState(result, &state);
2940 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2941 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2943 hr = IMFAsyncResult_GetStatus(result);
2944 ok(hr == S_OK, "Unexpected status %#lx.\n", hr);
2946 data->hrStatusResult = 123;
2947 hr = IMFAsyncResult_GetStatus(result);
2948 ok(hr == 123, "Unexpected status %#lx.\n", hr);
2950 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2951 ok(hr == S_OK, "Failed to set status, hr %#lx.\n", hr);
2952 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#lx.\n", hr);
2954 hr = IMFAsyncResult_GetObject(result, NULL);
2955 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2957 object = (void *)0xdeadbeef;
2958 hr = IMFAsyncResult_GetObject(result, &object);
2959 ok(hr == E_POINTER, "Failed to get object, hr %#lx.\n", hr);
2960 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2962 state = IMFAsyncResult_GetStateNoAddRef(result);
2963 ok(state == NULL, "Unexpected state.\n");
2965 /* Object. */
2966 hr = MFCreateAsyncResult((IUnknown *)result, &callback->IMFAsyncCallback_iface, NULL, &result2);
2967 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2969 data = (MFASYNCRESULT *)result2;
2970 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2971 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2972 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2973 ok(data->hEvent == NULL, "Unexpected event.\n");
2975 object = NULL;
2976 hr = IMFAsyncResult_GetObject(result2, &object);
2977 ok(hr == S_OK, "Failed to get object, hr %#lx.\n", hr);
2978 ok(object == (IUnknown *)result, "Unexpected object.\n");
2979 IUnknown_Release(object);
2981 IMFAsyncResult_Release(result2);
2983 /* State object. */
2984 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2985 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2987 data = (MFASYNCRESULT *)result2;
2988 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2989 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2990 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2991 ok(data->hEvent == NULL, "Unexpected event.\n");
2993 state = NULL;
2994 hr = IMFAsyncResult_GetState(result2, &state);
2995 ok(hr == S_OK, "Failed to get state object, hr %#lx.\n", hr);
2996 ok(state == (IUnknown *)result, "Unexpected state.\n");
2997 IUnknown_Release(state);
2999 state = IMFAsyncResult_GetStateNoAddRef(result2);
3000 ok(state == (IUnknown *)result, "Unexpected state.\n");
3002 refcount = IMFAsyncResult_Release(result2);
3003 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3004 refcount = IMFAsyncResult_Release(result);
3005 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3007 /* Event handle is closed on release. */
3008 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
3009 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3011 data = (MFASYNCRESULT *)result;
3012 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
3013 ok(data->hEvent != NULL, "Failed to create event.\n");
3014 ret = GetHandleInformation(event, &flags);
3015 ok(ret, "Failed to get handle info.\n");
3017 refcount = IMFAsyncResult_Release(result);
3018 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3019 ret = GetHandleInformation(event, &flags);
3020 ok(!ret, "Expected handle to be closed.\n");
3022 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3023 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3025 data = (MFASYNCRESULT *)result;
3026 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
3027 ok(data->hEvent != NULL, "Failed to create event.\n");
3028 ret = GetHandleInformation(event, &flags);
3029 ok(ret, "Failed to get handle info.\n");
3031 refcount = IMFAsyncResult_Release(result);
3032 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3033 ret = GetHandleInformation(event, &flags);
3034 ok(!ret, "Expected handle to be closed.\n");
3036 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3039 static void test_startup(void)
3041 DWORD queue;
3042 HRESULT hr;
3044 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
3045 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#lx.\n", hr);
3047 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3048 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3050 hr = MFAllocateWorkQueue(&queue);
3051 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3052 hr = MFUnlockWorkQueue(queue);
3053 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3055 hr = MFShutdown();
3056 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3058 hr = MFAllocateWorkQueue(&queue);
3059 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3061 /* Already shut down, has no effect. */
3062 hr = MFShutdown();
3063 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3065 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3066 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3068 hr = MFAllocateWorkQueue(&queue);
3069 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3070 hr = MFUnlockWorkQueue(queue);
3071 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3073 hr = MFShutdown();
3074 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3076 /* Platform lock. */
3077 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3078 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3080 hr = MFAllocateWorkQueue(&queue);
3081 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3082 hr = MFUnlockWorkQueue(queue);
3083 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3085 /* Unlocking implies shutdown. */
3086 hr = MFUnlockPlatform();
3087 ok(hr == S_OK, "Failed to unlock, %#lx.\n", hr);
3089 hr = MFAllocateWorkQueue(&queue);
3090 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3092 hr = MFLockPlatform();
3093 ok(hr == S_OK, "Failed to lock, %#lx.\n", hr);
3095 hr = MFAllocateWorkQueue(&queue);
3096 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3097 hr = MFUnlockWorkQueue(queue);
3098 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3100 hr = MFShutdown();
3101 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3104 static void test_allocate_queue(void)
3106 DWORD queue, queue2;
3107 HRESULT hr;
3109 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3110 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3112 hr = MFAllocateWorkQueue(&queue);
3113 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3114 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
3116 hr = MFUnlockWorkQueue(queue);
3117 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3119 hr = MFUnlockWorkQueue(queue);
3120 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
3122 hr = MFAllocateWorkQueue(&queue2);
3123 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3124 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
3126 hr = MFUnlockWorkQueue(queue2);
3127 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3129 /* Unlock in system queue range. */
3130 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
3131 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3133 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
3134 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3136 hr = MFUnlockWorkQueue(0x20);
3137 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3139 hr = MFShutdown();
3140 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3143 static void test_MFCopyImage(void)
3145 DWORD dest[4], src[4];
3146 HRESULT hr;
3148 if (!pMFCopyImage)
3150 win_skip("MFCopyImage() is not available.\n");
3151 return;
3154 memset(dest, 0xaa, sizeof(dest));
3155 memset(src, 0x11, sizeof(src));
3157 hr = pMFCopyImage((BYTE *)dest, 8, (const BYTE *)src, 8, 4, 1);
3158 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3159 ok(dest[0] == src[0] && dest[1] == 0xaaaaaaaa, "Unexpected buffer contents.\n");
3161 /* Negative destination stride. */
3162 memset(dest, 0xaa, sizeof(dest));
3164 src[0] = 0x11111111;
3165 src[1] = 0x22222222;
3166 src[2] = 0x33333333;
3167 src[3] = 0x44444444;
3169 hr = pMFCopyImage((BYTE *)(dest + 2), -8, (const BYTE *)src, 8, 4, 2);
3170 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3171 ok(dest[0] == 0x33333333, "Unexpected buffer contents %#lx.\n", dest[0]);
3172 ok(dest[1] == 0xaaaaaaaa, "Unexpected buffer contents %#lx.\n", dest[1]);
3173 ok(dest[2] == 0x11111111, "Unexpected buffer contents %#lx.\n", dest[2]);
3174 ok(dest[3] == 0xaaaaaaaa, "Unexpected buffer contents %#lx.\n", dest[3]);
3176 memset(dest, 0xaa, sizeof(dest));
3177 memset(src, 0x11, sizeof(src));
3179 hr = pMFCopyImage((BYTE *)dest, 8, (const BYTE *)src, 8, 16, 1);
3180 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3181 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3183 memset(dest, 0xaa, sizeof(dest));
3184 memset(src, 0x11, sizeof(src));
3186 hr = pMFCopyImage((BYTE *)dest, 8, (const BYTE *)src, 8, 8, 2);
3187 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3188 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3191 static void test_MFCreateCollection(void)
3193 IMFCollection *collection;
3194 IUnknown *element;
3195 DWORD count;
3196 HRESULT hr;
3198 hr = MFCreateCollection(NULL);
3199 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3201 hr = MFCreateCollection(&collection);
3202 ok(hr == S_OK, "Failed to create collection, hr %#lx.\n", hr);
3204 hr = IMFCollection_GetElementCount(collection, NULL);
3205 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3207 count = 1;
3208 hr = IMFCollection_GetElementCount(collection, &count);
3209 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3210 ok(count == 0, "Unexpected count %lu.\n", count);
3212 hr = IMFCollection_GetElement(collection, 0, NULL);
3213 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3215 element = (void *)0xdeadbeef;
3216 hr = IMFCollection_GetElement(collection, 0, &element);
3217 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3218 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3220 hr = IMFCollection_RemoveElement(collection, 0, NULL);
3221 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3223 element = (void *)0xdeadbeef;
3224 hr = IMFCollection_RemoveElement(collection, 0, &element);
3225 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#lx.\n", hr);
3226 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3228 hr = IMFCollection_RemoveAllElements(collection);
3229 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3231 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
3232 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3234 count = 0;
3235 hr = IMFCollection_GetElementCount(collection, &count);
3236 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3237 ok(count == 1, "Unexpected count %lu.\n", count);
3239 hr = IMFCollection_AddElement(collection, NULL);
3240 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3242 count = 0;
3243 hr = IMFCollection_GetElementCount(collection, &count);
3244 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3245 ok(count == 2, "Unexpected count %lu.\n", count);
3247 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
3248 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3250 count = 0;
3251 hr = IMFCollection_GetElementCount(collection, &count);
3252 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3253 ok(count == 11, "Unexpected count %lu.\n", count);
3255 hr = IMFCollection_GetElement(collection, 0, &element);
3256 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3257 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3258 IUnknown_Release(element);
3260 hr = IMFCollection_GetElement(collection, 1, &element);
3261 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3262 ok(!element, "Unexpected element.\n");
3264 hr = IMFCollection_GetElement(collection, 2, &element);
3265 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3266 ok(!element, "Unexpected element.\n");
3268 hr = IMFCollection_GetElement(collection, 10, &element);
3269 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3270 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3271 IUnknown_Release(element);
3273 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3274 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3276 hr = IMFCollection_GetElement(collection, 0, &element);
3277 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3279 hr = IMFCollection_RemoveAllElements(collection);
3280 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3282 count = 1;
3283 hr = IMFCollection_GetElementCount(collection, &count);
3284 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3285 ok(count == 0, "Unexpected count %lu.\n", count);
3287 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3288 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3290 IMFCollection_Release(collection);
3293 static void test_MFHeapAlloc(void)
3295 void *res;
3297 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
3298 ok(res != NULL, "MFHeapAlloc failed.\n");
3300 MFHeapFree(res);
3303 static void test_scheduled_items(void)
3305 struct test_callback *callback;
3306 IMFAsyncResult *result;
3307 MFWORKITEM_KEY key, key2;
3308 HRESULT hr;
3310 callback = create_test_callback(NULL);
3312 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3313 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3315 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3316 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3318 hr = MFCancelWorkItem(key);
3319 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3321 hr = MFCancelWorkItem(key);
3322 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#lx.\n", hr);
3324 if (!pMFPutWaitingWorkItem)
3326 win_skip("Waiting items are not supported.\n");
3327 return;
3330 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3331 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3333 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
3334 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3336 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
3337 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3339 hr = MFCancelWorkItem(key);
3340 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3342 hr = MFCancelWorkItem(key2);
3343 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3345 IMFAsyncResult_Release(result);
3347 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3348 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3350 hr = MFCancelWorkItem(key);
3351 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3353 hr = MFShutdown();
3354 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3356 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3359 static void test_serial_queue(void)
3361 static const DWORD queue_ids[] =
3363 MFASYNC_CALLBACK_QUEUE_STANDARD,
3364 MFASYNC_CALLBACK_QUEUE_RT,
3365 MFASYNC_CALLBACK_QUEUE_IO,
3366 MFASYNC_CALLBACK_QUEUE_TIMER,
3367 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
3368 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
3370 DWORD queue, serial_queue;
3371 unsigned int i;
3372 HRESULT hr;
3374 if (!pMFAllocateSerialWorkQueue)
3376 win_skip("Serial queues are not supported.\n");
3377 return;
3380 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3381 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3383 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
3385 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
3386 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
3388 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
3389 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
3390 "%u: failed to allocate a queue, hr %#lx.\n", i, hr);
3392 if (SUCCEEDED(hr))
3394 hr = MFUnlockWorkQueue(serial_queue);
3395 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#lx.\n", i, hr);
3399 /* Chain them together. */
3400 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
3401 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3403 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
3404 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3406 hr = MFUnlockWorkQueue(serial_queue);
3407 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3409 hr = MFUnlockWorkQueue(queue);
3410 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3412 hr = MFShutdown();
3413 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3416 static LONG periodic_counter;
3417 static void CALLBACK periodic_callback(IUnknown *context)
3419 InterlockedIncrement(&periodic_counter);
3422 static void test_periodic_callback(void)
3424 DWORD period, key;
3425 HRESULT hr;
3427 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3428 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3430 period = 0;
3431 hr = MFGetTimerPeriodicity(&period);
3432 ok(hr == S_OK, "Failed to get timer perdiod, hr %#lx.\n", hr);
3433 ok(period == 10, "Unexpected period %lu.\n", period);
3435 if (!pMFAddPeriodicCallback)
3437 win_skip("Periodic callbacks are not supported.\n");
3438 hr = MFShutdown();
3439 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3440 return;
3443 ok(periodic_counter == 0, "Unexpected counter value %lu.\n", periodic_counter);
3445 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
3446 ok(hr == S_OK, "Failed to add periodic callback, hr %#lx.\n", hr);
3447 ok(key != 0, "Unexpected key %#lx.\n", key);
3449 Sleep(10 * period);
3451 hr = pMFRemovePeriodicCallback(key);
3452 ok(hr == S_OK, "Failed to remove callback, hr %#lx.\n", hr);
3454 ok(periodic_counter > 0, "Unexpected counter value %lu.\n", periodic_counter);
3456 hr = MFShutdown();
3457 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3460 static void test_event_queue(void)
3462 struct test_callback *callback, *callback2;
3463 IMFMediaEvent *event, *event2;
3464 IMFMediaEventQueue *queue;
3465 IMFAsyncResult *result;
3466 HRESULT hr;
3467 DWORD ret;
3469 callback = create_test_callback(NULL);
3470 callback2 = create_test_callback(NULL);
3472 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3473 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3475 hr = MFCreateEventQueue(&queue);
3476 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3478 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3479 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
3481 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3482 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3484 if (is_win8_plus)
3486 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3487 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3489 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3490 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3491 ok(event2 == event, "Unexpected event object.\n");
3492 IMFMediaEvent_Release(event2);
3494 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3495 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3497 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3498 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3499 IMFMediaEvent_Release(event2);
3502 /* Async case. */
3503 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3504 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3506 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3507 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3509 /* Same callback, same state. */
3510 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3511 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3513 /* Same callback, different state. */
3514 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3515 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3517 /* Different callback, same state. */
3518 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)queue);
3519 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3521 /* Different callback, different state. */
3522 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3523 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3525 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3526 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3528 ret = WaitForSingleObject(callback->event, 500);
3529 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#lx.\n", ret);
3531 IMFMediaEvent_Release(event);
3533 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3534 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3536 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3537 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3539 /* Shutdown behavior. */
3540 hr = IMFMediaEventQueue_Shutdown(queue);
3541 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3543 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3544 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3546 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3547 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3548 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3549 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3550 IMFMediaEvent_Release(event);
3552 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3553 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3555 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3556 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3558 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3559 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3561 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3562 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3564 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3565 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3566 IMFAsyncResult_Release(result);
3568 /* Already shut down. */
3569 hr = IMFMediaEventQueue_Shutdown(queue);
3570 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3572 IMFMediaEventQueue_Release(queue);
3573 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3575 /* Release while subscribed. */
3576 callback = create_test_callback(NULL);
3578 hr = MFCreateEventQueue(&queue);
3579 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3581 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3582 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3583 EXPECT_REF(&callback->IMFAsyncCallback_iface, 2);
3585 IMFMediaEventQueue_Release(queue);
3586 ret = get_refcount(&callback->IMFAsyncCallback_iface);
3587 ok(ret == 1 || broken(ret == 2) /* Vista */,
3588 "Unexpected refcount %ld, expected 1.\n", ret);
3589 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3591 hr = MFShutdown();
3592 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3595 static void test_presentation_descriptor(void)
3597 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3598 IMFPresentationDescriptor *pd, *pd2;
3599 IMFMediaType *media_type;
3600 unsigned int i;
3601 BOOL selected;
3602 UINT64 value;
3603 DWORD count;
3604 HRESULT hr;
3606 hr = MFCreateMediaType(&media_type);
3607 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
3609 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3611 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3612 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3615 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3616 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr);
3618 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3619 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %lu.\n", count);
3621 for (i = 0; i < count; ++i)
3623 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3624 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3625 ok(!selected, "Unexpected selected state.\n");
3626 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3627 IMFStreamDescriptor_Release(stream_desc2);
3630 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3631 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3633 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3634 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3636 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3637 ok(hr == S_OK, "Failed to select a stream, hr %#lx.\n", hr);
3639 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3640 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3641 ok(!!selected, "Unexpected selected state.\n");
3642 IMFStreamDescriptor_Release(stream_desc2);
3644 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3645 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
3647 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3648 ok(hr == S_OK, "Failed to clone, hr %#lx.\n", hr);
3650 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3651 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3652 ok(!!selected, "Unexpected selected state.\n");
3653 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3654 IMFStreamDescriptor_Release(stream_desc2);
3656 value = 0;
3657 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3658 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
3659 ok(value == 1, "Unexpected attribute value.\n");
3661 IMFPresentationDescriptor_Release(pd2);
3662 IMFPresentationDescriptor_Release(pd);
3664 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3666 IMFStreamDescriptor_Release(stream_desc[i]);
3669 /* Partially initialized array. */
3670 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3671 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3672 stream_desc[0] = NULL;
3674 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3675 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3677 IMFStreamDescriptor_Release(stream_desc[1]);
3678 IMFMediaType_Release(media_type);
3681 enum clock_action
3683 CLOCK_START,
3684 CLOCK_STOP,
3685 CLOCK_PAUSE,
3686 CLOCK_RESTART,
3689 static void test_system_time_source(void)
3691 static const struct clock_state_test
3693 enum clock_action action;
3694 MFCLOCK_STATE state;
3695 BOOL is_invalid;
3697 clock_state_change[] =
3699 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3700 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3701 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3702 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3703 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3704 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3705 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3706 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3707 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3708 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3709 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3710 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3711 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3712 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3713 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3714 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3715 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3717 IMFPresentationTimeSource *time_source, *time_source2;
3718 IMFClockStateSink *statesink;
3719 IMFClock *clock, *clock2;
3720 MFCLOCK_PROPERTIES props;
3721 MFCLOCK_STATE state;
3722 unsigned int i;
3723 MFTIME systime;
3724 LONGLONG time;
3725 DWORD value;
3726 HRESULT hr;
3728 hr = MFCreateSystemTimeSource(&time_source);
3729 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3731 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3732 ok(hr == S_OK, "Failed to get flags, hr %#lx.\n", hr);
3733 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3734 "Unexpected flags %#lx.\n", value);
3736 value = 1;
3737 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3738 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3739 ok(value == 0, "Unexpected value %lu.\n", value);
3741 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3742 ok(hr == S_OK, "Failed to get state, hr %#lx.\n", hr);
3743 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3745 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3746 ok(hr == S_OK, "Failed to get state sink, hr %#lx.\n", hr);
3748 /* State changes. */
3749 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3751 switch (clock_state_change[i].action)
3753 case CLOCK_STOP:
3754 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3755 break;
3756 case CLOCK_RESTART:
3757 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3758 break;
3759 case CLOCK_PAUSE:
3760 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3761 break;
3762 case CLOCK_START:
3763 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3764 break;
3765 default:
3768 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#lx.\n", i, hr);
3769 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3770 ok(hr == S_OK, "%u: failed to get state, hr %#lx.\n", i, hr);
3771 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3774 IMFClockStateSink_Release(statesink);
3776 /* Properties. */
3777 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3778 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3780 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3781 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3783 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3784 wine_dbgstr_longlong(props.qwCorrelationRate));
3785 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3786 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3787 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3788 wine_dbgstr_longlong(props.qwClockFrequency));
3789 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3790 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3792 /* Underlying clock. */
3793 hr = MFCreateSystemTimeSource(&time_source2);
3794 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3795 EXPECT_REF(time_source2, 1);
3796 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3797 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3798 EXPECT_REF(time_source2, 1);
3799 EXPECT_REF(clock2, 2);
3801 EXPECT_REF(time_source, 1);
3802 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3803 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3804 EXPECT_REF(time_source, 1);
3805 EXPECT_REF(clock, 2);
3807 ok(clock != clock2, "Unexpected clock instance.\n");
3809 IMFPresentationTimeSource_Release(time_source2);
3810 IMFClock_Release(clock2);
3812 hr = IMFClock_GetClockCharacteristics(clock, &value);
3813 ok(hr == S_OK, "Failed to get clock flags, hr %#lx.\n", hr);
3814 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3815 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#lx.\n", value);
3817 hr = IMFClock_GetContinuityKey(clock, &value);
3818 ok(hr == S_OK, "Failed to get clock key, hr %#lx.\n", hr);
3819 ok(value == 0, "Unexpected key value %lu.\n", value);
3821 hr = IMFClock_GetState(clock, 0, &state);
3822 ok(hr == S_OK, "Failed to get clock state, hr %#lx.\n", hr);
3823 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3825 hr = IMFClock_GetProperties(clock, &props);
3826 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3828 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3829 wine_dbgstr_longlong(props.qwCorrelationRate));
3830 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3831 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3832 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3833 wine_dbgstr_longlong(props.qwClockFrequency));
3834 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3835 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3837 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3838 ok(hr == S_OK, "Failed to get clock time, hr %#lx.\n", hr);
3839 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3841 IMFClock_Release(clock);
3843 /* Test returned time regarding specified rate and offset. */
3844 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3845 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3847 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3848 ok(hr == S_OK, "Failed to get state %#lx.\n", hr);
3849 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3851 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3852 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3853 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3855 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3856 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3858 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3859 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3860 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3862 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3863 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3865 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3866 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3867 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3868 wine_dbgstr_longlong(systime));
3870 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3871 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3873 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3874 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3875 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3877 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3878 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3880 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3881 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3882 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3883 wine_dbgstr_longlong(systime));
3885 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3886 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3888 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3889 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3890 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3891 wine_dbgstr_longlong(systime));
3893 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3894 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3896 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3897 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3898 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3900 /* Increased rate. */
3901 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3902 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3904 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3905 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3907 hr = IMFClockStateSink_OnClockSetRate(statesink, 5, 2.0f);
3908 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3910 hr = IMFClockStateSink_OnClockPause(statesink, 6);
3911 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3913 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3914 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3915 ok(time == 12 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3916 wine_dbgstr_longlong(systime));
3918 hr = IMFClockStateSink_OnClockRestart(statesink, 7);
3919 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3921 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3922 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3924 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3925 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3926 ok(time == 14 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3927 wine_dbgstr_longlong(systime));
3929 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3930 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3932 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3933 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3934 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3935 wine_dbgstr_longlong(2 * systime));
3937 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3938 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3940 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3941 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3942 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3943 wine_dbgstr_longlong(2 * systime));
3945 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3946 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3948 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3949 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3950 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3951 wine_dbgstr_longlong(systime));
3953 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3954 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3956 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3957 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3958 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3959 wine_dbgstr_longlong(systime));
3961 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3962 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3964 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3965 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3966 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3967 wine_dbgstr_longlong(systime));
3969 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3970 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3972 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3973 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3974 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3976 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3977 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3979 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3980 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3981 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3982 wine_dbgstr_longlong(2 * systime));
3984 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3985 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3987 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3988 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3990 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3991 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3992 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3993 wine_dbgstr_longlong(2 * systime));
3995 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3996 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3998 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3999 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4000 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4001 wine_dbgstr_longlong(systime));
4003 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
4004 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
4006 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4007 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4008 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4009 wine_dbgstr_longlong(systime));
4011 hr = IMFClockStateSink_OnClockPause(statesink, 0);
4012 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4014 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4015 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4016 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4017 wine_dbgstr_longlong(systime));
4019 IMFClockStateSink_Release(statesink);
4020 IMFPresentationTimeSource_Release(time_source);
4022 /* PRESENTATION_CURRENT_POSITION */
4023 hr = MFCreateSystemTimeSource(&time_source);
4024 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
4026 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
4027 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
4029 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4030 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4031 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4032 wine_dbgstr_longlong(systime));
4034 /* INVALID -> RUNNING */
4035 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
4036 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4038 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4039 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4040 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4041 wine_dbgstr_longlong(systime));
4043 /* RUNNING -> RUNNING */
4044 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
4045 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4047 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4048 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4049 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4050 wine_dbgstr_longlong(systime));
4052 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
4053 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4055 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4056 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4057 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4058 wine_dbgstr_longlong(systime));
4060 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
4061 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4063 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4064 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4065 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4066 wine_dbgstr_longlong(systime));
4068 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
4069 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4071 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4072 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4073 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4074 wine_dbgstr_longlong(systime));
4076 /* STOPPED -> RUNNING */
4077 hr = IMFClockStateSink_OnClockStop(statesink, 567);
4078 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
4080 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4081 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4082 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4083 wine_dbgstr_longlong(systime));
4085 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
4086 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4088 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4089 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4090 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4091 wine_dbgstr_longlong(systime));
4093 /* PAUSED -> RUNNING */
4094 hr = IMFClockStateSink_OnClockPause(statesink, 8);
4095 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4097 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4098 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4099 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4100 wine_dbgstr_longlong(systime));
4102 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
4103 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4105 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4106 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4107 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4108 wine_dbgstr_longlong(systime));
4110 hr = IMFClockStateSink_OnClockPause(statesink, 7);
4111 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4113 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4114 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4115 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4116 wine_dbgstr_longlong(systime));
4118 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
4119 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4121 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4122 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4123 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4124 wine_dbgstr_longlong(systime));
4126 IMFClockStateSink_Release(statesink);
4127 IMFPresentationTimeSource_Release(time_source);
4130 static void test_MFInvokeCallback(void)
4132 struct test_callback *callback;
4133 IMFAsyncResult *result;
4134 MFASYNCRESULT *data;
4135 ULONG refcount;
4136 HRESULT hr;
4137 DWORD ret;
4139 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4140 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
4142 callback = create_test_callback(NULL);
4144 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
4145 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4147 data = (MFASYNCRESULT *)result;
4148 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
4149 ok(data->hEvent != NULL, "Failed to create event.\n");
4151 hr = MFInvokeCallback(result);
4152 ok(hr == S_OK, "Failed to invoke, hr %#lx.\n", hr);
4154 ret = WaitForSingleObject(data->hEvent, 100);
4155 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#lx.\n", ret);
4157 refcount = IMFAsyncResult_Release(result);
4158 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
4160 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4162 hr = MFShutdown();
4163 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4166 static void test_stream_descriptor(void)
4168 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
4169 IMFMediaTypeHandler *type_handler;
4170 IMFStreamDescriptor *stream_desc;
4171 GUID major_type;
4172 DWORD id, count;
4173 unsigned int i;
4174 HRESULT hr;
4176 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
4177 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4179 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4181 hr = MFCreateMediaType(&media_types[i]);
4182 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4185 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
4186 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4188 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4189 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4191 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
4192 ok(hr == S_OK, "Failed to get descriptor id, hr %#lx.\n", hr);
4193 ok(id == 123, "Unexpected id %#lx.\n", id);
4195 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4196 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4198 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4199 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4200 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4202 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
4203 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
4205 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4206 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4208 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4210 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
4211 ok(hr == S_OK, "Failed to get media type, hr %#lx.\n", hr);
4212 ok(media_type == media_types[i], "Unexpected object.\n");
4214 if (SUCCEEDED(hr))
4215 IMFMediaType_Release(media_type);
4218 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
4219 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#lx.\n", hr);
4221 /* IsMediaTypeSupported() */
4223 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
4224 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4226 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
4227 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4229 hr = MFCreateMediaType(&media_type);
4230 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4232 hr = MFCreateMediaType(&media_type3);
4233 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4235 media_type2 = (void *)0xdeadbeef;
4236 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4237 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4238 ok(!media_type2, "Unexpected pointer.\n");
4240 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
4241 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4243 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
4244 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4246 media_type2 = (void *)0xdeadbeef;
4247 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4248 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4249 ok(!media_type2, "Unexpected pointer.\n");
4251 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4252 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4254 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4255 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4257 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4258 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4259 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
4261 /* Mismatching major types. */
4262 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4263 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4265 media_type2 = (void *)0xdeadbeef;
4266 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4267 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4268 ok(!media_type2, "Unexpected pointer.\n");
4270 /* Subtype missing. */
4271 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4272 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4274 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4275 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4277 media_type2 = (void *)0xdeadbeef;
4278 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4279 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4280 ok(!media_type2, "Unexpected pointer.\n");
4282 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4283 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4285 media_type2 = (void *)0xdeadbeef;
4286 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4287 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4288 ok(!media_type2, "Unexpected pointer.\n");
4290 /* Mismatching subtype. */
4291 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4292 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4294 media_type2 = (void *)0xdeadbeef;
4295 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4296 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4297 ok(!media_type2, "Unexpected pointer.\n");
4299 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4300 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4301 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4303 IMFMediaTypeHandler_Release(type_handler);
4304 IMFStreamDescriptor_Release(stream_desc);
4306 /* IsMediaTypeSupported() for unset current type. */
4307 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4308 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4310 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4311 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4313 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
4314 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4316 /* Initialize one from initial type set. */
4317 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
4318 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4320 media_type2 = (void *)0xdeadbeef;
4321 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4322 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4323 ok(!media_type2, "Unexpected pointer.\n");
4325 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4326 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4328 media_type2 = (void *)0xdeadbeef;
4329 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4330 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4331 ok(!media_type2, "Unexpected pointer.\n");
4333 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4334 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4336 media_type2 = (void *)0xdeadbeef;
4337 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4338 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4339 ok(!media_type2, "Unexpected pointer.\n");
4341 /* Now set current type that's not compatible. */
4342 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4343 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4345 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4346 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4348 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
4349 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4351 media_type2 = (void *)0xdeadbeef;
4352 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4353 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4354 ok(!media_type2, "Unexpected pointer.\n");
4356 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
4357 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4359 media_type2 = (void *)0xdeadbeef;
4360 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4361 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4362 ok(!media_type2, "Unexpected pointer.\n");
4364 IMFMediaType_Release(media_type);
4365 IMFMediaType_Release(media_type3);
4367 IMFMediaTypeHandler_Release(type_handler);
4369 IMFStreamDescriptor_Release(stream_desc);
4371 /* Major type is returned for first entry. */
4372 hr = MFCreateMediaType(&media_types[0]);
4373 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4374 hr = MFCreateMediaType(&media_types[1]);
4375 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4377 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4378 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4379 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4380 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4382 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
4383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4385 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4386 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4388 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4389 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4390 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4392 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4393 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4394 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4395 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4397 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4398 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4399 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4401 IMFMediaType_Release(media_types[0]);
4402 IMFMediaType_Release(media_types[1]);
4404 IMFMediaTypeHandler_Release(type_handler);
4405 IMFStreamDescriptor_Release(stream_desc);
4408 static const struct image_size_test
4410 const GUID *subtype;
4411 UINT32 width;
4412 UINT32 height;
4413 UINT32 size;
4414 UINT32 plane_size; /* Matches image size when 0. */
4415 UINT32 max_length;
4416 UINT32 contiguous_length;
4417 UINT32 pitch;
4419 image_size_tests[] =
4421 /* RGB */
4422 { &MFVideoFormat_RGB8, 3, 5, 20, 0, 320, 20, 64 },
4423 { &MFVideoFormat_RGB8, 1, 1, 4, 0, 64, 4, 64 },
4424 { &MFVideoFormat_RGB8, 320, 240, 76800, 0, 76800, 76800, 320 },
4425 { &MFVideoFormat_RGB555, 3, 5, 40, 0, 320, 40, 64 },
4426 { &MFVideoFormat_RGB555, 1, 1, 4, 0, 64, 4, 64 },
4427 { &MFVideoFormat_RGB555, 320, 240, 153600, 0, 153600, 153600, 640 },
4428 { &MFVideoFormat_RGB565, 3, 5, 40, 0, 320, 40, 64 },
4429 { &MFVideoFormat_RGB565, 1, 1, 4, 0, 64, 4, 64 },
4430 { &MFVideoFormat_RGB565, 320, 240, 153600, 0, 153600, 153600, 640 },
4431 { &MFVideoFormat_RGB24, 3, 5, 60, 0, 320, 60, 64 },
4432 { &MFVideoFormat_RGB24, 1, 1, 4, 0, 64, 4, 64 },
4433 { &MFVideoFormat_RGB24, 4, 3, 36, 0, 192, 36, 64 },
4434 { &MFVideoFormat_RGB24, 320, 240, 230400, 0, 230400, 230400, 960 },
4435 { &MFVideoFormat_RGB32, 3, 5, 60, 0, 320, 60, 64 },
4436 { &MFVideoFormat_RGB32, 1, 1, 4, 0, 64, 4, 64 },
4437 { &MFVideoFormat_RGB32, 320, 240, 307200, 0, 307200, 307200, 1280 },
4438 { &MFVideoFormat_ARGB32, 3, 5, 60, 0, 320, 60, 64 },
4439 { &MFVideoFormat_ARGB32, 1, 1, 4, 0, 64, 4, 64 },
4440 { &MFVideoFormat_ARGB32, 320, 240, 307200, 0, 307200, 307200, 1280 },
4441 { &MFVideoFormat_A2R10G10B10, 3, 5, 60, 0, 320, 60, 64 },
4442 { &MFVideoFormat_A2R10G10B10, 1, 1, 4, 0, 64, 4, 64 },
4443 { &MFVideoFormat_A2R10G10B10, 320, 240, 307200, 0, 307200, 307200, 1280 },
4444 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120, 0, 320, 120, 64 },
4445 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8, 0, 64, 8, 64 },
4446 { &MFVideoFormat_A16B16G16R16F, 320, 240, 614400, 0, 614400, 614400, 2560 },
4448 { &MEDIASUBTYPE_RGB8, 3, 5, 20 },
4449 { &MEDIASUBTYPE_RGB8, 1, 1, 4 },
4450 { &MEDIASUBTYPE_RGB555, 3, 5, 40 },
4451 { &MEDIASUBTYPE_RGB555, 1, 1, 4 },
4452 { &MEDIASUBTYPE_RGB565, 3, 5, 40 },
4453 { &MEDIASUBTYPE_RGB565, 1, 1, 4 },
4454 { &MEDIASUBTYPE_RGB24, 3, 5, 60 },
4455 { &MEDIASUBTYPE_RGB24, 1, 1, 4 },
4456 { &MEDIASUBTYPE_RGB24, 4, 3, 36 },
4457 { &MEDIASUBTYPE_RGB32, 3, 5, 60 },
4458 { &MEDIASUBTYPE_RGB32, 1, 1, 4 },
4460 /* YUV 4:4:4, 32 bpp, packed */
4461 { &MFVideoFormat_AYUV, 1, 1, 4, 0, 64, 4, 64 },
4462 { &MFVideoFormat_AYUV, 2, 1, 8, 0, 64, 8, 64 },
4463 { &MFVideoFormat_AYUV, 1, 2, 8, 0, 128, 8, 64 },
4464 { &MFVideoFormat_AYUV, 4, 3, 48, 0, 192, 48, 64 },
4465 { &MFVideoFormat_AYUV, 320, 240, 307200, 0, 307200, 307200, 1280 },
4467 /* YUV 4:2:2, 16 bpp, packed */
4468 { &MFVideoFormat_YUY2, 2, 1, 4, 0, 64, 4, 64 },
4469 { &MFVideoFormat_YUY2, 4, 3, 24, 0, 192, 24, 64 },
4470 { &MFVideoFormat_YUY2, 128, 128, 32768, 0, 32768, 32768, 256 },
4471 { &MFVideoFormat_YUY2, 320, 240, 153600, 0, 153600, 153600, 640 },
4473 { &MFVideoFormat_UYVY, 2, 1, 4, 0, 64, 4, 64 },
4474 { &MFVideoFormat_UYVY, 4, 3, 24, 0, 192, 24, 64 },
4475 { &MFVideoFormat_UYVY, 128, 128, 32768, 0, 32768, 32768, 256 },
4476 { &MFVideoFormat_UYVY, 320, 240, 153600, 0, 153600, 153600, 640 },
4478 /* YUV 4:2:0, 16 bpp, planar (the secondary plane has the same
4479 * height, half the width and the same stride as the primary
4480 * one) */
4481 { &MFVideoFormat_IMC1, 1, 1, 4, 0, 256, 8, 128 },
4482 { &MFVideoFormat_IMC1, 2, 1, 4, 0, 256, 8, 128 },
4483 { &MFVideoFormat_IMC1, 1, 2, 8, 0, 512, 16, 128 },
4484 { &MFVideoFormat_IMC1, 2, 2, 8, 0, 512, 16, 128 },
4485 { &MFVideoFormat_IMC1, 2, 4, 16, 0, 1024, 32, 128 },
4486 { &MFVideoFormat_IMC1, 4, 2, 16, 0, 512, 32, 128 },
4487 { &MFVideoFormat_IMC1, 4, 3, 24, 0, 768, 48, 128 },
4488 { &MFVideoFormat_IMC1, 320, 240, 153600, 0, 307200, 307200, 640 },
4490 { &MFVideoFormat_IMC3, 1, 1, 4, 0, 256, 8, 128 },
4491 { &MFVideoFormat_IMC3, 2, 1, 4, 0, 256, 8, 128 },
4492 { &MFVideoFormat_IMC3, 1, 2, 8, 0, 512, 16, 128 },
4493 { &MFVideoFormat_IMC3, 2, 2, 8, 0, 512, 16, 128 },
4494 { &MFVideoFormat_IMC3, 2, 4, 16, 0, 1024, 32, 128 },
4495 { &MFVideoFormat_IMC3, 4, 2, 16, 0, 512, 32, 128 },
4496 { &MFVideoFormat_IMC3, 4, 3, 24, 0, 768, 48, 128 },
4497 { &MFVideoFormat_IMC3, 320, 240, 153600, 0, 307200, 307200, 640 },
4499 /* YUV 4:2:0, 12 bpp, planar, full stride (the secondary plane has
4500 * half the height, the same width and the same stride as the
4501 * primary one) */
4502 { &MFVideoFormat_NV12, 1, 3, 9, 4, 288, 4, 64 },
4503 { &MFVideoFormat_NV12, 1, 2, 6, 3, 192, 3, 64 },
4504 { &MFVideoFormat_NV12, 2, 2, 6, 6, 192, 6, 64 },
4505 { &MFVideoFormat_NV12, 2, 4, 12, 0, 384, 12, 64 },
4506 { &MFVideoFormat_NV12, 3, 2, 12, 9, 192, 9, 64 },
4507 { &MFVideoFormat_NV12, 4, 2, 12, 0, 192, 12, 64 },
4508 { &MFVideoFormat_NV12, 320, 240, 115200, 0, 115200, 115200, 320 },
4510 /* YUV 4:2:0, 12 bpp, planar, half stride (the secondary plane has
4511 * the same height, half the width and half the stride of the
4512 * primary one) */
4513 { &MFVideoFormat_IMC2, 1, 1, 3, 1, 192, 1, 128 },
4514 { &MFVideoFormat_IMC2, 1, 2, 6, 3, 384, 2, 128 },
4515 { &MFVideoFormat_IMC2, 1, 3, 9, 4, 576, 3, 128 },
4516 { &MFVideoFormat_IMC2, 2, 1, 3, 0, 192, 3, 128 },
4517 { &MFVideoFormat_IMC2, 2, 2, 6, 6, 384, 6, 128 },
4518 { &MFVideoFormat_IMC2, 2, 4, 12, 0, 768, 12, 128 },
4519 { &MFVideoFormat_IMC2, 3, 2, 12, 9, 384, 8, 128 },
4520 { &MFVideoFormat_IMC2, 3, 5, 30, 22, 960, 20, 128 },
4521 { &MFVideoFormat_IMC2, 4, 2, 12, 0, 384, 12, 128 },
4522 { &MFVideoFormat_IMC2, 4, 3, 18, 0, 576, 18, 128 },
4523 { &MFVideoFormat_IMC2, 320, 240, 115200, 0, 138240, 115200, 384 },
4525 { &MFVideoFormat_IMC4, 1, 1, 3, 1, 192, 1, 128 },
4526 { &MFVideoFormat_IMC4, 1, 2, 6, 3, 384, 2, 128 },
4527 { &MFVideoFormat_IMC4, 1, 3, 9, 4, 576, 3, 128 },
4528 { &MFVideoFormat_IMC4, 2, 1, 3, 0, 192, 3, 128 },
4529 { &MFVideoFormat_IMC4, 2, 2, 6, 6, 384, 6, 128 },
4530 { &MFVideoFormat_IMC4, 2, 4, 12, 0, 768, 12, 128 },
4531 { &MFVideoFormat_IMC4, 3, 2, 12, 9, 384, 8, 128 },
4532 { &MFVideoFormat_IMC4, 3, 5, 30, 22, 960, 20, 128 },
4533 { &MFVideoFormat_IMC4, 4, 2, 12, 0, 384, 12, 128 },
4534 { &MFVideoFormat_IMC4, 4, 3, 18, 0, 576, 18, 128 },
4535 { &MFVideoFormat_IMC4, 320, 240, 115200, 0, 138240, 115200, 384 },
4537 /* YUV 4:1:1, 12 bpp, semi-planar */
4538 { &MFVideoFormat_NV11, 1, 3, 18, 4, 576, 3, 128 },
4539 { &MFVideoFormat_NV11, 1, 2, 12, 3, 384, 2, 128 },
4540 { &MFVideoFormat_NV11, 2, 2, 12, 6, 384, 6, 128 },
4541 { &MFVideoFormat_NV11, 2, 4, 24, 12, 768, 12, 128 },
4542 { &MFVideoFormat_NV11, 3, 2, 12, 9, 384, 8, 128 },
4543 { &MFVideoFormat_NV11, 4, 2, 12, 0, 384, 12, 128 },
4544 { &MFVideoFormat_NV11, 320, 240, 115200, 0, 138240, 115200, 384 },
4546 { &MFVideoFormat_YV12, 1, 1, 3, 1, 192, 1, 128 },
4547 { &MFVideoFormat_YV12, 1, 2, 6, 3, 384, 2, 128 },
4548 { &MFVideoFormat_YV12, 1, 3, 9, 4, 576, 3, 128 },
4549 { &MFVideoFormat_YV12, 2, 1, 3, 0, 192, 3, 128 },
4550 { &MFVideoFormat_YV12, 2, 2, 6, 6, 384, 6, 128 },
4551 { &MFVideoFormat_YV12, 2, 4, 12, 0, 768, 12, 128 },
4552 { &MFVideoFormat_YV12, 3, 2, 12, 9, 384, 8, 128 },
4553 { &MFVideoFormat_YV12, 3, 5, 30, 22, 960, 20, 128 },
4554 { &MFVideoFormat_YV12, 4, 2, 12, 0, 384, 12, 128 },
4555 { &MFVideoFormat_YV12, 4, 3, 18, 0, 576, 18, 128 },
4556 { &MFVideoFormat_YV12, 320, 240, 115200, 0, 138240, 115200, 384 },
4558 { &MFVideoFormat_I420, 1, 1, 3, 1, 192, 1, 128 },
4559 { &MFVideoFormat_I420, 1, 2, 6, 3, 384, 2, 128 },
4560 { &MFVideoFormat_I420, 1, 3, 9, 4, 576, 3, 128 },
4561 { &MFVideoFormat_I420, 2, 1, 3, 0, 192, 3, 128 },
4562 { &MFVideoFormat_I420, 2, 2, 6, 6, 384, 6, 128 },
4563 { &MFVideoFormat_I420, 2, 4, 12, 0, 768, 12, 128 },
4564 { &MFVideoFormat_I420, 3, 2, 12, 9, 384, 8, 128 },
4565 { &MFVideoFormat_I420, 3, 5, 30, 22, 960, 20, 128 },
4566 { &MFVideoFormat_I420, 4, 2, 12, 0, 384, 12, 128 },
4567 { &MFVideoFormat_I420, 4, 3, 18, 0, 576, 18, 128 },
4568 { &MFVideoFormat_I420, 320, 240, 115200, 0, 138240, 115200, 384 },
4570 { &MFVideoFormat_IYUV, 1, 1, 3, 1, 192, 1, 128 },
4571 { &MFVideoFormat_IYUV, 1, 2, 6, 3, 384, 2, 128 },
4572 { &MFVideoFormat_IYUV, 1, 3, 9, 4, 576, 3, 128 },
4573 { &MFVideoFormat_IYUV, 2, 1, 3, 0, 192, 3, 128 },
4574 { &MFVideoFormat_IYUV, 2, 2, 6, 6, 384, 6, 128 },
4575 { &MFVideoFormat_IYUV, 2, 4, 12, 0, 768, 12, 128 },
4576 { &MFVideoFormat_IYUV, 3, 2, 12, 9, 384, 8, 128 },
4577 { &MFVideoFormat_IYUV, 3, 5, 30, 22, 960, 20, 128 },
4578 { &MFVideoFormat_IYUV, 4, 2, 12, 0, 384, 12, 128 },
4579 { &MFVideoFormat_IYUV, 4, 3, 18, 0, 576, 18, 128 },
4580 { &MFVideoFormat_IYUV, 320, 240, 115200, 0, 138240, 115200, 384 },
4583 static void test_MFCalculateImageSize(void)
4585 unsigned int i;
4586 UINT32 size;
4587 HRESULT hr;
4589 size = 1;
4590 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
4591 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#lx.\n", hr);
4592 ok(size == 0, "Unexpected size %u.\n", size);
4594 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4596 const struct image_size_test *ptr = &image_size_tests[i];
4598 /* Those are supported since Win10. */
4599 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
4600 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
4602 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4603 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr);
4604 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4605 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4609 static void test_MFGetPlaneSize(void)
4611 unsigned int i;
4612 DWORD size;
4613 HRESULT hr;
4615 if (!pMFGetPlaneSize)
4617 win_skip("MFGetPlaneSize() is not available.\n");
4618 return;
4621 size = 1;
4622 hr = pMFGetPlaneSize(0xdeadbeef, 64, 64, &size);
4623 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4624 ok(size == 0, "Unexpected size %lu.\n", size);
4626 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4628 const struct image_size_test *ptr = &image_size_tests[i];
4629 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4630 if ((is_MEDIASUBTYPE_RGB(ptr->subtype)))
4631 continue;
4633 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4634 ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr);
4635 ok(size == plane_size, "%u: unexpected plane size %lu, expected %u. Size %u x %u, format %s.\n", i, size, plane_size,
4636 ptr->width, ptr->height, wine_dbgstr_an((char*)&ptr->subtype->Data1, 4));
4640 static void test_MFCompareFullToPartialMediaType(void)
4642 IMFMediaType *full_type, *partial_type;
4643 HRESULT hr;
4644 BOOL ret;
4646 hr = MFCreateMediaType(&full_type);
4647 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4649 hr = MFCreateMediaType(&partial_type);
4650 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4652 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4653 ok(!ret, "Unexpected result %d.\n", ret);
4655 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4656 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4658 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4659 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4661 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4662 ok(ret, "Unexpected result %d.\n", ret);
4664 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4665 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4667 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4668 ok(ret, "Unexpected result %d.\n", ret);
4670 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4671 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4673 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4674 ok(!ret, "Unexpected result %d.\n", ret);
4676 IMFMediaType_Release(full_type);
4677 IMFMediaType_Release(partial_type);
4680 static void test_attributes_serialization(void)
4682 static const UINT8 blob[] = {1,2,3};
4683 IMFAttributes *attributes, *dest;
4684 UINT32 size, count, value32;
4685 double value_dbl;
4686 UINT64 value64;
4687 UINT8 *buffer;
4688 IUnknown *obj;
4689 HRESULT hr;
4690 WCHAR *str;
4691 GUID guid;
4693 hr = MFCreateAttributes(&attributes, 0);
4694 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4696 hr = MFCreateAttributes(&dest, 0);
4697 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4699 hr = MFGetAttributesAsBlobSize(attributes, &size);
4700 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4701 ok(size == 8, "Got size %u.\n", size);
4703 buffer = malloc(size);
4705 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4706 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4708 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4709 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
4711 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4712 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4714 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4715 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4717 hr = MFInitAttributesFromBlob(dest, buffer, size);
4718 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4720 /* Previous items are cleared. */
4721 hr = IMFAttributes_GetCount(dest, &count);
4722 ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr);
4723 ok(count == 0, "Unexpected count %u.\n", count);
4725 free(buffer);
4727 /* Set some attributes of various types. */
4728 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4729 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4730 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4731 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4732 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4733 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4734 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4736 hr = MFGetAttributesAsBlobSize(attributes, &size);
4737 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4738 ok(size > 8, "Got unexpected size %u.\n", size);
4740 buffer = malloc(size);
4741 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4742 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4743 hr = MFInitAttributesFromBlob(dest, buffer, size);
4744 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4745 free(buffer);
4747 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4748 ok(hr == S_OK, "Failed to get get uint32 value, hr %#lx.\n", hr);
4749 ok(value32 == 456, "Unexpected value %u.\n", value32);
4750 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4751 ok(hr == S_OK, "Failed to get get uint64 value, hr %#lx.\n", hr);
4752 ok(value64 == 123, "Unexpected value.\n");
4753 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4754 ok(hr == S_OK, "Failed to get get double value, hr %#lx.\n", hr);
4755 ok(value_dbl == 0.5, "Unexpected value.\n");
4756 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4757 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4758 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4759 ok(hr == S_OK, "Failed to get guid value, hr %#lx.\n", hr);
4760 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4761 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4762 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
4763 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4764 CoTaskMemFree(str);
4765 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4766 ok(hr == S_OK, "Failed to get blob value, hr %#lx.\n", hr);
4767 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4768 CoTaskMemFree(buffer);
4770 IMFAttributes_Release(attributes);
4771 IMFAttributes_Release(dest);
4774 static void test_wrapped_media_type(void)
4776 IMFMediaType *mediatype, *mediatype2;
4777 UINT32 count, type;
4778 HRESULT hr;
4779 GUID guid;
4781 hr = MFCreateMediaType(&mediatype);
4782 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4784 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4785 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4787 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4788 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4789 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4790 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4792 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4793 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
4795 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4796 ok(hr == S_OK, "Failed to create wrapped media type, hr %#lx.\n", hr);
4798 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4799 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4800 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4802 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4803 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
4804 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4806 hr = IMFMediaType_GetCount(mediatype2, &count);
4807 ok(hr == S_OK, "Failed to get item count, hr %#lx.\n", hr);
4808 ok(count == 3, "Unexpected count %u.\n", count);
4810 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4811 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
4812 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4814 IMFMediaType_Release(mediatype);
4816 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4817 ok(hr == S_OK, "Failed to unwrap, hr %#lx.\n", hr);
4819 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4820 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4821 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4823 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4824 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4826 IMFMediaType_Release(mediatype);
4827 IMFMediaType_Release(mediatype2);
4830 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4832 static const struct wave_fmt_test
4834 const GUID *subtype;
4835 WORD format_tag;
4837 wave_fmt_tests[] =
4839 { &MFAudioFormat_PCM, WAVE_FORMAT_PCM, },
4840 { &MFAudioFormat_Float, WAVE_FORMAT_IEEE_FLOAT, },
4842 WAVEFORMATEXTENSIBLE *format_ext;
4843 IMFMediaType *mediatype;
4844 WAVEFORMATEX *format;
4845 UINT32 size, i;
4846 HRESULT hr;
4848 hr = MFCreateMediaType(&mediatype);
4849 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4851 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4852 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4854 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4855 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4857 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4858 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4860 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4861 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4863 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4864 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4866 for (i = 0; i < ARRAY_SIZE(wave_fmt_tests); ++i)
4868 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, wave_fmt_tests[i].subtype);
4869 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4871 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4872 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4873 ok(format != NULL, "Expected format structure.\n");
4874 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4875 ok(format->wFormatTag == wave_fmt_tests[i].format_tag, "Expected tag %u, got %u.\n", wave_fmt_tests[i].format_tag, format->wFormatTag);
4876 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4877 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format->nSamplesPerSec);
4878 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n", format->nAvgBytesPerSec);
4879 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4880 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4881 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4882 CoTaskMemFree(format);
4884 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4885 MFWaveFormatExConvertFlag_ForceExtensible);
4886 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4887 ok(format_ext != NULL, "Expected format structure.\n");
4888 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4889 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4890 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4891 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format_ext->Format.nSamplesPerSec);
4892 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n",
4893 format_ext->Format.nAvgBytesPerSec);
4894 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4895 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4896 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4897 format_ext->Format.cbSize);
4898 CoTaskMemFree(format_ext);
4900 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4901 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4902 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4903 CoTaskMemFree(format);
4906 IMFMediaType_Release(mediatype);
4909 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4911 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4912 IMFByteStream *stream;
4913 IUnknown *object;
4914 HRESULT hr;
4916 ok(!!result, "Unexpected result object.\n");
4918 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4920 hr = IMFAsyncResult_GetObject(result, &object);
4921 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4923 hr = MFEndCreateFile(result, &stream);
4924 ok(hr == S_OK, "Failed to get file stream, hr %#lx.\n", hr);
4925 IMFByteStream_Release(stream);
4927 SetEvent(callback->event);
4929 return S_OK;
4932 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4934 testcallback_QueryInterface,
4935 testcallback_AddRef,
4936 testcallback_Release,
4937 testcallback_GetParameters,
4938 test_create_file_callback_Invoke,
4941 static void test_async_create_file(void)
4943 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4944 struct test_callback *callback;
4945 IUnknown *cancel_cookie;
4946 HRESULT hr;
4947 BOOL ret;
4949 callback = create_test_callback(&test_create_file_callback_vtbl);
4951 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4952 ok(hr == S_OK, "Fail to start up, hr %#lx.\n", hr);
4954 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4955 GetTempFileNameW(pathW, NULL, 0, fileW);
4957 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4958 &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface, &cancel_cookie);
4959 ok(hr == S_OK, "Async create request failed, hr %#lx.\n", hr);
4960 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4962 WaitForSingleObject(callback->event, INFINITE);
4964 IUnknown_Release(cancel_cookie);
4966 hr = MFShutdown();
4967 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4969 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4971 ret = DeleteFileW(fileW);
4972 ok(ret, "Failed to delete test file.\n");
4975 struct activate_object
4977 IMFActivate IMFActivate_iface;
4978 LONG refcount;
4981 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4983 if (IsEqualIID(riid, &IID_IMFActivate) ||
4984 IsEqualIID(riid, &IID_IMFAttributes) ||
4985 IsEqualIID(riid, &IID_IUnknown))
4987 *obj = iface;
4988 IMFActivate_AddRef(iface);
4989 return S_OK;
4992 *obj = NULL;
4993 return E_NOINTERFACE;
4996 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4998 return 2;
5001 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
5003 return 1;
5006 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
5008 return E_NOTIMPL;
5011 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
5013 return E_NOTIMPL;
5016 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
5018 return E_NOTIMPL;
5021 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
5022 BOOL *result)
5024 return E_NOTIMPL;
5027 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
5029 return E_NOTIMPL;
5032 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
5034 return E_NOTIMPL;
5037 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
5039 return E_NOTIMPL;
5042 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
5044 return E_NOTIMPL;
5047 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
5049 return E_NOTIMPL;
5052 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
5053 UINT32 size, UINT32 *length)
5055 return E_NOTIMPL;
5058 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
5059 WCHAR **value, UINT32 *length)
5061 return E_NOTIMPL;
5064 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
5066 return E_NOTIMPL;
5069 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
5070 UINT32 bufsize, UINT32 *blobsize)
5072 return E_NOTIMPL;
5075 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
5077 return E_NOTIMPL;
5080 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
5082 return E_NOTIMPL;
5085 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
5087 return E_NOTIMPL;
5090 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
5092 return E_NOTIMPL;
5095 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
5097 return E_NOTIMPL;
5100 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
5102 return E_NOTIMPL;
5105 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
5107 return E_NOTIMPL;
5110 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
5112 return E_NOTIMPL;
5115 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
5117 return E_NOTIMPL;
5120 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
5122 return E_NOTIMPL;
5125 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
5127 return E_NOTIMPL;
5130 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
5132 return E_NOTIMPL;
5135 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
5137 return E_NOTIMPL;
5140 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
5142 return E_NOTIMPL;
5145 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
5147 return E_NOTIMPL;
5150 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
5152 return E_NOTIMPL;
5155 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
5157 return E_NOTIMPL;
5160 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
5162 return E_NOTIMPL;
5165 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
5167 return E_NOTIMPL;
5170 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
5172 return E_NOTIMPL;
5175 static const IMFActivateVtbl activate_object_vtbl =
5177 activate_object_QueryInterface,
5178 activate_object_AddRef,
5179 activate_object_Release,
5180 activate_object_GetItem,
5181 activate_object_GetItemType,
5182 activate_object_CompareItem,
5183 activate_object_Compare,
5184 activate_object_GetUINT32,
5185 activate_object_GetUINT64,
5186 activate_object_GetDouble,
5187 activate_object_GetGUID,
5188 activate_object_GetStringLength,
5189 activate_object_GetString,
5190 activate_object_GetAllocatedString,
5191 activate_object_GetBlobSize,
5192 activate_object_GetBlob,
5193 activate_object_GetAllocatedBlob,
5194 activate_object_GetUnknown,
5195 activate_object_SetItem,
5196 activate_object_DeleteItem,
5197 activate_object_DeleteAllItems,
5198 activate_object_SetUINT32,
5199 activate_object_SetUINT64,
5200 activate_object_SetDouble,
5201 activate_object_SetGUID,
5202 activate_object_SetString,
5203 activate_object_SetBlob,
5204 activate_object_SetUnknown,
5205 activate_object_LockStore,
5206 activate_object_UnlockStore,
5207 activate_object_GetCount,
5208 activate_object_GetItemByIndex,
5209 activate_object_CopyAllItems,
5210 activate_object_ActivateObject,
5211 activate_object_ShutdownObject,
5212 activate_object_DetachObject,
5215 static void test_local_handlers(void)
5217 IMFActivate local_activate = { &activate_object_vtbl };
5218 static const WCHAR localW[] = L"local";
5219 HRESULT hr;
5221 if (!pMFRegisterLocalSchemeHandler)
5223 win_skip("Local handlers are not supported.\n");
5224 return;
5227 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
5228 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5230 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
5231 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5233 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
5234 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5236 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5237 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5239 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5240 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5242 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
5243 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5245 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
5246 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5248 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
5249 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5251 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
5252 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5254 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
5255 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5258 static void test_create_property_store(void)
5260 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
5261 IPropertyStore *store, *store2;
5262 PROPVARIANT value = {0};
5263 PROPERTYKEY key;
5264 ULONG refcount;
5265 DWORD count;
5266 HRESULT hr;
5268 hr = CreatePropertyStore(NULL);
5269 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5271 hr = CreatePropertyStore(&store);
5272 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5274 hr = CreatePropertyStore(&store2);
5275 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5276 ok(store2 != store, "Expected different store objects.\n");
5277 IPropertyStore_Release(store2);
5279 check_interface(store, &IID_IPropertyStoreCache, FALSE);
5280 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
5282 hr = IPropertyStore_GetCount(store, NULL);
5283 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5285 count = 0xdeadbeef;
5286 hr = IPropertyStore_GetCount(store, &count);
5287 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5288 ok(!count, "Unexpected count %lu.\n", count);
5290 hr = IPropertyStore_Commit(store);
5291 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5293 hr = IPropertyStore_GetAt(store, 0, &key);
5294 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5296 hr = IPropertyStore_GetValue(store, NULL, &value);
5297 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5299 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
5300 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5302 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5303 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5305 memset(&value, 0, sizeof(PROPVARIANT));
5306 value.vt = VT_I4;
5307 value.lVal = 0xdeadbeef;
5308 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5309 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5311 if (0)
5313 /* crashes on Windows */
5314 hr = IPropertyStore_SetValue(store, NULL, &value);
5315 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5318 hr = IPropertyStore_GetCount(store, &count);
5319 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5320 ok(count == 1, "Unexpected count %lu.\n", count);
5322 hr = IPropertyStore_Commit(store);
5323 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5325 hr = IPropertyStore_GetAt(store, 0, &key);
5326 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5327 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
5329 hr = IPropertyStore_GetAt(store, 1, &key);
5330 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5332 memset(&value, 0xcc, sizeof(PROPVARIANT));
5333 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5334 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5335 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
5336 ok(value.lVal == 0xdeadbeef, "Unexpected value %#lx.\n", value.lVal);
5338 memset(&value, 0, sizeof(PROPVARIANT));
5339 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5340 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5342 hr = IPropertyStore_GetCount(store, &count);
5343 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5344 ok(count == 1, "Unexpected count %lu.\n", count);
5346 memset(&value, 0xcc, sizeof(PROPVARIANT));
5347 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5348 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5349 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
5350 ok(!value.lVal, "Unexpected value %#lx.\n", value.lVal);
5352 refcount = IPropertyStore_Release(store);
5353 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
5356 struct test_thread_param
5358 IMFDXGIDeviceManager *manager;
5359 HANDLE handle;
5360 BOOL lock;
5363 static DWORD WINAPI test_device_manager_thread(void *arg)
5365 struct test_thread_param *param = arg;
5366 ID3D11Device *device;
5367 HRESULT hr;
5369 if (param->lock)
5371 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
5372 (void **)&device, FALSE);
5373 if (SUCCEEDED(hr))
5374 ID3D11Device_Release(device);
5376 else
5377 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
5379 return hr;
5382 static void test_dxgi_device_manager(void)
5384 IMFDXGIDeviceManager *manager, *manager2;
5385 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
5386 struct test_thread_param param;
5387 HANDLE handle1, handle, thread;
5388 UINT token, token2;
5389 IUnknown *unk;
5390 HRESULT hr;
5392 if (!pMFCreateDXGIDeviceManager)
5394 win_skip("MFCreateDXGIDeviceManager not found.\n");
5395 return;
5398 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
5399 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5401 token = 0;
5402 hr = pMFCreateDXGIDeviceManager(&token, NULL);
5403 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5404 ok(!token, "got wrong token: %u.\n", token);
5406 hr = pMFCreateDXGIDeviceManager(&token, &manager);
5407 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5408 EXPECT_REF(manager, 1);
5409 ok(!!token, "got wrong token: %u.\n", token);
5411 Sleep(50);
5412 token2 = 0;
5413 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
5414 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5415 EXPECT_REF(manager2, 1);
5416 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
5417 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
5418 EXPECT_REF(manager, 1);
5420 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5421 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5423 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5424 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5426 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
5427 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5429 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
5430 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
5431 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5432 EXPECT_REF(d3d11_dev, 1);
5434 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
5435 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5436 EXPECT_REF(d3d11_dev, 1);
5438 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
5439 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5441 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5442 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5443 EXPECT_REF(manager, 1);
5444 EXPECT_REF(d3d11_dev, 2);
5446 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
5447 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5448 EXPECT_REF(manager2, 1);
5449 EXPECT_REF(d3d11_dev, 2);
5451 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5452 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5453 EXPECT_REF(manager, 1);
5454 EXPECT_REF(d3d11_dev, 2);
5456 /* GetVideoService() on device change. */
5457 handle = NULL;
5458 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5459 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5460 ok(!!handle, "Unexpected handle value %p.\n", handle);
5462 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
5463 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
5464 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5465 EXPECT_REF(d3d11_dev2, 1);
5466 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
5467 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5468 EXPECT_REF(manager, 1);
5469 EXPECT_REF(d3d11_dev2, 2);
5470 EXPECT_REF(d3d11_dev, 1);
5472 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5473 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#lx.\n", hr);
5475 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5476 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5478 handle = NULL;
5479 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5480 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5481 ok(!!handle, "Unexpected handle value %p.\n", handle);
5483 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5484 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5486 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5487 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5488 IUnknown_Release(unk);
5490 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
5491 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5492 IUnknown_Release(unk);
5494 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
5495 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5496 IUnknown_Release(unk);
5498 handle1 = NULL;
5499 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5500 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5501 ok(handle != handle1, "Unexpected handle.\n");
5503 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5504 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5506 /* Already closed. */
5507 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5508 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5510 handle = NULL;
5511 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5512 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5514 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5517 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
5518 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5520 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5521 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5522 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
5523 ID3D11Device_Release(device);
5525 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5528 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5529 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5531 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
5532 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5534 /* Locked with one handle, unlock with another. */
5535 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5536 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5538 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5539 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5541 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5542 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5544 ID3D11Device_Release(device);
5546 /* Closing unlocks the device. */
5547 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5550 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5551 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5552 ID3D11Device_Release(device);
5554 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5557 /* Open two handles. */
5558 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5559 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5561 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5564 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5565 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5566 ID3D11Device_Release(device);
5568 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5569 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5570 ID3D11Device_Release(device);
5572 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5573 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5575 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5576 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5578 param.manager = manager;
5579 param.handle = handle;
5580 param.lock = TRUE;
5581 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5582 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5583 GetExitCodeThread(thread, (DWORD *)&hr);
5584 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#lx.\n", hr);
5585 CloseHandle(thread);
5587 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5588 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5590 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5591 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5593 /* Lock on main thread, unlock on another. */
5594 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5595 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5596 ID3D11Device_Release(device);
5598 param.manager = manager;
5599 param.handle = handle;
5600 param.lock = FALSE;
5601 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5602 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5603 GetExitCodeThread(thread, (DWORD *)&hr);
5604 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5605 CloseHandle(thread);
5607 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5608 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5610 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5611 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5613 IMFDXGIDeviceManager_Release(manager);
5614 EXPECT_REF(d3d11_dev2, 1);
5615 ID3D11Device_Release(d3d11_dev);
5616 ID3D11Device_Release(d3d11_dev2);
5617 IMFDXGIDeviceManager_Release(manager2);
5620 static void test_MFCreateTransformActivate(void)
5622 IMFActivate *activate;
5623 UINT32 count;
5624 HRESULT hr;
5626 if (!pMFCreateTransformActivate)
5628 win_skip("MFCreateTransformActivate() is not available.\n");
5629 return;
5632 hr = pMFCreateTransformActivate(&activate);
5633 ok(hr == S_OK, "Failed to create activator, hr %#lx.\n", hr);
5635 hr = IMFActivate_GetCount(activate, &count);
5636 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5637 ok(!count, "Unexpected attribute count %u.\n", count);
5639 IMFActivate_Release(activate);
5642 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5644 if (IsEqualIID(riid, &IID_IClassFactory) ||
5645 IsEqualIID(riid, &IID_IUnknown))
5647 *obj = iface;
5648 IClassFactory_AddRef(iface);
5649 return S_OK;
5652 *obj = NULL;
5653 return E_NOINTERFACE;
5656 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5658 return 2;
5661 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5663 return 1;
5666 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5668 ok(0, "Unexpected call.\n");
5669 return E_NOTIMPL;
5672 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5674 return S_OK;
5677 static const IClassFactoryVtbl test_mft_factory_vtbl =
5679 test_mft_factory_QueryInterface,
5680 test_mft_factory_AddRef,
5681 test_mft_factory_Release,
5682 test_mft_factory_CreateInstance,
5683 test_mft_factory_LockServer,
5686 static void test_MFTRegisterLocal(void)
5688 IClassFactory test_factory = { &test_mft_factory_vtbl };
5689 MFT_REGISTER_TYPE_INFO input_types[1], *in_types, *out_types;
5690 IMFAttributes *attributes;
5691 IMFActivate **activate;
5692 UINT32 count, count2;
5693 WCHAR *name;
5694 HRESULT hr;
5696 if (!pMFTRegisterLocal)
5698 win_skip("MFTRegisterLocal() is not available.\n");
5699 return;
5702 input_types[0].guidMajorType = MFMediaType_Audio;
5703 input_types[0].guidSubtype = MFAudioFormat_PCM;
5704 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5705 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5707 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5708 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5710 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5712 ok(count > 0, "Unexpected count %u.\n", count);
5713 CoTaskMemFree(activate);
5715 hr = pMFTUnregisterLocal(&test_factory);
5716 ok(hr == S_OK, "Failed to unregister MFT, hr %#lx.\n", hr);
5718 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5719 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5720 ok(count2 < count, "Unexpected count %u.\n", count2);
5721 CoTaskMemFree(activate);
5723 hr = pMFTUnregisterLocal(&test_factory);
5724 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5726 hr = pMFTUnregisterLocal(NULL);
5727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5729 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5730 0, NULL);
5731 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5733 hr = MFTGetInfo(MFT_CATEGORY_OTHER, &name, &in_types, &count, &out_types, &count2, &attributes);
5734 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5736 hr = pMFTUnregisterLocal(NULL);
5737 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5739 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5740 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5742 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5743 0, NULL);
5744 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5746 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5747 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5750 static void test_queue_com(void)
5752 static int system_queues[] =
5754 MFASYNC_CALLBACK_QUEUE_STANDARD,
5755 MFASYNC_CALLBACK_QUEUE_RT,
5756 MFASYNC_CALLBACK_QUEUE_IO,
5757 MFASYNC_CALLBACK_QUEUE_TIMER,
5758 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5759 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5762 static int user_queues[] =
5764 MF_STANDARD_WORKQUEUE,
5765 MF_WINDOW_WORKQUEUE,
5766 MF_MULTITHREADED_WORKQUEUE,
5769 char path_name[MAX_PATH];
5770 PROCESS_INFORMATION info;
5771 STARTUPINFOA startup;
5772 char **argv;
5773 int i;
5775 if (!pCoGetApartmentType)
5777 win_skip("CoGetApartmentType() is not available.\n");
5778 return;
5781 winetest_get_mainargs(&argv);
5783 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5785 memset(&startup, 0, sizeof(startup));
5786 startup.cb = sizeof(startup);
5787 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5788 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5789 "CreateProcess failed.\n" );
5790 wait_child_process(info.hProcess);
5791 CloseHandle(info.hProcess);
5792 CloseHandle(info.hThread);
5795 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5797 memset(&startup, 0, sizeof(startup));
5798 startup.cb = sizeof(startup);
5799 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5800 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5801 "CreateProcess failed.\n" );
5802 wait_child_process(info.hProcess);
5803 CloseHandle(info.hProcess);
5804 CloseHandle(info.hThread);
5808 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5810 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5811 APTTYPEQUALIFIER qualifier;
5812 APTTYPE com_type;
5813 HRESULT hr;
5815 hr = pCoGetApartmentType(&com_type, &qualifier);
5816 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#lx.\n", hr);
5817 if (SUCCEEDED(hr))
5819 todo_wine {
5820 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5821 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5822 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5823 else
5824 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5825 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5829 SetEvent(callback->event);
5830 return S_OK;
5833 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5835 testcallback_QueryInterface,
5836 testcallback_AddRef,
5837 testcallback_Release,
5838 testcallback_GetParameters,
5839 test_queue_com_state_callback_Invoke,
5842 static void test_queue_com_state(const char *name)
5844 struct test_callback *callback;
5845 DWORD queue, queue_type;
5846 HRESULT hr;
5848 callback = create_test_callback(&test_queue_com_state_callback_vtbl);
5850 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5851 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
5853 if (name[0] == 's')
5855 callback->param = name[1] - '0';
5856 hr = MFPutWorkItem(callback->param, &callback->IMFAsyncCallback_iface, NULL);
5857 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5858 WaitForSingleObject(callback->event, INFINITE);
5860 else if (name[0] == 'u')
5862 queue_type = name[1] - '0';
5864 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5865 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5866 "Failed to allocate a queue of type %lu, hr %#lx.\n", queue_type, hr);
5868 if (SUCCEEDED(hr))
5870 callback->param = queue;
5871 hr = MFPutWorkItem(queue, &callback->IMFAsyncCallback_iface, NULL);
5872 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5873 WaitForSingleObject(callback->event, INFINITE);
5875 hr = MFUnlockWorkQueue(queue);
5876 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
5880 hr = MFShutdown();
5881 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
5883 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
5886 static void test_MFGetStrideForBitmapInfoHeader(void)
5888 static const struct stride_test
5890 const GUID *subtype;
5891 unsigned int width;
5892 LONG stride;
5894 stride_tests[] =
5896 { &MFVideoFormat_RGB8, 3, -4 },
5897 { &MFVideoFormat_RGB8, 1, -4 },
5898 { &MFVideoFormat_RGB555, 3, -8 },
5899 { &MFVideoFormat_RGB555, 1, -4 },
5900 { &MFVideoFormat_RGB565, 3, -8 },
5901 { &MFVideoFormat_RGB565, 1, -4 },
5902 { &MFVideoFormat_RGB24, 3, -12 },
5903 { &MFVideoFormat_RGB24, 1, -4 },
5904 { &MFVideoFormat_RGB32, 3, -12 },
5905 { &MFVideoFormat_RGB32, 1, -4 },
5906 { &MFVideoFormat_ARGB32, 3, -12 },
5907 { &MFVideoFormat_ARGB32, 1, -4 },
5908 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5909 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5910 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5911 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5913 /* YUV */
5914 { &MFVideoFormat_NV12, 1, 1 },
5915 { &MFVideoFormat_NV12, 2, 2 },
5916 { &MFVideoFormat_NV12, 3, 3 },
5917 { &MFVideoFormat_AYUV, 1, 4 },
5918 { &MFVideoFormat_AYUV, 4, 16 },
5919 { &MFVideoFormat_AYUV, 5, 20 },
5920 { &MFVideoFormat_IMC1, 1, 4 },
5921 { &MFVideoFormat_IMC1, 2, 4 },
5922 { &MFVideoFormat_IMC1, 3, 8 },
5923 { &MFVideoFormat_IMC3, 1, 4 },
5924 { &MFVideoFormat_IMC3, 2, 4 },
5925 { &MFVideoFormat_IMC3, 3, 8 },
5926 { &MFVideoFormat_IMC2, 1, 1 },
5927 { &MFVideoFormat_IMC2, 2, 2 },
5928 { &MFVideoFormat_IMC2, 3, 3 },
5929 { &MFVideoFormat_IMC4, 1, 1 },
5930 { &MFVideoFormat_IMC4, 2, 2 },
5931 { &MFVideoFormat_IMC4, 3, 3 },
5932 { &MFVideoFormat_YV12, 1, 1 },
5933 { &MFVideoFormat_YV12, 2, 2 },
5934 { &MFVideoFormat_YV12, 3, 3 },
5935 { &MFVideoFormat_YV12, 320, 320 },
5936 { &MFVideoFormat_I420, 1, 1 },
5937 { &MFVideoFormat_I420, 2, 2 },
5938 { &MFVideoFormat_I420, 3, 3 },
5939 { &MFVideoFormat_I420, 320, 320 },
5940 { &MFVideoFormat_IYUV, 1, 1 },
5941 { &MFVideoFormat_IYUV, 2, 2 },
5942 { &MFVideoFormat_IYUV, 3, 3 },
5943 { &MFVideoFormat_IYUV, 320, 320 },
5944 { &MFVideoFormat_NV11, 1, 1 },
5945 { &MFVideoFormat_NV11, 2, 2 },
5946 { &MFVideoFormat_NV11, 3, 3 },
5948 unsigned int i;
5949 LONG stride;
5950 HRESULT hr;
5952 if (!pMFGetStrideForBitmapInfoHeader)
5954 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5955 return;
5958 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5959 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5961 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5963 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5964 ok(hr == S_OK, "%u: failed to get stride, hr %#lx.\n", i, hr);
5965 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %ld, expected %ld.\n", i,
5966 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5970 static void test_MFCreate2DMediaBuffer(void)
5972 static const char two_aas[] = { 0xaa, 0xaa };
5973 static const char eight_bbs[] = { 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb };
5974 DWORD max_length, length, length2;
5975 BYTE *buffer_start, *data, *data2;
5976 LONG pitch, pitch2, stride;
5977 IMF2DBuffer2 *_2dbuffer2;
5978 IMF2DBuffer *_2dbuffer;
5979 IMFMediaBuffer *buffer;
5980 int i, j, k;
5981 HRESULT hr;
5982 BOOL ret;
5984 if (!pMFCreate2DMediaBuffer)
5986 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5987 return;
5990 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5991 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5993 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5994 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5996 /* YUV formats can't be bottom-up. */
5997 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5998 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
6000 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
6001 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6003 check_interface(buffer, &IID_IMFGetService, TRUE);
6004 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6006 /* Full backing buffer size, with 64 bytes per row alignment. */
6007 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6008 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6009 ok(max_length > 0, "Unexpected length %lu.\n", max_length);
6011 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6012 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
6013 ok(!length, "Unexpected length.\n");
6015 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
6016 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
6018 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6019 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
6020 ok(length == 10, "Unexpected length.\n");
6022 /* Linear lock/unlock. */
6024 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
6025 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
6027 /* Linear locking call returns plane size.*/
6028 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
6029 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6030 ok(max_length == length, "Unexpected length.\n");
6032 memset(data, 0xaa, length);
6034 length = 0;
6035 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
6036 ok(max_length == length && length == 9, "Unexpected length %lu.\n", length);
6038 /* Already locked */
6039 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6040 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6041 ok(data2 == data, "Unexpected pointer.\n");
6043 hr = IMFMediaBuffer_Unlock(buffer);
6044 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6046 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6047 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6049 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6050 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6052 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6053 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6054 ok(length == 9, "Unexpected length %lu.\n", length);
6056 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
6057 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6059 /* 2D lock. */
6060 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6061 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
6063 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6064 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6066 hr = IMFMediaBuffer_Unlock(buffer);
6067 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6069 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6070 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6072 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
6073 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6075 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
6076 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6078 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
6079 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6081 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6082 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6083 ok(!!data, "Expected data pointer.\n");
6084 ok(pitch == 64, "Unexpected pitch %ld.\n", pitch);
6086 for (i = 0; i < 4; i++)
6087 ok(memcmp(&data[64 * i], two_aas, sizeof(two_aas)) == 0, "Invalid data instead of 0xaa.\n");
6088 memset(data, 0xbb, 194);
6090 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
6091 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6092 ok(data == data2, "Expected data pointer.\n");
6094 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
6095 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6097 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
6098 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6100 /* Active 2D lock */
6101 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6102 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6104 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6105 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6107 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6108 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6110 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6111 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6113 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6114 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6116 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6117 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6119 ok(memcmp(data, eight_bbs, sizeof(eight_bbs)) == 0, "Invalid data instead of 0xbb.\n");
6121 hr = IMFMediaBuffer_Unlock(buffer);
6122 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6124 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6125 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#lx.\n", hr);
6127 if (SUCCEEDED(hr))
6129 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6130 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6132 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
6133 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6135 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6136 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6138 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6139 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6141 /* Flags are ignored. */
6142 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
6143 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6145 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
6146 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6148 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6149 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6151 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6152 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6154 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
6155 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6157 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
6158 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6160 IMF2DBuffer2_Release(_2dbuffer2);
6162 else
6163 win_skip("IMF2DBuffer2 is not supported.\n");
6165 IMF2DBuffer_Release(_2dbuffer);
6167 IMFMediaBuffer_Release(buffer);
6169 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
6171 const struct image_size_test *ptr = &image_size_tests[i];
6173 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
6174 continue;
6176 winetest_push_context("%u, %u x %u, format %s", i, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6178 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
6179 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6181 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6182 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6183 ok(length == ptr->max_length, "Unexpected maximum length %lu.\n", length);
6185 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6186 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6188 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6189 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6191 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6192 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6193 ok(length == ptr->contiguous_length, "Unexpected contiguous length %lu.\n", length);
6195 data2 = malloc(ptr->contiguous_length + 16);
6196 ok(!!data2, "Failed to allocate buffer.\n");
6198 for (j = 0; j < ptr->contiguous_length + 16; j++)
6199 data2[j] = j & 0x7f;
6201 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length - 1);
6202 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6204 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6205 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6206 ok(length2 == ptr->contiguous_length, "Unexpected linear buffer length %lu.\n", length2);
6208 memset(data, 0xff, length2);
6210 hr = IMFMediaBuffer_Unlock(buffer);
6211 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6213 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length + 16);
6214 ok(hr == S_OK, "Failed to copy from contiguous buffer, hr %#lx.\n", hr);
6216 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6217 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6218 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6219 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6221 for (j = 0; j < ptr->contiguous_length; j++)
6223 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6225 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6226 continue;
6227 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6228 continue;
6230 if (data[j] != (j & 0x7f))
6231 break;
6233 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j);
6235 memset(data, 0xff, length2);
6237 hr = IMFMediaBuffer_Unlock(buffer);
6238 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6240 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length);
6241 ok(hr == S_OK, "Failed to copy from contiguous buffer, hr %#lx.\n", hr);
6243 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6244 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6245 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6246 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6248 for (j = 0; j < ptr->contiguous_length; j++)
6250 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6252 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6253 continue;
6254 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6255 continue;
6257 if (data[j] != (j & 0x7f))
6258 break;
6260 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j);
6262 hr = IMFMediaBuffer_Unlock(buffer);
6263 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6265 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length - 1);
6266 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6268 memset(data2, 0xff, ptr->contiguous_length + 16);
6270 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length + 16);
6271 ok(hr == S_OK, "Failed to copy to contiguous buffer, hr %#lx.\n", hr);
6273 for (j = 0; j < ptr->contiguous_length; j++)
6275 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6277 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6278 continue;
6279 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6280 continue;
6282 if (data2[j] != (j & 0x7f))
6283 break;
6285 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data2[j], j & 0x7f, j);
6287 memset(data2, 0xff, ptr->contiguous_length + 16);
6289 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length);
6290 ok(hr == S_OK, "Failed to copy to contiguous buffer, hr %#lx.\n", hr);
6292 for (j = 0; j < ptr->contiguous_length; j++)
6294 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6296 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6297 continue;
6298 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6299 continue;
6301 if (data2[j] != (j & 0x7f))
6302 break;
6304 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data2[j], j & 0x7f, j);
6306 free(data2);
6308 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6309 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6310 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6311 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6313 hr = pMFGetStrideForBitmapInfoHeader(ptr->subtype->Data1, ptr->width, &stride);
6314 ok(hr == S_OK, "Failed to get stride, hr %#lx.\n", hr);
6315 stride = abs(stride);
6317 /* primary plane */
6318 ok(ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6319 ptr->height * stride, length2);
6320 for (j = 0; j < ptr->height; j++)
6321 for (k = 0; k < stride; k++)
6322 data[j * stride + k] = ((j % 16) << 4) + (k % 16);
6324 data += ptr->height * stride;
6326 /* secondary planes */
6327 switch (ptr->subtype->Data1)
6329 case MAKEFOURCC('I','M','C','1'):
6330 case MAKEFOURCC('I','M','C','3'):
6331 ok(2 * ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6332 2 * ptr->height * stride, length2);
6333 for (j = 0; j < ptr->height; j++)
6334 for (k = 0; k < stride / 2; k++)
6335 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6336 break;
6338 case MAKEFOURCC('I','M','C','2'):
6339 case MAKEFOURCC('I','M','C','4'):
6340 case MAKEFOURCC('N','V','1','1'):
6341 case MAKEFOURCC('Y','V','1','2'):
6342 case MAKEFOURCC('I','4','2','0'):
6343 case MAKEFOURCC('I','Y','U','V'):
6344 ok(stride * 3 / 2 * ptr->height <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6345 stride * 3 / 2 * ptr->height, length2);
6346 for (j = 0; j < ptr->height; j++)
6347 for (k = 0; k < stride / 2; k++)
6348 data[j * (stride / 2) + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6349 break;
6351 case MAKEFOURCC('N','V','1','2'):
6352 ok(stride * ptr->height * 3 / 2 <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6353 stride * ptr->height * 3 / 2, length2);
6354 for (j = 0; j < ptr->height / 2; j++)
6355 for (k = 0; k < stride; k++)
6356 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6357 break;
6360 hr = IMFMediaBuffer_Unlock(buffer);
6361 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6363 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6364 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6366 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
6367 ok(hr == S_OK, "Failed to get scanline, hr %#lx.\n", hr);
6368 ok(data2 == data, "Unexpected data pointer.\n");
6369 ok(pitch == pitch2, "Unexpected pitch.\n");
6371 /* primary plane */
6372 for (j = 0; j < ptr->height; j++)
6373 for (k = 0; k < stride; k++)
6374 ok(data[j * pitch + k] == ((j % 16) << 4) + (k % 16),
6375 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6376 data[j * pitch + k], ((j % 16) << 4) + (k % 16), j, k);
6378 data += ptr->height * pitch;
6380 /* secondary planes */
6381 switch (ptr->subtype->Data1)
6383 case MAKEFOURCC('I','M','C','1'):
6384 case MAKEFOURCC('I','M','C','3'):
6385 for (j = 0; j < ptr->height; j++)
6386 for (k = 0; k < stride / 2; k++)
6387 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6388 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6389 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6390 break;
6392 case MAKEFOURCC('I','M','C','2'):
6393 case MAKEFOURCC('I','M','C','4'):
6394 case MAKEFOURCC('N','V','1','1'):
6395 case MAKEFOURCC('Y','V','1','2'):
6396 case MAKEFOURCC('I','4','2','0'):
6397 case MAKEFOURCC('I','Y','U','V'):
6398 for (j = 0; j < ptr->height; j++)
6399 for (k = 0; k < stride / 2; k++)
6400 ok(data[j * (pitch / 2) + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6401 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6402 data[j * (pitch / 2) + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6403 break;
6405 case MAKEFOURCC('N','V','1','2'):
6406 for (j = 0; j < ptr->height / 2; j++)
6407 for (k = 0; k < stride; k++)
6408 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6409 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6410 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6411 break;
6413 default:
6417 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6418 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6420 ok(pitch == ptr->pitch, "Unexpected pitch %ld, expected %d.\n", pitch, ptr->pitch);
6422 ret = TRUE;
6423 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
6424 ok(hr == S_OK, "Failed to get format flag, hr %#lx.\n", hr);
6425 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
6427 IMF2DBuffer_Release(_2dbuffer);
6428 IMF2DBuffer2_Release(_2dbuffer2);
6430 IMFMediaBuffer_Release(buffer);
6432 winetest_pop_context();
6435 /* Alignment tests */
6436 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
6438 const struct image_size_test *ptr = &image_size_tests[i];
6440 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
6441 continue;
6443 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
6444 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6446 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6447 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6449 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6450 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6451 ok(((uintptr_t)data & MF_64_BYTE_ALIGNMENT) == 0, "Misaligned data at %p.\n", data);
6453 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6454 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6456 IMF2DBuffer_Release(_2dbuffer);
6457 IMFMediaBuffer_Release(buffer);
6461 static void test_MFCreateMediaBufferFromMediaType(void)
6463 static struct audio_buffer_test
6465 unsigned int duration;
6466 unsigned int min_length;
6467 unsigned int min_alignment;
6468 unsigned int block_alignment;
6469 unsigned int bytes_per_second;
6470 unsigned int buffer_length;
6471 } audio_tests[] =
6473 { 0, 0, 0, 4, 0, 20 },
6474 { 0, 16, 0, 4, 0, 20 },
6475 { 0, 0, 32, 4, 0, 36 },
6476 { 0, 64, 32, 4, 0, 64 },
6477 { 1, 0, 0, 4, 16, 36 },
6478 { 2, 0, 0, 4, 16, 52 },
6479 { 2, 0, 64, 4, 16, 68 },
6480 { 2, 0, 128, 4, 16,132 },
6482 IMFMediaType *media_type, *media_type2;
6483 unsigned int i, alignment;
6484 IMFMediaBuffer *buffer;
6485 DWORD length, max;
6486 BYTE *data;
6487 HRESULT hr;
6489 if (!pMFCreateMediaBufferFromMediaType)
6491 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
6492 return;
6495 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
6496 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6498 hr = MFCreateMediaType(&media_type);
6499 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6501 hr = MFCreateMediaType(&media_type2);
6502 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6504 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
6505 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6507 hr = IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)media_type2);
6508 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6510 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
6512 const struct audio_buffer_test *ptr = &audio_tests[i];
6514 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
6515 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6517 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
6518 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6520 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
6521 ptr->min_alignment, &buffer);
6522 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#lx.\n", hr);
6523 if (FAILED(hr))
6524 break;
6526 check_interface(buffer, &IID_IMFGetService, FALSE);
6528 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6529 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6530 ok(ptr->buffer_length == length, "%d: unexpected buffer length %lu, expected %u.\n", i, length, ptr->buffer_length);
6532 alignment = ptr->min_alignment ? ptr->min_alignment - 1 : MF_16_BYTE_ALIGNMENT;
6533 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6534 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6535 ok(ptr->buffer_length == max && !length, "Unexpected length.\n");
6536 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6537 hr = IMFMediaBuffer_Unlock(buffer);
6538 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6540 IMFMediaBuffer_Release(buffer);
6542 /* Only major type is set. */
6543 hr = pMFCreateMediaBufferFromMediaType(media_type2, ptr->duration * 10000000, ptr->min_length,
6544 ptr->min_alignment, &buffer);
6545 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6547 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6548 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6549 ok(ptr->min_length == length, "%u: unexpected buffer length %lu, expected %u.\n", i, length, ptr->min_length);
6551 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6552 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6553 ok(ptr->min_length == max && !length, "Unexpected length.\n");
6554 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6555 hr = IMFMediaBuffer_Unlock(buffer);
6556 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6558 IMFMediaBuffer_Release(buffer);
6561 IMFMediaType_Release(media_type);
6562 IMFMediaType_Release(media_type2);
6565 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
6567 GUID guid, subtype;
6568 UINT32 value;
6569 HRESULT hr;
6571 hr = IMFMediaType_GetMajorType(mediatype, &guid);
6572 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
6573 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
6575 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
6576 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
6578 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
6580 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
6581 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6583 if (fex->dwChannelMask)
6585 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
6586 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6587 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
6590 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
6592 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
6593 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6594 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
6597 else
6599 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
6600 subtype.Data1 = format->wFormatTag;
6601 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6603 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
6604 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6605 ok(value, "Unexpected value.\n");
6608 if (format->nChannels)
6610 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
6611 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6612 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
6615 if (format->nSamplesPerSec)
6617 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
6618 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6619 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
6622 if (format->nAvgBytesPerSec)
6624 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
6625 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6626 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
6629 if (format->nBlockAlign)
6631 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
6632 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6633 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
6636 if (format->wBitsPerSample)
6638 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
6639 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6640 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
6643 /* Only set for uncompressed formats. */
6644 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
6645 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
6646 IsEqualGUID(&guid, &MFAudioFormat_PCM))
6648 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6649 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
6651 else
6652 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
6655 static void test_MFInitMediaTypeFromWaveFormatEx(void)
6657 static const WAVEFORMATEX waveformatex_tests[] =
6659 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
6660 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
6661 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
6662 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
6663 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
6664 { 1234, 0, 0, 0, 0, 0 },
6665 { WAVE_FORMAT_ALAW },
6666 { WAVE_FORMAT_CREATIVE_ADPCM },
6667 { WAVE_FORMAT_MPEGLAYER3 },
6668 { WAVE_FORMAT_MPEG_ADTS_AAC },
6669 { WAVE_FORMAT_ALAC },
6670 { WAVE_FORMAT_AMR_NB },
6671 { WAVE_FORMAT_AMR_WB },
6672 { WAVE_FORMAT_AMR_WP },
6673 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
6674 { WAVE_FORMAT_DRM },
6675 { WAVE_FORMAT_DTS },
6676 { WAVE_FORMAT_FLAC },
6677 { WAVE_FORMAT_MPEG },
6678 { WAVE_FORMAT_WMAVOICE9 },
6679 { WAVE_FORMAT_OPUS },
6680 { WAVE_FORMAT_WMAUDIO2 },
6681 { WAVE_FORMAT_WMAUDIO3 },
6682 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
6683 { WAVE_FORMAT_WMASPDIF },
6686 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
6687 WAVEFORMATEXTENSIBLE waveformatext;
6688 MPEGLAYER3WAVEFORMAT mp3format;
6689 IMFMediaType *mediatype;
6690 unsigned int i, size;
6691 HRESULT hr;
6693 hr = MFCreateMediaType(&mediatype);
6694 ok(hr == S_OK, "Failed to create mediatype, hr %#lx.\n", hr);
6696 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
6698 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
6699 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#lx.\n", i, waveformatex_tests[i].wFormatTag, hr);
6701 validate_media_type(mediatype, &waveformatex_tests[i]);
6703 waveformatext.Format = waveformatex_tests[i];
6704 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
6705 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
6706 waveformatext.Samples.wSamplesPerBlock = 123;
6707 waveformatext.dwChannelMask = 0x8;
6708 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
6709 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
6711 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
6712 ok(hr == S_OK, "Failed to initialize media type, hr %#lx.\n", hr);
6714 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
6715 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
6717 validate_media_type(mediatype, &waveformatext.Format);
6720 /* MPEGLAYER3WAVEFORMAT */
6721 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
6722 mp3format.wfx.nChannels = 2;
6723 mp3format.wfx.nSamplesPerSec = 44100;
6724 mp3format.wfx.nAvgBytesPerSec = 16000;
6725 mp3format.wfx.nBlockAlign = 1;
6726 mp3format.wfx.wBitsPerSample = 0;
6727 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
6728 mp3format.wID = MPEGLAYER3_ID_MPEG;
6729 mp3format.fdwFlags = 0;
6730 mp3format.nBlockSize = 417;
6731 mp3format.nFramesPerBlock = 0;
6732 mp3format.nCodecDelay = 0;
6734 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
6735 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6737 validate_media_type(mediatype, &mp3format.wfx);
6738 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
6739 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6740 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
6741 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
6743 IMFMediaType_Release(mediatype);
6746 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
6748 MFVIDEOFORMAT *video_format;
6749 IMFMediaType *media_type;
6750 UINT32 size;
6751 HRESULT hr;
6753 hr = MFCreateMediaType(&media_type);
6754 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6756 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
6757 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6758 ok(!!video_format, "Unexpected format.\n");
6759 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
6760 CoTaskMemFree(video_format);
6762 IMFMediaType_Release(media_type);
6765 static void test_MFCreateDXSurfaceBuffer(void)
6767 IDirect3DSurface9 *backbuffer = NULL, *surface;
6768 IDirect3DSwapChain9 *swapchain;
6769 D3DLOCKED_RECT locked_rect;
6770 DWORD length, max_length;
6771 IDirect3DDevice9 *device;
6772 IMF2DBuffer2 *_2dbuffer2;
6773 BOOL value, broken_test;
6774 IMFMediaBuffer *buffer;
6775 IMF2DBuffer *_2dbuffer;
6776 BYTE *data, *data2;
6777 IMFGetService *gs;
6778 IDirect3D9 *d3d;
6779 DWORD color;
6780 HWND window;
6781 HRESULT hr;
6782 LONG pitch;
6784 if (!pMFCreateDXSurfaceBuffer)
6786 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
6787 return;
6790 window = create_window();
6791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6792 ok(!!d3d, "Failed to create a D3D object.\n");
6793 if (!(device = create_d3d9_device(d3d, window)))
6795 skip("Failed to create a D3D device, skipping tests.\n");
6796 goto done;
6799 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
6800 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08lx)\n", hr);
6802 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6803 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08lx)\n", hr);
6804 ok(backbuffer != NULL, "The back buffer is NULL\n");
6806 IDirect3DSwapChain9_Release(swapchain);
6808 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
6809 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6811 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
6812 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6814 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6815 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6816 check_interface(buffer, &IID_IMFGetService, TRUE);
6818 /* Surface is accessible. */
6819 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
6820 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6821 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
6822 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6823 ok(surface == backbuffer, "Unexpected surface pointer.\n");
6824 IDirect3DSurface9_Release(surface);
6825 IMFGetService_Release(gs);
6827 max_length = 0;
6828 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6829 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6830 ok(!!max_length, "Unexpected length %lu.\n", max_length);
6832 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6833 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6834 ok(!length, "Unexpected length %lu.\n", length);
6836 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6837 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6839 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6840 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6841 ok(length == 2 * max_length, "Unexpected length %lu.\n", length);
6843 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6844 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6846 /* Cannot lock while the surface is locked. */
6847 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6848 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6850 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6851 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6853 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6854 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6855 /* Broken on Windows 8 and 10 v1507 */
6856 broken_test = length == 0;
6857 ok(length == max_length || broken(broken_test), "Unexpected length %lu instead of %lu.\n", length, max_length);
6859 /* You can lock the surface while the media buffer is locked. */
6860 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6861 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6863 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6864 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6866 hr = IMFMediaBuffer_Unlock(buffer);
6867 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6869 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6870 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6872 /* Unlock twice. */
6873 hr = IMFMediaBuffer_Unlock(buffer);
6874 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6876 hr = IMFMediaBuffer_Unlock(buffer);
6877 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6879 /* Lock twice. */
6880 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6881 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6883 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6884 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6885 ok(data == data2, "Unexpected pointer.\n");
6887 hr = IMFMediaBuffer_Unlock(buffer);
6888 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6890 hr = IMFMediaBuffer_Unlock(buffer);
6891 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6893 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6894 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6896 /* Unlocked. */
6897 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6898 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6900 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6901 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6903 /* Cannot lock the buffer while the surface is locked. */
6904 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6905 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6907 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6908 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6910 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6911 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6913 /* Cannot lock the surface once the buffer is locked. */
6914 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6915 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6917 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6918 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6920 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6921 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6923 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6924 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6926 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6927 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6929 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6930 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6932 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6933 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6935 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6936 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6938 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6939 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
6941 hr = IMFMediaBuffer_Unlock(buffer);
6942 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6944 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
6945 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6946 ok(!value, "Unexpected return value %d.\n", value);
6948 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6949 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6950 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6951 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6952 ok(length == max_length, "Unexpected length %lu.\n", length);
6954 IMF2DBuffer_Release(_2dbuffer);
6956 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6957 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6959 /* Lock flags are ignored, so writing is allowed when locking for
6960 * reading and viceversa. */
6961 put_d3d9_surface_color(backbuffer, 0, 0, 0xcdcdcdcd);
6962 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6963 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6964 ok(data == data2, "Unexpected scanline pointer.\n");
6965 ok(data[0] == 0xcd, "Unexpected leading byte.\n");
6966 memset(data, 0xab, 4);
6967 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6969 color = get_d3d9_surface_color(backbuffer, 0, 0);
6970 ok(color == 0xabababab, "Unexpected leading dword.\n");
6971 put_d3d9_surface_color(backbuffer, 0, 0, 0xefefefef);
6973 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6974 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6975 ok(data[0] == 0xef, "Unexpected leading byte.\n");
6976 memset(data, 0x89, 4);
6977 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6979 color = get_d3d9_surface_color(backbuffer, 0, 0);
6980 ok(color == 0x89898989, "Unexpected leading dword.\n");
6982 /* Also, flags incompatibilities are not taken into account even
6983 * if a buffer is already locked. */
6984 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6985 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6986 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6987 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6988 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6989 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6990 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6991 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6992 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6993 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6994 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6996 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6997 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6998 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6999 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7000 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7002 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7003 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7005 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7006 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7007 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7008 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7009 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7010 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7011 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7012 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7013 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7014 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7015 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7016 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7017 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7018 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7019 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7020 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7021 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7022 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7023 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7024 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7026 /* Except when originally locking for writing. */
7027 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7028 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7029 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7030 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7031 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7032 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7033 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7034 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7035 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7036 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7037 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7038 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7039 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7040 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7042 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7043 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7045 IMF2DBuffer2_Release(_2dbuffer2);
7047 IMFMediaBuffer_Release(buffer);
7048 IDirect3DDevice9_Release(device);
7050 done:
7051 if (backbuffer)
7052 IDirect3DSurface9_Release(backbuffer);
7053 ok(!IDirect3D9_Release(d3d), "Unexpected refcount.\n");
7054 DestroyWindow(window);
7057 static void test_MFCreateTrackedSample(void)
7059 IMFTrackedSample *tracked_sample;
7060 IMFSample *sample;
7061 IUnknown *unk;
7062 HRESULT hr;
7064 if (!pMFCreateTrackedSample)
7066 win_skip("MFCreateTrackedSample() is not available.\n");
7067 return;
7070 hr = pMFCreateTrackedSample(&tracked_sample);
7071 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7073 /* It's actually a sample. */
7074 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
7075 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7077 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
7078 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7079 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
7080 IUnknown_Release(unk);
7082 IMFSample_Release(sample);
7084 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
7086 IMFTrackedSample_Release(tracked_sample);
7089 static void test_MFFrameRateToAverageTimePerFrame(void)
7091 static const struct frame_rate_test
7093 unsigned int numerator;
7094 unsigned int denominator;
7095 UINT64 avgtime;
7096 } frame_rate_tests[] =
7098 { 60000, 1001, 166833 },
7099 { 30000, 1001, 333667 },
7100 { 24000, 1001, 417188 },
7101 { 60, 1, 166667 },
7102 { 30, 1, 333333 },
7103 { 50, 1, 200000 },
7104 { 25, 1, 400000 },
7105 { 24, 1, 416667 },
7107 { 39, 1, 256410 },
7108 { 120, 1, 83333 },
7110 unsigned int i;
7111 UINT64 avgtime;
7112 HRESULT hr;
7114 avgtime = 1;
7115 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
7116 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7117 ok(!avgtime, "Unexpected frame time.\n");
7119 avgtime = 1;
7120 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
7121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7122 ok(!avgtime, "Unexpected frame time.\n");
7124 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
7126 avgtime = 0;
7127 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
7128 frame_rate_tests[i].denominator, &avgtime);
7129 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7130 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
7131 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
7135 static void test_MFAverageTimePerFrameToFrameRate(void)
7137 static const struct frame_rate_test
7139 unsigned int numerator;
7140 unsigned int denominator;
7141 UINT64 avgtime;
7142 } frame_rate_tests[] =
7144 { 60000, 1001, 166833 },
7145 { 30000, 1001, 333667 },
7146 { 24000, 1001, 417188 },
7147 { 60, 1, 166667 },
7148 { 30, 1, 333333 },
7149 { 50, 1, 200000 },
7150 { 25, 1, 400000 },
7151 { 24, 1, 416667 },
7153 { 1000000, 25641, 256410 },
7154 { 10000000, 83333, 83333 },
7155 { 1, 10, 100000000 },
7156 { 1, 10, 100000001 },
7157 { 1, 10, 200000000 },
7158 { 1, 1, 10000000 },
7159 { 1, 2, 20000000 },
7160 { 5, 1, 2000000 },
7161 { 10, 1, 1000000 },
7163 unsigned int i, numerator, denominator;
7164 HRESULT hr;
7166 numerator = denominator = 1;
7167 hr = MFAverageTimePerFrameToFrameRate(0, &numerator, &denominator);
7168 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7169 ok(!numerator && !denominator, "Unexpected output %u/%u.\n", numerator, denominator);
7171 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
7173 numerator = denominator = 12345;
7174 hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
7175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7176 ok(numerator == frame_rate_tests[i].numerator && denominator == frame_rate_tests[i].denominator,
7177 "%u: unexpected %u/%u, expected %u/%u.\n", i, numerator, denominator, frame_rate_tests[i].numerator,
7178 frame_rate_tests[i].denominator);
7182 static void test_MFMapDXGIFormatToDX9Format(void)
7184 static const struct format_pair
7186 DXGI_FORMAT dxgi_format;
7187 DWORD d3d9_format;
7189 formats_map[] =
7191 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
7192 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
7193 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
7194 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
7195 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
7196 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
7197 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
7198 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
7199 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
7200 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
7201 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
7202 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
7203 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
7204 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
7205 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
7206 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
7207 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
7208 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
7209 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
7210 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
7211 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
7212 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
7213 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
7214 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
7215 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
7216 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
7217 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
7218 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
7219 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
7220 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
7221 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
7222 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
7223 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
7224 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
7225 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
7226 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
7227 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
7228 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
7229 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
7230 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
7231 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
7232 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
7233 { DXGI_FORMAT_P8, D3DFMT_P8 },
7234 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
7236 unsigned int i;
7237 DWORD format;
7239 if (!pMFMapDXGIFormatToDX9Format)
7241 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
7242 return;
7245 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
7247 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
7248 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
7252 static void test_MFMapDX9FormatToDXGIFormat(void)
7254 static const struct format_pair
7256 DXGI_FORMAT dxgi_format;
7257 DWORD d3d9_format;
7259 formats_map[] =
7261 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
7262 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
7263 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
7264 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
7265 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
7266 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
7267 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
7268 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
7269 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
7270 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
7271 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
7272 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
7273 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
7274 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
7275 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
7276 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
7277 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
7278 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
7279 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
7280 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
7281 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
7282 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
7283 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
7284 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
7285 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
7286 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
7287 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
7288 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
7289 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
7290 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
7291 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
7292 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
7293 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
7294 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
7295 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
7296 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
7297 { DXGI_FORMAT_P8, D3DFMT_P8 },
7298 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
7300 DXGI_FORMAT format;
7301 unsigned int i;
7303 if (!pMFMapDX9FormatToDXGIFormat)
7305 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
7306 return;
7309 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
7311 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
7312 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#lx.\n",
7313 format, formats_map[i].d3d9_format);
7317 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
7318 REFIID riid, void **obj)
7320 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
7321 IsEqualIID(riid, &IID_IUnknown))
7323 *obj = iface;
7324 IMFVideoSampleAllocatorNotify_AddRef(iface);
7325 return S_OK;
7328 *obj = NULL;
7329 return E_NOINTERFACE;
7332 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
7334 return 2;
7337 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
7339 return 1;
7342 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
7344 return E_NOTIMPL;
7347 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
7349 test_notify_callback_QueryInterface,
7350 test_notify_callback_AddRef,
7351 test_notify_callback_Release,
7352 test_notify_callback_NotifyRelease,
7355 static IMFMediaType * create_video_type(const GUID *subtype)
7357 IMFMediaType *video_type;
7358 HRESULT hr;
7360 hr = MFCreateMediaType(&video_type);
7361 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7363 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
7364 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7366 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
7367 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7369 return video_type;
7372 static ID3D11Device *create_d3d11_device(void)
7374 static const D3D_FEATURE_LEVEL default_feature_level[] =
7376 D3D_FEATURE_LEVEL_11_0,
7377 D3D_FEATURE_LEVEL_10_1,
7378 D3D_FEATURE_LEVEL_10_0,
7380 const D3D_FEATURE_LEVEL *feature_level;
7381 unsigned int feature_level_count;
7382 ID3D11Device *device;
7384 feature_level = default_feature_level;
7385 feature_level_count = ARRAY_SIZE(default_feature_level);
7387 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
7388 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7389 return device;
7390 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
7391 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7392 return device;
7393 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
7394 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7395 return device;
7397 return NULL;
7400 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
7401 const BYTE *data, unsigned int src_pitch)
7403 ID3D11DeviceContext *immediate_context;
7404 ID3D11Device *device;
7406 ID3D11Texture2D_GetDevice(texture, &device);
7407 ID3D11Device_GetImmediateContext(device, &immediate_context);
7409 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
7410 sub_resource_idx, NULL, data, src_pitch, 0);
7412 ID3D11DeviceContext_Release(immediate_context);
7413 ID3D11Device_Release(device);
7416 static ID3D12Device *create_d3d12_device(void)
7418 ID3D12Device *device;
7419 HRESULT hr;
7421 if (!pD3D12CreateDevice) return NULL;
7423 hr = pD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
7424 if (FAILED(hr))
7425 return NULL;
7427 return device;
7430 static void test_d3d11_surface_buffer(void)
7432 DWORD max_length, cur_length, length, color;
7433 BYTE *data, *data2, *buffer_start;
7434 IMFDXGIBuffer *dxgi_buffer;
7435 D3D11_TEXTURE2D_DESC desc;
7436 IMF2DBuffer2 *_2dbuffer2;
7437 ID3D11Texture2D *texture;
7438 IMF2DBuffer *_2d_buffer;
7439 IMFMediaBuffer *buffer;
7440 ID3D11Device *device;
7441 BYTE buff[64 * 64 * 4];
7442 LONG pitch, pitch2;
7443 UINT index, size;
7444 IUnknown *obj;
7445 HRESULT hr;
7447 if (!pMFCreateDXGISurfaceBuffer)
7449 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
7450 return;
7453 /* d3d11 */
7454 if (!(device = create_d3d11_device()))
7456 skip("Failed to create a D3D11 device, skipping tests.\n");
7457 return;
7460 memset(&desc, 0, sizeof(desc));
7461 desc.Width = 64;
7462 desc.Height = 64;
7463 desc.ArraySize = 1;
7464 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7465 desc.SampleDesc.Count = 1;
7466 desc.SampleDesc.Quality = 0;
7468 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7469 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7471 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
7472 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7474 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7475 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7476 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7477 check_interface(buffer, &IID_IMFGetService, FALSE);
7479 max_length = 0;
7480 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
7481 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7482 ok(!!max_length, "Unexpected length %lu.\n", max_length);
7484 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7485 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7486 ok(!cur_length, "Unexpected length %lu.\n", cur_length);
7488 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
7489 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7491 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7492 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7493 ok(cur_length == 2 * max_length, "Unexpected length %lu.\n", cur_length);
7495 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7498 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
7499 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7500 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
7501 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7502 ok(length == max_length, "Unexpected length %lu.\n", length);
7503 IMF2DBuffer_Release(_2d_buffer);
7505 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7506 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7508 EXPECT_REF(texture, 2);
7509 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
7510 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7511 EXPECT_REF(texture, 3);
7512 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
7513 IUnknown_Release(obj);
7515 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
7516 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7518 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
7519 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7520 ok(index == 0, "Unexpected subresource index.\n");
7522 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7523 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7525 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7528 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7529 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#lx.\n", hr);
7531 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
7532 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7534 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
7535 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7536 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
7537 IUnknown_Release(obj);
7539 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7540 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7542 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
7543 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7545 IMFDXGIBuffer_Release(dxgi_buffer);
7547 /* Texture updates. */
7548 color = get_d3d11_texture_color(texture, 0, 0);
7549 ok(!color, "Unexpected texture color %#lx.\n", color);
7551 max_length = cur_length = 0;
7552 data = NULL;
7553 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7554 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7555 ok(max_length && max_length == cur_length, "Unexpected length %lu.\n", max_length);
7556 if (data) *(DWORD *)data = ~0u;
7558 color = get_d3d11_texture_color(texture, 0, 0);
7559 ok(!color, "Unexpected texture color %#lx.\n", color);
7561 hr = IMFMediaBuffer_Unlock(buffer);
7562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7564 color = get_d3d11_texture_color(texture, 0, 0);
7565 ok(color == ~0u, "Unexpected texture color %#lx.\n", color);
7567 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7568 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7569 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#lx.\n", *(DWORD *)data);
7571 hr = IMFMediaBuffer_Unlock(buffer);
7572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7574 /* Lock2D()/Unlock2D() */
7575 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7576 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7578 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7579 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7581 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7582 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7583 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7585 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7586 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7587 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7589 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7591 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7593 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7594 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
7596 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7597 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7599 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7600 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7602 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7603 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7605 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7606 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7608 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7609 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
7611 hr = IMFMediaBuffer_Unlock(buffer);
7612 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7614 IMF2DBuffer_Release(_2d_buffer);
7616 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
7617 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7619 /* Lock flags are honored, so reads and writes are discarded if
7620 * the flags are not correct. Also, previous content is discarded
7621 * when locking for writing and not for reading. */
7622 put_d3d11_texture_color(texture, 0, 0, 0xcdcdcdcd);
7623 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7624 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7625 ok(data == data2, "Unexpected scanline pointer.\n");
7626 ok(*(DWORD *)data == 0xcdcdcdcd, "Unexpected leading dword %#lx.\n", *(DWORD *)data);
7627 memset(data, 0xab, 4);
7628 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7630 color = get_d3d11_texture_color(texture, 0, 0);
7631 ok(color == 0xcdcdcdcd, "Unexpected leading dword %#lx.\n", color);
7632 put_d3d11_texture_color(texture, 0, 0, 0xefefefef);
7634 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7635 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7636 ok(*(DWORD *)data != 0xefefefef, "Unexpected leading dword.\n");
7637 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7639 color = get_d3d11_texture_color(texture, 0, 0);
7640 ok(color != 0xefefefef, "Unexpected leading dword.\n");
7642 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7643 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7644 ok(*(DWORD *)data != 0xefefefef, "Unexpected leading dword.\n");
7645 memset(data, 0x89, 4);
7646 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7648 color = get_d3d11_texture_color(texture, 0, 0);
7649 ok(color == 0x89898989, "Unexpected leading dword %#lx.\n", color);
7651 /* When relocking for writing, stores are committed even if they
7652 * were issued before relocking. */
7653 put_d3d11_texture_color(texture, 0, 0, 0xcdcdcdcd);
7654 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7655 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7656 memset(data, 0xab, 4);
7657 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7659 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7660 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7662 color = get_d3d11_texture_color(texture, 0, 0);
7663 ok(color == 0xabababab, "Unexpected leading dword %#lx.\n", color);
7665 /* Flags incompatibilities. */
7666 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7667 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7668 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7669 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7670 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7671 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7672 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7673 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7674 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7675 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7676 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7677 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7678 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7679 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7680 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7681 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7682 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7683 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7684 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7685 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7687 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7688 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7689 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7690 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7691 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7692 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7693 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7694 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7695 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7696 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7697 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7698 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7699 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7700 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7701 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7702 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7703 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7704 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7705 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7706 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7708 /* Except when originally locking for writing. */
7709 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7710 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7711 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7712 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7713 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7714 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7715 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7716 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7717 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7718 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7719 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7720 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7721 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7722 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7724 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7725 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7727 IMF2DBuffer2_Release(_2dbuffer2);
7728 IMFMediaBuffer_Release(buffer);
7730 /* Bottom up. */
7731 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
7732 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7734 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7735 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7737 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7738 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7739 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7741 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7742 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7743 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7745 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7746 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7748 IMF2DBuffer_Release(_2d_buffer);
7749 IMFMediaBuffer_Release(buffer);
7751 ID3D11Texture2D_Release(texture);
7753 memset(&desc, 0, sizeof(desc));
7754 desc.Width = 64;
7755 desc.Height = 64;
7756 desc.ArraySize = 1;
7757 desc.MipLevels = 1;
7758 desc.Format = DXGI_FORMAT_NV12;
7759 desc.SampleDesc.Count = 1;
7760 desc.SampleDesc.Quality = 0;
7762 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7763 if (SUCCEEDED(hr))
7765 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
7766 ok(hr == S_OK, "got %#lx.\n", hr);
7767 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
7768 ok(hr == S_OK, "got %#lx.\n", hr);
7770 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &buffer_start, &length);
7771 ok(hr == S_OK, "got %#lx.\n", hr);
7773 ok(pitch >= desc.Width, "got %ld.\n", pitch);
7774 ok(length == pitch * desc.Height * 3 / 2, "got %lu.\n", length);
7776 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7777 ok(hr == S_OK, "got %#lx.\n", hr);
7779 IMF2DBuffer2_Release(_2dbuffer2);
7780 IMFMediaBuffer_Release(buffer);
7781 ID3D11Texture2D_Release(texture);
7783 else
7785 win_skip("Failed to create NV12 texture, hr %#lx, skipping test.\n", hr);
7786 ID3D11Device_Release(device);
7787 return;
7790 /* Subresource index 1.
7791 * When WARP d3d11 device is used, this test leaves the device in a broken state, so it should
7792 * be kept last. */
7793 memset(&desc, 0, sizeof(desc));
7794 desc.Width = 64;
7795 desc.Height = 64;
7796 desc.ArraySize = 1;
7797 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7798 desc.SampleDesc.Count = 1;
7799 desc.SampleDesc.Quality = 0;
7801 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7802 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7804 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
7805 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7807 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7808 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7810 /* Pitch reflects top level. */
7811 memset(buff, 0, sizeof(buff));
7812 *(DWORD *)buff = 0xff00ff00;
7813 update_d3d11_texture(texture, 1, buff, 64 * 4);
7815 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7817 ok(pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7818 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#lx.\n", *(DWORD *)data);
7820 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7823 IMF2DBuffer_Release(_2d_buffer);
7824 IMFMediaBuffer_Release(buffer);
7825 ID3D11Texture2D_Release(texture);
7827 ID3D11Device_Release(device);
7830 static void test_d3d12_surface_buffer(void)
7832 IMFDXGIBuffer *dxgi_buffer;
7833 D3D12_HEAP_PROPERTIES heap_props;
7834 D3D12_RESOURCE_DESC desc;
7835 ID3D12Resource *resource;
7836 IMFMediaBuffer *buffer;
7837 unsigned int refcount;
7838 ID3D12Device *device;
7839 IUnknown *obj;
7840 HRESULT hr;
7842 /* d3d12 */
7843 if (!(device = create_d3d12_device()))
7845 skip("Failed to create a D3D12 device, skipping tests.\n");
7846 return;
7849 memset(&heap_props, 0, sizeof(heap_props));
7850 heap_props.Type = D3D12_HEAP_TYPE_DEFAULT;
7852 memset(&desc, 0, sizeof(desc));
7853 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
7854 desc.Alignment = 0;
7855 desc.Width = 32;
7856 desc.Height = 32;
7857 desc.DepthOrArraySize = 1;
7858 desc.MipLevels = 1;
7859 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7860 desc.SampleDesc.Count = 1;
7861 desc.SampleDesc.Quality = 0;
7862 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
7863 desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
7865 hr = ID3D12Device_CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE,
7866 &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&resource);
7867 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7869 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D12Resource, (IUnknown *)resource, 0, FALSE, &buffer);
7870 if (hr == E_INVALIDARG)
7872 todo_wine
7873 win_skip("D3D12 resource buffers are not supported.\n");
7874 goto notsupported;
7876 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7878 if (SUCCEEDED(hr))
7880 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7881 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7882 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7883 check_interface(buffer, &IID_IMFGetService, FALSE);
7885 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7886 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7888 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&obj);
7889 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7890 ok(obj == (IUnknown *)resource, "Unexpected resource pointer.\n");
7891 IUnknown_Release(obj);
7893 IMFDXGIBuffer_Release(dxgi_buffer);
7894 IMFMediaBuffer_Release(buffer);
7897 notsupported:
7898 ID3D12Resource_Release(resource);
7899 refcount = ID3D12Device_Release(device);
7900 ok(!refcount, "Unexpected device refcount %u.\n", refcount);
7903 static void test_sample_allocator_sysmem(void)
7905 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
7906 IMFMediaType *media_type, *video_type, *video_type2;
7907 IMFVideoSampleAllocatorCallback *allocator_cb;
7908 IMFVideoSampleAllocatorEx *allocatorex;
7909 IMFVideoSampleAllocator *allocator;
7910 IMFSample *sample, *sample2;
7911 IMFAttributes *attributes;
7912 IMFMediaBuffer *buffer;
7913 LONG refcount, count;
7914 DWORD buffer_count;
7915 IUnknown *unk;
7916 HRESULT hr;
7918 if (!pMFCreateVideoSampleAllocatorEx)
7919 return;
7921 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
7922 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7924 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
7925 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
7926 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
7928 IUnknown_Release(unk);
7930 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7933 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7934 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7936 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7937 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7939 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
7940 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7942 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7943 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7945 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
7946 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7948 count = 10;
7949 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7950 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7951 ok(!count, "Unexpected count %ld.\n", count);
7953 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7956 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7957 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7959 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
7960 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7962 hr = MFCreateMediaType(&media_type);
7963 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7965 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
7966 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7968 video_type = create_video_type(&MFVideoFormat_RGB32);
7969 video_type2 = create_video_type(&MFVideoFormat_RGB32);
7971 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7972 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7974 /* Frame size is required. */
7975 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7976 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7978 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7979 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7981 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
7982 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7984 EXPECT_REF(video_type, 1);
7985 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7986 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7987 EXPECT_REF(video_type, 2);
7989 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
7990 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7992 /* Setting identical type does not replace it. */
7993 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7994 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7995 EXPECT_REF(video_type, 2);
7996 EXPECT_REF(video_type2, 1);
7998 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7999 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8001 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
8002 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8003 EXPECT_REF(video_type2, 2);
8004 EXPECT_REF(video_type, 1);
8006 /* Modify referenced type. */
8007 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
8008 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8010 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8011 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8012 EXPECT_REF(video_type, 2);
8013 EXPECT_REF(video_type2, 1);
8015 count = 0;
8016 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8017 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8018 ok(count == 1, "Unexpected count %ld.\n", count);
8020 sample = NULL;
8021 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8022 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8023 refcount = get_refcount(sample);
8025 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8026 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8027 ok(!count, "Unexpected count %ld.\n", count);
8029 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
8030 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
8032 /* Reinitialize with active sample. */
8033 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
8034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8035 ok(refcount == get_refcount(sample), "Unexpected refcount %lu.\n", get_refcount(sample));
8036 EXPECT_REF(video_type, 2);
8038 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8039 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8040 todo_wine
8041 ok(!count, "Unexpected count %ld.\n", count);
8043 check_interface(sample, &IID_IMFTrackedSample, TRUE);
8044 check_interface(sample, &IID_IMFDesiredSample, FALSE);
8046 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8047 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8049 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8050 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8051 check_interface(buffer, &IID_IMFGetService, TRUE);
8052 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
8054 IMFMediaBuffer_Release(buffer);
8056 hr = IMFSample_GetBufferCount(sample, &buffer_count);
8057 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8058 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
8060 IMFSample_Release(sample);
8062 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
8063 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8064 todo_wine
8065 EXPECT_REF(video_type, 2);
8067 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8068 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8069 ok(!count, "Unexpected count %ld.\n", count);
8071 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8072 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
8074 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
8075 IMFVideoSampleAllocator_Release(allocator);
8077 /* IMFVideoSampleAllocatorEx */
8078 hr = MFCreateAttributes(&attributes, 0);
8079 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8081 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8082 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8084 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
8085 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8087 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
8088 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8090 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
8091 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8093 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8094 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
8096 EXPECT_REF(attributes, 1);
8097 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8098 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8099 EXPECT_REF(attributes, 2);
8101 count = 0;
8102 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8104 ok(count == 1, "Unexpected count %ld.\n", count);
8106 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8107 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8109 hr = IMFSample_GetBufferCount(sample, &buffer_count);
8110 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8111 ok(buffer_count == 2, "Unexpected buffer count %lu.\n", buffer_count);
8113 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
8114 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
8116 /* Reinitialize with already allocated samples. */
8117 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
8118 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8119 EXPECT_REF(attributes, 1);
8121 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
8122 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8123 IMFSample_Release(sample2);
8125 IMFSample_Release(sample);
8127 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
8128 IMFVideoSampleAllocatorEx_Release(allocatorex);
8129 IMFAttributes_Release(attributes);
8132 static void test_sample_allocator_d3d9(void)
8134 IDirect3DDeviceManager9 *d3d9_manager;
8135 IMFVideoSampleAllocator *allocator;
8136 IDirect3DDevice9 *d3d9_device;
8137 IMFMediaType *video_type;
8138 IMFMediaBuffer *buffer;
8139 unsigned int token;
8140 IMFSample *sample;
8141 IDirect3D9 *d3d9;
8142 HWND window;
8143 HRESULT hr;
8145 if (!pMFCreateVideoSampleAllocatorEx)
8146 return;
8148 window = create_window();
8149 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8150 ok(!!d3d9, "Failed to create a D3D9 object.\n");
8151 if (!(d3d9_device = create_d3d9_device(d3d9, window)))
8153 skip("Failed to create a D3D9 device, skipping tests.\n");
8154 goto done;
8157 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
8158 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8160 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
8161 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8163 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8166 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
8167 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8169 video_type = create_video_type(&MFVideoFormat_RGB32);
8171 /* Frame size is required. */
8172 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8173 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8175 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8176 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8178 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8181 check_interface(sample, &IID_IMFTrackedSample, TRUE);
8182 check_interface(sample, &IID_IMFDesiredSample, FALSE);
8184 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8185 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8187 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8188 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8189 check_interface(buffer, &IID_IMFGetService, TRUE);
8190 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
8192 IMFSample_Release(sample);
8193 IMFMediaBuffer_Release(buffer);
8195 IMFVideoSampleAllocator_Release(allocator);
8196 IMFMediaType_Release(video_type);
8197 IDirect3DDeviceManager9_Release(d3d9_manager);
8198 IDirect3DDevice9_Release(d3d9_device);
8200 done:
8201 IDirect3D9_Release(d3d9);
8202 DestroyWindow(window);
8205 static void test_sample_allocator_d3d11(void)
8207 IMFMediaType *video_type;
8208 IMFVideoSampleAllocatorEx *allocatorex;
8209 IMFVideoSampleAllocator *allocator;
8210 unsigned int i, token;
8211 IMFDXGIDeviceManager *manager;
8212 IMFSample *sample;
8213 IMFDXGIBuffer *dxgi_buffer;
8214 IMFAttributes *attributes;
8215 D3D11_TEXTURE2D_DESC desc;
8216 ID3D11Texture2D *texture;
8217 IMFMediaBuffer *buffer;
8218 ID3D11Device *device;
8219 HRESULT hr;
8220 BYTE *data;
8221 static const unsigned int usage[] =
8223 D3D11_USAGE_DEFAULT,
8224 D3D11_USAGE_IMMUTABLE,
8225 D3D11_USAGE_DYNAMIC,
8226 D3D11_USAGE_STAGING,
8227 D3D11_USAGE_STAGING + 1,
8229 static const unsigned int sharing[] =
8231 D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
8232 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
8233 D3D11_RESOURCE_MISC_SHARED,
8236 if (!pMFCreateVideoSampleAllocatorEx)
8237 return;
8239 if (!(device = create_d3d11_device()))
8241 skip("Failed to create a D3D11 device, skipping tests.\n");
8242 return;
8245 hr = pMFCreateDXGIDeviceManager(&token, &manager);
8246 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
8248 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
8249 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
8251 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8252 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8254 EXPECT_REF(manager, 1);
8255 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
8256 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8257 EXPECT_REF(manager, 2);
8259 video_type = create_video_type(&MFVideoFormat_RGB32);
8260 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8261 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8263 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8264 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8266 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8267 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8269 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8272 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8273 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8274 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8275 check_interface(buffer, &IID_IMFGetService, FALSE);
8277 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8278 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8280 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8281 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8283 ID3D11Texture2D_GetDesc(texture, &desc);
8284 ok(desc.Width == 64, "Unexpected width %u.\n", desc.Width);
8285 ok(desc.Height == 64, "Unexpected height %u.\n", desc.Height);
8286 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
8287 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
8288 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
8289 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
8290 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
8291 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
8292 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
8293 desc.BindFlags);
8294 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8295 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
8297 ID3D11Texture2D_Release(texture);
8298 IMFDXGIBuffer_Release(dxgi_buffer);
8300 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
8301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8303 hr = IMFMediaBuffer_Unlock(buffer);
8304 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8306 IMFMediaBuffer_Release(buffer);
8307 IMFSample_Release(sample);
8309 IMFVideoSampleAllocator_Release(allocator);
8311 /* MF_SA_D3D11_USAGE */
8312 hr = MFCreateAttributes(&attributes, 1);
8313 ok(hr == S_OK, "Failed to create attributes, hr %#lx.\n", hr);
8315 for (i = 0; i < ARRAY_SIZE(usage); ++i)
8317 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8318 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8320 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
8321 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8323 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
8324 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8326 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8327 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
8329 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8330 IMFVideoSampleAllocatorEx_Release(allocatorex);
8331 continue;
8333 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", usage[i], hr);
8335 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
8336 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8338 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8341 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8342 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8344 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8345 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8347 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8348 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8350 ID3D11Texture2D_GetDesc(texture, &desc);
8351 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
8352 if (usage[i] == D3D11_USAGE_DEFAULT)
8354 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
8355 desc.BindFlags);
8356 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8358 else if (usage[i] == D3D11_USAGE_DYNAMIC)
8360 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
8361 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8363 else if (usage[i] == D3D11_USAGE_STAGING)
8365 ok(!desc.BindFlags, "Unexpected bind flags %#x.\n", desc.BindFlags);
8366 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
8367 desc.CPUAccessFlags);
8369 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
8371 ID3D11Texture2D_Release(texture);
8372 IMFDXGIBuffer_Release(dxgi_buffer);
8373 IMFMediaBuffer_Release(buffer);
8375 IMFSample_Release(sample);
8377 IMFVideoSampleAllocatorEx_Release(allocatorex);
8380 /* MF_SA_D3D11_SHARED, MF_SA_D3D11_SHARED_WITHOUT_MUTEX */
8381 for (i = 0; i < ARRAY_SIZE(sharing); ++i)
8383 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8384 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8386 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
8387 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8389 hr = IMFAttributes_DeleteAllItems(attributes);
8390 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8392 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
8393 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8395 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
8397 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED, TRUE);
8398 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8401 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED)
8403 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
8404 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8407 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8408 if (sharing[i] == (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED))
8410 todo_wine
8411 ok(hr == E_INVALIDARG, "%u: Unexpected hr %#lx.\n", i, hr);
8412 IMFVideoSampleAllocatorEx_Release(allocatorex);
8413 continue;
8415 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", i, hr);
8417 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8418 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8420 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8421 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8423 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8424 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8426 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8427 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8429 ID3D11Texture2D_GetDesc(texture, &desc);
8430 ok(desc.MiscFlags == sharing[i], "%u: unexpected misc flags %#x.\n", i, desc.MiscFlags);
8432 ID3D11Texture2D_Release(texture);
8433 IMFDXGIBuffer_Release(dxgi_buffer);
8434 IMFMediaBuffer_Release(buffer);
8436 IMFSample_Release(sample);
8438 IMFVideoSampleAllocatorEx_Release(allocatorex);
8441 IMFAttributes_Release(attributes);
8443 IMFDXGIDeviceManager_Release(manager);
8444 ID3D11Device_Release(device);
8447 static void test_sample_allocator_d3d12(void)
8449 IMFVideoSampleAllocator *allocator = NULL;
8450 D3D12_HEAP_PROPERTIES heap_props;
8451 IMFDXGIDeviceManager *manager;
8452 D3D12_HEAP_FLAGS heap_flags;
8453 IMFDXGIBuffer *dxgi_buffer;
8454 IMFMediaType *video_type;
8455 ID3D12Resource *resource;
8456 D3D12_RESOURCE_DESC desc;
8457 IMFMediaBuffer *buffer;
8458 ID3D12Device *device;
8459 unsigned int token;
8460 IMFSample *sample;
8461 HRESULT hr;
8463 if (!(device = create_d3d12_device()))
8465 skip("Failed to create a D3D12 device, skipping tests.\n");
8466 return;
8469 hr = pMFCreateDXGIDeviceManager(&token, &manager);
8470 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
8472 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
8473 if (FAILED(hr))
8475 win_skip("Device manager does not support D3D12 devices.\n");
8476 goto done;
8478 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
8480 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8481 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8483 EXPECT_REF(manager, 1);
8484 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
8485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8486 EXPECT_REF(manager, 2);
8488 video_type = create_video_type(&MFVideoFormat_RGB32);
8489 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8490 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8491 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_D3D_RESOURCE_VERSION, MF_D3D12_RESOURCE);
8492 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8494 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8495 todo_wine
8496 ok(hr == S_OK || broken(hr == MF_E_UNEXPECTED) /* Some Win10 versions fail. */, "Unexpected hr %#lx.\n", hr);
8497 if (FAILED(hr)) goto done;
8499 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8500 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8502 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8503 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8505 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8506 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8507 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8508 check_interface(buffer, &IID_IMFGetService, FALSE);
8510 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8511 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8513 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&resource);
8514 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8516 resource->lpVtbl->GetDesc(resource, &desc);
8517 ok(desc.Width == 64, "Unexpected width.\n");
8518 ok(desc.Height == 64, "Unexpected height.\n");
8519 ok(desc.DepthOrArraySize == 1, "Unexpected array size %u.\n", desc.DepthOrArraySize);
8520 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
8521 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
8522 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
8523 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
8524 ok(!desc.Layout, "Unexpected layout %u.\n", desc.Layout);
8525 ok(!desc.Flags, "Unexpected flags %#x.\n", desc.Flags);
8527 hr = ID3D12Resource_GetHeapProperties(resource, &heap_props, &heap_flags);
8528 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8529 ok(heap_props.Type == D3D12_HEAP_TYPE_DEFAULT, "Unexpected heap type %u.\n", heap_props.Type);
8530 ok(heap_props.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN, "Unexpected page property %u.\n",
8531 heap_props.CPUPageProperty);
8532 ok(!heap_props.MemoryPoolPreference, "Unexpected pool preference %u.\n", heap_props.MemoryPoolPreference);
8533 ok(heap_flags == D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, "Unexpected heap flags %#x.\n", heap_flags);
8535 ID3D12Resource_Release(resource);
8536 IMFDXGIBuffer_Release(dxgi_buffer);
8537 IMFMediaBuffer_Release(buffer);
8538 IMFSample_Release(sample);
8540 done:
8541 if (allocator)
8542 IMFVideoSampleAllocator_Release(allocator);
8543 IMFDXGIDeviceManager_Release(manager);
8544 ID3D12Device_Release(device);
8547 static void test_MFLockSharedWorkQueue(void)
8549 DWORD taskid, queue, queue2;
8550 HRESULT hr;
8552 if (!pMFLockSharedWorkQueue)
8554 win_skip("MFLockSharedWorkQueue() is not available.\n");
8555 return;
8558 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
8559 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
8561 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
8562 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8564 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
8565 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8567 taskid = 0;
8568 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
8569 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8571 queue = 0;
8572 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
8573 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
8575 queue2 = 0;
8576 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
8577 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8578 ok(queue == queue2, "Unexpected queue %#lx.\n", queue2);
8580 hr = MFUnlockWorkQueue(queue2);
8581 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8583 hr = MFUnlockWorkQueue(queue);
8584 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8586 hr = MFShutdown();
8587 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
8590 static void test_MFllMulDiv(void)
8592 /* (a * b + d) / c */
8593 static const struct muldivtest
8595 LONGLONG a;
8596 LONGLONG b;
8597 LONGLONG c;
8598 LONGLONG d;
8599 LONGLONG result;
8601 muldivtests[] =
8603 { 0, 0, 0, 0, _I64_MAX },
8604 { 1000000, 1000000, 2, 0, 500000000000 },
8605 { _I64_MAX, 3, _I64_MAX, 0, 3 },
8606 { _I64_MAX, 3, _I64_MAX, 1, 3 },
8607 { -10000, 3, 100, 0, -300 },
8608 { 2, 0, 3, 5, 1 },
8609 { 2, 1, 1, -3, -1 },
8610 /* a * b product does not fit in uint64_t */
8611 { _I64_MAX, 4, 8, 0, _I64_MAX / 2 },
8612 /* Large a * b product, large denominator */
8613 { _I64_MAX, 4, 0x100000000, 0, 0x1ffffffff },
8615 unsigned int i;
8617 for (i = 0; i < ARRAY_SIZE(muldivtests); ++i)
8619 LONGLONG result;
8621 result = MFllMulDiv(muldivtests[i].a, muldivtests[i].b, muldivtests[i].c, muldivtests[i].d);
8622 ok(result == muldivtests[i].result, "%u: unexpected result %s, expected %s.\n", i,
8623 wine_dbgstr_longlong(result), wine_dbgstr_longlong(muldivtests[i].result));
8627 static void test_shared_dxgi_device_manager(void)
8629 IMFDXGIDeviceManager *manager;
8630 HRESULT hr;
8631 UINT token;
8633 if (!pMFLockDXGIDeviceManager)
8635 win_skip("Shared DXGI device manager is not supported.\n");
8636 return;
8639 hr = pMFUnlockDXGIDeviceManager();
8640 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8642 manager = NULL;
8643 hr = pMFLockDXGIDeviceManager(NULL, &manager);
8644 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8645 ok(!!manager, "Unexpected instance.\n");
8647 hr = pMFLockDXGIDeviceManager(&token, &manager);
8648 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8650 EXPECT_REF(manager, 3);
8652 hr = pMFUnlockDXGIDeviceManager();
8653 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8655 EXPECT_REF(manager, 2);
8657 hr = pMFUnlockDXGIDeviceManager();
8658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8661 static void check_video_format(const MFVIDEOFORMAT *format, unsigned int width, unsigned int height,
8662 DWORD d3dformat)
8664 unsigned int transfer_function;
8665 GUID guid;
8667 if (!d3dformat) d3dformat = D3DFMT_X8R8G8B8;
8669 switch (d3dformat)
8671 case D3DFMT_X8R8G8B8:
8672 case D3DFMT_R8G8B8:
8673 case D3DFMT_A8R8G8B8:
8674 case D3DFMT_R5G6B5:
8675 case D3DFMT_X1R5G5B5:
8676 case D3DFMT_A2B10G10R10:
8677 case D3DFMT_P8:
8678 transfer_function = MFVideoTransFunc_sRGB;
8679 break;
8680 default:
8681 transfer_function = MFVideoTransFunc_10;
8684 memcpy(&guid, &MFVideoFormat_Base, sizeof(guid));
8685 guid.Data1 = d3dformat;
8687 ok(format->dwSize == sizeof(*format), "Unexpected format size.\n");
8688 ok(format->videoInfo.dwWidth == width, "Unexpected width %lu.\n", format->videoInfo.dwWidth);
8689 ok(format->videoInfo.dwHeight == height, "Unexpected height %lu.\n", format->videoInfo.dwHeight);
8690 ok(format->videoInfo.PixelAspectRatio.Numerator == 1 &&
8691 format->videoInfo.PixelAspectRatio.Denominator == 1, "Unexpected PAR.\n");
8692 ok(format->videoInfo.SourceChromaSubsampling == MFVideoChromaSubsampling_Unknown, "Unexpected chroma subsampling.\n");
8693 ok(format->videoInfo.InterlaceMode == MFVideoInterlace_Progressive, "Unexpected interlace mode %u.\n",
8694 format->videoInfo.InterlaceMode);
8695 ok(format->videoInfo.TransferFunction == transfer_function, "Unexpected transfer function %u.\n",
8696 format->videoInfo.TransferFunction);
8697 ok(format->videoInfo.ColorPrimaries == MFVideoPrimaries_BT709, "Unexpected color primaries %u.\n",
8698 format->videoInfo.ColorPrimaries);
8699 ok(format->videoInfo.TransferMatrix == MFVideoTransferMatrix_Unknown, "Unexpected transfer matrix.\n");
8700 ok(format->videoInfo.SourceLighting == MFVideoLighting_office, "Unexpected source lighting %u.\n",
8701 format->videoInfo.SourceLighting);
8702 ok(format->videoInfo.FramesPerSecond.Numerator == 60 &&
8703 format->videoInfo.FramesPerSecond.Denominator == 1, "Unexpected frame rate %lu/%lu.\n",
8704 format->videoInfo.FramesPerSecond.Numerator, format->videoInfo.FramesPerSecond.Denominator);
8705 ok(format->videoInfo.NominalRange == MFNominalRange_Normal, "Unexpected nominal range %u.\n",
8706 format->videoInfo.NominalRange);
8707 ok(format->videoInfo.GeometricAperture.Area.cx == width && format->videoInfo.GeometricAperture.Area.cy == height,
8708 "Unexpected geometric aperture.\n");
8709 ok(!memcmp(&format->videoInfo.GeometricAperture, &format->videoInfo.MinimumDisplayAperture, sizeof(MFVideoArea)),
8710 "Unexpected minimum display aperture.\n");
8711 ok(format->videoInfo.PanScanAperture.Area.cx == 0 && format->videoInfo.PanScanAperture.Area.cy == 0,
8712 "Unexpected geometric aperture.\n");
8713 ok(format->videoInfo.VideoFlags == 0, "Unexpected video flags.\n");
8714 ok(IsEqualGUID(&format->guidFormat, &guid), "Unexpected format guid %s.\n", wine_dbgstr_guid(&format->guidFormat));
8715 ok(format->compressedInfo.AvgBitrate == 0, "Unexpected bitrate.\n");
8716 ok(format->compressedInfo.AvgBitErrorRate == 0, "Unexpected error bitrate.\n");
8717 ok(format->compressedInfo.MaxKeyFrameSpacing == 0, "Unexpected MaxKeyFrameSpacing.\n");
8718 ok(format->surfaceInfo.Format == d3dformat, "Unexpected format %lu.\n", format->surfaceInfo.Format);
8719 ok(format->surfaceInfo.PaletteEntries == 0, "Unexpected palette size %lu.\n", format->surfaceInfo.PaletteEntries);
8722 static void test_MFInitVideoFormat_RGB(void)
8724 static const DWORD formats[] =
8726 0, /* same D3DFMT_X8R8G8B8 */
8727 D3DFMT_X8R8G8B8,
8728 D3DFMT_R8G8B8,
8729 D3DFMT_A8R8G8B8,
8730 D3DFMT_R5G6B5,
8731 D3DFMT_X1R5G5B5,
8732 D3DFMT_A2B10G10R10,
8733 D3DFMT_P8,
8734 D3DFMT_L8,
8735 D3DFMT_YUY2,
8736 D3DFMT_DXT1,
8737 D3DFMT_D16,
8738 D3DFMT_L16,
8739 D3DFMT_A16B16G16R16F,
8741 MFVIDEOFORMAT format;
8742 unsigned int i;
8743 HRESULT hr;
8745 if (!pMFInitVideoFormat_RGB)
8747 win_skip("MFInitVideoFormat_RGB is not available.\n");
8748 return;
8751 hr = pMFInitVideoFormat_RGB(NULL, 64, 32, 0);
8752 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8754 for (i = 0; i < ARRAY_SIZE(formats); ++i)
8756 memset(&format, 0, sizeof(format));
8757 hr = pMFInitVideoFormat_RGB(&format, 64, 32, formats[i]);
8758 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8759 if (SUCCEEDED(hr))
8760 check_video_format(&format, 64, 32, formats[i]);
8764 static void test_MFCreateVideoMediaTypeFromVideoInfoHeader(void)
8766 IMFVideoMediaType *media_type;
8767 KS_VIDEOINFOHEADER vih;
8768 UINT32 value32;
8769 UINT64 value64;
8770 HRESULT hr;
8771 GUID guid;
8773 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(NULL, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8774 todo_wine
8775 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8777 memset(&vih, 0, sizeof(vih));
8778 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8779 todo_wine
8780 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8781 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8782 todo_wine
8783 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8784 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8785 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8786 todo_wine
8787 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8789 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8790 vih.bmiHeader.biPlanes = 1;
8791 vih.bmiHeader.biWidth = 16;
8792 vih.bmiHeader.biHeight = 32;
8793 vih.bmiHeader.biBitCount = 32;
8795 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8796 MFVideoFlag_AnalogProtected, &GUID_NULL, &media_type);
8797 todo_wine
8798 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8799 if (FAILED(hr)) return;
8800 IMFVideoMediaType_Release(media_type);
8802 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8803 MFVideoFlag_AnalogProtected, NULL, &media_type);
8804 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8806 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8807 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8808 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8809 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8810 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8811 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8812 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8813 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8814 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8815 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8817 ok(value64 == ((UINT64)3 << 32 | 2), "Unexpected value %#I64x.\n", value64);
8818 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DRM_FLAGS, &value32);
8819 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8820 ok(value32 == MFVideoDRMFlag_AnalogProtected, "Unexpected value %#x.\n", value32);
8821 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8822 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8823 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8824 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8825 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8826 ok(value32 == 2048, "Unexpected value %u.\n", value32);
8827 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8828 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8829 ok(value32 == -64, "Unexpected value %d.\n", value32);
8830 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8831 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8832 ok(!!value32, "Unexpected value %#x.\n", value32);
8833 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8834 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8835 ok(!!value32, "Unexpected value %#x.\n", value32);
8837 IMFVideoMediaType_Release(media_type);
8839 /* Negative height. */
8840 vih.bmiHeader.biHeight = -32;
8841 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8842 MFVideoFlag_AnalogProtected, NULL, &media_type);
8843 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8844 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8845 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8846 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8847 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8848 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8849 ok(value32 == 64, "Unexpected value %d.\n", value32);
8850 IMFVideoMediaType_Release(media_type);
8853 static void test_MFInitMediaTypeFromVideoInfoHeader(void)
8855 IMFMediaType *media_type;
8856 VIDEOINFOHEADER vih;
8857 UINT32 value32;
8858 UINT64 value64;
8859 HRESULT hr;
8860 GUID guid;
8862 hr = MFCreateMediaType(&media_type);
8863 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8865 memset(&vih, 0, sizeof(vih));
8866 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, 0, NULL);
8867 todo_wine
8868 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8869 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8870 todo_wine
8871 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8873 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8874 vih.bmiHeader.biPlanes = 1;
8875 vih.bmiHeader.biWidth = 16;
8876 vih.bmiHeader.biHeight = 32;
8877 vih.bmiHeader.biBitCount = 32;
8879 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
8880 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8882 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8883 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8884 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8885 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8886 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8887 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
8888 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8889 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8890 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8891 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8892 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8893 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8894 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8895 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8896 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8898 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8899 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8900 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8901 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8902 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8903 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8904 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8905 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8907 vih.bmiHeader.biHeight = -32;
8908 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
8909 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8910 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8911 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8912 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8914 vih.bmiHeader.biHeight = 32;
8915 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8916 todo_wine
8917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8918 if (FAILED(hr)) goto failed;
8920 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8921 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8922 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8923 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8924 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8925 todo_wine
8926 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8927 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8928 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8929 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8930 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8932 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8933 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8934 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8935 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8936 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8937 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8938 ok(value32 == 2048, "Unexpected value %u.\n", value32);
8939 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8940 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8941 ok(value32 == -64, "Unexpected value %d.\n", value32);
8942 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8943 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8944 ok(!!value32, "Unexpected value %#x.\n", value32);
8945 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8946 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8947 ok(!!value32, "Unexpected value %#x.\n", value32);
8949 /* Negative height. */
8950 vih.bmiHeader.biHeight = -32;
8951 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8952 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8953 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8955 ok(value32 == 64, "Unexpected value %d.\n", value32);
8956 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8957 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8958 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8960 failed:
8961 IMFMediaType_Release(media_type);
8964 static void test_MFInitMediaTypeFromAMMediaType(void)
8966 IMFMediaType *media_type;
8967 AM_MEDIA_TYPE mt;
8968 UINT32 value32;
8969 UINT64 value64;
8970 HRESULT hr;
8971 GUID guid;
8972 VIDEOINFOHEADER vih =
8974 {0}, {0}, 0, 0, 0,
8975 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, 0xdeadbeef}
8977 static const struct guid_type_pair
8979 const GUID *am_type;
8980 const GUID *mf_type;
8981 } guid_types[] =
8983 { &MEDIASUBTYPE_I420, &MFVideoFormat_I420 },
8984 { &MEDIASUBTYPE_AYUV, &MFVideoFormat_AYUV },
8985 { &MEDIASUBTYPE_YV12, &MFVideoFormat_YV12 },
8986 { &MEDIASUBTYPE_YUY2, &MFVideoFormat_YUY2 },
8987 { &MEDIASUBTYPE_UYVY, &MFVideoFormat_UYVY },
8988 { &MEDIASUBTYPE_YVYU, &MFVideoFormat_YVYU },
8989 { &MEDIASUBTYPE_NV12, &MFVideoFormat_NV12 },
8990 { &MEDIASUBTYPE_ARGB32, &MFVideoFormat_ARGB32 },
8992 unsigned int i;
8994 hr = MFCreateMediaType(&media_type);
8995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8997 memset(&mt, 0, sizeof(mt));
8998 mt.majortype = MEDIATYPE_Video;
8999 mt.formattype = FORMAT_VideoInfo;
9000 mt.cbFormat = sizeof(VIDEOINFOHEADER);
9001 mt.pbFormat = (BYTE *)&vih;
9003 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, 123);
9004 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9006 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9007 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9009 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9010 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9011 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9012 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9013 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9014 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
9015 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9016 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9017 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9018 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9019 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9020 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9021 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9022 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9023 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9024 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9025 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9026 ok(!!value32, "Unexpected value %#x.\n", value32);
9028 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9029 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9030 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9031 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9032 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9033 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9035 vih.bmiHeader.biHeight = -24;
9037 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9038 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9039 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9040 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9041 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9043 memcpy(&mt.subtype, &MEDIASUBTYPE_RGB32, sizeof(GUID));
9044 vih.bmiHeader.biHeight = 24;
9046 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9047 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9049 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9050 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9051 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9052 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9053 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9054 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9055 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9056 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9057 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9058 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9059 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9060 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9061 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9062 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9063 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9064 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9065 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9066 ok(value32 == 3072, "Unexpected value %u.\n", value32);
9067 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9068 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9069 ok(!!value32, "Unexpected value %#x.\n", value32);
9070 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9071 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9072 ok(!!value32, "Unexpected value %u.\n", value32);
9073 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9074 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9075 ok(value32 == -128, "Unexpected value %d.\n", value32);
9077 /* Negative height. */
9078 vih.bmiHeader.biHeight = -24;
9080 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9081 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9083 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9084 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9085 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9086 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9087 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9088 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9089 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9090 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9091 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9092 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9093 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9094 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9095 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9096 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9097 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9098 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9100 ok(value32 == 3072, "Unexpected value %u.\n", value32);
9101 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9102 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9103 ok(!!value32, "Unexpected value %#x.\n", value32);
9104 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9105 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9106 ok(!!value32, "Unexpected value %u.\n", value32);
9107 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9108 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9109 ok(value32 == 128, "Unexpected value %d.\n", value32);
9111 vih.bmiHeader.biHeight = 24;
9112 for (i = 0; i < ARRAY_SIZE(guid_types); ++i)
9114 memcpy(&mt.subtype, guid_types[i].am_type, sizeof(GUID));
9116 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9119 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9120 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9121 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9122 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9123 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9124 ok(IsEqualGUID(&guid, guid_types[i].mf_type), "Unexpected guid %s.\n", debugstr_guid(&guid));
9127 IMFMediaType_Release(media_type);
9130 static void test_MFCreatePathFromURL(void)
9132 static const struct
9134 const WCHAR *url;
9135 const WCHAR *path;
9136 HRESULT hr;
9138 tests[] =
9140 /* 0 leading slash */
9141 { L"file:c:/foo/bar", L"c:\\foo\\bar" },
9142 { L"file:c|/foo/bar", L"c:\\foo\\bar" },
9143 { L"file:cx|/foo/bar", L"cx|\\foo\\bar" },
9144 { L"file:c:foo/bar", L"c:foo\\bar" },
9145 { L"file:c|foo/bar", L"c:foo\\bar" },
9146 { L"file:c:/foo%20ba%2fr", L"c:\\foo ba/r" },
9147 { L"file:foo%20ba%2fr", L"foo ba/r" },
9148 { L"file:foo/bar/", L"foo\\bar\\" },
9150 /* 1 leading (back)slash */
9151 { L"file:/c:/foo/bar", L"c:\\foo\\bar" },
9152 { L"file:\\c:/foo/bar", L"c:\\foo\\bar" },
9153 { L"file:/c|/foo/bar", L"c:\\foo\\bar" },
9154 { L"file:/cx|/foo/bar", L"\\cx|\\foo\\bar" },
9155 { L"file:/c:foo/bar", L"c:foo\\bar" },
9156 { L"file:/c|foo/bar", L"c:foo\\bar" },
9157 { L"file:/c:/foo%20ba%2fr", L"c:\\foo ba/r" },
9158 { L"file:/foo%20ba%2fr", L"\\foo ba/r" },
9159 { L"file:/foo/bar/", L"\\foo\\bar\\" },
9161 /* 2 leading (back)slashes */
9162 { L"file://c:/foo/bar", L"c:\\foo\\bar" },
9163 { L"file://c:/d:/foo/bar", L"c:\\d:\\foo\\bar" },
9164 { L"file://c|/d|/foo/bar", L"c:\\d|\\foo\\bar" },
9165 { L"file://cx|/foo/bar", L"\\\\cx|\\foo\\bar" },
9166 { L"file://c:foo/bar", L"c:foo\\bar" },
9167 { L"file://c|foo/bar", L"c:foo\\bar" },
9168 { L"file://c:/foo%20ba%2fr", L"c:\\foo%20ba%2fr" },
9169 { L"file://c%3a/foo/../bar", L"\\\\c:\\foo\\..\\bar" },
9170 { L"file://c%7c/foo/../bar", L"\\\\c|\\foo\\..\\bar" },
9171 { L"file://foo%20ba%2fr", L"\\\\foo ba/r" },
9172 { L"file://localhost/c:/foo/bar", L"c:\\foo\\bar" },
9173 { L"file://localhost/c:/foo%20ba%5Cr", L"c:\\foo ba\\r" },
9174 { L"file://LocalHost/c:/foo/bar", L"c:\\foo\\bar" },
9175 { L"file:\\\\localhost\\c:\\foo\\bar", L"c:\\foo\\bar" },
9176 { L"file://incomplete", L"\\\\incomplete" },
9178 /* 3 leading (back)slashes (omitting hostname) */
9179 { L"file:///c:/foo/bar", L"c:\\foo\\bar" },
9180 { L"File:///c:/foo/bar", L"c:\\foo\\bar" },
9181 { L"file:///c:/foo%20ba%2fr", L"c:\\foo ba/r" },
9182 { L"file:///foo%20ba%2fr", L"\\foo ba/r" },
9183 { L"file:///foo/bar/", L"\\foo\\bar\\" },
9184 { L"file:///localhost/c:/foo/bar", L"\\localhost\\c:\\foo\\bar" },
9186 /* 4 leading (back)slashes */
9187 { L"file:////c:/foo/bar", L"c:\\foo\\bar" },
9188 { L"file:////c:/foo%20ba%2fr", L"c:\\foo%20ba%2fr" },
9189 { L"file:////foo%20ba%2fr", L"\\\\foo%20ba%2fr" },
9191 /* 5 and more leading (back)slashes */
9192 { L"file://///c:/foo/bar", L"\\\\c:\\foo\\bar" },
9193 { L"file://///c:/foo%20ba%2fr", L"\\\\c:\\foo ba/r" },
9194 { L"file://///foo%20ba%2fr", L"\\\\foo ba/r" },
9195 { L"file://////c:/foo/bar", L"\\\\c:\\foo\\bar" },
9197 /* Leading (back)slashes cannot be escaped */
9198 { L"file:%2f%2flocalhost%2fc:/foo/bar", L"//localhost/c:\\foo\\bar" },
9199 { L"file:%5C%5Clocalhost%5Cc:/foo/bar", L"\\\\localhost\\c:\\foo\\bar" },
9201 /* Hostname handling */
9202 { L"file://l%6fcalhost/c:/foo/bar", L"\\\\localhostc:\\foo\\bar" },
9203 { L"file://localhost:80/c:/foo/bar", L"\\\\localhost:80c:\\foo\\bar" },
9204 { L"file://host/c:/foo/bar", L"\\\\hostc:\\foo\\bar" },
9205 { L"file://host//c:/foo/bar", L"\\\\host\\\\c:\\foo\\bar" },
9206 { L"file://host/\\c:/foo/bar", L"\\\\host\\\\c:\\foo\\bar" },
9207 { L"file://host/c:foo/bar", L"\\\\hostc:foo\\bar" },
9208 { L"file://host/foo/bar", L"\\\\host\\foo\\bar" },
9209 { L"file:\\\\host\\c:\\foo\\bar", L"\\\\hostc:\\foo\\bar" },
9210 { L"file:\\\\host\\ca\\foo\\bar", L"\\\\host\\ca\\foo\\bar" },
9211 { L"file:\\\\host\\c|\\foo\\bar", L"\\\\hostc|\\foo\\bar" },
9212 { L"file:\\%5Chost\\c:\\foo\\bar", L"\\\\host\\c:\\foo\\bar" },
9213 { L"file:\\\\host\\cx:\\foo\\bar", L"\\\\host\\cx:\\foo\\bar" },
9214 { L"file:///host/c:/foo/bar", L"\\host\\c:\\foo\\bar" },
9216 /* Not file URLs */
9217 { L"c:\\foo\\bar", NULL, E_INVALIDARG },
9218 { L"foo/bar", NULL, E_INVALIDARG },
9219 { L"http://foo/bar", NULL, E_INVALIDARG },
9221 unsigned int i;
9222 WCHAR *path;
9223 HRESULT hr;
9225 if (!pMFCreatePathFromURL)
9227 win_skip("MFCreatePathFromURL() is not available.\n");
9228 return;
9231 hr = pMFCreatePathFromURL(NULL, NULL);
9232 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
9234 path = (void *)0xdeadbeef;
9235 hr = pMFCreatePathFromURL(NULL, &path);
9236 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
9237 ok(path == (void *)0xdeadbeef, "Unexpected pointer %p.\n", path);
9239 hr = pMFCreatePathFromURL(L"file://foo", NULL);
9240 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
9242 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9244 hr = pMFCreatePathFromURL(tests[i].url, &path);
9245 ok(hr == tests[i].hr, "Unexpected hr %#lx, expected %#lx.\n", hr, tests[i].hr);
9246 if (SUCCEEDED(hr))
9248 ok(!wcscmp(path, tests[i].path), "Unexpected path %s, expected %s.\n",
9249 debugstr_w(path), debugstr_w(tests[i].path));
9250 CoTaskMemFree(path);
9255 START_TEST(mfplat)
9257 char **argv;
9258 int argc;
9260 init_functions();
9262 argc = winetest_get_mainargs(&argv);
9263 if (argc >= 3)
9265 test_queue_com_state(argv[2]);
9266 return;
9269 if (!pMFCreateVideoSampleAllocatorEx)
9270 win_skip("MFCreateVideoSampleAllocatorEx() is not available. Some tests will be skipped.\n");
9272 if (!pD3D12CreateDevice)
9273 skip("Missing d3d12 support, some tests will be skipped.\n");
9275 CoInitialize(NULL);
9277 test_startup();
9278 test_register();
9279 test_media_type();
9280 test_MFCreateMediaEvent();
9281 test_attributes();
9282 test_sample();
9283 test_file_stream();
9284 test_MFCreateMFByteStreamOnStream();
9285 test_system_memory_buffer();
9286 test_system_memory_aligned_buffer();
9287 test_source_resolver();
9288 test_MFCreateAsyncResult();
9289 test_allocate_queue();
9290 test_MFLockSharedWorkQueue();
9291 test_MFCopyImage();
9292 test_MFCreateCollection();
9293 test_MFHeapAlloc();
9294 test_scheduled_items();
9295 test_serial_queue();
9296 test_periodic_callback();
9297 test_event_queue();
9298 test_presentation_descriptor();
9299 test_system_time_source();
9300 test_MFInvokeCallback();
9301 test_stream_descriptor();
9302 test_MFCalculateImageSize();
9303 test_MFGetPlaneSize();
9304 test_MFCompareFullToPartialMediaType();
9305 test_attributes_serialization();
9306 test_wrapped_media_type();
9307 test_MFCreateWaveFormatExFromMFMediaType();
9308 test_async_create_file();
9309 test_local_handlers();
9310 test_create_property_store();
9311 test_dxgi_device_manager();
9312 test_MFCreateTransformActivate();
9313 test_MFTRegisterLocal();
9314 test_queue_com();
9315 test_MFGetStrideForBitmapInfoHeader();
9316 test_MFCreate2DMediaBuffer();
9317 test_MFCreateMediaBufferFromMediaType();
9318 test_MFInitMediaTypeFromWaveFormatEx();
9319 test_MFCreateMFVideoFormatFromMFMediaType();
9320 test_MFCreateDXSurfaceBuffer();
9321 test_MFCreateTrackedSample();
9322 test_MFFrameRateToAverageTimePerFrame();
9323 test_MFAverageTimePerFrameToFrameRate();
9324 test_MFMapDXGIFormatToDX9Format();
9325 test_d3d11_surface_buffer();
9326 test_d3d12_surface_buffer();
9327 test_sample_allocator_sysmem();
9328 test_sample_allocator_d3d9();
9329 test_sample_allocator_d3d11();
9330 test_sample_allocator_d3d12();
9331 test_MFMapDX9FormatToDXGIFormat();
9332 test_MFllMulDiv();
9333 test_shared_dxgi_device_manager();
9334 test_MFInitVideoFormat_RGB();
9335 test_MFCreateVideoMediaTypeFromVideoInfoHeader();
9336 test_MFInitMediaTypeFromVideoInfoHeader();
9337 test_MFInitMediaTypeFromAMMediaType();
9338 test_MFCreatePathFromURL();
9340 CoUninitialize();