mfplat/tests: Test IMF2DBuffer::ContiguousCopyTo().
[wine.git] / dlls / mfplat / tests / mfplat.c
blob6fc84f37e7de6acd77aa5776704df43e2fce23b8
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 *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
401 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
402 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
403 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
404 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
405 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
406 IMFMediaBuffer **buffer);
407 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
408 static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
409 static HRESULT (WINAPI *pMFLockDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
410 static HRESULT (WINAPI *pMFUnlockDXGIDeviceManager)(void);
411 static HRESULT (WINAPI *pMFInitVideoFormat_RGB)(MFVIDEOFORMAT *format, DWORD width, DWORD height, DWORD d3dformat);
413 static HWND create_window(void)
415 RECT r = {0, 0, 640, 480};
417 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
419 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
420 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
423 static IDirect3DDevice9 *create_d3d9_device(IDirect3D9 *d3d9, HWND focus_window)
425 D3DPRESENT_PARAMETERS present_parameters = {0};
426 IDirect3DDevice9 *device = NULL;
428 present_parameters.BackBufferWidth = 640;
429 present_parameters.BackBufferHeight = 480;
430 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
431 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
432 present_parameters.hDeviceWindow = focus_window;
433 present_parameters.Windowed = TRUE;
434 present_parameters.EnableAutoDepthStencil = TRUE;
435 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
436 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
438 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
439 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
441 return device;
444 static const WCHAR fileschemeW[] = L"file://";
446 static WCHAR *load_resource(const WCHAR *name)
448 static WCHAR pathW[MAX_PATH];
449 DWORD written;
450 HANDLE file;
451 HRSRC res;
452 void *ptr;
454 GetTempPathW(ARRAY_SIZE(pathW), pathW);
455 lstrcatW(pathW, name);
457 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
458 NULL, CREATE_ALWAYS, 0, 0);
459 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n",
460 wine_dbgstr_w(pathW), GetLastError());
462 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
463 ok(res != 0, "couldn't find resource\n");
464 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
465 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
466 &written, NULL);
467 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
468 "couldn't write resource\n" );
469 CloseHandle(file);
471 return pathW;
474 static BOOL is_MEDIASUBTYPE_RGB(const GUID *subtype)
476 return IsEqualGUID(subtype, &MEDIASUBTYPE_RGB8)
477 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB555)
478 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB565)
479 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB24)
480 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB32);
483 struct test_callback
485 IMFAsyncCallback IMFAsyncCallback_iface;
486 LONG refcount;
487 HANDLE event;
488 DWORD param;
489 IMFMediaEvent *media_event;
492 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
494 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
497 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
499 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
500 IsEqualIID(riid, &IID_IUnknown))
502 *obj = iface;
503 IMFAsyncCallback_AddRef(iface);
504 return S_OK;
507 *obj = NULL;
508 return E_NOINTERFACE;
511 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
513 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
514 return InterlockedIncrement(&callback->refcount);
517 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
519 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
520 ULONG refcount = InterlockedDecrement(&callback->refcount);
522 if (!refcount)
523 free(callback);
525 return refcount;
528 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
530 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
531 return E_NOTIMPL;
534 static BOOL check_clsid(CLSID *clsids, UINT32 count)
536 int i;
537 for (i = 0; i < count; i++)
539 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
540 return TRUE;
542 return FALSE;
545 static void test_register(void)
547 MFT_REGISTER_TYPE_INFO *in_types, *out_types;
548 WCHAR name[] = L"Wine test";
549 MFT_REGISTER_TYPE_INFO input[] =
551 { DUMMY_CLSID, DUMMY_GUID1 }
553 MFT_REGISTER_TYPE_INFO output[] =
555 { DUMMY_CLSID, DUMMY_GUID2 }
557 UINT32 count, in_count, out_count;
558 IMFAttributes *attributes;
559 WCHAR *mft_name;
560 CLSID *clsids;
561 HRESULT hr, ret;
563 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
564 if (ret == E_ACCESSDENIED)
566 win_skip("Not enough permissions to register a transform.\n");
567 return;
569 ok(ret == S_OK, "Failed to register dummy transform, hr %#lx.\n", ret);
571 if(0)
573 /* NULL name crashes on windows */
574 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
575 ok(ret == E_INVALIDARG, "Unexpected hr %#lx.\n", ret);
578 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
579 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
581 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
582 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
584 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
585 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
587 if(0)
589 /* NULL clsids/count crashes on windows (vista) */
590 count = 0;
591 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
592 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
593 ok(count == 0, "Expected count == 0\n");
595 clsids = NULL;
596 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
597 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
599 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, NULL, NULL, NULL, NULL, NULL);
600 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
601 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
602 CoTaskMemFree(mft_name);
604 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, NULL);
605 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
607 in_count = out_count = 1;
608 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, &in_count, NULL, &out_count, NULL);
609 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
610 ok(!in_count, "Unexpected count %u.\n", in_count);
611 ok(!out_count, "Unexpected count %u.\n", out_count);
613 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, &attributes);
614 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
615 ok(!!attributes, "Unexpected attributes.\n");
616 IMFAttributes_Release(attributes);
618 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, &in_types, &in_count, &out_types, &out_count, &attributes);
619 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
620 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
621 ok(!!in_types, "Unexpected pointer.\n");
622 ok(!!out_types, "Unexpected pointer.\n");
623 ok(in_count == 1, "Unexpected count %u.\n", in_count);
624 ok(out_count == 1, "Unexpected count %u.\n", out_count);
625 ok(IsEqualGUID(&in_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
626 wine_dbgstr_guid(&in_types->guidMajorType));
627 ok(IsEqualGUID(&in_types->guidSubtype, &DUMMY_GUID1), "Unexpected type guid %s.\n",
628 wine_dbgstr_guid(&in_types->guidSubtype));
629 ok(IsEqualGUID(&out_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
630 wine_dbgstr_guid(&out_types->guidMajorType));
631 ok(IsEqualGUID(&out_types->guidSubtype, &DUMMY_GUID2), "Unexpected type guid %s.\n",
632 wine_dbgstr_guid(&out_types->guidSubtype));
633 ok(!!attributes, "Unexpected attributes.\n");
634 count = 1;
635 hr = IMFAttributes_GetCount(attributes, &count);
636 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
637 ok(!count, "Unexpected count %u.\n", count);
638 CoTaskMemFree(mft_name);
639 CoTaskMemFree(in_types);
640 CoTaskMemFree(out_types);
641 IMFAttributes_Release(attributes);
643 count = 0;
644 clsids = NULL;
645 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
646 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
647 ok(count > 0, "Expected count > 0\n");
648 ok(clsids != NULL, "Expected clsids != NULL\n");
649 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
650 CoTaskMemFree(clsids);
652 count = 0;
653 clsids = NULL;
654 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
655 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
656 ok(count > 0, "Expected count > 0\n");
657 ok(clsids != NULL, "Expected clsids != NULL\n");
658 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
659 CoTaskMemFree(clsids);
661 count = 0;
662 clsids = NULL;
663 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
664 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
665 ok(count > 0, "Expected count > 0\n");
666 ok(clsids != NULL, "Expected clsids != NULL\n");
667 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
668 CoTaskMemFree(clsids);
670 count = 0;
671 clsids = NULL;
672 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
673 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
674 ok(count > 0, "Expected count > 0\n");
675 ok(clsids != NULL, "Expected clsids != NULL\n");
676 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
677 CoTaskMemFree(clsids);
679 /* exchange input and output */
680 count = 0;
681 clsids = NULL;
682 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
683 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
684 ok(!count, "got %d\n", count);
685 ok(clsids == NULL, "Expected clsids == NULL\n");
687 ret = MFTUnregister(DUMMY_CLSID);
688 ok(ret == S_OK ||
689 /* w7pro64 */
690 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
692 ret = MFTUnregister(DUMMY_CLSID);
693 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
696 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
698 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
699 IMFSourceResolver *resolver;
700 IUnknown *object, *object2;
701 MF_OBJECT_TYPE obj_type;
702 HRESULT hr;
704 ok(!!result, "Unexpected result object.\n");
706 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
708 object = NULL;
709 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
710 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
712 hr = IMFAsyncResult_GetObject(result, &object2);
713 ok(hr == S_OK, "Failed to get result object, hr %#lx.\n", hr);
714 ok(object2 == object, "Unexpected object.\n");
716 if (object)
717 IUnknown_Release(object);
718 IUnknown_Release(object2);
720 SetEvent(callback->event);
722 return S_OK;
725 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
727 testcallback_QueryInterface,
728 testcallback_AddRef,
729 testcallback_Release,
730 testcallback_GetParameters,
731 test_create_from_url_callback_Invoke,
734 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
736 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
737 IMFSchemeHandler *handler;
738 IUnknown *object, *object2;
739 MF_OBJECT_TYPE obj_type;
740 HRESULT hr;
742 ok(!!result, "Unexpected result object.\n");
744 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
746 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
747 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
749 if (SUCCEEDED(hr))
751 hr = IMFAsyncResult_GetObject(result, &object2);
752 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
754 IUnknown_Release(object);
757 SetEvent(callback->event);
759 return S_OK;
762 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
764 testcallback_QueryInterface,
765 testcallback_AddRef,
766 testcallback_Release,
767 testcallback_GetParameters,
768 test_create_from_file_handler_callback_Invoke,
771 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
773 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
774 IMFMediaEventGenerator *generator;
775 HRESULT hr;
777 ok(!!result, "Unexpected result object.\n");
779 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
781 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
782 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
784 SetEvent(callback->event);
786 return S_OK;
789 static const IMFAsyncCallbackVtbl events_callback_vtbl =
791 testcallback_QueryInterface,
792 testcallback_AddRef,
793 testcallback_Release,
794 testcallback_GetParameters,
795 source_events_callback_Invoke,
798 static const IMFAsyncCallbackVtbl testcallbackvtbl;
800 static struct test_callback * create_test_callback(const IMFAsyncCallbackVtbl *vtbl)
802 struct test_callback *callback = calloc(1, sizeof(*callback));
804 callback->IMFAsyncCallback_iface.lpVtbl = vtbl ? vtbl : &testcallbackvtbl;
805 callback->refcount = 1;
807 return callback;
810 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
812 struct test_callback *callback;
813 MediaEventType event_type;
814 BOOL ret = FALSE;
815 HRESULT hr;
817 callback = create_test_callback(&events_callback_vtbl);
818 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
820 for (;;)
822 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback->IMFAsyncCallback_iface,
823 (IUnknown *)generator);
824 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
826 if (WaitForSingleObject(callback->event, 1000) == WAIT_TIMEOUT)
828 ok(0, "timeout\n");
829 break;
832 Sleep(10);
834 hr = IMFMediaEvent_GetType(callback->media_event, &event_type);
835 ok(hr == S_OK, "Failed to event type, hr %#lx.\n", hr);
837 if ((ret = (event_type == expected_event_type)))
839 if (value)
841 hr = IMFMediaEvent_GetValue(callback->media_event, value);
842 ok(hr == S_OK, "Failed to get value of event, hr %#lx.\n", hr);
845 break;
849 CloseHandle(callback->event);
850 if (callback->media_event)
851 IMFMediaEvent_Release(callback->media_event);
852 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
854 return ret;
857 static const IMFByteStreamVtbl *bytestream_vtbl_orig;
859 static int bytestream_closed = 0;
860 static HRESULT WINAPI bytestream_wrapper_Close(IMFByteStream *iface)
862 bytestream_closed = 1;
863 return bytestream_vtbl_orig->Close(iface);
866 static void test_source_resolver(void)
868 struct test_callback *callback, *callback2;
869 IMFByteStreamVtbl bytestream_vtbl_wrapper;
870 IMFSourceResolver *resolver, *resolver2;
871 IMFPresentationDescriptor *descriptor;
872 IMFSchemeHandler *scheme_handler;
873 IMFMediaStream *video_stream;
874 IMFAttributes *attributes;
875 IMFMediaSource *mediasource;
876 IMFMediaTypeHandler *handler;
877 IMFMediaType *media_type;
878 BOOL selected, do_uninit;
879 MF_OBJECT_TYPE obj_type;
880 IMFStreamDescriptor *sd;
881 IUnknown *cancel_cookie;
882 IMFByteStream *stream;
883 IMFGetService *get_service;
884 IMFRateSupport *rate_support;
885 WCHAR pathW[MAX_PATH];
886 int i, sample_count;
887 WCHAR *filename;
888 PROPVARIANT var;
889 HRESULT hr;
890 GUID guid;
891 float rate;
892 UINT32 rotation;
894 if (!pMFCreateSourceResolver)
896 win_skip("MFCreateSourceResolver() not found\n");
897 return;
900 callback = create_test_callback(&test_create_from_url_callback_vtbl);
901 callback2 = create_test_callback(&test_create_from_file_handler_callback_vtbl);
903 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
904 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
906 hr = pMFCreateSourceResolver(NULL);
907 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
909 hr = pMFCreateSourceResolver(&resolver);
910 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
912 hr = pMFCreateSourceResolver(&resolver2);
913 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
914 ok(resolver != resolver2, "Expected new instance\n");
916 IMFSourceResolver_Release(resolver2);
918 filename = load_resource(L"test.mp4");
920 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
921 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
923 hr = IMFSourceResolver_CreateObjectFromByteStream(
924 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
925 &obj_type, (IUnknown **)&mediasource);
926 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
928 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
929 NULL, (IUnknown **)&mediasource);
930 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
932 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
933 &obj_type, NULL);
934 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
936 IMFByteStream_Release(stream);
938 /* Create from URL. */
939 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
941 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
942 (IUnknown **)&stream);
943 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
945 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
946 (IUnknown **)&stream);
947 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
948 IMFByteStream_Release(stream);
950 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
951 &cancel_cookie, &callback->IMFAsyncCallback_iface, (IUnknown *)resolver);
952 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
953 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
954 IUnknown_Release(cancel_cookie);
956 if (SUCCEEDED(hr))
957 WaitForSingleObject(callback->event, INFINITE);
959 /* With explicit scheme. */
960 lstrcpyW(pathW, fileschemeW);
961 lstrcatW(pathW, filename);
963 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
964 (IUnknown **)&stream);
965 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
966 IMFByteStream_Release(stream);
968 /* We have to create a new bytestream here, because all following
969 * calls to CreateObjectFromByteStream will fail. */
970 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
971 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
973 /* Wrap ::Close to test when the media source calls it */
974 bytestream_vtbl_orig = stream->lpVtbl;
975 bytestream_vtbl_wrapper = *bytestream_vtbl_orig;
976 bytestream_vtbl_wrapper.Close = bytestream_wrapper_Close;
977 stream->lpVtbl = &bytestream_vtbl_wrapper;
979 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
980 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
981 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
982 ok(hr == S_OK, "Failed to set string value, hr %#lx.\n", hr);
983 IMFAttributes_Release(attributes);
985 /* Start of gstreamer dependent tests */
987 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
988 &obj_type, (IUnknown **)&mediasource);
989 if (strcmp(winetest_platform, "wine"))
990 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
991 if (FAILED(hr))
993 IMFByteStream_Release(stream);
994 IMFSourceResolver_Release(resolver);
996 hr = MFShutdown();
997 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
999 DeleteFileW(filename);
1000 return;
1002 ok(mediasource != NULL, "got %p\n", mediasource);
1003 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
1005 check_interface(mediasource, &IID_IMFGetService, TRUE);
1006 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
1008 hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service);
1009 ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
1011 hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support);
1012 ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
1014 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1015 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1016 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
1017 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1018 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1019 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
1020 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1021 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1022 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
1023 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1024 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1025 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
1027 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1028 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1029 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1030 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1031 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1032 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1033 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1034 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1035 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1036 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1037 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1038 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1040 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, NULL);
1041 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1042 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, &rate);
1043 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1044 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1046 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1.0f, &rate);
1047 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1048 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1049 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1.0f, &rate);
1050 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1051 ok(rate == -1.0f, "Unexpected rate %f.\n", rate);
1052 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1e6f + 1.0f, &rate);
1053 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
1054 ok(rate == 1e6f + 1.0f || broken(rate == 1e6f) /* Win7 */, "Unexpected %f.\n", rate);
1055 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f, &rate);
1056 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1057 ok(rate == -1e6f, "Unexpected rate %f.\n", rate);
1059 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f - 1.0f, &rate);
1060 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
1061 ok(rate == -1e6f - 1.0f || broken(rate == -1e6f) /* Win7 */, "Unexpected rate %f.\n", rate);
1063 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
1064 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
1065 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#lx.\n", hr);
1066 ok(descriptor != NULL, "got %p\n", descriptor);
1068 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
1069 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
1071 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
1072 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
1073 IMFStreamDescriptor_Release(sd);
1075 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
1076 ok(hr == S_OK, "Failed to get stream major type, hr %#lx.\n", hr);
1078 /* Check major/minor type for the test media. */
1079 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
1081 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
1082 ok(hr == S_OK, "Failed to get current media type, hr %#lx.\n", hr);
1083 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
1084 ok(hr == S_OK, "Failed to get media sub type, hr %#lx.\n", hr);
1085 todo_wine
1086 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
1088 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_ROTATION, &rotation);
1089 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Win7 */, "Failed to get rotation, hr %#lx.\n", hr);
1090 if (hr == S_OK)
1091 ok(rotation == MFVideoRotationFormat_0, "Got wrong rotation %u.\n", rotation);
1093 IMFMediaType_Release(media_type);
1095 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
1096 ok(hr == S_OK, "Failed to select video stream, hr %#lx.\n", hr);
1098 var.vt = VT_EMPTY;
1099 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1100 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1102 video_stream = NULL;
1103 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
1105 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
1106 video_stream = (IMFMediaStream *)var.punkVal;
1109 hr = IMFMediaSource_Pause(mediasource);
1110 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1111 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
1112 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1114 var.vt = VT_EMPTY;
1115 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1116 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1118 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
1119 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1121 hr = IMFMediaSource_Pause(mediasource);
1122 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1123 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
1124 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1126 var.vt = VT_I8;
1127 var.uhVal.QuadPart = 0;
1128 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1129 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1131 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceSeeked, &var))
1132 ok(var.vt == VT_I8, "Unexpected value type.\n");
1134 hr = IMFMediaSource_Stop(mediasource);
1135 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1136 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStopped, &var))
1137 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1139 var.vt = VT_I8;
1140 var.uhVal.QuadPart = 0;
1141 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1142 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1144 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
1145 ok(var.vt == VT_I8, "Unexpected value type.\n");
1147 sample_count = 10;
1149 for (i = 0; i < sample_count; ++i)
1151 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1152 ok(hr == S_OK, "Failed to request sample %u, hr %#lx.\n", i + 1, hr);
1153 if (hr != S_OK)
1154 break;
1157 for (i = 0; i < sample_count; ++i)
1159 static const LONGLONG MILLI_TO_100_NANO = 10000;
1160 LONGLONG duration, time;
1161 DWORD buffer_count;
1162 IMFSample *sample;
1163 BOOL ret;
1165 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
1166 ok(ret, "Sample %u not received.\n", i + 1);
1167 if (!ret)
1168 break;
1170 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
1171 sample = (IMFSample *)var.punkVal;
1173 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1174 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1175 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
1177 hr = IMFSample_GetSampleDuration(sample, &duration);
1178 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
1179 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
1181 hr = IMFSample_GetSampleTime(sample, &time);
1182 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
1183 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
1185 IMFSample_Release(sample);
1188 if (i == sample_count)
1190 IMFMediaEvent *event;
1192 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
1193 Sleep(100);
1194 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
1195 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
1197 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1198 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1199 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
1203 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1204 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1206 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
1208 IMFMediaStream_Release(video_stream);
1209 IMFMediaTypeHandler_Release(handler);
1210 IMFPresentationDescriptor_Release(descriptor);
1212 ok(!bytestream_closed, "IMFByteStream::Close called unexpectedly\n");
1214 hr = IMFMediaSource_Shutdown(mediasource);
1215 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1217 ok(bytestream_closed, "Missing IMFByteStream::Close call\n");
1219 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
1220 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
1222 IMFRateSupport_Release(rate_support);
1223 IMFGetService_Release(get_service);
1224 IMFMediaSource_Release(mediasource);
1225 IMFByteStream_Release(stream);
1227 /* Create directly through scheme handler. */
1228 hr = CoInitialize(NULL);
1229 ok(SUCCEEDED(hr), "Failed to initialize, hr %#lx.\n", hr);
1230 do_uninit = hr == S_OK;
1232 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
1233 (void **)&scheme_handler);
1234 ok(hr == S_OK, "Failed to create handler object, hr %#lx.\n", hr);
1236 callback2->event = callback->event;
1237 cancel_cookie = NULL;
1238 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
1239 &callback2->IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
1240 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
1241 ok(!!cancel_cookie, "Unexpected cancel object.\n");
1242 IUnknown_Release(cancel_cookie);
1244 WaitForSingleObject(callback2->event, INFINITE);
1246 IMFSchemeHandler_Release(scheme_handler);
1248 if (do_uninit)
1249 CoUninitialize();
1251 CloseHandle(callback->event);
1253 IMFSourceResolver_Release(resolver);
1255 hr = MFShutdown();
1256 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
1258 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
1259 IMFAsyncCallback_Release(&callback2->IMFAsyncCallback_iface);
1261 DeleteFileW(filename);
1264 static void init_functions(void)
1266 HMODULE mod = GetModuleHandleA("mfplat.dll");
1268 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
1269 X(MFAddPeriodicCallback);
1270 X(MFAllocateSerialWorkQueue);
1271 X(MFAllocateWorkQueueEx);
1272 X(MFCopyImage);
1273 X(MFCreate2DMediaBuffer);
1274 X(MFCreateDXGIDeviceManager);
1275 X(MFCreateDXGISurfaceBuffer);
1276 X(MFCreateDXSurfaceBuffer);
1277 X(MFCreateSourceResolver);
1278 X(MFCreateMediaBufferFromMediaType);
1279 X(MFCreateMFByteStreamOnStream);
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 U(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 U(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 U(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 U(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 U(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 U(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 U(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 U(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 U(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 U(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 U(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 U(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 BYTE dest[16], src[16];
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(dest, 8, src, 8, 4, 1);
3158 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3159 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
3161 memset(dest, 0xaa, sizeof(dest));
3162 memset(src, 0x11, sizeof(src));
3164 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
3165 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3166 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3168 memset(dest, 0xaa, sizeof(dest));
3169 memset(src, 0x11, sizeof(src));
3171 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
3172 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3173 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3176 static void test_MFCreateCollection(void)
3178 IMFCollection *collection;
3179 IUnknown *element;
3180 DWORD count;
3181 HRESULT hr;
3183 hr = MFCreateCollection(NULL);
3184 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3186 hr = MFCreateCollection(&collection);
3187 ok(hr == S_OK, "Failed to create collection, hr %#lx.\n", hr);
3189 hr = IMFCollection_GetElementCount(collection, NULL);
3190 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3192 count = 1;
3193 hr = IMFCollection_GetElementCount(collection, &count);
3194 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3195 ok(count == 0, "Unexpected count %lu.\n", count);
3197 hr = IMFCollection_GetElement(collection, 0, NULL);
3198 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3200 element = (void *)0xdeadbeef;
3201 hr = IMFCollection_GetElement(collection, 0, &element);
3202 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3203 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3205 hr = IMFCollection_RemoveElement(collection, 0, NULL);
3206 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3208 element = (void *)0xdeadbeef;
3209 hr = IMFCollection_RemoveElement(collection, 0, &element);
3210 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#lx.\n", hr);
3211 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3213 hr = IMFCollection_RemoveAllElements(collection);
3214 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3216 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
3217 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3219 count = 0;
3220 hr = IMFCollection_GetElementCount(collection, &count);
3221 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3222 ok(count == 1, "Unexpected count %lu.\n", count);
3224 hr = IMFCollection_AddElement(collection, NULL);
3225 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3227 count = 0;
3228 hr = IMFCollection_GetElementCount(collection, &count);
3229 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3230 ok(count == 2, "Unexpected count %lu.\n", count);
3232 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
3233 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3235 count = 0;
3236 hr = IMFCollection_GetElementCount(collection, &count);
3237 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3238 ok(count == 11, "Unexpected count %lu.\n", count);
3240 hr = IMFCollection_GetElement(collection, 0, &element);
3241 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3242 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3243 IUnknown_Release(element);
3245 hr = IMFCollection_GetElement(collection, 1, &element);
3246 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3247 ok(!element, "Unexpected element.\n");
3249 hr = IMFCollection_GetElement(collection, 2, &element);
3250 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3251 ok(!element, "Unexpected element.\n");
3253 hr = IMFCollection_GetElement(collection, 10, &element);
3254 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3255 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3256 IUnknown_Release(element);
3258 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3259 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3261 hr = IMFCollection_GetElement(collection, 0, &element);
3262 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3264 hr = IMFCollection_RemoveAllElements(collection);
3265 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3267 count = 1;
3268 hr = IMFCollection_GetElementCount(collection, &count);
3269 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3270 ok(count == 0, "Unexpected count %lu.\n", count);
3272 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3273 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3275 IMFCollection_Release(collection);
3278 static void test_MFHeapAlloc(void)
3280 void *res;
3282 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
3283 ok(res != NULL, "MFHeapAlloc failed.\n");
3285 MFHeapFree(res);
3288 static void test_scheduled_items(void)
3290 struct test_callback *callback;
3291 IMFAsyncResult *result;
3292 MFWORKITEM_KEY key, key2;
3293 HRESULT hr;
3295 callback = create_test_callback(NULL);
3297 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3298 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3300 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3301 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3303 hr = MFCancelWorkItem(key);
3304 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3306 hr = MFCancelWorkItem(key);
3307 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#lx.\n", hr);
3309 if (!pMFPutWaitingWorkItem)
3311 win_skip("Waiting items are not supported.\n");
3312 return;
3315 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3316 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3318 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
3319 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3321 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
3322 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3324 hr = MFCancelWorkItem(key);
3325 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3327 hr = MFCancelWorkItem(key2);
3328 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3330 IMFAsyncResult_Release(result);
3332 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3333 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3335 hr = MFCancelWorkItem(key);
3336 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3338 hr = MFShutdown();
3339 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3341 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3344 static void test_serial_queue(void)
3346 static const DWORD queue_ids[] =
3348 MFASYNC_CALLBACK_QUEUE_STANDARD,
3349 MFASYNC_CALLBACK_QUEUE_RT,
3350 MFASYNC_CALLBACK_QUEUE_IO,
3351 MFASYNC_CALLBACK_QUEUE_TIMER,
3352 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
3353 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
3355 DWORD queue, serial_queue;
3356 unsigned int i;
3357 HRESULT hr;
3359 if (!pMFAllocateSerialWorkQueue)
3361 win_skip("Serial queues are not supported.\n");
3362 return;
3365 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3366 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3368 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
3370 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
3371 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
3373 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
3374 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
3375 "%u: failed to allocate a queue, hr %#lx.\n", i, hr);
3377 if (SUCCEEDED(hr))
3379 hr = MFUnlockWorkQueue(serial_queue);
3380 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#lx.\n", i, hr);
3384 /* Chain them together. */
3385 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
3386 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3388 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
3389 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3391 hr = MFUnlockWorkQueue(serial_queue);
3392 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3394 hr = MFUnlockWorkQueue(queue);
3395 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3397 hr = MFShutdown();
3398 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3401 static LONG periodic_counter;
3402 static void CALLBACK periodic_callback(IUnknown *context)
3404 InterlockedIncrement(&periodic_counter);
3407 static void test_periodic_callback(void)
3409 DWORD period, key;
3410 HRESULT hr;
3412 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3413 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3415 period = 0;
3416 hr = MFGetTimerPeriodicity(&period);
3417 ok(hr == S_OK, "Failed to get timer perdiod, hr %#lx.\n", hr);
3418 ok(period == 10, "Unexpected period %lu.\n", period);
3420 if (!pMFAddPeriodicCallback)
3422 win_skip("Periodic callbacks are not supported.\n");
3423 hr = MFShutdown();
3424 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3425 return;
3428 ok(periodic_counter == 0, "Unexpected counter value %lu.\n", periodic_counter);
3430 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
3431 ok(hr == S_OK, "Failed to add periodic callback, hr %#lx.\n", hr);
3432 ok(key != 0, "Unexpected key %#lx.\n", key);
3434 Sleep(10 * period);
3436 hr = pMFRemovePeriodicCallback(key);
3437 ok(hr == S_OK, "Failed to remove callback, hr %#lx.\n", hr);
3439 ok(periodic_counter > 0, "Unexpected counter value %lu.\n", periodic_counter);
3441 hr = MFShutdown();
3442 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3445 static void test_event_queue(void)
3447 struct test_callback *callback, *callback2;
3448 IMFMediaEvent *event, *event2;
3449 IMFMediaEventQueue *queue;
3450 IMFAsyncResult *result;
3451 HRESULT hr;
3452 DWORD ret;
3454 callback = create_test_callback(NULL);
3455 callback2 = create_test_callback(NULL);
3457 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3458 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3460 hr = MFCreateEventQueue(&queue);
3461 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3463 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3464 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
3466 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3467 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3469 if (is_win8_plus)
3471 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3472 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3474 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3475 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3476 ok(event2 == event, "Unexpected event object.\n");
3477 IMFMediaEvent_Release(event2);
3479 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3480 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3482 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3483 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3484 IMFMediaEvent_Release(event2);
3487 /* Async case. */
3488 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3489 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3491 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3492 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3494 /* Same callback, same state. */
3495 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3496 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3498 /* Same callback, different state. */
3499 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3500 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3502 /* Different callback, same state. */
3503 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)queue);
3504 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3506 /* Different callback, different state. */
3507 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3508 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3510 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
3512 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3513 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3515 ret = WaitForSingleObject(callback->event, 500);
3516 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#lx.\n", ret);
3518 CloseHandle(callback->event);
3520 IMFMediaEvent_Release(event);
3522 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3523 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3525 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3526 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3528 /* Shutdown behavior. */
3529 hr = IMFMediaEventQueue_Shutdown(queue);
3530 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3532 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3533 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3535 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3536 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3537 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3538 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3539 IMFMediaEvent_Release(event);
3541 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3542 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3544 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3545 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3547 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3548 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3550 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3551 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3553 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3554 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3555 IMFAsyncResult_Release(result);
3557 /* Already shut down. */
3558 hr = IMFMediaEventQueue_Shutdown(queue);
3559 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3561 IMFMediaEventQueue_Release(queue);
3562 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3564 /* Release while subscribed. */
3565 callback = create_test_callback(NULL);
3567 hr = MFCreateEventQueue(&queue);
3568 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3570 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3571 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3572 EXPECT_REF(&callback->IMFAsyncCallback_iface, 2);
3574 IMFMediaEventQueue_Release(queue);
3575 ret = get_refcount(&callback->IMFAsyncCallback_iface);
3576 ok(ret == 1 || broken(ret == 2) /* Vista */,
3577 "Unexpected refcount %ld, expected 1.\n", ret);
3578 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3580 hr = MFShutdown();
3581 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3584 static void test_presentation_descriptor(void)
3586 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3587 IMFPresentationDescriptor *pd, *pd2;
3588 IMFMediaType *media_type;
3589 unsigned int i;
3590 BOOL selected;
3591 UINT64 value;
3592 DWORD count;
3593 HRESULT hr;
3595 hr = MFCreateMediaType(&media_type);
3596 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
3598 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3600 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3601 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3604 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3605 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr);
3607 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3608 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %lu.\n", count);
3610 for (i = 0; i < count; ++i)
3612 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3613 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3614 ok(!selected, "Unexpected selected state.\n");
3615 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3616 IMFStreamDescriptor_Release(stream_desc2);
3619 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3620 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3622 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3623 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3625 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3626 ok(hr == S_OK, "Failed to select a stream, hr %#lx.\n", hr);
3628 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3629 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3630 ok(!!selected, "Unexpected selected state.\n");
3631 IMFStreamDescriptor_Release(stream_desc2);
3633 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3634 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
3636 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3637 ok(hr == S_OK, "Failed to clone, hr %#lx.\n", hr);
3639 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 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 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3643 IMFStreamDescriptor_Release(stream_desc2);
3645 value = 0;
3646 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3647 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
3648 ok(value == 1, "Unexpected attribute value.\n");
3650 IMFPresentationDescriptor_Release(pd2);
3651 IMFPresentationDescriptor_Release(pd);
3653 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3655 IMFStreamDescriptor_Release(stream_desc[i]);
3658 /* Partially initialized array. */
3659 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3660 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3661 stream_desc[0] = NULL;
3663 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3664 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3666 IMFStreamDescriptor_Release(stream_desc[1]);
3667 IMFMediaType_Release(media_type);
3670 enum clock_action
3672 CLOCK_START,
3673 CLOCK_STOP,
3674 CLOCK_PAUSE,
3675 CLOCK_RESTART,
3678 static void test_system_time_source(void)
3680 static const struct clock_state_test
3682 enum clock_action action;
3683 MFCLOCK_STATE state;
3684 BOOL is_invalid;
3686 clock_state_change[] =
3688 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3689 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3690 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3691 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3692 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3693 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3694 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3695 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3696 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3697 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3698 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3699 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3700 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3701 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3702 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3703 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3704 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3706 IMFPresentationTimeSource *time_source, *time_source2;
3707 IMFClockStateSink *statesink;
3708 IMFClock *clock, *clock2;
3709 MFCLOCK_PROPERTIES props;
3710 MFCLOCK_STATE state;
3711 unsigned int i;
3712 MFTIME systime;
3713 LONGLONG time;
3714 DWORD value;
3715 HRESULT hr;
3717 hr = MFCreateSystemTimeSource(&time_source);
3718 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3720 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3721 ok(hr == S_OK, "Failed to get flags, hr %#lx.\n", hr);
3722 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3723 "Unexpected flags %#lx.\n", value);
3725 value = 1;
3726 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3728 ok(value == 0, "Unexpected value %lu.\n", value);
3730 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3731 ok(hr == S_OK, "Failed to get state, hr %#lx.\n", hr);
3732 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3734 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3735 ok(hr == S_OK, "Failed to get state sink, hr %#lx.\n", hr);
3737 /* State changes. */
3738 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3740 switch (clock_state_change[i].action)
3742 case CLOCK_STOP:
3743 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3744 break;
3745 case CLOCK_RESTART:
3746 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3747 break;
3748 case CLOCK_PAUSE:
3749 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3750 break;
3751 case CLOCK_START:
3752 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3753 break;
3754 default:
3757 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#lx.\n", i, hr);
3758 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3759 ok(hr == S_OK, "%u: failed to get state, hr %#lx.\n", i, hr);
3760 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3763 IMFClockStateSink_Release(statesink);
3765 /* Properties. */
3766 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3767 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3769 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3770 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3772 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3773 wine_dbgstr_longlong(props.qwCorrelationRate));
3774 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3775 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3776 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3777 wine_dbgstr_longlong(props.qwClockFrequency));
3778 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3779 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3781 /* Underlying clock. */
3782 hr = MFCreateSystemTimeSource(&time_source2);
3783 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3784 EXPECT_REF(time_source2, 1);
3785 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3786 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3787 EXPECT_REF(time_source2, 1);
3788 EXPECT_REF(clock2, 2);
3790 EXPECT_REF(time_source, 1);
3791 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3792 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3793 EXPECT_REF(time_source, 1);
3794 EXPECT_REF(clock, 2);
3796 ok(clock != clock2, "Unexpected clock instance.\n");
3798 IMFPresentationTimeSource_Release(time_source2);
3799 IMFClock_Release(clock2);
3801 hr = IMFClock_GetClockCharacteristics(clock, &value);
3802 ok(hr == S_OK, "Failed to get clock flags, hr %#lx.\n", hr);
3803 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3804 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#lx.\n", value);
3806 hr = IMFClock_GetContinuityKey(clock, &value);
3807 ok(hr == S_OK, "Failed to get clock key, hr %#lx.\n", hr);
3808 ok(value == 0, "Unexpected key value %lu.\n", value);
3810 hr = IMFClock_GetState(clock, 0, &state);
3811 ok(hr == S_OK, "Failed to get clock state, hr %#lx.\n", hr);
3812 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3814 hr = IMFClock_GetProperties(clock, &props);
3815 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3817 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3818 wine_dbgstr_longlong(props.qwCorrelationRate));
3819 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3820 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3821 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3822 wine_dbgstr_longlong(props.qwClockFrequency));
3823 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3824 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3826 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3827 ok(hr == S_OK, "Failed to get clock time, hr %#lx.\n", hr);
3828 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3830 IMFClock_Release(clock);
3832 /* Test returned time regarding specified rate and offset. */
3833 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3834 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3836 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3837 ok(hr == S_OK, "Failed to get state %#lx.\n", hr);
3838 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3840 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3841 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3842 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3844 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3845 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3847 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3848 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3849 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3851 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3852 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3854 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3855 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3856 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3857 wine_dbgstr_longlong(systime));
3859 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3860 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3862 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3863 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3864 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3866 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3867 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3869 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3870 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3871 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3872 wine_dbgstr_longlong(systime));
3874 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3875 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3877 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3878 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3879 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3880 wine_dbgstr_longlong(systime));
3882 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3883 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3885 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3886 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3887 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3889 /* Increased rate. */
3890 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3891 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3893 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3894 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3896 hr = IMFClockStateSink_OnClockSetRate(statesink, 5, 2.0f);
3897 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3899 hr = IMFClockStateSink_OnClockPause(statesink, 6);
3900 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3902 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3903 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3904 ok(time == 12 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3905 wine_dbgstr_longlong(systime));
3907 hr = IMFClockStateSink_OnClockRestart(statesink, 7);
3908 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3910 hr = IMFClockStateSink_OnClockPause(statesink, 8);
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 == 14 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3916 wine_dbgstr_longlong(systime));
3918 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3919 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3921 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3922 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3923 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3924 wine_dbgstr_longlong(2 * systime));
3926 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3927 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3929 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3930 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3931 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3932 wine_dbgstr_longlong(2 * systime));
3934 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3935 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3937 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3938 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3939 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3940 wine_dbgstr_longlong(systime));
3942 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3943 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3945 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3946 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3947 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3948 wine_dbgstr_longlong(systime));
3950 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3951 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3953 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3954 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3955 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3956 wine_dbgstr_longlong(systime));
3958 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3959 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3961 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3962 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3963 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3965 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3966 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3968 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3969 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3970 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3971 wine_dbgstr_longlong(2 * systime));
3973 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3974 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3976 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
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, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3982 wine_dbgstr_longlong(2 * systime));
3984 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3985 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3987 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3988 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3989 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3990 wine_dbgstr_longlong(systime));
3992 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3993 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3995 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3996 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3997 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3998 wine_dbgstr_longlong(systime));
4000 hr = IMFClockStateSink_OnClockPause(statesink, 0);
4001 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4003 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4004 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4005 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4006 wine_dbgstr_longlong(systime));
4008 IMFClockStateSink_Release(statesink);
4009 IMFPresentationTimeSource_Release(time_source);
4011 /* PRESENTATION_CURRENT_POSITION */
4012 hr = MFCreateSystemTimeSource(&time_source);
4013 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
4015 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
4016 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
4018 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4019 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4020 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4021 wine_dbgstr_longlong(systime));
4023 /* INVALID -> RUNNING */
4024 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
4025 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4027 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4028 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4029 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4030 wine_dbgstr_longlong(systime));
4032 /* RUNNING -> RUNNING */
4033 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
4034 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4036 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4037 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4038 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4039 wine_dbgstr_longlong(systime));
4041 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
4042 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4044 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4045 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4046 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4047 wine_dbgstr_longlong(systime));
4049 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
4050 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4052 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4053 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4054 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4055 wine_dbgstr_longlong(systime));
4057 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
4058 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4060 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4061 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4062 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4063 wine_dbgstr_longlong(systime));
4065 /* STOPPED -> RUNNING */
4066 hr = IMFClockStateSink_OnClockStop(statesink, 567);
4067 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
4069 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4070 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4071 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4072 wine_dbgstr_longlong(systime));
4074 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
4075 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4077 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4078 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4079 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4080 wine_dbgstr_longlong(systime));
4082 /* PAUSED -> RUNNING */
4083 hr = IMFClockStateSink_OnClockPause(statesink, 8);
4084 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4086 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4087 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4088 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4089 wine_dbgstr_longlong(systime));
4091 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
4092 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4094 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4095 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4096 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4097 wine_dbgstr_longlong(systime));
4099 hr = IMFClockStateSink_OnClockPause(statesink, 7);
4100 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4102 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4103 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4104 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4105 wine_dbgstr_longlong(systime));
4107 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
4108 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4110 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4111 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4112 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4113 wine_dbgstr_longlong(systime));
4115 IMFClockStateSink_Release(statesink);
4116 IMFPresentationTimeSource_Release(time_source);
4119 static void test_MFInvokeCallback(void)
4121 struct test_callback *callback;
4122 IMFAsyncResult *result;
4123 MFASYNCRESULT *data;
4124 ULONG refcount;
4125 HRESULT hr;
4126 DWORD ret;
4128 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4129 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
4131 callback = create_test_callback(NULL);
4133 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
4134 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4136 data = (MFASYNCRESULT *)result;
4137 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
4138 ok(data->hEvent != NULL, "Failed to create event.\n");
4140 hr = MFInvokeCallback(result);
4141 ok(hr == S_OK, "Failed to invoke, hr %#lx.\n", hr);
4143 ret = WaitForSingleObject(data->hEvent, 100);
4144 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#lx.\n", ret);
4146 refcount = IMFAsyncResult_Release(result);
4147 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
4149 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4151 hr = MFShutdown();
4152 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4155 static void test_stream_descriptor(void)
4157 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
4158 IMFMediaTypeHandler *type_handler;
4159 IMFStreamDescriptor *stream_desc;
4160 GUID major_type;
4161 DWORD id, count;
4162 unsigned int i;
4163 HRESULT hr;
4165 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
4166 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4168 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4170 hr = MFCreateMediaType(&media_types[i]);
4171 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4174 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
4175 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4177 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4180 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
4181 ok(hr == S_OK, "Failed to get descriptor id, hr %#lx.\n", hr);
4182 ok(id == 123, "Unexpected id %#lx.\n", id);
4184 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4185 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4187 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4188 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4189 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4191 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
4192 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
4194 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4195 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4197 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4199 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
4200 ok(hr == S_OK, "Failed to get media type, hr %#lx.\n", hr);
4201 ok(media_type == media_types[i], "Unexpected object.\n");
4203 if (SUCCEEDED(hr))
4204 IMFMediaType_Release(media_type);
4207 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
4208 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#lx.\n", hr);
4210 /* IsMediaTypeSupported() */
4212 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
4213 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4215 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
4216 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4218 hr = MFCreateMediaType(&media_type);
4219 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4221 hr = MFCreateMediaType(&media_type3);
4222 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4224 media_type2 = (void *)0xdeadbeef;
4225 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4226 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4227 ok(!media_type2, "Unexpected pointer.\n");
4229 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
4230 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4232 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
4233 ok(hr == S_OK, "Failed to set current 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_GetMajorType(type_handler, &major_type);
4241 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4243 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4244 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4246 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4247 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4248 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
4250 /* Mismatching major types. */
4251 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4252 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4254 media_type2 = (void *)0xdeadbeef;
4255 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4256 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4257 ok(!media_type2, "Unexpected pointer.\n");
4259 /* Subtype missing. */
4260 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4261 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4263 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4264 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4266 media_type2 = (void *)0xdeadbeef;
4267 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4268 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4269 ok(!media_type2, "Unexpected pointer.\n");
4271 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4272 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4274 media_type2 = (void *)0xdeadbeef;
4275 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4277 ok(!media_type2, "Unexpected pointer.\n");
4279 /* Mismatching subtype. */
4280 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4281 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4283 media_type2 = (void *)0xdeadbeef;
4284 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4285 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4286 ok(!media_type2, "Unexpected pointer.\n");
4288 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4289 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4290 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4292 IMFMediaTypeHandler_Release(type_handler);
4293 IMFStreamDescriptor_Release(stream_desc);
4295 /* IsMediaTypeSupported() for unset current type. */
4296 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4297 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4299 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4300 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4302 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
4303 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4305 /* Initialize one from initial type set. */
4306 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
4307 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4309 media_type2 = (void *)0xdeadbeef;
4310 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4311 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4312 ok(!media_type2, "Unexpected pointer.\n");
4314 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4315 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4317 media_type2 = (void *)0xdeadbeef;
4318 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4319 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4320 ok(!media_type2, "Unexpected pointer.\n");
4322 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4323 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4325 media_type2 = (void *)0xdeadbeef;
4326 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4327 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4328 ok(!media_type2, "Unexpected pointer.\n");
4330 /* Now set current type that's not compatible. */
4331 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4332 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4334 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4335 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4337 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
4338 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4340 media_type2 = (void *)0xdeadbeef;
4341 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4342 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4343 ok(!media_type2, "Unexpected pointer.\n");
4345 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
4346 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4348 media_type2 = (void *)0xdeadbeef;
4349 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4350 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4351 ok(!media_type2, "Unexpected pointer.\n");
4353 IMFMediaType_Release(media_type);
4354 IMFMediaType_Release(media_type3);
4356 IMFMediaTypeHandler_Release(type_handler);
4358 IMFStreamDescriptor_Release(stream_desc);
4360 /* Major type is returned for first entry. */
4361 hr = MFCreateMediaType(&media_types[0]);
4362 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4363 hr = MFCreateMediaType(&media_types[1]);
4364 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4366 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4367 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4368 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4369 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4371 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
4372 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4374 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4375 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4377 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4378 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4379 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4381 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4382 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4383 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4384 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4386 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4387 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4388 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4390 IMFMediaType_Release(media_types[0]);
4391 IMFMediaType_Release(media_types[1]);
4393 IMFMediaTypeHandler_Release(type_handler);
4394 IMFStreamDescriptor_Release(stream_desc);
4397 static const struct image_size_test
4399 const GUID *subtype;
4400 UINT32 width;
4401 UINT32 height;
4402 UINT32 size;
4403 UINT32 plane_size; /* Matches image size when 0. */
4404 UINT32 max_length;
4405 UINT32 contiguous_length;
4406 UINT32 pitch;
4408 image_size_tests[] =
4410 /* RGB */
4411 { &MFVideoFormat_RGB8, 3, 5, 20, 0, 320, 20, 64 },
4412 { &MFVideoFormat_RGB8, 1, 1, 4, 0, 64, 4, 64 },
4413 { &MFVideoFormat_RGB8, 320, 240, 76800, 0, 76800, 76800, 320 },
4414 { &MFVideoFormat_RGB555, 3, 5, 40, 0, 320, 40, 64 },
4415 { &MFVideoFormat_RGB555, 1, 1, 4, 0, 64, 4, 64 },
4416 { &MFVideoFormat_RGB555, 320, 240, 153600, 0, 153600, 153600, 640 },
4417 { &MFVideoFormat_RGB565, 3, 5, 40, 0, 320, 40, 64 },
4418 { &MFVideoFormat_RGB565, 1, 1, 4, 0, 64, 4, 64 },
4419 { &MFVideoFormat_RGB565, 320, 240, 153600, 0, 153600, 153600, 640 },
4420 { &MFVideoFormat_RGB24, 3, 5, 60, 0, 320, 60, 64 },
4421 { &MFVideoFormat_RGB24, 1, 1, 4, 0, 64, 4, 64 },
4422 { &MFVideoFormat_RGB24, 4, 3, 36, 0, 192, 36, 64 },
4423 { &MFVideoFormat_RGB24, 320, 240, 230400, 0, 230400, 230400, 960 },
4424 { &MFVideoFormat_RGB32, 3, 5, 60, 0, 320, 60, 64 },
4425 { &MFVideoFormat_RGB32, 1, 1, 4, 0, 64, 4, 64 },
4426 { &MFVideoFormat_RGB32, 320, 240, 307200, 0, 307200, 307200, 1280 },
4427 { &MFVideoFormat_ARGB32, 3, 5, 60, 0, 320, 60, 64 },
4428 { &MFVideoFormat_ARGB32, 1, 1, 4, 0, 64, 4, 64 },
4429 { &MFVideoFormat_ARGB32, 320, 240, 307200, 0, 307200, 307200, 1280 },
4430 { &MFVideoFormat_A2R10G10B10, 3, 5, 60, 0, 320, 60, 64 },
4431 { &MFVideoFormat_A2R10G10B10, 1, 1, 4, 0, 64, 4, 64 },
4432 { &MFVideoFormat_A2R10G10B10, 320, 240, 307200, 0, 307200, 307200, 1280 },
4433 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120, 0, 320, 120, 64 },
4434 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8, 0, 64, 8, 64 },
4435 { &MFVideoFormat_A16B16G16R16F, 320, 240, 614400, 0, 614400, 614400, 2560 },
4437 { &MEDIASUBTYPE_RGB8, 3, 5, 20 },
4438 { &MEDIASUBTYPE_RGB8, 1, 1, 4 },
4439 { &MEDIASUBTYPE_RGB555, 3, 5, 40 },
4440 { &MEDIASUBTYPE_RGB555, 1, 1, 4 },
4441 { &MEDIASUBTYPE_RGB565, 3, 5, 40 },
4442 { &MEDIASUBTYPE_RGB565, 1, 1, 4 },
4443 { &MEDIASUBTYPE_RGB24, 3, 5, 60 },
4444 { &MEDIASUBTYPE_RGB24, 1, 1, 4 },
4445 { &MEDIASUBTYPE_RGB24, 4, 3, 36 },
4446 { &MEDIASUBTYPE_RGB32, 3, 5, 60 },
4447 { &MEDIASUBTYPE_RGB32, 1, 1, 4 },
4449 /* YUV 4:4:4, 32 bpp, packed */
4450 { &MFVideoFormat_AYUV, 1, 1, 4, 0, 64, 4, 64 },
4451 { &MFVideoFormat_AYUV, 2, 1, 8, 0, 64, 8, 64 },
4452 { &MFVideoFormat_AYUV, 1, 2, 8, 0, 128, 8, 64 },
4453 { &MFVideoFormat_AYUV, 4, 3, 48, 0, 192, 48, 64 },
4454 { &MFVideoFormat_AYUV, 320, 240, 307200, 0, 307200, 307200, 1280 },
4456 /* YUV 4:2:2, 16 bpp, packed */
4457 { &MFVideoFormat_YUY2, 2, 1, 4, 0, 64, 4, 64 },
4458 { &MFVideoFormat_YUY2, 4, 3, 24, 0, 192, 24, 64 },
4459 { &MFVideoFormat_YUY2, 128, 128, 32768, 0, 32768, 32768, 256 },
4460 { &MFVideoFormat_YUY2, 320, 240, 153600, 0, 153600, 153600, 640 },
4462 { &MFVideoFormat_UYVY, 2, 1, 4, 0, 64, 4, 64 },
4463 { &MFVideoFormat_UYVY, 4, 3, 24, 0, 192, 24, 64 },
4464 { &MFVideoFormat_UYVY, 128, 128, 32768, 0, 32768, 32768, 256 },
4465 { &MFVideoFormat_UYVY, 320, 240, 153600, 0, 153600, 153600, 640 },
4467 /* YUV 4:2:0, 16 bpp, planar (the secondary plane has the same
4468 * height, half the width and the same stride as the primary
4469 * one) */
4470 { &MFVideoFormat_IMC1, 1, 1, 4, 0, 256, 8, 128 },
4471 { &MFVideoFormat_IMC1, 2, 1, 4, 0, 256, 8, 128 },
4472 { &MFVideoFormat_IMC1, 1, 2, 8, 0, 512, 16, 128 },
4473 { &MFVideoFormat_IMC1, 2, 2, 8, 0, 512, 16, 128 },
4474 { &MFVideoFormat_IMC1, 2, 4, 16, 0, 1024, 32, 128 },
4475 { &MFVideoFormat_IMC1, 4, 2, 16, 0, 512, 32, 128 },
4476 { &MFVideoFormat_IMC1, 4, 3, 24, 0, 768, 48, 128 },
4477 { &MFVideoFormat_IMC1, 320, 240, 153600, 0, 307200, 307200, 640 },
4479 { &MFVideoFormat_IMC3, 1, 1, 4, 0, 256, 8, 128 },
4480 { &MFVideoFormat_IMC3, 2, 1, 4, 0, 256, 8, 128 },
4481 { &MFVideoFormat_IMC3, 1, 2, 8, 0, 512, 16, 128 },
4482 { &MFVideoFormat_IMC3, 2, 2, 8, 0, 512, 16, 128 },
4483 { &MFVideoFormat_IMC3, 2, 4, 16, 0, 1024, 32, 128 },
4484 { &MFVideoFormat_IMC3, 4, 2, 16, 0, 512, 32, 128 },
4485 { &MFVideoFormat_IMC3, 4, 3, 24, 0, 768, 48, 128 },
4486 { &MFVideoFormat_IMC3, 320, 240, 153600, 0, 307200, 307200, 640 },
4488 /* YUV 4:2:0, 12 bpp, planar, full stride (the secondary plane has
4489 * half the height, the same width and the same stride as the
4490 * primary one) */
4491 { &MFVideoFormat_NV12, 1, 3, 9, 4, 288, 4, 64 },
4492 { &MFVideoFormat_NV12, 1, 2, 6, 3, 192, 3, 64 },
4493 { &MFVideoFormat_NV12, 2, 2, 6, 6, 192, 6, 64 },
4494 { &MFVideoFormat_NV12, 2, 4, 12, 0, 384, 12, 64 },
4495 { &MFVideoFormat_NV12, 3, 2, 12, 9, 192, 9, 64 },
4496 { &MFVideoFormat_NV12, 4, 2, 12, 0, 192, 12, 64 },
4497 { &MFVideoFormat_NV12, 320, 240, 115200, 0, 115200, 115200, 320 },
4499 /* YUV 4:2:0, 12 bpp, planar, half stride (the secondary plane has
4500 * the same height, half the width and half the stride of the
4501 * primary one) */
4502 { &MFVideoFormat_IMC2, 1, 1, 3, 1, 192, 1, 128 },
4503 { &MFVideoFormat_IMC2, 1, 2, 6, 3, 384, 2, 128 },
4504 { &MFVideoFormat_IMC2, 1, 3, 9, 4, 576, 3, 128 },
4505 { &MFVideoFormat_IMC2, 2, 1, 3, 0, 192, 3, 128 },
4506 { &MFVideoFormat_IMC2, 2, 2, 6, 6, 384, 6, 128 },
4507 { &MFVideoFormat_IMC2, 2, 4, 12, 0, 768, 12, 128 },
4508 { &MFVideoFormat_IMC2, 3, 2, 12, 9, 384, 8, 128 },
4509 { &MFVideoFormat_IMC2, 3, 5, 30, 22, 960, 20, 128 },
4510 { &MFVideoFormat_IMC2, 4, 2, 12, 0, 384, 12, 128 },
4511 { &MFVideoFormat_IMC2, 4, 3, 18, 0, 576, 18, 128 },
4512 { &MFVideoFormat_IMC2, 320, 240, 115200, 0, 138240, 115200, 384 },
4514 { &MFVideoFormat_IMC4, 1, 1, 3, 1, 192, 1, 128 },
4515 { &MFVideoFormat_IMC4, 1, 2, 6, 3, 384, 2, 128 },
4516 { &MFVideoFormat_IMC4, 1, 3, 9, 4, 576, 3, 128 },
4517 { &MFVideoFormat_IMC4, 2, 1, 3, 0, 192, 3, 128 },
4518 { &MFVideoFormat_IMC4, 2, 2, 6, 6, 384, 6, 128 },
4519 { &MFVideoFormat_IMC4, 2, 4, 12, 0, 768, 12, 128 },
4520 { &MFVideoFormat_IMC4, 3, 2, 12, 9, 384, 8, 128 },
4521 { &MFVideoFormat_IMC4, 3, 5, 30, 22, 960, 20, 128 },
4522 { &MFVideoFormat_IMC4, 4, 2, 12, 0, 384, 12, 128 },
4523 { &MFVideoFormat_IMC4, 4, 3, 18, 0, 576, 18, 128 },
4524 { &MFVideoFormat_IMC4, 320, 240, 115200, 0, 138240, 115200, 384 },
4526 /* YUV 4:1:1, 12 bpp, semi-planar */
4527 { &MFVideoFormat_NV11, 1, 3, 18, 4, 576, 3, 128 },
4528 { &MFVideoFormat_NV11, 1, 2, 12, 3, 384, 2, 128 },
4529 { &MFVideoFormat_NV11, 2, 2, 12, 6, 384, 6, 128 },
4530 { &MFVideoFormat_NV11, 2, 4, 24, 12, 768, 12, 128 },
4531 { &MFVideoFormat_NV11, 3, 2, 12, 9, 384, 8, 128 },
4532 { &MFVideoFormat_NV11, 4, 2, 12, 0, 384, 12, 128 },
4533 { &MFVideoFormat_NV11, 320, 240, 115200, 0, 138240, 115200, 384 },
4535 { &MFVideoFormat_YV12, 1, 1, 3, 1, 192, 1, 128 },
4536 { &MFVideoFormat_YV12, 1, 2, 6, 3, 384, 2, 128 },
4537 { &MFVideoFormat_YV12, 1, 3, 9, 4, 576, 3, 128 },
4538 { &MFVideoFormat_YV12, 2, 1, 3, 0, 192, 3, 128 },
4539 { &MFVideoFormat_YV12, 2, 2, 6, 6, 384, 6, 128 },
4540 { &MFVideoFormat_YV12, 2, 4, 12, 0, 768, 12, 128 },
4541 { &MFVideoFormat_YV12, 3, 2, 12, 9, 384, 8, 128 },
4542 { &MFVideoFormat_YV12, 3, 5, 30, 22, 960, 20, 128 },
4543 { &MFVideoFormat_YV12, 4, 2, 12, 0, 384, 12, 128 },
4544 { &MFVideoFormat_YV12, 4, 3, 18, 0, 576, 18, 128 },
4545 { &MFVideoFormat_YV12, 320, 240, 115200, 0, 138240, 115200, 384 },
4547 { &MFVideoFormat_I420, 1, 1, 3, 1, 192, 1, 128 },
4548 { &MFVideoFormat_I420, 1, 2, 6, 3, 384, 2, 128 },
4549 { &MFVideoFormat_I420, 1, 3, 9, 4, 576, 3, 128 },
4550 { &MFVideoFormat_I420, 2, 1, 3, 0, 192, 3, 128 },
4551 { &MFVideoFormat_I420, 2, 2, 6, 6, 384, 6, 128 },
4552 { &MFVideoFormat_I420, 2, 4, 12, 0, 768, 12, 128 },
4553 { &MFVideoFormat_I420, 3, 2, 12, 9, 384, 8, 128 },
4554 { &MFVideoFormat_I420, 3, 5, 30, 22, 960, 20, 128 },
4555 { &MFVideoFormat_I420, 4, 2, 12, 0, 384, 12, 128 },
4556 { &MFVideoFormat_I420, 4, 3, 18, 0, 576, 18, 128 },
4557 { &MFVideoFormat_I420, 320, 240, 115200, 0, 138240, 115200, 384 },
4559 { &MFVideoFormat_IYUV, 1, 1, 3, 1, 192, 1, 128 },
4560 { &MFVideoFormat_IYUV, 1, 2, 6, 3, 384, 2, 128 },
4561 { &MFVideoFormat_IYUV, 1, 3, 9, 4, 576, 3, 128 },
4562 { &MFVideoFormat_IYUV, 2, 1, 3, 0, 192, 3, 128 },
4563 { &MFVideoFormat_IYUV, 2, 2, 6, 6, 384, 6, 128 },
4564 { &MFVideoFormat_IYUV, 2, 4, 12, 0, 768, 12, 128 },
4565 { &MFVideoFormat_IYUV, 3, 2, 12, 9, 384, 8, 128 },
4566 { &MFVideoFormat_IYUV, 3, 5, 30, 22, 960, 20, 128 },
4567 { &MFVideoFormat_IYUV, 4, 2, 12, 0, 384, 12, 128 },
4568 { &MFVideoFormat_IYUV, 4, 3, 18, 0, 576, 18, 128 },
4569 { &MFVideoFormat_IYUV, 320, 240, 115200, 0, 138240, 115200, 384 },
4572 static void test_MFCalculateImageSize(void)
4574 unsigned int i;
4575 UINT32 size;
4576 HRESULT hr;
4578 size = 1;
4579 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
4580 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#lx.\n", hr);
4581 ok(size == 0, "Unexpected size %u.\n", size);
4583 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4585 const struct image_size_test *ptr = &image_size_tests[i];
4587 /* Those are supported since Win10. */
4588 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
4589 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
4591 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4592 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr);
4593 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4594 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4598 static void test_MFGetPlaneSize(void)
4600 unsigned int i;
4601 DWORD size;
4602 HRESULT hr;
4604 if (!pMFGetPlaneSize)
4606 win_skip("MFGetPlaneSize() is not available.\n");
4607 return;
4610 size = 1;
4611 hr = pMFGetPlaneSize(0xdeadbeef, 64, 64, &size);
4612 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4613 ok(size == 0, "Unexpected size %lu.\n", size);
4615 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4617 const struct image_size_test *ptr = &image_size_tests[i];
4618 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4619 if ((is_MEDIASUBTYPE_RGB(ptr->subtype)))
4620 continue;
4622 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4623 ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr);
4624 ok(size == plane_size, "%u: unexpected plane size %lu, expected %u. Size %u x %u, format %s.\n", i, size, plane_size,
4625 ptr->width, ptr->height, wine_dbgstr_an((char*)&ptr->subtype->Data1, 4));
4629 static void test_MFCompareFullToPartialMediaType(void)
4631 IMFMediaType *full_type, *partial_type;
4632 HRESULT hr;
4633 BOOL ret;
4635 hr = MFCreateMediaType(&full_type);
4636 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4638 hr = MFCreateMediaType(&partial_type);
4639 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4641 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4642 ok(!ret, "Unexpected result %d.\n", ret);
4644 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4645 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4647 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4648 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4650 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4651 ok(ret, "Unexpected result %d.\n", ret);
4653 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4654 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4656 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4657 ok(ret, "Unexpected result %d.\n", ret);
4659 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4660 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4662 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4663 ok(!ret, "Unexpected result %d.\n", ret);
4665 IMFMediaType_Release(full_type);
4666 IMFMediaType_Release(partial_type);
4669 static void test_attributes_serialization(void)
4671 static const UINT8 blob[] = {1,2,3};
4672 IMFAttributes *attributes, *dest;
4673 UINT32 size, count, value32;
4674 double value_dbl;
4675 UINT64 value64;
4676 UINT8 *buffer;
4677 IUnknown *obj;
4678 HRESULT hr;
4679 WCHAR *str;
4680 GUID guid;
4682 hr = MFCreateAttributes(&attributes, 0);
4683 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4685 hr = MFCreateAttributes(&dest, 0);
4686 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4688 hr = MFGetAttributesAsBlobSize(attributes, &size);
4689 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4690 ok(size == 8, "Got size %u.\n", size);
4692 buffer = malloc(size);
4694 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4695 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4697 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4698 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
4700 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4701 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4703 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4704 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4706 hr = MFInitAttributesFromBlob(dest, buffer, size);
4707 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4709 /* Previous items are cleared. */
4710 hr = IMFAttributes_GetCount(dest, &count);
4711 ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr);
4712 ok(count == 0, "Unexpected count %u.\n", count);
4714 free(buffer);
4716 /* Set some attributes of various types. */
4717 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4718 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4719 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4720 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4721 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4722 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4723 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4725 hr = MFGetAttributesAsBlobSize(attributes, &size);
4726 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4727 ok(size > 8, "Got unexpected size %u.\n", size);
4729 buffer = malloc(size);
4730 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4731 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4732 hr = MFInitAttributesFromBlob(dest, buffer, size);
4733 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4734 free(buffer);
4736 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4737 ok(hr == S_OK, "Failed to get get uint32 value, hr %#lx.\n", hr);
4738 ok(value32 == 456, "Unexpected value %u.\n", value32);
4739 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4740 ok(hr == S_OK, "Failed to get get uint64 value, hr %#lx.\n", hr);
4741 ok(value64 == 123, "Unexpected value.\n");
4742 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4743 ok(hr == S_OK, "Failed to get get double value, hr %#lx.\n", hr);
4744 ok(value_dbl == 0.5, "Unexpected value.\n");
4745 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4746 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4747 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4748 ok(hr == S_OK, "Failed to get guid value, hr %#lx.\n", hr);
4749 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4750 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4751 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
4752 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4753 CoTaskMemFree(str);
4754 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4755 ok(hr == S_OK, "Failed to get blob value, hr %#lx.\n", hr);
4756 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4757 CoTaskMemFree(buffer);
4759 IMFAttributes_Release(attributes);
4760 IMFAttributes_Release(dest);
4763 static void test_wrapped_media_type(void)
4765 IMFMediaType *mediatype, *mediatype2;
4766 UINT32 count, type;
4767 HRESULT hr;
4768 GUID guid;
4770 hr = MFCreateMediaType(&mediatype);
4771 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4773 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4774 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4776 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4777 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4778 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4779 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4781 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4782 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
4784 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4785 ok(hr == S_OK, "Failed to create wrapped media type, hr %#lx.\n", hr);
4787 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4788 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4789 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4791 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4792 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
4793 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4795 hr = IMFMediaType_GetCount(mediatype2, &count);
4796 ok(hr == S_OK, "Failed to get item count, hr %#lx.\n", hr);
4797 ok(count == 3, "Unexpected count %u.\n", count);
4799 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4800 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
4801 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4803 IMFMediaType_Release(mediatype);
4805 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4806 ok(hr == S_OK, "Failed to unwrap, hr %#lx.\n", hr);
4808 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4809 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4810 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4812 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4813 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4815 IMFMediaType_Release(mediatype);
4816 IMFMediaType_Release(mediatype2);
4819 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4821 static const struct wave_fmt_test
4823 const GUID *subtype;
4824 WORD format_tag;
4826 wave_fmt_tests[] =
4828 { &MFAudioFormat_PCM, WAVE_FORMAT_PCM, },
4829 { &MFAudioFormat_Float, WAVE_FORMAT_IEEE_FLOAT, },
4831 WAVEFORMATEXTENSIBLE *format_ext;
4832 IMFMediaType *mediatype;
4833 WAVEFORMATEX *format;
4834 UINT32 size, i;
4835 HRESULT hr;
4837 hr = MFCreateMediaType(&mediatype);
4838 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4840 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4841 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4843 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4844 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4846 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4847 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4849 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4850 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4852 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4853 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4855 for (i = 0; i < ARRAY_SIZE(wave_fmt_tests); ++i)
4857 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, wave_fmt_tests[i].subtype);
4858 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4860 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4861 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4862 ok(format != NULL, "Expected format structure.\n");
4863 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4864 ok(format->wFormatTag == wave_fmt_tests[i].format_tag, "Expected tag %u, got %u.\n", wave_fmt_tests[i].format_tag, format->wFormatTag);
4865 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4866 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format->nSamplesPerSec);
4867 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n", format->nAvgBytesPerSec);
4868 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4869 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4870 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4871 CoTaskMemFree(format);
4873 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4874 MFWaveFormatExConvertFlag_ForceExtensible);
4875 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4876 ok(format_ext != NULL, "Expected format structure.\n");
4877 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4878 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4879 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4880 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format_ext->Format.nSamplesPerSec);
4881 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n",
4882 format_ext->Format.nAvgBytesPerSec);
4883 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4884 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4885 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4886 format_ext->Format.cbSize);
4887 CoTaskMemFree(format_ext);
4889 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4890 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4891 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4892 CoTaskMemFree(format);
4895 IMFMediaType_Release(mediatype);
4898 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4900 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4901 IMFByteStream *stream;
4902 IUnknown *object;
4903 HRESULT hr;
4905 ok(!!result, "Unexpected result object.\n");
4907 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4909 hr = IMFAsyncResult_GetObject(result, &object);
4910 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4912 hr = MFEndCreateFile(result, &stream);
4913 ok(hr == S_OK, "Failed to get file stream, hr %#lx.\n", hr);
4914 IMFByteStream_Release(stream);
4916 SetEvent(callback->event);
4918 return S_OK;
4921 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4923 testcallback_QueryInterface,
4924 testcallback_AddRef,
4925 testcallback_Release,
4926 testcallback_GetParameters,
4927 test_create_file_callback_Invoke,
4930 static void test_async_create_file(void)
4932 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4933 struct test_callback *callback;
4934 IUnknown *cancel_cookie;
4935 HRESULT hr;
4936 BOOL ret;
4938 callback = create_test_callback(&test_create_file_callback_vtbl);
4940 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4941 ok(hr == S_OK, "Fail to start up, hr %#lx.\n", hr);
4943 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
4945 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4946 GetTempFileNameW(pathW, NULL, 0, fileW);
4948 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4949 &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface, &cancel_cookie);
4950 ok(hr == S_OK, "Async create request failed, hr %#lx.\n", hr);
4951 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4953 WaitForSingleObject(callback->event, INFINITE);
4955 IUnknown_Release(cancel_cookie);
4957 CloseHandle(callback->event);
4959 hr = MFShutdown();
4960 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4962 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4964 ret = DeleteFileW(fileW);
4965 ok(ret, "Failed to delete test file.\n");
4968 struct activate_object
4970 IMFActivate IMFActivate_iface;
4971 LONG refcount;
4974 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4976 if (IsEqualIID(riid, &IID_IMFActivate) ||
4977 IsEqualIID(riid, &IID_IMFAttributes) ||
4978 IsEqualIID(riid, &IID_IUnknown))
4980 *obj = iface;
4981 IMFActivate_AddRef(iface);
4982 return S_OK;
4985 *obj = NULL;
4986 return E_NOINTERFACE;
4989 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4991 return 2;
4994 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4996 return 1;
4999 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
5001 return E_NOTIMPL;
5004 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
5006 return E_NOTIMPL;
5009 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
5011 return E_NOTIMPL;
5014 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
5015 BOOL *result)
5017 return E_NOTIMPL;
5020 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
5022 return E_NOTIMPL;
5025 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
5027 return E_NOTIMPL;
5030 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
5032 return E_NOTIMPL;
5035 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
5037 return E_NOTIMPL;
5040 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
5042 return E_NOTIMPL;
5045 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
5046 UINT32 size, UINT32 *length)
5048 return E_NOTIMPL;
5051 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
5052 WCHAR **value, UINT32 *length)
5054 return E_NOTIMPL;
5057 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
5059 return E_NOTIMPL;
5062 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
5063 UINT32 bufsize, UINT32 *blobsize)
5065 return E_NOTIMPL;
5068 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
5070 return E_NOTIMPL;
5073 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
5075 return E_NOTIMPL;
5078 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
5080 return E_NOTIMPL;
5083 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
5085 return E_NOTIMPL;
5088 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
5090 return E_NOTIMPL;
5093 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
5095 return E_NOTIMPL;
5098 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
5100 return E_NOTIMPL;
5103 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
5105 return E_NOTIMPL;
5108 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
5110 return E_NOTIMPL;
5113 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
5115 return E_NOTIMPL;
5118 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
5120 return E_NOTIMPL;
5123 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
5125 return E_NOTIMPL;
5128 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
5130 return E_NOTIMPL;
5133 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
5135 return E_NOTIMPL;
5138 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
5140 return E_NOTIMPL;
5143 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
5145 return E_NOTIMPL;
5148 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
5150 return E_NOTIMPL;
5153 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
5155 return E_NOTIMPL;
5158 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
5160 return E_NOTIMPL;
5163 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
5165 return E_NOTIMPL;
5168 static const IMFActivateVtbl activate_object_vtbl =
5170 activate_object_QueryInterface,
5171 activate_object_AddRef,
5172 activate_object_Release,
5173 activate_object_GetItem,
5174 activate_object_GetItemType,
5175 activate_object_CompareItem,
5176 activate_object_Compare,
5177 activate_object_GetUINT32,
5178 activate_object_GetUINT64,
5179 activate_object_GetDouble,
5180 activate_object_GetGUID,
5181 activate_object_GetStringLength,
5182 activate_object_GetString,
5183 activate_object_GetAllocatedString,
5184 activate_object_GetBlobSize,
5185 activate_object_GetBlob,
5186 activate_object_GetAllocatedBlob,
5187 activate_object_GetUnknown,
5188 activate_object_SetItem,
5189 activate_object_DeleteItem,
5190 activate_object_DeleteAllItems,
5191 activate_object_SetUINT32,
5192 activate_object_SetUINT64,
5193 activate_object_SetDouble,
5194 activate_object_SetGUID,
5195 activate_object_SetString,
5196 activate_object_SetBlob,
5197 activate_object_SetUnknown,
5198 activate_object_LockStore,
5199 activate_object_UnlockStore,
5200 activate_object_GetCount,
5201 activate_object_GetItemByIndex,
5202 activate_object_CopyAllItems,
5203 activate_object_ActivateObject,
5204 activate_object_ShutdownObject,
5205 activate_object_DetachObject,
5208 static void test_local_handlers(void)
5210 IMFActivate local_activate = { &activate_object_vtbl };
5211 static const WCHAR localW[] = L"local";
5212 HRESULT hr;
5214 if (!pMFRegisterLocalSchemeHandler)
5216 win_skip("Local handlers are not supported.\n");
5217 return;
5220 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
5221 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5223 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
5224 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5226 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
5227 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5229 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5230 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5232 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5233 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5235 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
5236 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5238 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
5239 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5241 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
5242 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5244 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
5245 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5247 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
5248 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5251 static void test_create_property_store(void)
5253 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
5254 IPropertyStore *store, *store2;
5255 PROPVARIANT value = {0};
5256 PROPERTYKEY key;
5257 ULONG refcount;
5258 DWORD count;
5259 HRESULT hr;
5261 hr = CreatePropertyStore(NULL);
5262 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5264 hr = CreatePropertyStore(&store);
5265 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5267 hr = CreatePropertyStore(&store2);
5268 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5269 ok(store2 != store, "Expected different store objects.\n");
5270 IPropertyStore_Release(store2);
5272 check_interface(store, &IID_IPropertyStoreCache, FALSE);
5273 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
5275 hr = IPropertyStore_GetCount(store, NULL);
5276 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5278 count = 0xdeadbeef;
5279 hr = IPropertyStore_GetCount(store, &count);
5280 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5281 ok(!count, "Unexpected count %lu.\n", count);
5283 hr = IPropertyStore_Commit(store);
5284 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5286 hr = IPropertyStore_GetAt(store, 0, &key);
5287 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5289 hr = IPropertyStore_GetValue(store, NULL, &value);
5290 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5292 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
5293 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5295 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5296 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5298 memset(&value, 0, sizeof(PROPVARIANT));
5299 value.vt = VT_I4;
5300 value.lVal = 0xdeadbeef;
5301 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5302 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5304 if (0)
5306 /* crashes on Windows */
5307 hr = IPropertyStore_SetValue(store, NULL, &value);
5308 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5311 hr = IPropertyStore_GetCount(store, &count);
5312 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5313 ok(count == 1, "Unexpected count %lu.\n", count);
5315 hr = IPropertyStore_Commit(store);
5316 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5318 hr = IPropertyStore_GetAt(store, 0, &key);
5319 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5320 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
5322 hr = IPropertyStore_GetAt(store, 1, &key);
5323 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5325 memset(&value, 0xcc, sizeof(PROPVARIANT));
5326 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5327 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5328 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
5329 ok(value.lVal == 0xdeadbeef, "Unexpected value %#lx.\n", value.lVal);
5331 memset(&value, 0, sizeof(PROPVARIANT));
5332 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5333 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5335 hr = IPropertyStore_GetCount(store, &count);
5336 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5337 ok(count == 1, "Unexpected count %lu.\n", count);
5339 memset(&value, 0xcc, sizeof(PROPVARIANT));
5340 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5342 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
5343 ok(!value.lVal, "Unexpected value %#lx.\n", value.lVal);
5345 refcount = IPropertyStore_Release(store);
5346 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
5349 struct test_thread_param
5351 IMFDXGIDeviceManager *manager;
5352 HANDLE handle;
5353 BOOL lock;
5356 static DWORD WINAPI test_device_manager_thread(void *arg)
5358 struct test_thread_param *param = arg;
5359 ID3D11Device *device;
5360 HRESULT hr;
5362 if (param->lock)
5364 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
5365 (void **)&device, FALSE);
5366 if (SUCCEEDED(hr))
5367 ID3D11Device_Release(device);
5369 else
5370 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
5372 return hr;
5375 static void test_dxgi_device_manager(void)
5377 IMFDXGIDeviceManager *manager, *manager2;
5378 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
5379 struct test_thread_param param;
5380 HANDLE handle1, handle, thread;
5381 UINT token, token2;
5382 IUnknown *unk;
5383 HRESULT hr;
5385 if (!pMFCreateDXGIDeviceManager)
5387 win_skip("MFCreateDXGIDeviceManager not found.\n");
5388 return;
5391 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
5392 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5394 token = 0;
5395 hr = pMFCreateDXGIDeviceManager(&token, NULL);
5396 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5397 ok(!token, "got wrong token: %u.\n", token);
5399 hr = pMFCreateDXGIDeviceManager(&token, &manager);
5400 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5401 EXPECT_REF(manager, 1);
5402 ok(!!token, "got wrong token: %u.\n", token);
5404 Sleep(50);
5405 token2 = 0;
5406 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
5407 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5408 EXPECT_REF(manager2, 1);
5409 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
5410 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
5411 EXPECT_REF(manager, 1);
5413 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5414 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5416 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5417 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5419 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
5420 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5422 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
5423 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
5424 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5425 EXPECT_REF(d3d11_dev, 1);
5427 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
5428 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5429 EXPECT_REF(d3d11_dev, 1);
5431 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
5432 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5434 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5435 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5436 EXPECT_REF(manager, 1);
5437 EXPECT_REF(d3d11_dev, 2);
5439 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
5440 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5441 EXPECT_REF(manager2, 1);
5442 EXPECT_REF(d3d11_dev, 2);
5444 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5445 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5446 EXPECT_REF(manager, 1);
5447 EXPECT_REF(d3d11_dev, 2);
5449 /* GetVideoService() on device change. */
5450 handle = NULL;
5451 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5452 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5453 ok(!!handle, "Unexpected handle value %p.\n", handle);
5455 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
5456 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
5457 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5458 EXPECT_REF(d3d11_dev2, 1);
5459 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
5460 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5461 EXPECT_REF(manager, 1);
5462 EXPECT_REF(d3d11_dev2, 2);
5463 EXPECT_REF(d3d11_dev, 1);
5465 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5466 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#lx.\n", hr);
5468 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5469 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5471 handle = NULL;
5472 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5473 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5474 ok(!!handle, "Unexpected handle value %p.\n", handle);
5476 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5477 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5479 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5480 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5481 IUnknown_Release(unk);
5483 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
5484 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5485 IUnknown_Release(unk);
5487 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
5488 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5489 IUnknown_Release(unk);
5491 handle1 = NULL;
5492 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5493 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5494 ok(handle != handle1, "Unexpected handle.\n");
5496 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5497 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5499 /* Already closed. */
5500 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5501 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5503 handle = NULL;
5504 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5505 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5507 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5508 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5510 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
5511 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5513 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5514 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5515 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
5516 ID3D11Device_Release(device);
5518 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5519 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5521 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5522 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5524 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
5525 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5527 /* Locked with one handle, unlock with another. */
5528 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5529 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5531 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5532 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5534 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5535 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5537 ID3D11Device_Release(device);
5539 /* Closing unlocks the device. */
5540 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5541 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5543 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5544 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5545 ID3D11Device_Release(device);
5547 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5550 /* Open two handles. */
5551 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5552 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5554 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5557 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5558 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5559 ID3D11Device_Release(device);
5561 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5563 ID3D11Device_Release(device);
5565 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5566 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5568 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5569 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5571 param.manager = manager;
5572 param.handle = handle;
5573 param.lock = TRUE;
5574 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5575 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5576 GetExitCodeThread(thread, (DWORD *)&hr);
5577 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#lx.\n", hr);
5578 CloseHandle(thread);
5580 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5581 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5583 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5584 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5586 /* Lock on main thread, unlock on another. */
5587 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5588 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5589 ID3D11Device_Release(device);
5591 param.manager = manager;
5592 param.handle = handle;
5593 param.lock = FALSE;
5594 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5595 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5596 GetExitCodeThread(thread, (DWORD *)&hr);
5597 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5598 CloseHandle(thread);
5600 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5603 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5604 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5606 IMFDXGIDeviceManager_Release(manager);
5607 EXPECT_REF(d3d11_dev2, 1);
5608 ID3D11Device_Release(d3d11_dev);
5609 ID3D11Device_Release(d3d11_dev2);
5610 IMFDXGIDeviceManager_Release(manager2);
5613 static void test_MFCreateTransformActivate(void)
5615 IMFActivate *activate;
5616 UINT32 count;
5617 HRESULT hr;
5619 if (!pMFCreateTransformActivate)
5621 win_skip("MFCreateTransformActivate() is not available.\n");
5622 return;
5625 hr = pMFCreateTransformActivate(&activate);
5626 ok(hr == S_OK, "Failed to create activator, hr %#lx.\n", hr);
5628 hr = IMFActivate_GetCount(activate, &count);
5629 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5630 ok(!count, "Unexpected attribute count %u.\n", count);
5632 IMFActivate_Release(activate);
5635 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5637 if (IsEqualIID(riid, &IID_IClassFactory) ||
5638 IsEqualIID(riid, &IID_IUnknown))
5640 *obj = iface;
5641 IClassFactory_AddRef(iface);
5642 return S_OK;
5645 *obj = NULL;
5646 return E_NOINTERFACE;
5649 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5651 return 2;
5654 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5656 return 1;
5659 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5661 ok(0, "Unexpected call.\n");
5662 return E_NOTIMPL;
5665 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5667 return S_OK;
5670 static const IClassFactoryVtbl test_mft_factory_vtbl =
5672 test_mft_factory_QueryInterface,
5673 test_mft_factory_AddRef,
5674 test_mft_factory_Release,
5675 test_mft_factory_CreateInstance,
5676 test_mft_factory_LockServer,
5679 static void test_MFTRegisterLocal(void)
5681 IClassFactory test_factory = { &test_mft_factory_vtbl };
5682 MFT_REGISTER_TYPE_INFO input_types[1], *in_types, *out_types;
5683 IMFAttributes *attributes;
5684 IMFActivate **activate;
5685 UINT32 count, count2;
5686 WCHAR *name;
5687 HRESULT hr;
5689 if (!pMFTRegisterLocal)
5691 win_skip("MFTRegisterLocal() is not available.\n");
5692 return;
5695 input_types[0].guidMajorType = MFMediaType_Audio;
5696 input_types[0].guidSubtype = MFAudioFormat_PCM;
5697 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5698 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5700 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5701 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5703 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5704 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5705 ok(count > 0, "Unexpected count %u.\n", count);
5706 CoTaskMemFree(activate);
5708 hr = pMFTUnregisterLocal(&test_factory);
5709 ok(hr == S_OK, "Failed to unregister MFT, hr %#lx.\n", hr);
5711 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5712 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5713 ok(count2 < count, "Unexpected count %u.\n", count2);
5714 CoTaskMemFree(activate);
5716 hr = pMFTUnregisterLocal(&test_factory);
5717 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5719 hr = pMFTUnregisterLocal(NULL);
5720 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5722 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5723 0, NULL);
5724 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5726 hr = MFTGetInfo(MFT_CATEGORY_OTHER, &name, &in_types, &count, &out_types, &count2, &attributes);
5727 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5729 hr = pMFTUnregisterLocal(NULL);
5730 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5732 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5733 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5735 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5736 0, NULL);
5737 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5739 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5740 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5743 static void test_queue_com(void)
5745 static int system_queues[] =
5747 MFASYNC_CALLBACK_QUEUE_STANDARD,
5748 MFASYNC_CALLBACK_QUEUE_RT,
5749 MFASYNC_CALLBACK_QUEUE_IO,
5750 MFASYNC_CALLBACK_QUEUE_TIMER,
5751 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5752 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5755 static int user_queues[] =
5757 MF_STANDARD_WORKQUEUE,
5758 MF_WINDOW_WORKQUEUE,
5759 MF_MULTITHREADED_WORKQUEUE,
5762 char path_name[MAX_PATH];
5763 PROCESS_INFORMATION info;
5764 STARTUPINFOA startup;
5765 char **argv;
5766 int i;
5768 if (!pCoGetApartmentType)
5770 win_skip("CoGetApartmentType() is not available.\n");
5771 return;
5774 winetest_get_mainargs(&argv);
5776 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5778 memset(&startup, 0, sizeof(startup));
5779 startup.cb = sizeof(startup);
5780 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5781 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5782 "CreateProcess failed.\n" );
5783 wait_child_process(info.hProcess);
5784 CloseHandle(info.hProcess);
5785 CloseHandle(info.hThread);
5788 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5790 memset(&startup, 0, sizeof(startup));
5791 startup.cb = sizeof(startup);
5792 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5793 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5794 "CreateProcess failed.\n" );
5795 wait_child_process(info.hProcess);
5796 CloseHandle(info.hProcess);
5797 CloseHandle(info.hThread);
5801 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5803 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5804 APTTYPEQUALIFIER qualifier;
5805 APTTYPE com_type;
5806 HRESULT hr;
5808 hr = pCoGetApartmentType(&com_type, &qualifier);
5809 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#lx.\n", hr);
5810 if (SUCCEEDED(hr))
5812 todo_wine {
5813 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5814 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5815 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5816 else
5817 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5818 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5822 SetEvent(callback->event);
5823 return S_OK;
5826 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5828 testcallback_QueryInterface,
5829 testcallback_AddRef,
5830 testcallback_Release,
5831 testcallback_GetParameters,
5832 test_queue_com_state_callback_Invoke,
5835 static void test_queue_com_state(const char *name)
5837 struct test_callback *callback;
5838 DWORD queue, queue_type;
5839 HRESULT hr;
5841 callback = create_test_callback(&test_queue_com_state_callback_vtbl);
5842 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
5844 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5845 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
5847 if (name[0] == 's')
5849 callback->param = name[1] - '0';
5850 hr = MFPutWorkItem(callback->param, &callback->IMFAsyncCallback_iface, NULL);
5851 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5852 WaitForSingleObject(callback->event, INFINITE);
5854 else if (name[0] == 'u')
5856 queue_type = name[1] - '0';
5858 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5859 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5860 "Failed to allocate a queue of type %lu, hr %#lx.\n", queue_type, hr);
5862 if (SUCCEEDED(hr))
5864 callback->param = queue;
5865 hr = MFPutWorkItem(queue, &callback->IMFAsyncCallback_iface, NULL);
5866 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5867 WaitForSingleObject(callback->event, INFINITE);
5869 hr = MFUnlockWorkQueue(queue);
5870 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
5874 CloseHandle(callback->event);
5876 hr = MFShutdown();
5877 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
5879 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
5882 static void test_MFGetStrideForBitmapInfoHeader(void)
5884 static const struct stride_test
5886 const GUID *subtype;
5887 unsigned int width;
5888 LONG stride;
5890 stride_tests[] =
5892 { &MFVideoFormat_RGB8, 3, -4 },
5893 { &MFVideoFormat_RGB8, 1, -4 },
5894 { &MFVideoFormat_RGB555, 3, -8 },
5895 { &MFVideoFormat_RGB555, 1, -4 },
5896 { &MFVideoFormat_RGB565, 3, -8 },
5897 { &MFVideoFormat_RGB565, 1, -4 },
5898 { &MFVideoFormat_RGB24, 3, -12 },
5899 { &MFVideoFormat_RGB24, 1, -4 },
5900 { &MFVideoFormat_RGB32, 3, -12 },
5901 { &MFVideoFormat_RGB32, 1, -4 },
5902 { &MFVideoFormat_ARGB32, 3, -12 },
5903 { &MFVideoFormat_ARGB32, 1, -4 },
5904 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5905 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5906 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5907 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5909 /* YUV */
5910 { &MFVideoFormat_NV12, 1, 1 },
5911 { &MFVideoFormat_NV12, 2, 2 },
5912 { &MFVideoFormat_NV12, 3, 3 },
5913 { &MFVideoFormat_AYUV, 1, 4 },
5914 { &MFVideoFormat_AYUV, 4, 16 },
5915 { &MFVideoFormat_AYUV, 5, 20 },
5916 { &MFVideoFormat_IMC1, 1, 4 },
5917 { &MFVideoFormat_IMC1, 2, 4 },
5918 { &MFVideoFormat_IMC1, 3, 8 },
5919 { &MFVideoFormat_IMC3, 1, 4 },
5920 { &MFVideoFormat_IMC3, 2, 4 },
5921 { &MFVideoFormat_IMC3, 3, 8 },
5922 { &MFVideoFormat_IMC2, 1, 1 },
5923 { &MFVideoFormat_IMC2, 2, 2 },
5924 { &MFVideoFormat_IMC2, 3, 3 },
5925 { &MFVideoFormat_IMC4, 1, 1 },
5926 { &MFVideoFormat_IMC4, 2, 2 },
5927 { &MFVideoFormat_IMC4, 3, 3 },
5928 { &MFVideoFormat_YV12, 1, 1 },
5929 { &MFVideoFormat_YV12, 2, 2 },
5930 { &MFVideoFormat_YV12, 3, 3 },
5931 { &MFVideoFormat_YV12, 320, 320 },
5932 { &MFVideoFormat_I420, 1, 1 },
5933 { &MFVideoFormat_I420, 2, 2 },
5934 { &MFVideoFormat_I420, 3, 3 },
5935 { &MFVideoFormat_I420, 320, 320 },
5936 { &MFVideoFormat_IYUV, 1, 1 },
5937 { &MFVideoFormat_IYUV, 2, 2 },
5938 { &MFVideoFormat_IYUV, 3, 3 },
5939 { &MFVideoFormat_IYUV, 320, 320 },
5940 { &MFVideoFormat_NV11, 1, 1 },
5941 { &MFVideoFormat_NV11, 2, 2 },
5942 { &MFVideoFormat_NV11, 3, 3 },
5944 unsigned int i;
5945 LONG stride;
5946 HRESULT hr;
5948 if (!pMFGetStrideForBitmapInfoHeader)
5950 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5951 return;
5954 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5955 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5957 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5959 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5960 ok(hr == S_OK, "%u: failed to get stride, hr %#lx.\n", i, hr);
5961 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %ld, expected %ld.\n", i,
5962 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5966 static void test_MFCreate2DMediaBuffer(void)
5968 static const char two_aas[] = { 0xaa, 0xaa };
5969 static const char eight_bbs[] = { 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb };
5970 DWORD max_length, length, length2;
5971 BYTE *buffer_start, *data, *data2;
5972 LONG pitch, pitch2, stride;
5973 IMF2DBuffer2 *_2dbuffer2;
5974 IMF2DBuffer *_2dbuffer;
5975 IMFMediaBuffer *buffer;
5976 int i, j, k;
5977 HRESULT hr;
5978 BOOL ret;
5980 if (!pMFCreate2DMediaBuffer)
5982 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5983 return;
5986 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5987 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5989 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5990 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5992 /* YUV formats can't be bottom-up. */
5993 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5994 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5996 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5997 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
5999 check_interface(buffer, &IID_IMFGetService, TRUE);
6000 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6002 /* Full backing buffer size, with 64 bytes per row alignment. */
6003 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6004 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6005 ok(max_length > 0, "Unexpected length %lu.\n", max_length);
6007 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6008 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
6009 ok(!length, "Unexpected length.\n");
6011 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
6012 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
6014 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6015 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
6016 ok(length == 10, "Unexpected length.\n");
6018 /* Linear lock/unlock. */
6020 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
6021 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
6023 /* Linear locking call returns plane size.*/
6024 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
6025 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6026 ok(max_length == length, "Unexpected length.\n");
6028 memset(data, 0xaa, length);
6030 length = 0;
6031 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
6032 ok(max_length == length && length == 9, "Unexpected length %lu.\n", length);
6034 /* Already locked */
6035 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6036 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6037 ok(data2 == data, "Unexpected pointer.\n");
6039 hr = IMFMediaBuffer_Unlock(buffer);
6040 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6042 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6043 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6045 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6046 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6048 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6049 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6050 ok(length == 9, "Unexpected length %lu.\n", length);
6052 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
6053 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6055 /* 2D lock. */
6056 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6057 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
6059 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6060 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6062 hr = IMFMediaBuffer_Unlock(buffer);
6063 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6065 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6066 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6068 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
6069 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6071 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
6072 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6074 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
6075 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6077 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6078 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6079 ok(!!data, "Expected data pointer.\n");
6080 ok(pitch == 64, "Unexpected pitch %ld.\n", pitch);
6082 for (i = 0; i < 4; i++)
6083 ok(memcmp(&data[64 * i], two_aas, sizeof(two_aas)) == 0, "Invalid data instead of 0xaa.\n");
6084 memset(data, 0xbb, 194);
6086 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
6087 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6088 ok(data == data2, "Expected data pointer.\n");
6090 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
6091 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6093 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
6094 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6096 /* Active 2D lock */
6097 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6098 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6100 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6101 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6103 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6104 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6106 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6107 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6109 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6110 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6112 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6113 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6115 ok(memcmp(data, eight_bbs, sizeof(eight_bbs)) == 0, "Invalid data instead of 0xbb.\n");
6117 hr = IMFMediaBuffer_Unlock(buffer);
6118 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6120 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6121 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#lx.\n", hr);
6123 if (SUCCEEDED(hr))
6125 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6126 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6128 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
6129 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6131 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6132 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6134 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6135 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6137 /* Flags are ignored. */
6138 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
6139 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6141 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
6142 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6144 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6145 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6147 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6148 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6150 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
6151 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6153 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
6154 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6156 IMF2DBuffer2_Release(_2dbuffer2);
6158 else
6159 win_skip("IMF2DBuffer2 is not supported.\n");
6161 IMF2DBuffer_Release(_2dbuffer);
6163 IMFMediaBuffer_Release(buffer);
6165 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
6167 const struct image_size_test *ptr = &image_size_tests[i];
6169 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
6170 continue;
6172 winetest_push_context("%u, %u x %u, format %s", i, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6174 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
6175 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6177 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6179 ok(length == ptr->max_length, "Unexpected maximum length %lu.\n", length);
6181 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6182 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6184 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6185 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6187 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6188 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6189 ok(length == ptr->contiguous_length, "Unexpected contiguous length %lu.\n", length);
6191 data2 = malloc(ptr->contiguous_length + 16);
6192 ok(!!data2, "Failed to allocate buffer.\n");
6194 for (j = 0; j < ptr->contiguous_length + 16; j++)
6195 data2[j] = j & 0x7f;
6197 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length - 1);
6198 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6200 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6201 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6202 ok(length2 == ptr->contiguous_length, "Unexpected linear buffer length %lu.\n", length2);
6204 memset(data, 0xff, length2);
6206 hr = IMFMediaBuffer_Unlock(buffer);
6207 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6209 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length + 16);
6210 ok(hr == S_OK, "Failed to copy from contiguous buffer, hr %#lx.\n", hr);
6212 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6213 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6214 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6215 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6217 for (j = 0; j < ptr->contiguous_length; j++)
6219 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6221 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6222 continue;
6223 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6224 continue;
6226 if (data[j] != (j & 0x7f))
6227 break;
6229 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j);
6231 memset(data, 0xff, length2);
6233 hr = IMFMediaBuffer_Unlock(buffer);
6234 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6236 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length);
6237 ok(hr == S_OK, "Failed to copy from contiguous buffer, hr %#lx.\n", hr);
6239 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6240 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6241 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6242 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6244 for (j = 0; j < ptr->contiguous_length; j++)
6246 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6248 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6249 continue;
6250 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6251 continue;
6253 if (data[j] != (j & 0x7f))
6254 break;
6256 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j);
6258 hr = IMFMediaBuffer_Unlock(buffer);
6259 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6261 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length - 1);
6262 todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6264 memset(data2, 0xff, ptr->contiguous_length + 16);
6266 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length + 16);
6267 todo_wine ok(hr == S_OK, "Failed to copy to contiguous buffer, hr %#lx.\n", hr);
6269 for (j = 0; j < ptr->contiguous_length; j++)
6271 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6273 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6274 continue;
6275 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6276 continue;
6278 if (data2[j] != (j & 0x7f))
6279 break;
6281 todo_wine ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data2[j], j & 0x7f, j);
6283 memset(data2, 0xff, ptr->contiguous_length + 16);
6285 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length);
6286 todo_wine ok(hr == S_OK, "Failed to copy to contiguous buffer, hr %#lx.\n", hr);
6288 for (j = 0; j < ptr->contiguous_length; j++)
6290 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6292 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6293 continue;
6294 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6295 continue;
6297 if (data2[j] != (j & 0x7f))
6298 break;
6300 todo_wine ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data2[j], j & 0x7f, j);
6302 free(data2);
6304 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6305 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6306 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6307 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6309 hr = pMFGetStrideForBitmapInfoHeader(ptr->subtype->Data1, ptr->width, &stride);
6310 ok(hr == S_OK, "Failed to get stride, hr %#lx.\n", hr);
6311 stride = abs(stride);
6313 /* primary plane */
6314 ok(ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6315 ptr->height * stride, length2);
6316 for (j = 0; j < ptr->height; j++)
6317 for (k = 0; k < stride; k++)
6318 data[j * stride + k] = ((j % 16) << 4) + (k % 16);
6320 data += ptr->height * stride;
6322 /* secondary planes */
6323 switch (ptr->subtype->Data1)
6325 case MAKEFOURCC('I','M','C','1'):
6326 case MAKEFOURCC('I','M','C','3'):
6327 ok(2 * ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6328 2 * ptr->height * stride, length2);
6329 for (j = 0; j < ptr->height; j++)
6330 for (k = 0; k < stride / 2; k++)
6331 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6332 break;
6334 case MAKEFOURCC('I','M','C','2'):
6335 case MAKEFOURCC('I','M','C','4'):
6336 case MAKEFOURCC('N','V','1','1'):
6337 case MAKEFOURCC('Y','V','1','2'):
6338 case MAKEFOURCC('I','4','2','0'):
6339 case MAKEFOURCC('I','Y','U','V'):
6340 ok(stride * 3 / 2 * ptr->height <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6341 stride * 3 / 2 * ptr->height, length2);
6342 for (j = 0; j < ptr->height; j++)
6343 for (k = 0; k < stride / 2; k++)
6344 data[j * (stride / 2) + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6345 break;
6347 case MAKEFOURCC('N','V','1','2'):
6348 ok(stride * ptr->height * 3 / 2 <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6349 stride * ptr->height * 3 / 2, length2);
6350 for (j = 0; j < ptr->height / 2; j++)
6351 for (k = 0; k < stride; k++)
6352 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6353 break;
6356 hr = IMFMediaBuffer_Unlock(buffer);
6357 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6359 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6360 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6362 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
6363 ok(hr == S_OK, "Failed to get scanline, hr %#lx.\n", hr);
6364 ok(data2 == data, "Unexpected data pointer.\n");
6365 ok(pitch == pitch2, "Unexpected pitch.\n");
6367 /* primary plane */
6368 for (j = 0; j < ptr->height; j++)
6369 for (k = 0; k < stride; k++)
6370 ok(data[j * pitch + k] == ((j % 16) << 4) + (k % 16),
6371 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6372 data[j * pitch + k], ((j % 16) << 4) + (k % 16), j, k);
6374 data += ptr->height * pitch;
6376 /* secondary planes */
6377 switch (ptr->subtype->Data1)
6379 case MAKEFOURCC('I','M','C','1'):
6380 case MAKEFOURCC('I','M','C','3'):
6381 for (j = 0; j < ptr->height; j++)
6382 for (k = 0; k < stride / 2; k++)
6383 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6384 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6385 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6386 break;
6388 case MAKEFOURCC('I','M','C','2'):
6389 case MAKEFOURCC('I','M','C','4'):
6390 case MAKEFOURCC('N','V','1','1'):
6391 case MAKEFOURCC('Y','V','1','2'):
6392 case MAKEFOURCC('I','4','2','0'):
6393 case MAKEFOURCC('I','Y','U','V'):
6394 for (j = 0; j < ptr->height; j++)
6395 for (k = 0; k < stride / 2; k++)
6396 ok(data[j * (pitch / 2) + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6397 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6398 data[j * (pitch / 2) + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6399 break;
6401 case MAKEFOURCC('N','V','1','2'):
6402 for (j = 0; j < ptr->height / 2; j++)
6403 for (k = 0; k < stride; k++)
6404 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6405 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6406 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6407 break;
6409 default:
6413 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6414 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6416 ok(pitch == ptr->pitch, "Unexpected pitch %ld, expected %d.\n", pitch, ptr->pitch);
6418 ret = TRUE;
6419 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
6420 ok(hr == S_OK, "Failed to get format flag, hr %#lx.\n", hr);
6421 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
6423 IMF2DBuffer_Release(_2dbuffer);
6424 IMF2DBuffer2_Release(_2dbuffer2);
6426 IMFMediaBuffer_Release(buffer);
6428 winetest_pop_context();
6431 /* Alignment tests */
6432 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
6434 const struct image_size_test *ptr = &image_size_tests[i];
6436 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
6437 continue;
6439 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
6440 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6442 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6443 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6445 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6446 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6447 ok(((uintptr_t)data & MF_64_BYTE_ALIGNMENT) == 0, "Misaligned data at %p.\n", data);
6449 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6450 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6452 IMF2DBuffer_Release(_2dbuffer);
6453 IMFMediaBuffer_Release(buffer);
6457 static void test_MFCreateMediaBufferFromMediaType(void)
6459 static struct audio_buffer_test
6461 unsigned int duration;
6462 unsigned int min_length;
6463 unsigned int min_alignment;
6464 unsigned int block_alignment;
6465 unsigned int bytes_per_second;
6466 unsigned int buffer_length;
6467 } audio_tests[] =
6469 { 0, 0, 0, 4, 0, 20 },
6470 { 0, 16, 0, 4, 0, 20 },
6471 { 0, 0, 32, 4, 0, 36 },
6472 { 0, 64, 32, 4, 0, 64 },
6473 { 1, 0, 0, 4, 16, 36 },
6474 { 2, 0, 0, 4, 16, 52 },
6475 { 2, 0, 64, 4, 16, 68 },
6476 { 2, 0, 128, 4, 16,132 },
6478 IMFMediaType *media_type, *media_type2;
6479 unsigned int i, alignment;
6480 IMFMediaBuffer *buffer;
6481 DWORD length, max;
6482 BYTE *data;
6483 HRESULT hr;
6485 if (!pMFCreateMediaBufferFromMediaType)
6487 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
6488 return;
6491 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
6492 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6494 hr = MFCreateMediaType(&media_type);
6495 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6497 hr = MFCreateMediaType(&media_type2);
6498 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6500 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
6501 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6503 hr = IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)media_type2);
6504 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6506 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
6508 const struct audio_buffer_test *ptr = &audio_tests[i];
6510 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
6511 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6513 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
6514 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6516 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
6517 ptr->min_alignment, &buffer);
6518 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#lx.\n", hr);
6519 if (FAILED(hr))
6520 break;
6522 check_interface(buffer, &IID_IMFGetService, FALSE);
6524 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6525 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6526 ok(ptr->buffer_length == length, "%d: unexpected buffer length %lu, expected %u.\n", i, length, ptr->buffer_length);
6528 alignment = ptr->min_alignment ? ptr->min_alignment - 1 : MF_16_BYTE_ALIGNMENT;
6529 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6530 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6531 ok(ptr->buffer_length == max && !length, "Unexpected length.\n");
6532 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6533 hr = IMFMediaBuffer_Unlock(buffer);
6534 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6536 IMFMediaBuffer_Release(buffer);
6538 /* Only major type is set. */
6539 hr = pMFCreateMediaBufferFromMediaType(media_type2, ptr->duration * 10000000, ptr->min_length,
6540 ptr->min_alignment, &buffer);
6541 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6543 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6544 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6545 ok(ptr->min_length == length, "%u: unexpected buffer length %lu, expected %u.\n", i, length, ptr->min_length);
6547 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6548 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6549 ok(ptr->min_length == max && !length, "Unexpected length.\n");
6550 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6551 hr = IMFMediaBuffer_Unlock(buffer);
6552 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6554 IMFMediaBuffer_Release(buffer);
6557 IMFMediaType_Release(media_type);
6558 IMFMediaType_Release(media_type2);
6561 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
6563 GUID guid, subtype;
6564 UINT32 value;
6565 HRESULT hr;
6567 hr = IMFMediaType_GetMajorType(mediatype, &guid);
6568 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
6569 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
6571 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
6572 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
6574 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
6576 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
6577 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6579 if (fex->dwChannelMask)
6581 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
6582 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6583 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
6586 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
6588 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
6589 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6590 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
6593 else
6595 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
6596 subtype.Data1 = format->wFormatTag;
6597 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6599 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
6600 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6601 ok(value, "Unexpected value.\n");
6604 if (format->nChannels)
6606 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
6607 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6608 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
6611 if (format->nSamplesPerSec)
6613 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
6614 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6615 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
6618 if (format->nAvgBytesPerSec)
6620 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
6621 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6622 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
6625 if (format->nBlockAlign)
6627 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
6628 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6629 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
6632 if (format->wBitsPerSample)
6634 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
6635 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6636 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
6639 /* Only set for uncompressed formats. */
6640 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
6641 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
6642 IsEqualGUID(&guid, &MFAudioFormat_PCM))
6644 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6645 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
6647 else
6648 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
6651 static void test_MFInitMediaTypeFromWaveFormatEx(void)
6653 static const WAVEFORMATEX waveformatex_tests[] =
6655 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
6656 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
6657 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
6658 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
6659 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
6660 { 1234, 0, 0, 0, 0, 0 },
6661 { WAVE_FORMAT_ALAW },
6662 { WAVE_FORMAT_CREATIVE_ADPCM },
6663 { WAVE_FORMAT_MPEGLAYER3 },
6664 { WAVE_FORMAT_MPEG_ADTS_AAC },
6665 { WAVE_FORMAT_ALAC },
6666 { WAVE_FORMAT_AMR_NB },
6667 { WAVE_FORMAT_AMR_WB },
6668 { WAVE_FORMAT_AMR_WP },
6669 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
6670 { WAVE_FORMAT_DRM },
6671 { WAVE_FORMAT_DTS },
6672 { WAVE_FORMAT_FLAC },
6673 { WAVE_FORMAT_MPEG },
6674 { WAVE_FORMAT_WMAVOICE9 },
6675 { WAVE_FORMAT_OPUS },
6676 { WAVE_FORMAT_WMAUDIO2 },
6677 { WAVE_FORMAT_WMAUDIO3 },
6678 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
6679 { WAVE_FORMAT_WMASPDIF },
6682 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
6683 WAVEFORMATEXTENSIBLE waveformatext;
6684 MPEGLAYER3WAVEFORMAT mp3format;
6685 IMFMediaType *mediatype;
6686 unsigned int i, size;
6687 HRESULT hr;
6689 hr = MFCreateMediaType(&mediatype);
6690 ok(hr == S_OK, "Failed to create mediatype, hr %#lx.\n", hr);
6692 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
6694 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
6695 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#lx.\n", i, waveformatex_tests[i].wFormatTag, hr);
6697 validate_media_type(mediatype, &waveformatex_tests[i]);
6699 waveformatext.Format = waveformatex_tests[i];
6700 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
6701 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
6702 waveformatext.Samples.wSamplesPerBlock = 123;
6703 waveformatext.dwChannelMask = 0x8;
6704 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
6705 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
6707 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
6708 ok(hr == S_OK, "Failed to initialize media type, hr %#lx.\n", hr);
6710 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
6711 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
6713 validate_media_type(mediatype, &waveformatext.Format);
6716 /* MPEGLAYER3WAVEFORMAT */
6717 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
6718 mp3format.wfx.nChannels = 2;
6719 mp3format.wfx.nSamplesPerSec = 44100;
6720 mp3format.wfx.nAvgBytesPerSec = 16000;
6721 mp3format.wfx.nBlockAlign = 1;
6722 mp3format.wfx.wBitsPerSample = 0;
6723 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
6724 mp3format.wID = MPEGLAYER3_ID_MPEG;
6725 mp3format.fdwFlags = 0;
6726 mp3format.nBlockSize = 417;
6727 mp3format.nFramesPerBlock = 0;
6728 mp3format.nCodecDelay = 0;
6730 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
6731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6733 validate_media_type(mediatype, &mp3format.wfx);
6734 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
6735 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6736 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
6737 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
6739 IMFMediaType_Release(mediatype);
6742 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
6744 MFVIDEOFORMAT *video_format;
6745 IMFMediaType *media_type;
6746 UINT32 size;
6747 HRESULT hr;
6749 hr = MFCreateMediaType(&media_type);
6750 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6752 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
6753 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6754 ok(!!video_format, "Unexpected format.\n");
6755 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
6756 CoTaskMemFree(video_format);
6758 IMFMediaType_Release(media_type);
6761 static void test_MFCreateDXSurfaceBuffer(void)
6763 IDirect3DSurface9 *backbuffer = NULL, *surface;
6764 IDirect3DSwapChain9 *swapchain;
6765 D3DLOCKED_RECT locked_rect;
6766 DWORD length, max_length;
6767 IDirect3DDevice9 *device;
6768 IMF2DBuffer2 *_2dbuffer2;
6769 BOOL value, broken_test;
6770 IMFMediaBuffer *buffer;
6771 IMF2DBuffer *_2dbuffer;
6772 BYTE *data, *data2;
6773 IMFGetService *gs;
6774 IDirect3D9 *d3d;
6775 DWORD color;
6776 HWND window;
6777 HRESULT hr;
6778 LONG pitch;
6780 if (!pMFCreateDXSurfaceBuffer)
6782 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
6783 return;
6786 window = create_window();
6787 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6788 ok(!!d3d, "Failed to create a D3D object.\n");
6789 if (!(device = create_d3d9_device(d3d, window)))
6791 skip("Failed to create a D3D device, skipping tests.\n");
6792 goto done;
6795 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
6796 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08lx)\n", hr);
6798 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6799 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08lx)\n", hr);
6800 ok(backbuffer != NULL, "The back buffer is NULL\n");
6802 IDirect3DSwapChain9_Release(swapchain);
6804 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
6805 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6807 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
6808 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6810 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6811 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6812 check_interface(buffer, &IID_IMFGetService, TRUE);
6814 /* Surface is accessible. */
6815 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
6816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6817 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
6818 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6819 ok(surface == backbuffer, "Unexpected surface pointer.\n");
6820 IDirect3DSurface9_Release(surface);
6821 IMFGetService_Release(gs);
6823 max_length = 0;
6824 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6825 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6826 ok(!!max_length, "Unexpected length %lu.\n", max_length);
6828 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6829 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6830 ok(!length, "Unexpected length %lu.\n", length);
6832 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6833 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6835 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6836 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6837 ok(length == 2 * max_length, "Unexpected length %lu.\n", length);
6839 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6840 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6842 /* Cannot lock while the surface is locked. */
6843 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6844 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6846 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6847 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6849 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6850 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6851 /* Broken on Windows 8 and 10 v1507 */
6852 broken_test = length == 0;
6853 ok(length == max_length || broken(broken_test), "Unexpected length %lu instead of %lu.\n", length, max_length);
6855 /* You can lock the surface while the media buffer is locked. */
6856 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6857 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6859 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6860 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6862 hr = IMFMediaBuffer_Unlock(buffer);
6863 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6865 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6866 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6868 /* Unlock twice. */
6869 hr = IMFMediaBuffer_Unlock(buffer);
6870 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6872 hr = IMFMediaBuffer_Unlock(buffer);
6873 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6875 /* Lock twice. */
6876 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6877 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6879 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6880 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6881 ok(data == data2, "Unexpected pointer.\n");
6883 hr = IMFMediaBuffer_Unlock(buffer);
6884 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6886 hr = IMFMediaBuffer_Unlock(buffer);
6887 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6889 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6890 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6892 /* Unlocked. */
6893 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6894 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6896 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6897 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6899 /* Cannot lock the buffer while the surface is locked. */
6900 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6901 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6903 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6904 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6906 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6907 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6909 /* Cannot lock the surface once the buffer is locked. */
6910 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6911 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6913 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6914 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6916 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6917 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6919 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6920 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6922 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6923 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6925 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6926 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6928 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6929 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6931 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6932 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6934 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6935 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
6937 hr = IMFMediaBuffer_Unlock(buffer);
6938 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6940 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
6941 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6942 ok(!value, "Unexpected return value %d.\n", value);
6944 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6945 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6946 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6947 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6948 ok(length == max_length, "Unexpected length %lu.\n", length);
6950 IMF2DBuffer_Release(_2dbuffer);
6952 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6953 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6955 /* Lock flags are ignored, so writing is allowed when locking for
6956 * reading and viceversa. */
6957 put_d3d9_surface_color(backbuffer, 0, 0, 0xcdcdcdcd);
6958 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6959 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6960 ok(data == data2, "Unexpected scanline pointer.\n");
6961 ok(data[0] == 0xcd, "Unexpected leading byte.\n");
6962 memset(data, 0xab, 4);
6963 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6965 color = get_d3d9_surface_color(backbuffer, 0, 0);
6966 ok(color == 0xabababab, "Unexpected leading dword.\n");
6967 put_d3d9_surface_color(backbuffer, 0, 0, 0xefefefef);
6969 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6970 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6971 ok(data[0] == 0xef, "Unexpected leading byte.\n");
6972 memset(data, 0x89, 4);
6973 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6975 color = get_d3d9_surface_color(backbuffer, 0, 0);
6976 ok(color == 0x89898989, "Unexpected leading dword.\n");
6978 /* Also, flags incompatibilities are not taken into account even
6979 * if a buffer is already locked. */
6980 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6982 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6983 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6984 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6985 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6986 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6987 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6988 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6989 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6990 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
6991 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6992 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
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);
7001 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7002 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7003 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7004 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7005 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7006 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7007 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7008 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7009 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7010 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7011 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7012 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7013 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
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);
7022 /* Except when originally locking for writing. */
7023 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7024 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7025 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7026 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7027 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7028 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7029 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7030 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7031 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7032 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7033 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7035 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7036 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7038 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7039 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7041 IMF2DBuffer2_Release(_2dbuffer2);
7043 IMFMediaBuffer_Release(buffer);
7044 IDirect3DDevice9_Release(device);
7046 done:
7047 if (backbuffer)
7048 IDirect3DSurface9_Release(backbuffer);
7049 ok(!IDirect3D9_Release(d3d), "Unexpected refcount.\n");
7050 DestroyWindow(window);
7053 static void test_MFCreateTrackedSample(void)
7055 IMFTrackedSample *tracked_sample;
7056 IMFSample *sample;
7057 IUnknown *unk;
7058 HRESULT hr;
7060 if (!pMFCreateTrackedSample)
7062 win_skip("MFCreateTrackedSample() is not available.\n");
7063 return;
7066 hr = pMFCreateTrackedSample(&tracked_sample);
7067 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7069 /* It's actually a sample. */
7070 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
7071 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7073 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
7074 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7075 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
7076 IUnknown_Release(unk);
7078 IMFSample_Release(sample);
7080 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
7082 IMFTrackedSample_Release(tracked_sample);
7085 static void test_MFFrameRateToAverageTimePerFrame(void)
7087 static const struct frame_rate_test
7089 unsigned int numerator;
7090 unsigned int denominator;
7091 UINT64 avgtime;
7092 } frame_rate_tests[] =
7094 { 60000, 1001, 166833 },
7095 { 30000, 1001, 333667 },
7096 { 24000, 1001, 417188 },
7097 { 60, 1, 166667 },
7098 { 30, 1, 333333 },
7099 { 50, 1, 200000 },
7100 { 25, 1, 400000 },
7101 { 24, 1, 416667 },
7103 { 39, 1, 256410 },
7104 { 120, 1, 83333 },
7106 unsigned int i;
7107 UINT64 avgtime;
7108 HRESULT hr;
7110 avgtime = 1;
7111 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
7112 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7113 ok(!avgtime, "Unexpected frame time.\n");
7115 avgtime = 1;
7116 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
7117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7118 ok(!avgtime, "Unexpected frame time.\n");
7120 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
7122 avgtime = 0;
7123 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
7124 frame_rate_tests[i].denominator, &avgtime);
7125 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7126 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
7127 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
7131 static void test_MFAverageTimePerFrameToFrameRate(void)
7133 static const struct frame_rate_test
7135 unsigned int numerator;
7136 unsigned int denominator;
7137 UINT64 avgtime;
7138 } frame_rate_tests[] =
7140 { 60000, 1001, 166833 },
7141 { 30000, 1001, 333667 },
7142 { 24000, 1001, 417188 },
7143 { 60, 1, 166667 },
7144 { 30, 1, 333333 },
7145 { 50, 1, 200000 },
7146 { 25, 1, 400000 },
7147 { 24, 1, 416667 },
7149 { 1000000, 25641, 256410 },
7150 { 10000000, 83333, 83333 },
7151 { 1, 10, 100000000 },
7152 { 1, 10, 100000001 },
7153 { 1, 10, 200000000 },
7154 { 1, 1, 10000000 },
7155 { 1, 2, 20000000 },
7156 { 5, 1, 2000000 },
7157 { 10, 1, 1000000 },
7159 unsigned int i, numerator, denominator;
7160 HRESULT hr;
7162 numerator = denominator = 1;
7163 hr = MFAverageTimePerFrameToFrameRate(0, &numerator, &denominator);
7164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7165 ok(!numerator && !denominator, "Unexpected output %u/%u.\n", numerator, denominator);
7167 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
7169 numerator = denominator = 12345;
7170 hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
7171 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7172 ok(numerator == frame_rate_tests[i].numerator && denominator == frame_rate_tests[i].denominator,
7173 "%u: unexpected %u/%u, expected %u/%u.\n", i, numerator, denominator, frame_rate_tests[i].numerator,
7174 frame_rate_tests[i].denominator);
7178 static void test_MFMapDXGIFormatToDX9Format(void)
7180 static const struct format_pair
7182 DXGI_FORMAT dxgi_format;
7183 DWORD d3d9_format;
7185 formats_map[] =
7187 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
7188 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
7189 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
7190 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
7191 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
7192 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
7193 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
7194 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
7195 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
7196 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
7197 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
7198 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
7199 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
7200 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
7201 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
7202 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
7203 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
7204 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
7205 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
7206 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
7207 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
7208 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
7209 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
7210 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
7211 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
7212 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
7213 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
7214 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
7215 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
7216 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
7217 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
7218 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
7219 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
7220 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
7221 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
7222 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
7223 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
7224 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
7225 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
7226 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
7227 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
7228 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
7229 { DXGI_FORMAT_P8, D3DFMT_P8 },
7230 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
7232 unsigned int i;
7233 DWORD format;
7235 if (!pMFMapDXGIFormatToDX9Format)
7237 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
7238 return;
7241 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
7243 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
7244 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
7248 static void test_MFMapDX9FormatToDXGIFormat(void)
7250 static const struct format_pair
7252 DXGI_FORMAT dxgi_format;
7253 DWORD d3d9_format;
7255 formats_map[] =
7257 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
7258 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
7259 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
7260 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
7261 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
7262 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
7263 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
7264 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
7265 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
7266 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
7267 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
7268 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
7269 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
7270 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
7271 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
7272 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
7273 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
7274 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
7275 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
7276 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
7277 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
7278 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
7279 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
7280 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
7281 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
7282 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
7283 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
7284 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
7285 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
7286 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
7287 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
7288 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
7289 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
7290 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
7291 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
7292 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
7293 { DXGI_FORMAT_P8, D3DFMT_P8 },
7294 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
7296 DXGI_FORMAT format;
7297 unsigned int i;
7299 if (!pMFMapDX9FormatToDXGIFormat)
7301 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
7302 return;
7305 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
7307 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
7308 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#lx.\n",
7309 format, formats_map[i].d3d9_format);
7313 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
7314 REFIID riid, void **obj)
7316 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
7317 IsEqualIID(riid, &IID_IUnknown))
7319 *obj = iface;
7320 IMFVideoSampleAllocatorNotify_AddRef(iface);
7321 return S_OK;
7324 *obj = NULL;
7325 return E_NOINTERFACE;
7328 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
7330 return 2;
7333 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
7335 return 1;
7338 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
7340 return E_NOTIMPL;
7343 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
7345 test_notify_callback_QueryInterface,
7346 test_notify_callback_AddRef,
7347 test_notify_callback_Release,
7348 test_notify_callback_NotifyRelease,
7351 static IMFMediaType * create_video_type(const GUID *subtype)
7353 IMFMediaType *video_type;
7354 HRESULT hr;
7356 hr = MFCreateMediaType(&video_type);
7357 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7359 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
7360 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7362 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
7363 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7365 return video_type;
7368 static ID3D11Device *create_d3d11_device(void)
7370 static const D3D_FEATURE_LEVEL default_feature_level[] =
7372 D3D_FEATURE_LEVEL_11_0,
7373 D3D_FEATURE_LEVEL_10_1,
7374 D3D_FEATURE_LEVEL_10_0,
7376 const D3D_FEATURE_LEVEL *feature_level;
7377 unsigned int feature_level_count;
7378 ID3D11Device *device;
7380 feature_level = default_feature_level;
7381 feature_level_count = ARRAY_SIZE(default_feature_level);
7383 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
7384 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7385 return device;
7386 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
7387 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7388 return device;
7389 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
7390 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7391 return device;
7393 return NULL;
7396 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
7397 const BYTE *data, unsigned int src_pitch)
7399 ID3D11DeviceContext *immediate_context;
7400 ID3D11Device *device;
7402 ID3D11Texture2D_GetDevice(texture, &device);
7403 ID3D11Device_GetImmediateContext(device, &immediate_context);
7405 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
7406 sub_resource_idx, NULL, data, src_pitch, 0);
7408 ID3D11DeviceContext_Release(immediate_context);
7409 ID3D11Device_Release(device);
7412 static ID3D12Device *create_d3d12_device(void)
7414 ID3D12Device *device;
7415 HRESULT hr;
7417 if (!pD3D12CreateDevice) return NULL;
7419 hr = pD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
7420 if (FAILED(hr))
7421 return NULL;
7423 return device;
7426 static void test_d3d11_surface_buffer(void)
7428 DWORD max_length, cur_length, length, color;
7429 BYTE *data, *data2, *buffer_start;
7430 IMFDXGIBuffer *dxgi_buffer;
7431 D3D11_TEXTURE2D_DESC desc;
7432 IMF2DBuffer2 *_2dbuffer2;
7433 ID3D11Texture2D *texture;
7434 IMF2DBuffer *_2d_buffer;
7435 IMFMediaBuffer *buffer;
7436 ID3D11Device *device;
7437 BYTE buff[64 * 64 * 4];
7438 LONG pitch, pitch2;
7439 UINT index, size;
7440 IUnknown *obj;
7441 HRESULT hr;
7443 if (!pMFCreateDXGISurfaceBuffer)
7445 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
7446 return;
7449 /* d3d11 */
7450 if (!(device = create_d3d11_device()))
7452 skip("Failed to create a D3D11 device, skipping tests.\n");
7453 return;
7456 memset(&desc, 0, sizeof(desc));
7457 desc.Width = 64;
7458 desc.Height = 64;
7459 desc.ArraySize = 1;
7460 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7461 desc.SampleDesc.Count = 1;
7462 desc.SampleDesc.Quality = 0;
7464 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7465 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7467 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
7468 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7470 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7471 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7472 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7473 check_interface(buffer, &IID_IMFGetService, FALSE);
7475 max_length = 0;
7476 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
7477 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7478 ok(!!max_length, "Unexpected length %lu.\n", max_length);
7480 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7481 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7482 ok(!cur_length, "Unexpected length %lu.\n", cur_length);
7484 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
7485 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7487 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7488 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7489 ok(cur_length == 2 * max_length, "Unexpected length %lu.\n", cur_length);
7491 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7492 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7494 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
7495 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7496 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
7497 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7498 ok(length == max_length, "Unexpected length %lu.\n", length);
7499 IMF2DBuffer_Release(_2d_buffer);
7501 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7502 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7504 EXPECT_REF(texture, 2);
7505 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
7506 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7507 EXPECT_REF(texture, 3);
7508 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
7509 IUnknown_Release(obj);
7511 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
7512 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7514 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
7515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7516 ok(index == 0, "Unexpected subresource index.\n");
7518 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7519 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7521 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7522 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7524 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7525 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#lx.\n", hr);
7527 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
7528 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7530 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
7531 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7532 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
7533 IUnknown_Release(obj);
7535 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7536 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7538 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
7539 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7541 IMFDXGIBuffer_Release(dxgi_buffer);
7543 /* Texture updates. */
7544 color = get_d3d11_texture_color(texture, 0, 0);
7545 ok(!color, "Unexpected texture color %#lx.\n", color);
7547 max_length = cur_length = 0;
7548 data = NULL;
7549 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7550 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7551 ok(max_length && max_length == cur_length, "Unexpected length %lu.\n", max_length);
7552 if (data) *(DWORD *)data = ~0u;
7554 color = get_d3d11_texture_color(texture, 0, 0);
7555 ok(!color, "Unexpected texture color %#lx.\n", color);
7557 hr = IMFMediaBuffer_Unlock(buffer);
7558 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7560 color = get_d3d11_texture_color(texture, 0, 0);
7561 ok(color == ~0u, "Unexpected texture color %#lx.\n", color);
7563 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7564 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7565 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#lx.\n", *(DWORD *)data);
7567 hr = IMFMediaBuffer_Unlock(buffer);
7568 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7570 /* Lock2D()/Unlock2D() */
7571 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7574 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7575 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7577 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7578 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7579 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
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_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7586 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7587 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7589 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7590 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
7592 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7593 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7595 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7598 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7599 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7601 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7604 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7605 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
7607 hr = IMFMediaBuffer_Unlock(buffer);
7608 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7610 IMF2DBuffer_Release(_2d_buffer);
7612 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
7613 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7615 /* Lock flags are honored, so reads and writes are discarded if
7616 * the flags are not correct. Also, previous content is discarded
7617 * when locking for writing and not for reading. */
7618 put_d3d11_texture_color(texture, 0, 0, 0xcdcdcdcd);
7619 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7620 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7621 ok(data == data2, "Unexpected scanline pointer.\n");
7622 ok(*(DWORD *)data == 0xcdcdcdcd, "Unexpected leading dword %#lx.\n", *(DWORD *)data);
7623 memset(data, 0xab, 4);
7624 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7626 color = get_d3d11_texture_color(texture, 0, 0);
7627 ok(color == 0xcdcdcdcd, "Unexpected leading dword %#lx.\n", color);
7628 put_d3d11_texture_color(texture, 0, 0, 0xefefefef);
7630 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7631 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7632 ok(*(DWORD *)data != 0xefefefef, "Unexpected leading dword.\n");
7633 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7635 color = get_d3d11_texture_color(texture, 0, 0);
7636 ok(color != 0xefefefef, "Unexpected leading dword.\n");
7638 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7639 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7640 ok(*(DWORD *)data != 0xefefefef, "Unexpected leading dword.\n");
7641 memset(data, 0x89, 4);
7642 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7644 color = get_d3d11_texture_color(texture, 0, 0);
7645 ok(color == 0x89898989, "Unexpected leading dword %#lx.\n", color);
7647 /* When relocking for writing, stores are committed even if they
7648 * were issued before relocking. */
7649 put_d3d11_texture_color(texture, 0, 0, 0xcdcdcdcd);
7650 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7651 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7652 memset(data, 0xab, 4);
7653 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7654 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7655 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7656 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7658 color = get_d3d11_texture_color(texture, 0, 0);
7659 ok(color == 0xabababab, "Unexpected leading dword %#lx.\n", color);
7661 /* Flags incompatibilities. */
7662 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7663 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7664 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7665 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7666 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7667 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7668 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7669 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7670 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7671 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7672 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7673 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7674 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
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);
7683 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7684 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7685 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7686 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7687 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7688 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7689 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7690 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7691 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7692 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7693 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7694 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7695 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
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);
7704 /* Except when originally locking for writing. */
7705 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7706 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7707 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7708 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7709 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7710 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7711 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7712 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7713 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7714 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7715 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7716 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7717 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7718 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7720 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7721 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7723 IMF2DBuffer2_Release(_2dbuffer2);
7724 IMFMediaBuffer_Release(buffer);
7726 /* Bottom up. */
7727 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
7728 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7730 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7733 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7734 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7735 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7737 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7738 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7739 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7741 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7742 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7744 IMF2DBuffer_Release(_2d_buffer);
7745 IMFMediaBuffer_Release(buffer);
7747 ID3D11Texture2D_Release(texture);
7749 memset(&desc, 0, sizeof(desc));
7750 desc.Width = 64;
7751 desc.Height = 64;
7752 desc.ArraySize = 1;
7753 desc.MipLevels = 1;
7754 desc.Format = DXGI_FORMAT_NV12;
7755 desc.SampleDesc.Count = 1;
7756 desc.SampleDesc.Quality = 0;
7758 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7759 if (SUCCEEDED(hr))
7761 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
7762 ok(hr == S_OK, "got %#lx.\n", hr);
7763 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
7764 ok(hr == S_OK, "got %#lx.\n", hr);
7766 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &buffer_start, &length);
7767 ok(hr == S_OK, "got %#lx.\n", hr);
7769 ok(pitch >= desc.Width, "got %ld.\n", pitch);
7770 ok(length == pitch * desc.Height * 3 / 2, "got %lu.\n", length);
7772 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7773 ok(hr == S_OK, "got %#lx.\n", hr);
7775 IMF2DBuffer2_Release(_2dbuffer2);
7776 IMFMediaBuffer_Release(buffer);
7777 ID3D11Texture2D_Release(texture);
7779 else
7781 win_skip("Failed to create NV12 texture, hr %#lx, skipping test.\n", hr);
7782 ID3D11Device_Release(device);
7783 return;
7786 /* Subresource index 1.
7787 * When WARP d3d11 device is used, this test leaves the device in a broken state, so it should
7788 * be kept last. */
7789 memset(&desc, 0, sizeof(desc));
7790 desc.Width = 64;
7791 desc.Height = 64;
7792 desc.ArraySize = 1;
7793 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7794 desc.SampleDesc.Count = 1;
7795 desc.SampleDesc.Quality = 0;
7797 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7798 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7800 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
7801 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7803 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7804 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7806 /* Pitch reflects top level. */
7807 memset(buff, 0, sizeof(buff));
7808 *(DWORD *)buff = 0xff00ff00;
7809 update_d3d11_texture(texture, 1, buff, 64 * 4);
7811 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7813 ok(pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7814 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#lx.\n", *(DWORD *)data);
7816 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7817 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7819 IMF2DBuffer_Release(_2d_buffer);
7820 IMFMediaBuffer_Release(buffer);
7821 ID3D11Texture2D_Release(texture);
7823 ID3D11Device_Release(device);
7826 static void test_d3d12_surface_buffer(void)
7828 IMFDXGIBuffer *dxgi_buffer;
7829 D3D12_HEAP_PROPERTIES heap_props;
7830 D3D12_RESOURCE_DESC desc;
7831 ID3D12Resource *resource;
7832 IMFMediaBuffer *buffer;
7833 unsigned int refcount;
7834 ID3D12Device *device;
7835 IUnknown *obj;
7836 HRESULT hr;
7838 /* d3d12 */
7839 if (!(device = create_d3d12_device()))
7841 skip("Failed to create a D3D12 device, skipping tests.\n");
7842 return;
7845 memset(&heap_props, 0, sizeof(heap_props));
7846 heap_props.Type = D3D12_HEAP_TYPE_DEFAULT;
7848 memset(&desc, 0, sizeof(desc));
7849 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
7850 desc.Alignment = 0;
7851 desc.Width = 32;
7852 desc.Height = 32;
7853 desc.DepthOrArraySize = 1;
7854 desc.MipLevels = 1;
7855 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7856 desc.SampleDesc.Count = 1;
7857 desc.SampleDesc.Quality = 0;
7858 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
7859 desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
7861 hr = ID3D12Device_CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE,
7862 &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&resource);
7863 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7865 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D12Resource, (IUnknown *)resource, 0, FALSE, &buffer);
7866 if (hr == E_INVALIDARG)
7868 todo_wine
7869 win_skip("D3D12 resource buffers are not supported.\n");
7870 goto notsupported;
7872 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7874 if (SUCCEEDED(hr))
7876 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7877 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7878 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7879 check_interface(buffer, &IID_IMFGetService, FALSE);
7881 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7882 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7884 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&obj);
7885 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7886 ok(obj == (IUnknown *)resource, "Unexpected resource pointer.\n");
7887 IUnknown_Release(obj);
7889 IMFDXGIBuffer_Release(dxgi_buffer);
7890 IMFMediaBuffer_Release(buffer);
7893 notsupported:
7894 ID3D12Resource_Release(resource);
7895 refcount = ID3D12Device_Release(device);
7896 ok(!refcount, "Unexpected device refcount %u.\n", refcount);
7899 static void test_sample_allocator_sysmem(void)
7901 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
7902 IMFMediaType *media_type, *video_type, *video_type2;
7903 IMFVideoSampleAllocatorCallback *allocator_cb;
7904 IMFVideoSampleAllocatorEx *allocatorex;
7905 IMFVideoSampleAllocator *allocator;
7906 IMFSample *sample, *sample2;
7907 IMFAttributes *attributes;
7908 IMFMediaBuffer *buffer;
7909 LONG refcount, count;
7910 DWORD buffer_count;
7911 IUnknown *unk;
7912 HRESULT hr;
7914 if (!pMFCreateVideoSampleAllocatorEx)
7915 return;
7917 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
7918 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7920 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
7921 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
7922 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
7924 IUnknown_Release(unk);
7926 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7927 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7929 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7930 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7932 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7933 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7935 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
7936 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7938 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7939 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7941 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
7942 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7944 count = 10;
7945 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7946 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7947 ok(!count, "Unexpected count %ld.\n", count);
7949 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7950 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7952 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7953 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7955 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
7956 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7958 hr = MFCreateMediaType(&media_type);
7959 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7961 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
7962 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7964 video_type = create_video_type(&MFVideoFormat_RGB32);
7965 video_type2 = create_video_type(&MFVideoFormat_RGB32);
7967 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7968 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7970 /* Frame size is required. */
7971 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7972 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7974 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7975 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7977 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
7978 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7980 EXPECT_REF(video_type, 1);
7981 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7982 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7983 EXPECT_REF(video_type, 2);
7985 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
7986 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7988 /* Setting identical type does not replace it. */
7989 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7990 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7991 EXPECT_REF(video_type, 2);
7992 EXPECT_REF(video_type2, 1);
7994 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7997 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7998 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7999 EXPECT_REF(video_type2, 2);
8000 EXPECT_REF(video_type, 1);
8002 /* Modify referenced type. */
8003 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
8004 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8006 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8007 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8008 EXPECT_REF(video_type, 2);
8009 EXPECT_REF(video_type2, 1);
8011 count = 0;
8012 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8013 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8014 ok(count == 1, "Unexpected count %ld.\n", count);
8016 sample = NULL;
8017 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8018 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8019 refcount = get_refcount(sample);
8021 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8022 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8023 ok(!count, "Unexpected count %ld.\n", count);
8025 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
8026 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
8028 /* Reinitialize with active sample. */
8029 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
8030 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8031 ok(refcount == get_refcount(sample), "Unexpected refcount %lu.\n", get_refcount(sample));
8032 EXPECT_REF(video_type, 2);
8034 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8035 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8036 todo_wine
8037 ok(!count, "Unexpected count %ld.\n", count);
8039 check_interface(sample, &IID_IMFTrackedSample, TRUE);
8040 check_interface(sample, &IID_IMFDesiredSample, FALSE);
8042 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8043 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8045 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8046 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8047 check_interface(buffer, &IID_IMFGetService, TRUE);
8048 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
8050 IMFMediaBuffer_Release(buffer);
8052 hr = IMFSample_GetBufferCount(sample, &buffer_count);
8053 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8054 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
8056 IMFSample_Release(sample);
8058 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
8059 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8060 todo_wine
8061 EXPECT_REF(video_type, 2);
8063 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8064 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8065 ok(!count, "Unexpected count %ld.\n", count);
8067 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8068 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
8070 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
8071 IMFVideoSampleAllocator_Release(allocator);
8073 /* IMFVideoSampleAllocatorEx */
8074 hr = MFCreateAttributes(&attributes, 0);
8075 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8077 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8078 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8080 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
8081 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8083 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
8084 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8086 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
8087 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8089 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8090 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
8092 EXPECT_REF(attributes, 1);
8093 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8094 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8095 EXPECT_REF(attributes, 2);
8097 count = 0;
8098 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8100 ok(count == 1, "Unexpected count %ld.\n", count);
8102 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8105 hr = IMFSample_GetBufferCount(sample, &buffer_count);
8106 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8107 ok(buffer_count == 2, "Unexpected buffer count %lu.\n", buffer_count);
8109 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
8110 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
8112 /* Reinitialize with already allocated samples. */
8113 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
8114 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8115 EXPECT_REF(attributes, 1);
8117 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
8118 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8119 IMFSample_Release(sample2);
8121 IMFSample_Release(sample);
8123 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
8124 IMFVideoSampleAllocatorEx_Release(allocatorex);
8125 IMFAttributes_Release(attributes);
8128 static void test_sample_allocator_d3d9(void)
8130 IDirect3DDeviceManager9 *d3d9_manager;
8131 IMFVideoSampleAllocator *allocator;
8132 IDirect3DDevice9 *d3d9_device;
8133 IMFMediaType *video_type;
8134 IMFMediaBuffer *buffer;
8135 unsigned int token;
8136 IMFSample *sample;
8137 IDirect3D9 *d3d9;
8138 HWND window;
8139 HRESULT hr;
8141 if (!pMFCreateVideoSampleAllocatorEx)
8142 return;
8144 window = create_window();
8145 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8146 ok(!!d3d9, "Failed to create a D3D9 object.\n");
8147 if (!(d3d9_device = create_d3d9_device(d3d9, window)))
8149 skip("Failed to create a D3D9 device, skipping tests.\n");
8150 goto done;
8153 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
8154 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8156 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
8157 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8159 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8160 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8162 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
8163 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8165 video_type = create_video_type(&MFVideoFormat_RGB32);
8167 /* Frame size is required. */
8168 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8169 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8171 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8172 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8174 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8177 check_interface(sample, &IID_IMFTrackedSample, TRUE);
8178 check_interface(sample, &IID_IMFDesiredSample, FALSE);
8180 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8181 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8183 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8184 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8185 check_interface(buffer, &IID_IMFGetService, TRUE);
8186 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
8188 IMFSample_Release(sample);
8189 IMFMediaBuffer_Release(buffer);
8191 IMFVideoSampleAllocator_Release(allocator);
8192 IMFMediaType_Release(video_type);
8193 IDirect3DDeviceManager9_Release(d3d9_manager);
8194 IDirect3DDevice9_Release(d3d9_device);
8196 done:
8197 IDirect3D9_Release(d3d9);
8198 DestroyWindow(window);
8201 static void test_sample_allocator_d3d11(void)
8203 IMFMediaType *video_type;
8204 IMFVideoSampleAllocatorEx *allocatorex;
8205 IMFVideoSampleAllocator *allocator;
8206 unsigned int i, token;
8207 IMFDXGIDeviceManager *manager;
8208 IMFSample *sample;
8209 IMFDXGIBuffer *dxgi_buffer;
8210 IMFAttributes *attributes;
8211 D3D11_TEXTURE2D_DESC desc;
8212 ID3D11Texture2D *texture;
8213 IMFMediaBuffer *buffer;
8214 ID3D11Device *device;
8215 HRESULT hr;
8216 BYTE *data;
8217 static const unsigned int usage[] =
8219 D3D11_USAGE_DEFAULT,
8220 D3D11_USAGE_IMMUTABLE,
8221 D3D11_USAGE_DYNAMIC,
8222 D3D11_USAGE_STAGING,
8223 D3D11_USAGE_STAGING + 1,
8225 static const unsigned int sharing[] =
8227 D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
8228 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
8229 D3D11_RESOURCE_MISC_SHARED,
8232 if (!pMFCreateVideoSampleAllocatorEx)
8233 return;
8235 if (!(device = create_d3d11_device()))
8237 skip("Failed to create a D3D11 device, skipping tests.\n");
8238 return;
8241 hr = pMFCreateDXGIDeviceManager(&token, &manager);
8242 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
8244 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
8245 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
8247 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8248 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8250 EXPECT_REF(manager, 1);
8251 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
8252 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8253 EXPECT_REF(manager, 2);
8255 video_type = create_video_type(&MFVideoFormat_RGB32);
8256 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8257 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8259 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8260 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8262 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8263 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8265 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8266 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8268 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8269 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8270 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8271 check_interface(buffer, &IID_IMFGetService, FALSE);
8273 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8274 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8276 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8277 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8279 ID3D11Texture2D_GetDesc(texture, &desc);
8280 ok(desc.Width == 64, "Unexpected width %u.\n", desc.Width);
8281 ok(desc.Height == 64, "Unexpected height %u.\n", desc.Height);
8282 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
8283 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
8284 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
8285 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
8286 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
8287 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
8288 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
8289 desc.BindFlags);
8290 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8291 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
8293 ID3D11Texture2D_Release(texture);
8294 IMFDXGIBuffer_Release(dxgi_buffer);
8296 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
8297 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8299 hr = IMFMediaBuffer_Unlock(buffer);
8300 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8302 IMFMediaBuffer_Release(buffer);
8303 IMFSample_Release(sample);
8305 IMFVideoSampleAllocator_Release(allocator);
8307 /* MF_SA_D3D11_USAGE */
8308 hr = MFCreateAttributes(&attributes, 1);
8309 ok(hr == S_OK, "Failed to create attributes, hr %#lx.\n", hr);
8311 for (i = 0; i < ARRAY_SIZE(usage); ++i)
8313 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8314 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8316 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
8317 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8319 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
8320 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8322 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8323 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
8325 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8326 IMFVideoSampleAllocatorEx_Release(allocatorex);
8327 continue;
8329 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", usage[i], hr);
8331 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
8332 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8334 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8335 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8337 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8338 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8340 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8341 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8343 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8344 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8346 ID3D11Texture2D_GetDesc(texture, &desc);
8347 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
8348 if (usage[i] == D3D11_USAGE_DEFAULT)
8350 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
8351 desc.BindFlags);
8352 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8354 else if (usage[i] == D3D11_USAGE_DYNAMIC)
8356 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
8357 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8359 else if (usage[i] == D3D11_USAGE_STAGING)
8361 ok(!desc.BindFlags, "Unexpected bind flags %#x.\n", desc.BindFlags);
8362 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
8363 desc.CPUAccessFlags);
8365 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
8367 ID3D11Texture2D_Release(texture);
8368 IMFDXGIBuffer_Release(dxgi_buffer);
8369 IMFMediaBuffer_Release(buffer);
8371 IMFSample_Release(sample);
8373 IMFVideoSampleAllocatorEx_Release(allocatorex);
8376 /* MF_SA_D3D11_SHARED, MF_SA_D3D11_SHARED_WITHOUT_MUTEX */
8377 for (i = 0; i < ARRAY_SIZE(sharing); ++i)
8379 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8380 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8382 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
8383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8385 hr = IMFAttributes_DeleteAllItems(attributes);
8386 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8388 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
8389 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8391 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
8393 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED, TRUE);
8394 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8397 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED)
8399 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
8400 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8403 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8404 if (sharing[i] == (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED))
8406 todo_wine
8407 ok(hr == E_INVALIDARG, "%u: Unexpected hr %#lx.\n", i, hr);
8408 IMFVideoSampleAllocatorEx_Release(allocatorex);
8409 continue;
8411 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", i, hr);
8413 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8414 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8416 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8417 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8419 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8420 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8422 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8423 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8425 ID3D11Texture2D_GetDesc(texture, &desc);
8426 ok(desc.MiscFlags == sharing[i], "%u: unexpected misc flags %#x.\n", i, desc.MiscFlags);
8428 ID3D11Texture2D_Release(texture);
8429 IMFDXGIBuffer_Release(dxgi_buffer);
8430 IMFMediaBuffer_Release(buffer);
8432 IMFSample_Release(sample);
8434 IMFVideoSampleAllocatorEx_Release(allocatorex);
8437 IMFAttributes_Release(attributes);
8439 IMFDXGIDeviceManager_Release(manager);
8440 ID3D11Device_Release(device);
8443 static void test_sample_allocator_d3d12(void)
8445 IMFVideoSampleAllocator *allocator = NULL;
8446 D3D12_HEAP_PROPERTIES heap_props;
8447 IMFDXGIDeviceManager *manager;
8448 D3D12_HEAP_FLAGS heap_flags;
8449 IMFDXGIBuffer *dxgi_buffer;
8450 IMFMediaType *video_type;
8451 ID3D12Resource *resource;
8452 D3D12_RESOURCE_DESC desc;
8453 IMFMediaBuffer *buffer;
8454 ID3D12Device *device;
8455 unsigned int token;
8456 IMFSample *sample;
8457 HRESULT hr;
8459 if (!(device = create_d3d12_device()))
8461 skip("Failed to create a D3D12 device, skipping tests.\n");
8462 return;
8465 hr = pMFCreateDXGIDeviceManager(&token, &manager);
8466 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
8468 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
8469 if (FAILED(hr))
8471 win_skip("Device manager does not support D3D12 devices.\n");
8472 goto done;
8474 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
8476 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8477 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8479 EXPECT_REF(manager, 1);
8480 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
8481 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8482 EXPECT_REF(manager, 2);
8484 video_type = create_video_type(&MFVideoFormat_RGB32);
8485 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8486 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8487 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_D3D_RESOURCE_VERSION, MF_D3D12_RESOURCE);
8488 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8490 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8491 todo_wine
8492 ok(hr == S_OK || broken(hr == MF_E_UNEXPECTED) /* Some Win10 versions fail. */, "Unexpected hr %#lx.\n", hr);
8493 if (FAILED(hr)) goto done;
8495 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8498 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8499 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8501 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8502 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8503 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8504 check_interface(buffer, &IID_IMFGetService, FALSE);
8506 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8507 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8509 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&resource);
8510 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8512 resource->lpVtbl->GetDesc(resource, &desc);
8513 ok(desc.Width == 64, "Unexpected width.\n");
8514 ok(desc.Height == 64, "Unexpected height.\n");
8515 ok(desc.DepthOrArraySize == 1, "Unexpected array size %u.\n", desc.DepthOrArraySize);
8516 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
8517 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
8518 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
8519 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
8520 ok(!desc.Layout, "Unexpected layout %u.\n", desc.Layout);
8521 ok(!desc.Flags, "Unexpected flags %#x.\n", desc.Flags);
8523 hr = ID3D12Resource_GetHeapProperties(resource, &heap_props, &heap_flags);
8524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8525 ok(heap_props.Type == D3D12_HEAP_TYPE_DEFAULT, "Unexpected heap type %u.\n", heap_props.Type);
8526 ok(heap_props.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN, "Unexpected page property %u.\n",
8527 heap_props.CPUPageProperty);
8528 ok(!heap_props.MemoryPoolPreference, "Unexpected pool preference %u.\n", heap_props.MemoryPoolPreference);
8529 ok(heap_flags == D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, "Unexpected heap flags %#x.\n", heap_flags);
8531 ID3D12Resource_Release(resource);
8532 IMFDXGIBuffer_Release(dxgi_buffer);
8533 IMFMediaBuffer_Release(buffer);
8534 IMFSample_Release(sample);
8536 done:
8537 if (allocator)
8538 IMFVideoSampleAllocator_Release(allocator);
8539 IMFDXGIDeviceManager_Release(manager);
8540 ID3D12Device_Release(device);
8543 static void test_MFLockSharedWorkQueue(void)
8545 DWORD taskid, queue, queue2;
8546 HRESULT hr;
8548 if (!pMFLockSharedWorkQueue)
8550 win_skip("MFLockSharedWorkQueue() is not available.\n");
8551 return;
8554 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
8555 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
8557 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
8558 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8560 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
8561 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8563 taskid = 0;
8564 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
8565 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8567 queue = 0;
8568 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
8569 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
8571 queue2 = 0;
8572 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
8573 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8574 ok(queue == queue2, "Unexpected queue %#lx.\n", queue2);
8576 hr = MFUnlockWorkQueue(queue2);
8577 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8579 hr = MFUnlockWorkQueue(queue);
8580 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8582 hr = MFShutdown();
8583 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
8586 static void test_MFllMulDiv(void)
8588 /* (a * b + d) / c */
8589 static const struct muldivtest
8591 LONGLONG a;
8592 LONGLONG b;
8593 LONGLONG c;
8594 LONGLONG d;
8595 LONGLONG result;
8597 muldivtests[] =
8599 { 0, 0, 0, 0, _I64_MAX },
8600 { 1000000, 1000000, 2, 0, 500000000000 },
8601 { _I64_MAX, 3, _I64_MAX, 0, 3 },
8602 { _I64_MAX, 3, _I64_MAX, 1, 3 },
8603 { -10000, 3, 100, 0, -300 },
8604 { 2, 0, 3, 5, 1 },
8605 { 2, 1, 1, -3, -1 },
8606 /* a * b product does not fit in uint64_t */
8607 { _I64_MAX, 4, 8, 0, _I64_MAX / 2 },
8608 /* Large a * b product, large denominator */
8609 { _I64_MAX, 4, 0x100000000, 0, 0x1ffffffff },
8611 unsigned int i;
8613 for (i = 0; i < ARRAY_SIZE(muldivtests); ++i)
8615 LONGLONG result;
8617 result = MFllMulDiv(muldivtests[i].a, muldivtests[i].b, muldivtests[i].c, muldivtests[i].d);
8618 ok(result == muldivtests[i].result, "%u: unexpected result %s, expected %s.\n", i,
8619 wine_dbgstr_longlong(result), wine_dbgstr_longlong(muldivtests[i].result));
8623 static void test_shared_dxgi_device_manager(void)
8625 IMFDXGIDeviceManager *manager;
8626 HRESULT hr;
8627 UINT token;
8629 if (!pMFLockDXGIDeviceManager)
8631 win_skip("Shared DXGI device manager is not supported.\n");
8632 return;
8635 hr = pMFUnlockDXGIDeviceManager();
8636 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8638 manager = NULL;
8639 hr = pMFLockDXGIDeviceManager(NULL, &manager);
8640 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8641 ok(!!manager, "Unexpected instance.\n");
8643 hr = pMFLockDXGIDeviceManager(&token, &manager);
8644 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8646 EXPECT_REF(manager, 3);
8648 hr = pMFUnlockDXGIDeviceManager();
8649 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8651 EXPECT_REF(manager, 2);
8653 hr = pMFUnlockDXGIDeviceManager();
8654 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8657 static void check_video_format(const MFVIDEOFORMAT *format, unsigned int width, unsigned int height,
8658 DWORD d3dformat)
8660 unsigned int transfer_function;
8661 GUID guid;
8663 if (!d3dformat) d3dformat = D3DFMT_X8R8G8B8;
8665 switch (d3dformat)
8667 case D3DFMT_X8R8G8B8:
8668 case D3DFMT_R8G8B8:
8669 case D3DFMT_A8R8G8B8:
8670 case D3DFMT_R5G6B5:
8671 case D3DFMT_X1R5G5B5:
8672 case D3DFMT_A2B10G10R10:
8673 case D3DFMT_P8:
8674 transfer_function = MFVideoTransFunc_sRGB;
8675 break;
8676 default:
8677 transfer_function = MFVideoTransFunc_10;
8680 memcpy(&guid, &MFVideoFormat_Base, sizeof(guid));
8681 guid.Data1 = d3dformat;
8683 ok(format->dwSize == sizeof(*format), "Unexpected format size.\n");
8684 ok(format->videoInfo.dwWidth == width, "Unexpected width %lu.\n", format->videoInfo.dwWidth);
8685 ok(format->videoInfo.dwHeight == height, "Unexpected height %lu.\n", format->videoInfo.dwHeight);
8686 ok(format->videoInfo.PixelAspectRatio.Numerator == 1 &&
8687 format->videoInfo.PixelAspectRatio.Denominator == 1, "Unexpected PAR.\n");
8688 ok(format->videoInfo.SourceChromaSubsampling == MFVideoChromaSubsampling_Unknown, "Unexpected chroma subsampling.\n");
8689 ok(format->videoInfo.InterlaceMode == MFVideoInterlace_Progressive, "Unexpected interlace mode %u.\n",
8690 format->videoInfo.InterlaceMode);
8691 ok(format->videoInfo.TransferFunction == transfer_function, "Unexpected transfer function %u.\n",
8692 format->videoInfo.TransferFunction);
8693 ok(format->videoInfo.ColorPrimaries == MFVideoPrimaries_BT709, "Unexpected color primaries %u.\n",
8694 format->videoInfo.ColorPrimaries);
8695 ok(format->videoInfo.TransferMatrix == MFVideoTransferMatrix_Unknown, "Unexpected transfer matrix.\n");
8696 ok(format->videoInfo.SourceLighting == MFVideoLighting_office, "Unexpected source lighting %u.\n",
8697 format->videoInfo.SourceLighting);
8698 ok(format->videoInfo.FramesPerSecond.Numerator == 60 &&
8699 format->videoInfo.FramesPerSecond.Denominator == 1, "Unexpected frame rate %lu/%lu.\n",
8700 format->videoInfo.FramesPerSecond.Numerator, format->videoInfo.FramesPerSecond.Denominator);
8701 ok(format->videoInfo.NominalRange == MFNominalRange_Normal, "Unexpected nominal range %u.\n",
8702 format->videoInfo.NominalRange);
8703 ok(format->videoInfo.GeometricAperture.Area.cx == width && format->videoInfo.GeometricAperture.Area.cy == height,
8704 "Unexpected geometric aperture.\n");
8705 ok(!memcmp(&format->videoInfo.GeometricAperture, &format->videoInfo.MinimumDisplayAperture, sizeof(MFVideoArea)),
8706 "Unexpected minimum display aperture.\n");
8707 ok(format->videoInfo.PanScanAperture.Area.cx == 0 && format->videoInfo.PanScanAperture.Area.cy == 0,
8708 "Unexpected geometric aperture.\n");
8709 ok(format->videoInfo.VideoFlags == 0, "Unexpected video flags.\n");
8710 ok(IsEqualGUID(&format->guidFormat, &guid), "Unexpected format guid %s.\n", wine_dbgstr_guid(&format->guidFormat));
8711 ok(format->compressedInfo.AvgBitrate == 0, "Unexpected bitrate.\n");
8712 ok(format->compressedInfo.AvgBitErrorRate == 0, "Unexpected error bitrate.\n");
8713 ok(format->compressedInfo.MaxKeyFrameSpacing == 0, "Unexpected MaxKeyFrameSpacing.\n");
8714 ok(format->surfaceInfo.Format == d3dformat, "Unexpected format %lu.\n", format->surfaceInfo.Format);
8715 ok(format->surfaceInfo.PaletteEntries == 0, "Unexpected palette size %lu.\n", format->surfaceInfo.PaletteEntries);
8718 static void test_MFInitVideoFormat_RGB(void)
8720 static const DWORD formats[] =
8722 0, /* same D3DFMT_X8R8G8B8 */
8723 D3DFMT_X8R8G8B8,
8724 D3DFMT_R8G8B8,
8725 D3DFMT_A8R8G8B8,
8726 D3DFMT_R5G6B5,
8727 D3DFMT_X1R5G5B5,
8728 D3DFMT_A2B10G10R10,
8729 D3DFMT_P8,
8730 D3DFMT_L8,
8731 D3DFMT_YUY2,
8732 D3DFMT_DXT1,
8733 D3DFMT_D16,
8734 D3DFMT_L16,
8735 D3DFMT_A16B16G16R16F,
8737 MFVIDEOFORMAT format;
8738 unsigned int i;
8739 HRESULT hr;
8741 if (!pMFInitVideoFormat_RGB)
8743 win_skip("MFInitVideoFormat_RGB is not available.\n");
8744 return;
8747 hr = pMFInitVideoFormat_RGB(NULL, 64, 32, 0);
8748 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8750 for (i = 0; i < ARRAY_SIZE(formats); ++i)
8752 memset(&format, 0, sizeof(format));
8753 hr = pMFInitVideoFormat_RGB(&format, 64, 32, formats[i]);
8754 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8755 if (SUCCEEDED(hr))
8756 check_video_format(&format, 64, 32, formats[i]);
8760 static void test_MFCreateVideoMediaTypeFromVideoInfoHeader(void)
8762 IMFVideoMediaType *media_type;
8763 KS_VIDEOINFOHEADER vih;
8764 UINT32 value32;
8765 UINT64 value64;
8766 HRESULT hr;
8767 GUID guid;
8769 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(NULL, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8770 todo_wine
8771 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8773 memset(&vih, 0, sizeof(vih));
8774 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8775 todo_wine
8776 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8777 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
8778 todo_wine
8779 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8780 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
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);
8785 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8786 vih.bmiHeader.biPlanes = 1;
8787 vih.bmiHeader.biWidth = 16;
8788 vih.bmiHeader.biHeight = 32;
8789 vih.bmiHeader.biBitCount = 32;
8791 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8792 MFVideoFlag_AnalogProtected, &GUID_NULL, &media_type);
8793 todo_wine
8794 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8795 if (FAILED(hr)) return;
8796 IMFVideoMediaType_Release(media_type);
8798 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8799 MFVideoFlag_AnalogProtected, NULL, &media_type);
8800 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8802 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8803 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8804 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8805 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8806 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8807 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8808 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8809 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8810 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8811 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8813 ok(value64 == ((UINT64)3 << 32 | 2), "Unexpected value %#I64x.\n", value64);
8814 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DRM_FLAGS, &value32);
8815 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8816 ok(value32 == MFVideoDRMFlag_AnalogProtected, "Unexpected value %#x.\n", value32);
8817 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8818 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8819 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8820 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8822 ok(value32 == 2048, "Unexpected value %u.\n", value32);
8823 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8824 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8825 ok(value32 == -64, "Unexpected value %d.\n", value32);
8826 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8827 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8828 ok(!!value32, "Unexpected value %#x.\n", value32);
8829 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8830 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8831 ok(!!value32, "Unexpected value %#x.\n", value32);
8833 IMFVideoMediaType_Release(media_type);
8835 /* Negative height. */
8836 vih.bmiHeader.biHeight = -32;
8837 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
8838 MFVideoFlag_AnalogProtected, NULL, &media_type);
8839 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8840 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8841 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8842 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8843 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8844 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8845 ok(value32 == 64, "Unexpected value %d.\n", value32);
8846 IMFVideoMediaType_Release(media_type);
8849 static void test_MFInitMediaTypeFromVideoInfoHeader(void)
8851 IMFMediaType *media_type;
8852 VIDEOINFOHEADER vih;
8853 UINT32 value32;
8854 UINT64 value64;
8855 HRESULT hr;
8856 GUID guid;
8858 hr = MFCreateMediaType(&media_type);
8859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8861 memset(&vih, 0, sizeof(vih));
8862 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, 0, NULL);
8863 todo_wine
8864 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8865 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8866 todo_wine
8867 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8869 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
8870 vih.bmiHeader.biPlanes = 1;
8871 vih.bmiHeader.biWidth = 16;
8872 vih.bmiHeader.biHeight = 32;
8873 vih.bmiHeader.biBitCount = 32;
8875 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
8876 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8878 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8879 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8880 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8881 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8882 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8883 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
8884 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8885 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8886 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8887 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8888 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8889 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8890 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8891 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8892 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8894 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8895 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8896 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8897 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8898 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8899 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8900 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8901 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8903 vih.bmiHeader.biHeight = -32;
8904 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
8905 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8906 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8907 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8908 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8910 vih.bmiHeader.biHeight = 32;
8911 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8912 todo_wine
8913 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8914 if (FAILED(hr)) goto failed;
8916 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
8917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8918 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
8919 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
8920 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8921 todo_wine
8922 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
8923 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8924 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8925 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8926 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
8927 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8928 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
8929 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
8930 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8931 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
8932 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
8933 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8934 ok(value32 == 2048, "Unexpected value %u.\n", value32);
8935 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8936 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8937 ok(value32 == -64, "Unexpected value %d.\n", value32);
8938 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
8939 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8940 ok(!!value32, "Unexpected value %#x.\n", value32);
8941 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
8942 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8943 ok(!!value32, "Unexpected value %#x.\n", value32);
8945 /* Negative height. */
8946 vih.bmiHeader.biHeight = -32;
8947 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
8948 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8949 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
8950 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8951 ok(value32 == 64, "Unexpected value %d.\n", value32);
8952 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
8953 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8954 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
8956 failed:
8957 IMFMediaType_Release(media_type);
8960 static void test_MFInitMediaTypeFromAMMediaType(void)
8962 IMFMediaType *media_type;
8963 AM_MEDIA_TYPE mt;
8964 UINT32 value32;
8965 UINT64 value64;
8966 HRESULT hr;
8967 GUID guid;
8968 VIDEOINFOHEADER vih =
8970 {0}, {0}, 0, 0, 0,
8971 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, 0xdeadbeef}
8973 static const struct guid_type_pair
8975 const GUID *am_type;
8976 const GUID *mf_type;
8977 } guid_types[] =
8979 { &MEDIASUBTYPE_I420, &MFVideoFormat_I420 },
8980 { &MEDIASUBTYPE_AYUV, &MFVideoFormat_AYUV },
8981 { &MEDIASUBTYPE_YV12, &MFVideoFormat_YV12 },
8982 { &MEDIASUBTYPE_YUY2, &MFVideoFormat_YUY2 },
8983 { &MEDIASUBTYPE_UYVY, &MFVideoFormat_UYVY },
8984 { &MEDIASUBTYPE_YVYU, &MFVideoFormat_YVYU },
8985 { &MEDIASUBTYPE_NV12, &MFVideoFormat_NV12 },
8986 { &MEDIASUBTYPE_ARGB32, &MFVideoFormat_ARGB32 },
8988 unsigned int i;
8990 hr = MFCreateMediaType(&media_type);
8991 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8993 memset(&mt, 0, sizeof(mt));
8994 mt.majortype = MEDIATYPE_Video;
8995 mt.formattype = FORMAT_VideoInfo;
8996 mt.cbFormat = sizeof(VIDEOINFOHEADER);
8997 mt.pbFormat = (BYTE *)&vih;
8999 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, 123);
9000 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9002 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9003 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9005 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9006 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9007 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9008 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9009 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9010 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
9011 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9012 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9013 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9014 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9015 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9016 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9017 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9018 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9019 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9020 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9021 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9022 ok(!!value32, "Unexpected value %#x.\n", value32);
9024 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9025 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9026 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9027 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9028 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9029 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9031 vih.bmiHeader.biHeight = -24;
9033 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9035 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9036 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9037 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9039 memcpy(&mt.subtype, &MEDIASUBTYPE_RGB32, sizeof(GUID));
9040 vih.bmiHeader.biHeight = 24;
9042 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9043 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9045 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9046 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9047 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9048 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9049 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9050 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9051 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9053 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9054 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9055 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9056 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9057 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9058 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9059 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9060 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9061 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9062 ok(value32 == 3072, "Unexpected value %u.\n", value32);
9063 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9064 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9065 ok(!!value32, "Unexpected value %#x.\n", value32);
9066 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9067 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9068 ok(!!value32, "Unexpected value %u.\n", value32);
9069 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9071 ok(value32 == -128, "Unexpected value %d.\n", value32);
9073 /* Negative height. */
9074 vih.bmiHeader.biHeight = -24;
9076 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9077 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9079 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9080 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9081 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9082 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9083 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9084 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9085 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9086 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9087 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9088 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9089 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9090 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9091 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9092 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9093 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9094 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9095 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9096 ok(value32 == 3072, "Unexpected value %u.\n", value32);
9097 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9098 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9099 ok(!!value32, "Unexpected value %#x.\n", value32);
9100 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9101 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9102 ok(!!value32, "Unexpected value %u.\n", value32);
9103 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9104 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9105 ok(value32 == 128, "Unexpected value %d.\n", value32);
9107 vih.bmiHeader.biHeight = 24;
9108 for (i = 0; i < ARRAY_SIZE(guid_types); ++i)
9110 memcpy(&mt.subtype, guid_types[i].am_type, sizeof(GUID));
9112 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9113 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9115 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9116 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9117 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9118 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9119 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9120 ok(IsEqualGUID(&guid, guid_types[i].mf_type), "Unexpected guid %s.\n", debugstr_guid(&guid));
9123 IMFMediaType_Release(media_type);
9126 START_TEST(mfplat)
9128 char **argv;
9129 int argc;
9131 init_functions();
9133 argc = winetest_get_mainargs(&argv);
9134 if (argc >= 3)
9136 test_queue_com_state(argv[2]);
9137 return;
9140 if (!pMFCreateVideoSampleAllocatorEx)
9141 win_skip("MFCreateVideoSampleAllocatorEx() is not available. Some tests will be skipped.\n");
9143 if (!pD3D12CreateDevice)
9144 skip("Missing d3d12 support, some tests will be skipped.\n");
9146 CoInitialize(NULL);
9148 test_startup();
9149 test_register();
9150 test_media_type();
9151 test_MFCreateMediaEvent();
9152 test_attributes();
9153 test_sample();
9154 test_file_stream();
9155 test_MFCreateMFByteStreamOnStream();
9156 test_system_memory_buffer();
9157 test_system_memory_aligned_buffer();
9158 test_source_resolver();
9159 test_MFCreateAsyncResult();
9160 test_allocate_queue();
9161 test_MFLockSharedWorkQueue();
9162 test_MFCopyImage();
9163 test_MFCreateCollection();
9164 test_MFHeapAlloc();
9165 test_scheduled_items();
9166 test_serial_queue();
9167 test_periodic_callback();
9168 test_event_queue();
9169 test_presentation_descriptor();
9170 test_system_time_source();
9171 test_MFInvokeCallback();
9172 test_stream_descriptor();
9173 test_MFCalculateImageSize();
9174 test_MFGetPlaneSize();
9175 test_MFCompareFullToPartialMediaType();
9176 test_attributes_serialization();
9177 test_wrapped_media_type();
9178 test_MFCreateWaveFormatExFromMFMediaType();
9179 test_async_create_file();
9180 test_local_handlers();
9181 test_create_property_store();
9182 test_dxgi_device_manager();
9183 test_MFCreateTransformActivate();
9184 test_MFTRegisterLocal();
9185 test_queue_com();
9186 test_MFGetStrideForBitmapInfoHeader();
9187 test_MFCreate2DMediaBuffer();
9188 test_MFCreateMediaBufferFromMediaType();
9189 test_MFInitMediaTypeFromWaveFormatEx();
9190 test_MFCreateMFVideoFormatFromMFMediaType();
9191 test_MFCreateDXSurfaceBuffer();
9192 test_MFCreateTrackedSample();
9193 test_MFFrameRateToAverageTimePerFrame();
9194 test_MFAverageTimePerFrameToFrameRate();
9195 test_MFMapDXGIFormatToDX9Format();
9196 test_d3d11_surface_buffer();
9197 test_d3d12_surface_buffer();
9198 test_sample_allocator_sysmem();
9199 test_sample_allocator_d3d9();
9200 test_sample_allocator_d3d11();
9201 test_sample_allocator_d3d12();
9202 test_MFMapDX9FormatToDXGIFormat();
9203 test_MFllMulDiv();
9204 test_shared_dxgi_device_manager();
9205 test_MFInitVideoFormat_RGB();
9206 test_MFCreateVideoMediaTypeFromVideoInfoHeader();
9207 test_MFInitMediaTypeFromVideoInfoHeader();
9208 test_MFInitMediaTypeFromAMMediaType();
9210 CoUninitialize();