d3d10/effect: Add support for 'imul' instruction.
[wine.git] / dlls / mfplat / tests / mfplat.c
blobf7ae614a109c6dae73e04ca36debf97260792aea
1 /*
2 * Unit test suite for mfplat.
4 * Copyright 2015 Michael Müller
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <string.h>
23 #include <limits.h>
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "ole2.h"
32 #include "ks.h"
33 #include "ksmedia.h"
34 #include "amvideo.h"
35 #include "mfapi.h"
36 #include "mfidl.h"
37 #include "mferror.h"
38 #include "mfreadwrite.h"
39 #include "propvarutil.h"
40 #include "strsafe.h"
41 #include "uuids.h"
42 #include "evr.h"
43 #include "mfmediaengine.h"
45 #include "wine/test.h"
47 #define D3D11_INIT_GUID
48 #include "initguid.h"
49 #include "d3d11_4.h"
50 #include "d3d9.h"
51 #include "d3d9types.h"
52 #include "ks.h"
53 #include "ksmedia.h"
54 #include "dxva2api.h"
55 #include "d3d12.h"
56 #undef EXTERN_GUID
57 #define EXTERN_GUID DEFINE_GUID
58 #include "mfd3d12.h"
59 #include "wmcodecdsp.h"
61 DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
62 DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
63 DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
64 DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
66 extern const CLSID CLSID_FileSchemePlugin;
68 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1'));
69 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2'));
70 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3'));
71 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4'));
73 static BOOL is_win8_plus;
75 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
76 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
78 ULONG rc;
79 IUnknown_AddRef(obj);
80 rc = IUnknown_Release(obj);
81 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %ld, expected %ld.\n", rc, ref);
84 static ULONG get_refcount(void *iface)
86 IUnknown *unknown = iface;
87 IUnknown_AddRef(unknown);
88 return IUnknown_Release(unknown);
91 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
92 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
94 IUnknown *iface = iface_ptr;
95 HRESULT hr, expected_hr;
96 IUnknown *unk;
98 expected_hr = supported ? S_OK : E_NOINTERFACE;
100 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
101 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
102 if (SUCCEEDED(hr))
103 IUnknown_Release(unk);
106 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
107 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
109 IUnknown *iface = iface_ptr;
110 HRESULT hr, expected_hr;
111 IMFGetService *gs;
112 IUnknown *unk;
114 expected_hr = supported ? S_OK : E_NOINTERFACE;
116 if (SUCCEEDED(hr = IUnknown_QueryInterface(iface, &IID_IMFGetService, (void **)&gs)))
118 hr = IMFGetService_GetService(gs, service, iid, (void **)&unk);
119 IMFGetService_Release(gs);
121 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
122 if (SUCCEEDED(hr))
123 IUnknown_Release(unk);
126 struct d3d9_surface_readback
128 IDirect3DSurface9 *surface, *readback_surface;
129 D3DLOCKED_RECT map_desc;
130 D3DSURFACE_DESC surf_desc;
133 static void get_d3d9_surface_readback(IDirect3DSurface9 *surface, struct d3d9_surface_readback *rb)
135 IDirect3DDevice9 *device;
136 HRESULT hr;
138 rb->surface = surface;
140 hr = IDirect3DSurface9_GetDevice(surface, &device);
141 ok(hr == D3D_OK, "Failed to get device, hr %#lx.\n", hr);
143 hr = IDirect3DSurface9_GetDesc(surface, &rb->surf_desc);
144 ok(hr == D3D_OK, "Failed to get surface desc, hr %#lx.\n", hr);
145 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, rb->surf_desc.Width, rb->surf_desc.Height,
146 rb->surf_desc.Format, D3DPOOL_SYSTEMMEM, &rb->readback_surface, NULL);
147 ok(hr == D3D_OK, "Failed to create surface, hr %#lx.\n", hr);
149 hr = IDirect3DDevice9Ex_GetRenderTargetData(device, surface, rb->readback_surface);
150 ok(hr == D3D_OK, "Failed to get render target data, hr %#lx.\n", hr);
152 hr = IDirect3DSurface9_LockRect(rb->readback_surface, &rb->map_desc, NULL, 0);
153 ok(hr == D3D_OK, "Failed to lock surface, hr %#lx.\n", hr);
155 IDirect3DDevice9_Release(device);
158 static void release_d3d9_surface_readback(struct d3d9_surface_readback *rb, BOOL upload)
160 ULONG refcount;
161 HRESULT hr;
163 hr = IDirect3DSurface9_UnlockRect(rb->readback_surface);
164 ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr);
166 if (upload)
168 IDirect3DDevice9 *device;
170 IDirect3DSurface9_GetDevice(rb->surface, &device);
171 ok(hr == D3D_OK, "Failed to get device, hr %#lx.\n", hr);
173 hr = IDirect3DDevice9_UpdateSurface(device, rb->readback_surface, NULL, rb->surface, NULL);
174 ok(hr == D3D_OK, "Failed to update surface, hr %#lx.\n", hr);
176 IDirect3DDevice9_Release(device);
179 refcount = IDirect3DSurface9_Release(rb->readback_surface);
180 ok(refcount == 0, "Readback surface still has references.\n");
183 static void *get_d3d9_readback_data(struct d3d9_surface_readback *rb,
184 unsigned int x, unsigned int y, unsigned byte_width)
186 return (BYTE *)rb->map_desc.pBits + y * rb->map_desc.Pitch + x * byte_width;
189 static DWORD get_d3d9_readback_u32(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y)
191 return *(DWORD *)get_d3d9_readback_data(rb, x, y, sizeof(DWORD));
194 static DWORD get_d3d9_readback_color(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y)
196 return get_d3d9_readback_u32(rb, x, y);
199 static DWORD get_d3d9_surface_color(IDirect3DSurface9 *surface, unsigned int x, unsigned int y)
201 struct d3d9_surface_readback rb;
202 DWORD color;
204 get_d3d9_surface_readback(surface, &rb);
205 color = get_d3d9_readback_color(&rb, x, y);
206 release_d3d9_surface_readback(&rb, FALSE);
208 return color;
211 static void put_d3d9_readback_u32(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y, DWORD color)
213 *(DWORD *)get_d3d9_readback_data(rb, x, y, sizeof(DWORD)) = color;
216 static void put_d3d9_readback_color(struct d3d9_surface_readback *rb, unsigned int x, unsigned int y, DWORD color)
218 put_d3d9_readback_u32(rb, x, y, color);
221 static void put_d3d9_surface_color(IDirect3DSurface9 *surface,
222 unsigned int x, unsigned int y, DWORD color)
224 struct d3d9_surface_readback rb;
226 get_d3d9_surface_readback(surface, &rb);
227 put_d3d9_readback_color(&rb, x, y, color);
228 release_d3d9_surface_readback(&rb, TRUE);
231 struct d3d11_resource_readback
233 ID3D11Resource *orig_resource, *resource;
234 D3D11_MAPPED_SUBRESOURCE map_desc;
235 ID3D11DeviceContext *immediate_context;
236 unsigned int width, height, depth, sub_resource_idx;
239 static void init_d3d11_resource_readback(ID3D11Resource *resource, ID3D11Resource *readback_resource,
240 unsigned int width, unsigned int height, unsigned int depth, unsigned int sub_resource_idx,
241 ID3D11Device *device, struct d3d11_resource_readback *rb)
243 HRESULT hr;
245 rb->orig_resource = resource;
246 rb->resource = readback_resource;
247 rb->width = width;
248 rb->height = height;
249 rb->depth = depth;
250 rb->sub_resource_idx = sub_resource_idx;
252 ID3D11Device_GetImmediateContext(device, &rb->immediate_context);
254 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->resource, resource);
255 if (FAILED(hr = ID3D11DeviceContext_Map(rb->immediate_context,
256 rb->resource, sub_resource_idx, D3D11_MAP_READ_WRITE, 0, &rb->map_desc)))
258 trace("Failed to map resource, hr %#lx.\n", hr);
259 ID3D11Resource_Release(rb->resource);
260 rb->resource = NULL;
261 ID3D11DeviceContext_Release(rb->immediate_context);
262 rb->immediate_context = NULL;
266 static void get_d3d11_texture2d_readback(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
267 struct d3d11_resource_readback *rb)
269 D3D11_TEXTURE2D_DESC texture_desc;
270 ID3D11Resource *rb_texture;
271 unsigned int miplevel;
272 ID3D11Device *device;
273 HRESULT hr;
275 memset(rb, 0, sizeof(*rb));
277 ID3D11Texture2D_GetDevice(texture, &device);
279 ID3D11Texture2D_GetDesc(texture, &texture_desc);
280 texture_desc.Usage = D3D11_USAGE_STAGING;
281 texture_desc.BindFlags = 0;
282 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
283 texture_desc.MiscFlags = 0;
284 if (FAILED(hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture)))
286 trace("Failed to create texture, hr %#lx.\n", hr);
287 ID3D11Device_Release(device);
288 return;
291 miplevel = sub_resource_idx % texture_desc.MipLevels;
292 init_d3d11_resource_readback((ID3D11Resource *)texture, rb_texture,
293 max(1, texture_desc.Width >> miplevel),
294 max(1, texture_desc.Height >> miplevel),
295 1, sub_resource_idx, device, rb);
297 ID3D11Device_Release(device);
300 static void release_d3d11_resource_readback(struct d3d11_resource_readback *rb, BOOL upload)
302 ID3D11DeviceContext_Unmap(rb->immediate_context, rb->resource, rb->sub_resource_idx);
304 if (upload)
306 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->orig_resource, rb->resource);
309 ID3D11Resource_Release(rb->resource);
310 ID3D11DeviceContext_Release(rb->immediate_context);
313 static void *get_d3d11_readback_data(struct d3d11_resource_readback *rb,
314 unsigned int x, unsigned int y, unsigned int z, unsigned byte_width)
316 return (BYTE *)rb->map_desc.pData + z * rb->map_desc.DepthPitch + y * rb->map_desc.RowPitch + x * byte_width;
319 static DWORD get_d3d11_readback_u32(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
321 return *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD));
324 static DWORD get_d3d11_readback_color(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
326 return get_d3d11_readback_u32(rb, x, y, z);
329 static DWORD get_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y)
331 struct d3d11_resource_readback rb;
332 DWORD color;
334 get_d3d11_texture2d_readback(texture, 0, &rb);
335 color = get_d3d11_readback_color(&rb, x, y, 0);
336 release_d3d11_resource_readback(&rb, FALSE);
338 return color;
341 static void put_d3d11_readback_u32(struct d3d11_resource_readback *rb,
342 unsigned int x, unsigned int y, unsigned int z, DWORD color)
344 *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD)) = color;
347 static void put_d3d11_readback_color(struct d3d11_resource_readback *rb,
348 unsigned int x, unsigned int y, unsigned int z, DWORD color)
350 put_d3d11_readback_u32(rb, x, y, z, color);
353 static void put_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y, DWORD color)
355 struct d3d11_resource_readback rb;
357 get_d3d11_texture2d_readback(texture, 0, &rb);
358 put_d3d11_readback_color(&rb, x, y, 0, color);
359 release_d3d11_resource_readback(&rb, TRUE);
362 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
363 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
364 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
365 static HRESULT (WINAPI *pD3D12CreateDevice)(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level,
366 REFIID iid, void **device);
368 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
370 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
371 DWORD width, DWORD lines);
372 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
373 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
374 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
375 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
376 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
377 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
378 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
379 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
380 IMFActivate *activate);
381 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
382 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
383 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
384 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
385 const MFT_REGISTER_TYPE_INFO* output_types);
386 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
387 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
388 const MFT_REGISTER_TYPE_INFO *output_types);
389 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
390 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
391 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
392 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
393 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
394 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
395 static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
396 static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
397 IMFMediaBuffer **buffer);
398 static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
399 DWORD min_alignment, IMFMediaBuffer **buffer);
400 static HRESULT (WINAPI *pMFCreatePathFromURL)(const WCHAR *url, WCHAR **path);
401 static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
402 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
403 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
404 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
405 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
406 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
407 IMFMediaBuffer **buffer);
408 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
409 static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
410 static HRESULT (WINAPI *pMFLockDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
411 static HRESULT (WINAPI *pMFUnlockDXGIDeviceManager)(void);
412 static HRESULT (WINAPI *pMFInitVideoFormat_RGB)(MFVIDEOFORMAT *format, DWORD width, DWORD height, DWORD d3dformat);
414 static HWND create_window(void)
416 RECT r = {0, 0, 640, 480};
418 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
420 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
421 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
424 static IDirect3DDevice9 *create_d3d9_device(IDirect3D9 *d3d9, HWND focus_window)
426 D3DPRESENT_PARAMETERS present_parameters = {0};
427 IDirect3DDevice9 *device = NULL;
429 present_parameters.BackBufferWidth = 640;
430 present_parameters.BackBufferHeight = 480;
431 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
432 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
433 present_parameters.hDeviceWindow = focus_window;
434 present_parameters.Windowed = TRUE;
435 present_parameters.EnableAutoDepthStencil = TRUE;
436 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
437 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
439 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
440 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
442 return device;
445 static const WCHAR fileschemeW[] = L"file://";
447 static WCHAR *load_resource(const WCHAR *name)
449 static WCHAR pathW[MAX_PATH];
450 DWORD written;
451 HANDLE file;
452 HRSRC res;
453 void *ptr;
455 GetTempPathW(ARRAY_SIZE(pathW), pathW);
456 lstrcatW(pathW, name);
458 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
459 NULL, CREATE_ALWAYS, 0, 0);
460 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n",
461 wine_dbgstr_w(pathW), GetLastError());
463 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
464 ok(res != 0, "couldn't find resource\n");
465 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
466 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
467 &written, NULL);
468 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
469 "couldn't write resource\n" );
470 CloseHandle(file);
472 return pathW;
475 static BOOL is_MEDIASUBTYPE_RGB(const GUID *subtype)
477 return IsEqualGUID(subtype, &MEDIASUBTYPE_RGB8)
478 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB555)
479 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB565)
480 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB24)
481 || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB32);
484 struct test_callback
486 IMFAsyncCallback IMFAsyncCallback_iface;
487 LONG refcount;
488 HANDLE event;
489 DWORD param;
490 IMFMediaEvent *media_event;
491 IMFAsyncResult *result;
494 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
496 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
499 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
501 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
502 IsEqualIID(riid, &IID_IUnknown))
504 *obj = iface;
505 IMFAsyncCallback_AddRef(iface);
506 return S_OK;
509 *obj = NULL;
510 return E_NOINTERFACE;
513 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
515 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
516 return InterlockedIncrement(&callback->refcount);
519 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
521 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
522 ULONG refcount = InterlockedDecrement(&callback->refcount);
524 if (!refcount)
526 CloseHandle(callback->event);
527 free(callback);
530 return refcount;
533 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
535 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
536 return E_NOTIMPL;
539 static HRESULT WINAPI test_async_callback_result_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
541 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
543 callback->result = result;
544 IMFAsyncResult_AddRef(callback->result);
545 SetEvent(callback->event);
547 return S_OK;
550 static const IMFAsyncCallbackVtbl test_async_callback_result_vtbl =
552 testcallback_QueryInterface,
553 testcallback_AddRef,
554 testcallback_Release,
555 testcallback_GetParameters,
556 test_async_callback_result_Invoke,
559 static DWORD wait_async_callback_result(IMFAsyncCallback *iface, DWORD timeout, IMFAsyncResult **result)
561 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
562 DWORD res = WaitForSingleObject(callback->event, timeout);
564 *result = callback->result;
565 callback->result = NULL;
567 return res;
570 static BOOL check_clsid(CLSID *clsids, UINT32 count)
572 int i;
573 for (i = 0; i < count; i++)
575 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
576 return TRUE;
578 return FALSE;
581 static void test_register(void)
583 MFT_REGISTER_TYPE_INFO *in_types, *out_types;
584 WCHAR name[] = L"Wine test";
585 MFT_REGISTER_TYPE_INFO input[] =
587 { DUMMY_CLSID, DUMMY_GUID1 }
589 MFT_REGISTER_TYPE_INFO output[] =
591 { DUMMY_CLSID, DUMMY_GUID2 }
593 UINT32 count, in_count, out_count;
594 IMFAttributes *attributes;
595 WCHAR *mft_name;
596 CLSID *clsids;
597 HRESULT hr, ret;
599 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
600 if (ret == E_ACCESSDENIED)
602 win_skip("Not enough permissions to register a transform.\n");
603 return;
605 ok(ret == S_OK, "Failed to register dummy transform, hr %#lx.\n", ret);
607 if(0)
609 /* NULL name crashes on windows */
610 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
611 ok(ret == E_INVALIDARG, "Unexpected hr %#lx.\n", ret);
614 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
615 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
617 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
618 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
620 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
621 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
623 if(0)
625 /* NULL clsids/count crashes on windows (vista) */
626 count = 0;
627 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
628 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
629 ok(count == 0, "Expected count == 0\n");
631 clsids = NULL;
632 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
633 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
635 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, NULL, NULL, NULL, NULL, NULL);
636 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
637 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
638 CoTaskMemFree(mft_name);
640 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, NULL);
641 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
643 in_count = out_count = 1;
644 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, &in_count, NULL, &out_count, NULL);
645 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
646 ok(!in_count, "Unexpected count %u.\n", in_count);
647 ok(!out_count, "Unexpected count %u.\n", out_count);
649 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, &attributes);
650 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
651 ok(!!attributes, "Unexpected attributes.\n");
652 IMFAttributes_Release(attributes);
654 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, &in_types, &in_count, &out_types, &out_count, &attributes);
655 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
656 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
657 ok(!!in_types, "Unexpected pointer.\n");
658 ok(!!out_types, "Unexpected pointer.\n");
659 ok(in_count == 1, "Unexpected count %u.\n", in_count);
660 ok(out_count == 1, "Unexpected count %u.\n", out_count);
661 ok(IsEqualGUID(&in_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
662 wine_dbgstr_guid(&in_types->guidMajorType));
663 ok(IsEqualGUID(&in_types->guidSubtype, &DUMMY_GUID1), "Unexpected type guid %s.\n",
664 wine_dbgstr_guid(&in_types->guidSubtype));
665 ok(IsEqualGUID(&out_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
666 wine_dbgstr_guid(&out_types->guidMajorType));
667 ok(IsEqualGUID(&out_types->guidSubtype, &DUMMY_GUID2), "Unexpected type guid %s.\n",
668 wine_dbgstr_guid(&out_types->guidSubtype));
669 ok(!!attributes, "Unexpected attributes.\n");
670 count = 1;
671 hr = IMFAttributes_GetCount(attributes, &count);
672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
673 ok(!count, "Unexpected count %u.\n", count);
674 CoTaskMemFree(mft_name);
675 CoTaskMemFree(in_types);
676 CoTaskMemFree(out_types);
677 IMFAttributes_Release(attributes);
679 count = 0;
680 clsids = NULL;
681 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
682 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
683 ok(count > 0, "Expected count > 0\n");
684 ok(clsids != NULL, "Expected clsids != NULL\n");
685 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
686 CoTaskMemFree(clsids);
688 count = 0;
689 clsids = NULL;
690 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
691 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
692 ok(count > 0, "Expected count > 0\n");
693 ok(clsids != NULL, "Expected clsids != NULL\n");
694 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
695 CoTaskMemFree(clsids);
697 count = 0;
698 clsids = NULL;
699 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
700 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
701 ok(count > 0, "Expected count > 0\n");
702 ok(clsids != NULL, "Expected clsids != NULL\n");
703 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
704 CoTaskMemFree(clsids);
706 count = 0;
707 clsids = NULL;
708 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
709 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
710 ok(count > 0, "Expected count > 0\n");
711 ok(clsids != NULL, "Expected clsids != NULL\n");
712 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
713 CoTaskMemFree(clsids);
715 /* exchange input and output */
716 count = 0;
717 clsids = NULL;
718 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
719 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
720 ok(!count, "got %d\n", count);
721 ok(clsids == NULL, "Expected clsids == NULL\n");
723 ret = MFTUnregister(DUMMY_CLSID);
724 ok(ret == S_OK ||
725 /* w7pro64 */
726 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
728 ret = MFTUnregister(DUMMY_CLSID);
729 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
732 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
734 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
735 IMFSourceResolver *resolver;
736 IUnknown *object, *object2;
737 MF_OBJECT_TYPE obj_type;
738 HRESULT hr;
740 ok(!!result, "Unexpected result object.\n");
742 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
744 object = NULL;
745 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
746 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
748 hr = IMFAsyncResult_GetObject(result, &object2);
749 ok(hr == S_OK, "Failed to get result object, hr %#lx.\n", hr);
750 ok(object2 == object, "Unexpected object.\n");
752 if (object)
753 IUnknown_Release(object);
754 IUnknown_Release(object2);
756 SetEvent(callback->event);
758 return S_OK;
761 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
763 testcallback_QueryInterface,
764 testcallback_AddRef,
765 testcallback_Release,
766 testcallback_GetParameters,
767 test_create_from_url_callback_Invoke,
770 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
772 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
773 IMFSchemeHandler *handler;
774 IUnknown *object, *object2;
775 MF_OBJECT_TYPE obj_type;
776 HRESULT hr;
778 ok(!!result, "Unexpected result object.\n");
780 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
782 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
783 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
785 if (SUCCEEDED(hr))
787 hr = IMFAsyncResult_GetObject(result, &object2);
788 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
790 IUnknown_Release(object);
793 SetEvent(callback->event);
795 return S_OK;
798 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
800 testcallback_QueryInterface,
801 testcallback_AddRef,
802 testcallback_Release,
803 testcallback_GetParameters,
804 test_create_from_file_handler_callback_Invoke,
807 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
809 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
810 IMFMediaEventGenerator *generator;
811 HRESULT hr;
813 ok(!!result, "Unexpected result object.\n");
815 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
817 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
818 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
820 SetEvent(callback->event);
822 return S_OK;
825 static const IMFAsyncCallbackVtbl events_callback_vtbl =
827 testcallback_QueryInterface,
828 testcallback_AddRef,
829 testcallback_Release,
830 testcallback_GetParameters,
831 source_events_callback_Invoke,
834 static const IMFAsyncCallbackVtbl testcallbackvtbl;
836 static struct test_callback * create_test_callback(const IMFAsyncCallbackVtbl *vtbl)
838 struct test_callback *callback = calloc(1, sizeof(*callback));
840 callback->IMFAsyncCallback_iface.lpVtbl = vtbl ? vtbl : &testcallbackvtbl;
841 callback->refcount = 1;
842 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
844 return callback;
847 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
849 struct test_callback *callback;
850 MediaEventType event_type;
851 BOOL ret = FALSE;
852 HRESULT hr;
854 callback = create_test_callback(&events_callback_vtbl);
856 for (;;)
858 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback->IMFAsyncCallback_iface,
859 (IUnknown *)generator);
860 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
862 if (WaitForSingleObject(callback->event, 1000) == WAIT_TIMEOUT)
864 ok(0, "timeout\n");
865 break;
868 Sleep(10);
870 hr = IMFMediaEvent_GetType(callback->media_event, &event_type);
871 ok(hr == S_OK, "Failed to event type, hr %#lx.\n", hr);
873 if ((ret = (event_type == expected_event_type)))
875 if (value)
877 hr = IMFMediaEvent_GetValue(callback->media_event, value);
878 ok(hr == S_OK, "Failed to get value of event, hr %#lx.\n", hr);
881 break;
885 if (callback->media_event)
886 IMFMediaEvent_Release(callback->media_event);
887 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
889 return ret;
892 static const IMFByteStreamVtbl *bytestream_vtbl_orig;
894 static int bytestream_closed = 0;
895 static HRESULT WINAPI bytestream_wrapper_Close(IMFByteStream *iface)
897 bytestream_closed = 1;
898 return bytestream_vtbl_orig->Close(iface);
901 static void test_source_resolver(void)
903 struct test_callback *callback, *callback2;
904 IMFByteStreamVtbl bytestream_vtbl_wrapper;
905 IMFSourceResolver *resolver, *resolver2;
906 IMFPresentationDescriptor *descriptor;
907 IMFSchemeHandler *scheme_handler;
908 IMFMediaStream *video_stream;
909 IMFAttributes *attributes;
910 IMFMediaSource *mediasource;
911 IMFMediaTypeHandler *handler;
912 IMFMediaType *media_type;
913 BOOL selected, do_uninit;
914 MF_OBJECT_TYPE obj_type;
915 IMFStreamDescriptor *sd;
916 IUnknown *cancel_cookie;
917 IMFByteStream *stream;
918 IMFGetService *get_service;
919 IMFRateSupport *rate_support;
920 WCHAR pathW[MAX_PATH];
921 int i, sample_count;
922 WCHAR *filename;
923 PROPVARIANT var;
924 HRESULT hr;
925 GUID guid;
926 float rate;
927 UINT32 rotation;
929 if (!pMFCreateSourceResolver)
931 win_skip("MFCreateSourceResolver() not found\n");
932 return;
935 callback = create_test_callback(&test_create_from_url_callback_vtbl);
936 callback2 = create_test_callback(&test_create_from_file_handler_callback_vtbl);
938 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
939 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
941 hr = pMFCreateSourceResolver(NULL);
942 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
944 hr = pMFCreateSourceResolver(&resolver);
945 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
947 hr = pMFCreateSourceResolver(&resolver2);
948 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
949 ok(resolver != resolver2, "Expected new instance\n");
951 IMFSourceResolver_Release(resolver2);
953 filename = load_resource(L"test.mp4");
955 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
956 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
958 hr = IMFSourceResolver_CreateObjectFromByteStream(
959 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
960 &obj_type, (IUnknown **)&mediasource);
961 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
963 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
964 NULL, (IUnknown **)&mediasource);
965 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
967 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
968 &obj_type, NULL);
969 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
971 IMFByteStream_Release(stream);
973 /* Create from URL. */
975 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
976 (IUnknown **)&stream);
977 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
979 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
980 (IUnknown **)&stream);
981 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
982 IMFByteStream_Release(stream);
984 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
985 &cancel_cookie, &callback->IMFAsyncCallback_iface, (IUnknown *)resolver);
986 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
987 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
988 IUnknown_Release(cancel_cookie);
990 if (SUCCEEDED(hr))
991 WaitForSingleObject(callback->event, INFINITE);
993 /* With explicit scheme. */
994 lstrcpyW(pathW, fileschemeW);
995 lstrcatW(pathW, filename);
997 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
998 (IUnknown **)&stream);
999 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
1000 IMFByteStream_Release(stream);
1002 /* We have to create a new bytestream here, because all following
1003 * calls to CreateObjectFromByteStream will fail. */
1004 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
1005 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1007 /* Wrap ::Close to test when the media source calls it */
1008 bytestream_vtbl_orig = stream->lpVtbl;
1009 bytestream_vtbl_wrapper = *bytestream_vtbl_orig;
1010 bytestream_vtbl_wrapper.Close = bytestream_wrapper_Close;
1011 stream->lpVtbl = &bytestream_vtbl_wrapper;
1013 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
1014 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1015 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
1016 ok(hr == S_OK, "Failed to set string value, hr %#lx.\n", hr);
1017 IMFAttributes_Release(attributes);
1019 /* Start of gstreamer dependent tests */
1021 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
1022 &obj_type, (IUnknown **)&mediasource);
1023 if (strcmp(winetest_platform, "wine"))
1024 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1025 if (FAILED(hr))
1027 IMFByteStream_Release(stream);
1028 IMFSourceResolver_Release(resolver);
1030 hr = MFShutdown();
1031 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
1033 DeleteFileW(filename);
1034 return;
1036 ok(mediasource != NULL, "got %p\n", mediasource);
1037 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
1039 check_interface(mediasource, &IID_IMFGetService, TRUE);
1040 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
1042 hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service);
1043 ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
1045 hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support);
1046 ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
1048 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1049 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1050 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
1051 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1052 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1053 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
1054 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1055 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1056 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
1057 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1058 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
1059 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
1061 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1062 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1063 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1064 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1065 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1066 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1067 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1068 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1069 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1070 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1071 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
1072 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
1074 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, NULL);
1075 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1076 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, &rate);
1077 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1078 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1080 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1.0f, &rate);
1081 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1082 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1083 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1.0f, &rate);
1084 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1085 ok(rate == -1.0f, "Unexpected rate %f.\n", rate);
1086 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1e6f + 1.0f, &rate);
1087 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
1088 ok(rate == 1e6f + 1.0f || broken(rate == 1e6f) /* Win7 */, "Unexpected %f.\n", rate);
1089 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f, &rate);
1090 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1091 ok(rate == -1e6f, "Unexpected rate %f.\n", rate);
1093 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f - 1.0f, &rate);
1094 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
1095 ok(rate == -1e6f - 1.0f || broken(rate == -1e6f) /* Win7 */, "Unexpected rate %f.\n", rate);
1097 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
1098 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
1099 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#lx.\n", hr);
1100 ok(descriptor != NULL, "got %p\n", descriptor);
1102 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
1103 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
1105 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
1106 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
1107 IMFStreamDescriptor_Release(sd);
1109 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
1110 ok(hr == S_OK, "Failed to get stream major type, hr %#lx.\n", hr);
1112 /* Check major/minor type for the test media. */
1113 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
1115 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
1116 ok(hr == S_OK, "Failed to get current media type, hr %#lx.\n", hr);
1117 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
1118 ok(hr == S_OK, "Failed to get media sub type, hr %#lx.\n", hr);
1119 todo_wine
1120 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
1122 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_ROTATION, &rotation);
1123 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Win7 */, "Failed to get rotation, hr %#lx.\n", hr);
1124 if (hr == S_OK)
1125 ok(rotation == MFVideoRotationFormat_0, "Got wrong rotation %u.\n", rotation);
1127 IMFMediaType_Release(media_type);
1129 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
1130 ok(hr == S_OK, "Failed to select video stream, hr %#lx.\n", hr);
1132 var.vt = VT_EMPTY;
1133 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1134 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1136 video_stream = NULL;
1137 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
1139 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
1140 video_stream = (IMFMediaStream *)var.punkVal;
1143 hr = IMFMediaSource_Pause(mediasource);
1144 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1145 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
1146 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1148 var.vt = VT_EMPTY;
1149 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1150 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1152 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
1153 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1155 hr = IMFMediaSource_Pause(mediasource);
1156 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1157 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
1158 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1160 var.vt = VT_I8;
1161 var.uhVal.QuadPart = 0;
1162 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1163 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1165 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceSeeked, &var))
1166 ok(var.vt == VT_I8, "Unexpected value type.\n");
1168 hr = IMFMediaSource_Stop(mediasource);
1169 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
1170 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStopped, &var))
1171 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
1173 var.vt = VT_I8;
1174 var.uhVal.QuadPart = 0;
1175 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
1176 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
1178 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
1179 ok(var.vt == VT_I8, "Unexpected value type.\n");
1181 sample_count = 10;
1183 for (i = 0; i < sample_count; ++i)
1185 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1186 ok(hr == S_OK, "Failed to request sample %u, hr %#lx.\n", i + 1, hr);
1187 if (hr != S_OK)
1188 break;
1191 for (i = 0; i < sample_count; ++i)
1193 static const LONGLONG MILLI_TO_100_NANO = 10000;
1194 LONGLONG duration, time;
1195 DWORD buffer_count;
1196 IMFSample *sample;
1197 BOOL ret;
1199 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
1200 ok(ret, "Sample %u not received.\n", i + 1);
1201 if (!ret)
1202 break;
1204 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
1205 sample = (IMFSample *)var.punkVal;
1207 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1208 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1209 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
1211 hr = IMFSample_GetSampleDuration(sample, &duration);
1212 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
1213 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
1215 hr = IMFSample_GetSampleTime(sample, &time);
1216 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
1217 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
1219 IMFSample_Release(sample);
1222 if (i == sample_count)
1224 IMFMediaEvent *event;
1226 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
1227 Sleep(100);
1228 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
1229 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
1231 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1232 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1233 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
1237 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1238 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1240 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
1242 IMFMediaStream_Release(video_stream);
1243 IMFMediaTypeHandler_Release(handler);
1244 IMFPresentationDescriptor_Release(descriptor);
1246 ok(!bytestream_closed, "IMFByteStream::Close called unexpectedly\n");
1248 hr = IMFMediaSource_Shutdown(mediasource);
1249 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1251 ok(bytestream_closed, "Missing IMFByteStream::Close call\n");
1253 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
1254 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
1256 IMFRateSupport_Release(rate_support);
1257 IMFGetService_Release(get_service);
1258 IMFMediaSource_Release(mediasource);
1259 IMFByteStream_Release(stream);
1261 /* Create directly through scheme handler. */
1262 hr = CoInitialize(NULL);
1263 ok(SUCCEEDED(hr), "Failed to initialize, hr %#lx.\n", hr);
1264 do_uninit = hr == S_OK;
1266 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
1267 (void **)&scheme_handler);
1268 ok(hr == S_OK, "Failed to create handler object, hr %#lx.\n", hr);
1270 cancel_cookie = NULL;
1271 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
1272 &callback2->IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
1273 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
1274 ok(!!cancel_cookie, "Unexpected cancel object.\n");
1275 IUnknown_Release(cancel_cookie);
1277 WaitForSingleObject(callback2->event, INFINITE);
1279 IMFSchemeHandler_Release(scheme_handler);
1281 if (do_uninit)
1282 CoUninitialize();
1284 IMFSourceResolver_Release(resolver);
1286 hr = MFShutdown();
1287 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
1289 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
1290 IMFAsyncCallback_Release(&callback2->IMFAsyncCallback_iface);
1292 DeleteFileW(filename);
1295 static void init_functions(void)
1297 HMODULE mod = GetModuleHandleA("mfplat.dll");
1299 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
1300 X(MFAddPeriodicCallback);
1301 X(MFAllocateSerialWorkQueue);
1302 X(MFAllocateWorkQueueEx);
1303 X(MFCopyImage);
1304 X(MFCreate2DMediaBuffer);
1305 X(MFCreateDXGIDeviceManager);
1306 X(MFCreateDXGISurfaceBuffer);
1307 X(MFCreateDXSurfaceBuffer);
1308 X(MFCreateSourceResolver);
1309 X(MFCreateMediaBufferFromMediaType);
1310 X(MFCreateMFByteStreamOnStream);
1311 X(MFCreatePathFromURL);
1312 X(MFCreateTrackedSample);
1313 X(MFCreateTransformActivate);
1314 X(MFCreateVideoMediaTypeFromSubtype);
1315 X(MFCreateVideoSampleAllocatorEx);
1316 X(MFGetPlaneSize);
1317 X(MFGetStrideForBitmapInfoHeader);
1318 X(MFInitVideoFormat_RGB);
1319 X(MFLockDXGIDeviceManager);
1320 X(MFLockSharedWorkQueue);
1321 X(MFMapDX9FormatToDXGIFormat);
1322 X(MFMapDXGIFormatToDX9Format);
1323 X(MFPutWaitingWorkItem);
1324 X(MFRegisterLocalByteStreamHandler);
1325 X(MFRegisterLocalSchemeHandler);
1326 X(MFRemovePeriodicCallback);
1327 X(MFTEnumEx);
1328 X(MFTRegisterLocal);
1329 X(MFTRegisterLocalByCLSID);
1330 X(MFTUnregisterLocal);
1331 X(MFTUnregisterLocalByCLSID);
1332 X(MFUnlockDXGIDeviceManager);
1334 if ((mod = LoadLibraryA("d3d11.dll")))
1336 X(D3D11CreateDevice);
1339 if ((mod = LoadLibraryA("d3d12.dll")))
1341 X(D3D12CreateDevice);
1344 mod = GetModuleHandleA("ole32.dll");
1346 X(CoGetApartmentType);
1347 #undef X
1349 is_win8_plus = pMFPutWaitingWorkItem != NULL;
1352 static void test_media_type(void)
1354 IMFMediaType *mediatype, *mediatype2;
1355 IMFVideoMediaType *video_type;
1356 IUnknown *unk, *unk2;
1357 BOOL compressed;
1358 DWORD flags;
1359 UINT count;
1360 HRESULT hr;
1361 GUID guid;
1363 if(0)
1365 /* Crash on Windows Vista/7 */
1366 hr = MFCreateMediaType(NULL);
1367 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1370 hr = MFCreateMediaType(&mediatype);
1371 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1373 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1374 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1376 compressed = FALSE;
1377 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1378 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1379 ok(compressed, "Unexpected value %d.\n", compressed);
1381 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
1382 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1384 compressed = FALSE;
1385 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1386 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1387 ok(compressed, "Unexpected value %d.\n", compressed);
1389 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 0);
1390 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1392 compressed = FALSE;
1393 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1394 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1395 ok(compressed, "Unexpected value %d.\n", compressed);
1397 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
1398 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1400 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 1);
1401 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1403 compressed = TRUE;
1404 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1405 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1406 ok(!compressed, "Unexpected value %d.\n", compressed);
1408 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_COMPRESSED);
1409 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1411 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1412 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1414 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1415 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
1416 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
1418 /* IsEqual() */
1419 hr = MFCreateMediaType(&mediatype2);
1420 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
1422 flags = 0xdeadbeef;
1423 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1424 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1425 ok(flags == 0, "Unexpected flags %#lx.\n", flags);
1427 /* Different major types. */
1428 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1429 ok(hr == S_OK, "Failed to set major type, 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_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1435 "Unexpected flags %#lx.\n", flags);
1437 /* Same major types, different subtypes. */
1438 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1439 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
1441 flags = 0;
1442 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1443 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1444 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
1445 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#lx.\n", flags);
1447 /* Different user data. */
1448 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
1449 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1451 flags = 0;
1452 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1453 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1454 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
1455 "Unexpected flags %#lx.\n", flags);
1457 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
1458 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1460 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1461 ok(hr == S_OK, "Failed to set subtype, hr %#lx.\n", hr);
1463 flags = 0;
1464 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1465 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1466 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1467 "Unexpected flags %#lx.\n", flags);
1469 IMFMediaType_Release(mediatype2);
1470 IMFMediaType_Release(mediatype);
1472 /* IMFVideoMediaType */
1473 hr = MFCreateMediaType(&mediatype);
1474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1476 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
1478 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1479 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1480 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1481 IUnknown_Release(unk);
1483 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1484 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1486 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
1487 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1489 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1490 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1491 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1492 IUnknown_Release(unk2);
1494 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1495 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1496 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1497 IUnknown_Release(unk2);
1499 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1500 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1501 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1502 IUnknown_Release(unk2);
1504 IUnknown_Release(unk);
1505 IMFMediaType_Release(mediatype);
1507 if (pMFCreateVideoMediaTypeFromSubtype)
1509 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
1510 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1512 check_interface(video_type, &IID_IMFMediaType, TRUE);
1513 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
1515 /* Major and subtype are set on creation. */
1516 hr = IMFVideoMediaType_GetCount(video_type, &count);
1517 ok(count == 2, "Unexpected attribute count %#lx.\n", hr);
1519 hr = IMFVideoMediaType_DeleteAllItems(video_type);
1520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1522 hr = IMFVideoMediaType_GetCount(video_type, &count);
1523 ok(!count, "Unexpected attribute count %#lx.\n", hr);
1525 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
1527 IMFVideoMediaType_Release(video_type);
1529 else
1530 win_skip("MFCreateVideoMediaTypeFromSubtype() is not available.\n");
1532 /* IMFAudioMediaType */
1533 hr = MFCreateMediaType(&mediatype);
1534 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1536 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
1538 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1539 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1540 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1541 IUnknown_Release(unk);
1543 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1544 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1546 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1547 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1549 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1550 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1551 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1552 IUnknown_Release(unk2);
1554 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1556 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1557 IUnknown_Release(unk2);
1559 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1560 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1561 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1562 IUnknown_Release(unk2);
1564 IUnknown_Release(unk);
1566 IMFMediaType_Release(mediatype);
1569 static void test_MFCreateMediaEvent(void)
1571 HRESULT hr;
1572 IMFMediaEvent *mediaevent;
1574 MediaEventType type;
1575 GUID extended_type;
1576 HRESULT status;
1577 PROPVARIANT value;
1579 PropVariantInit(&value);
1580 value.vt = VT_UNKNOWN;
1582 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1583 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1585 PropVariantClear(&value);
1587 hr = IMFMediaEvent_GetType(mediaevent, &type);
1588 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1589 ok(type == MEError, "got %#lx\n", type);
1591 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1592 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1593 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1594 wine_dbgstr_guid(&extended_type));
1596 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1597 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1598 ok(status == E_FAIL, "Unexpected hr %#lx.\n", status);
1600 PropVariantInit(&value);
1601 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1603 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1604 PropVariantClear(&value);
1606 IMFMediaEvent_Release(mediaevent);
1608 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1609 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1611 hr = IMFMediaEvent_GetType(mediaevent, &type);
1612 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1613 ok(type == MEUnknown, "got %#lx\n", type);
1615 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1616 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1617 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1618 wine_dbgstr_guid(&extended_type));
1620 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1621 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1622 ok(status == S_OK, "Unexpected hr %#lx.\n", status);
1624 PropVariantInit(&value);
1625 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1626 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1627 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1628 PropVariantClear(&value);
1630 IMFMediaEvent_Release(mediaevent);
1633 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1634 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1636 UINT32 count = expected + 1;
1637 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1638 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
1639 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1642 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1643 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1645 MF_ATTRIBUTE_TYPE type;
1646 HRESULT hr;
1648 hr = IMFAttributes_GetItemType(obj, key, &type);
1649 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
1650 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1653 static void test_attributes(void)
1655 static const WCHAR stringW[] = L"Wine";
1656 static const UINT8 blob[] = {0,1,2,3,4,5};
1657 IMFAttributes *attributes, *attributes1;
1658 UINT8 blob_value[256], *blob_buf = NULL;
1659 MF_ATTRIBUTES_MATCH_TYPE match_type;
1660 UINT32 value, string_length, size;
1661 PROPVARIANT propvar, ret_propvar;
1662 MF_ATTRIBUTE_TYPE type;
1663 double double_value;
1664 IUnknown *unk_value;
1665 WCHAR bufferW[256];
1666 UINT64 value64;
1667 WCHAR *string;
1668 BOOL result;
1669 HRESULT hr;
1670 GUID key;
1672 hr = MFCreateAttributes( &attributes, 3 );
1673 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1675 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1676 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1678 CHECK_ATTR_COUNT(attributes, 0);
1679 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1680 ok(hr == S_OK, "Failed to set UINT32 value, hr %#lx.\n", hr);
1681 CHECK_ATTR_COUNT(attributes, 1);
1682 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1684 value = 0xdeadbeef;
1685 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1686 ok(hr == S_OK, "Failed to get UINT32 value, hr %#lx.\n", hr);
1687 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1689 value64 = 0xdeadbeef;
1690 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1691 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1692 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1694 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1695 ok(hr == S_OK, "Failed to set UINT64 value, hr %#lx.\n", hr);
1696 CHECK_ATTR_COUNT(attributes, 1);
1697 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1699 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1700 ok(hr == S_OK, "Failed to get UINT64 value, hr %#lx.\n", hr);
1701 ok(value64 == 65536, "Unexpected value.\n");
1703 value = 0xdeadbeef;
1704 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1705 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1706 ok(value == 0xdeadbeef, "Unexpected value.\n");
1708 IMFAttributes_Release(attributes);
1710 hr = MFCreateAttributes(&attributes, 0);
1711 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1713 PropVariantInit(&propvar);
1714 propvar.vt = MF_ATTRIBUTE_UINT32;
1715 propvar.ulVal = 123;
1716 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1717 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1718 PropVariantInit(&ret_propvar);
1719 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1720 ret_propvar.ulVal = 0xdeadbeef;
1721 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1722 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1723 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1724 PropVariantClear(&ret_propvar);
1725 CHECK_ATTR_COUNT(attributes, 1);
1727 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1728 ok(hr == S_OK, "Item check failed, hr %#lx.\n", hr);
1730 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1731 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1733 PropVariantInit(&ret_propvar);
1734 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1735 ret_propvar.pwszVal = NULL;
1736 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1737 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1738 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1739 PropVariantClear(&ret_propvar);
1741 PropVariantClear(&propvar);
1743 PropVariantInit(&propvar);
1744 propvar.vt = MF_ATTRIBUTE_UINT64;
1745 propvar.uhVal.QuadPart = 65536;
1746 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1747 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1748 PropVariantInit(&ret_propvar);
1749 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1750 ret_propvar.ulVal = 0xdeadbeef;
1751 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1752 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1753 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1754 PropVariantClear(&ret_propvar);
1755 PropVariantClear(&propvar);
1756 CHECK_ATTR_COUNT(attributes, 1);
1758 PropVariantInit(&propvar);
1759 propvar.vt = VT_I4;
1760 propvar.lVal = 123;
1761 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1762 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#lx.\n", hr);
1763 PropVariantInit(&ret_propvar);
1764 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1765 ret_propvar.lVal = 0xdeadbeef;
1766 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1767 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1768 PropVariantClear(&propvar);
1769 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1770 PropVariantClear(&ret_propvar);
1772 PropVariantInit(&propvar);
1773 propvar.vt = MF_ATTRIBUTE_UINT32;
1774 propvar.ulVal = 123;
1775 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1776 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1778 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1779 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1780 CHECK_ATTR_COUNT(attributes, 2);
1782 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1783 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1784 CHECK_ATTR_COUNT(attributes, 2);
1786 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1787 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1788 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1789 PropVariantClear(&ret_propvar);
1790 PropVariantClear(&propvar);
1792 propvar.vt = MF_ATTRIBUTE_UINT64;
1793 propvar.uhVal.QuadPart = 65536;
1795 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1796 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1797 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1798 PropVariantClear(&ret_propvar);
1799 PropVariantClear(&propvar);
1801 /* Item ordering is not consistent across Windows version. */
1802 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1803 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1804 PropVariantClear(&ret_propvar);
1806 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1807 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1808 PropVariantClear(&ret_propvar);
1810 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1811 ok(hr == S_OK, "Failed to set double value, hr %#lx.\n", hr);
1812 CHECK_ATTR_COUNT(attributes, 3);
1813 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1815 double_value = 0xdeadbeef;
1816 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1817 ok(hr == S_OK, "Failed to get double value, hr %#lx.\n", hr);
1818 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1820 propvar.vt = MF_ATTRIBUTE_UINT64;
1821 propvar.uhVal.QuadPart = 22;
1822 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1823 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1824 ok(!result, "Unexpected result.\n");
1826 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1827 propvar.dblVal = 22.0;
1828 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1829 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1830 ok(result, "Unexpected result.\n");
1832 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1833 ok(hr == S_OK, "Failed to set string attribute, hr %#lx.\n", hr);
1834 CHECK_ATTR_COUNT(attributes, 3);
1835 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1837 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1838 ok(hr == S_OK, "Failed to get string length, hr %#lx.\n", hr);
1839 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1841 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, NULL);
1842 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1843 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1844 CoTaskMemFree(string);
1846 string_length = 0xdeadbeef;
1847 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1848 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1849 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1850 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1851 CoTaskMemFree(string);
1853 string_length = 0xdeadbeef;
1854 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1855 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1856 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1857 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1858 memset(bufferW, 0, sizeof(bufferW));
1860 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1861 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1862 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1863 memset(bufferW, 0, sizeof(bufferW));
1865 string_length = 0;
1866 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1867 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1868 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1869 ok(string_length, "Unexpected length.\n");
1871 string_length = 0xdeadbeef;
1872 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1873 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1874 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1876 /* VT_UNKNOWN */
1877 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1878 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1879 CHECK_ATTR_COUNT(attributes, 4);
1880 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1882 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1883 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1884 IUnknown_Release(unk_value);
1886 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1887 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1888 IUnknown_Release(unk_value);
1890 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1891 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1893 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1894 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1895 CHECK_ATTR_COUNT(attributes, 5);
1897 unk_value = NULL;
1898 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1899 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1901 /* CopyAllItems() */
1902 hr = MFCreateAttributes(&attributes1, 0);
1903 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1904 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1905 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1906 CHECK_ATTR_COUNT(attributes, 5);
1907 CHECK_ATTR_COUNT(attributes1, 5);
1909 hr = IMFAttributes_DeleteAllItems(attributes1);
1910 ok(hr == S_OK, "Failed to delete items, hr %#lx.\n", hr);
1911 CHECK_ATTR_COUNT(attributes1, 0);
1913 propvar.vt = MF_ATTRIBUTE_UINT64;
1914 propvar.uhVal.QuadPart = 22;
1915 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1916 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1917 ok(!result, "Unexpected result.\n");
1919 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1920 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1921 CHECK_ATTR_COUNT(attributes, 0);
1923 /* Blob */
1924 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1925 ok(hr == S_OK, "Failed to set blob attribute, hr %#lx.\n", hr);
1926 CHECK_ATTR_COUNT(attributes, 1);
1927 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1928 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1929 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
1930 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1932 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1933 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1935 size = 0;
1936 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1937 ok(hr == S_OK, "Failed to get blob, hr %#lx.\n", hr);
1938 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1939 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1941 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1942 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1944 memset(blob_value, 0, sizeof(blob_value));
1945 size = 0;
1946 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1947 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1948 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1949 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1950 CoTaskMemFree(blob_buf);
1952 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, NULL);
1953 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1954 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1955 CoTaskMemFree(blob_buf);
1957 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1958 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1960 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1961 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1963 IMFAttributes_Release(attributes);
1964 IMFAttributes_Release(attributes1);
1966 /* Compare() */
1967 hr = MFCreateAttributes(&attributes, 0);
1968 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1969 hr = MFCreateAttributes(&attributes1, 0);
1970 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1972 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1973 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1975 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1977 result = FALSE;
1978 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1979 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1980 ok(result, "Unexpected result %d.\n", result);
1982 result = FALSE;
1983 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1984 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1985 ok(result, "Unexpected result %d.\n", result);
1988 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1989 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1991 result = TRUE;
1992 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1993 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1994 ok(!result, "Unexpected result %d.\n", result);
1996 result = TRUE;
1997 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1998 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1999 ok(!result, "Unexpected result %d.\n", result);
2001 result = FALSE;
2002 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2003 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2004 ok(result, "Unexpected result %d.\n", result);
2006 result = FALSE;
2007 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2008 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2009 ok(result, "Unexpected result %d.\n", result);
2011 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
2012 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
2014 result = TRUE;
2015 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2016 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2017 ok(!result, "Unexpected result %d.\n", result);
2019 result = TRUE;
2020 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
2021 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2022 ok(!result, "Unexpected result %d.\n", result);
2024 result = TRUE;
2025 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2026 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2027 ok(!result, "Unexpected result %d.\n", result);
2029 result = TRUE;
2030 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2031 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2032 ok(!result, "Unexpected result %d.\n", result);
2034 result = TRUE;
2035 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2036 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2037 ok(!result, "Unexpected result %d.\n", result);
2039 result = TRUE;
2040 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2041 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2042 ok(!result, "Unexpected result %d.\n", result);
2044 result = TRUE;
2045 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
2046 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2047 ok(!result, "Unexpected result %d.\n", result);
2049 result = TRUE;
2050 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2051 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2052 ok(!result, "Unexpected result %d.\n", result);
2054 result = TRUE;
2055 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2056 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2057 ok(!result, "Unexpected result %d.\n", result);
2059 result = TRUE;
2060 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2061 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2062 ok(!result, "Unexpected result %d.\n", result);
2064 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
2065 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
2067 result = FALSE;
2068 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2069 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2070 ok(result, "Unexpected result %d.\n", result);
2072 result = FALSE;
2073 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2074 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2075 ok(result, "Unexpected result %d.\n", result);
2077 result = FALSE;
2078 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2079 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2080 ok(result, "Unexpected result %d.\n", result);
2082 result = FALSE;
2083 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2084 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2085 ok(result, "Unexpected result %d.\n", result);
2087 result = FALSE;
2088 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2089 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2090 ok(result, "Unexpected result %d.\n", result);
2092 result = FALSE;
2093 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2094 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2095 ok(result, "Unexpected result %d.\n", result);
2097 result = FALSE;
2098 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2099 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2100 ok(result, "Unexpected result %d.\n", result);
2102 result = FALSE;
2103 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2104 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2105 ok(result, "Unexpected result %d.\n", result);
2107 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
2108 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
2110 result = TRUE;
2111 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2112 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2113 ok(!result, "Unexpected result %d.\n", result);
2115 result = TRUE;
2116 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2117 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2118 ok(!result, "Unexpected result %d.\n", result);
2120 result = FALSE;
2121 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
2122 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2123 ok(result, "Unexpected result %d.\n", result);
2125 result = FALSE;
2126 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2127 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2128 ok(result, "Unexpected result %d.\n", result);
2130 result = FALSE;
2131 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2132 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2133 ok(result, "Unexpected result %d.\n", result);
2135 result = TRUE;
2136 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
2137 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2138 ok(!result, "Unexpected result %d.\n", result);
2140 result = FALSE;
2141 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
2142 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2143 ok(result, "Unexpected result %d.\n", result);
2145 result = TRUE;
2146 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
2147 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2148 ok(!result, "Unexpected result %d.\n", result);
2150 result = FALSE;
2151 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
2152 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2153 ok(result, "Unexpected result %d.\n", result);
2155 result = FALSE;
2156 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
2157 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
2158 ok(result, "Unexpected result %d.\n", result);
2160 IMFAttributes_Release(attributes);
2161 IMFAttributes_Release(attributes1);
2164 struct test_stream
2166 IStream IStream_iface;
2167 LONG refcount;
2169 HANDLE read_event;
2170 HANDLE done_event;
2173 static struct test_stream *impl_from_IStream(IStream *iface)
2175 return CONTAINING_RECORD(iface, struct test_stream, IStream_iface);
2178 static HRESULT WINAPI test_stream_QueryInterface(IStream *iface, REFIID iid, void **out)
2180 if (IsEqualIID(iid, &IID_IUnknown)
2181 || IsEqualIID(iid, &IID_IStream))
2183 *out = iface;
2184 IStream_AddRef(iface);
2185 return S_OK;
2188 *out = NULL;
2189 return E_NOINTERFACE;
2192 static ULONG WINAPI test_stream_AddRef(IStream *iface)
2194 struct test_stream *stream = impl_from_IStream(iface);
2195 return InterlockedIncrement(&stream->refcount);
2198 static ULONG WINAPI test_stream_Release(IStream *iface)
2200 struct test_stream *stream = impl_from_IStream(iface);
2201 ULONG ref = InterlockedDecrement(&stream->refcount);
2203 if (!ref)
2205 CloseHandle(stream->read_event);
2206 CloseHandle(stream->done_event);
2207 free(stream);
2210 return ref;
2213 static HRESULT WINAPI test_stream_Read(IStream *iface, void *data, ULONG size, ULONG *ret_size)
2215 struct test_stream *stream = impl_from_IStream(iface);
2216 DWORD res;
2218 SetEvent(stream->read_event);
2219 res = WaitForSingleObject(stream->done_event, 1000);
2220 ok(res == 0, "got %#lx\n", res);
2222 *ret_size = size;
2223 return S_OK;
2226 static HRESULT WINAPI test_stream_Write(IStream *iface, const void *data, ULONG size, ULONG *ret_size)
2228 ok(0, "Unexpected call.\n");
2229 return E_NOTIMPL;
2232 static HRESULT WINAPI test_stream_Seek(IStream *iface, LARGE_INTEGER offset, DWORD method, ULARGE_INTEGER *ret_offset)
2234 return S_OK;
2237 static HRESULT WINAPI test_stream_SetSize(IStream *iface, ULARGE_INTEGER size)
2239 ok(0, "Unexpected call.\n");
2240 return E_NOTIMPL;
2243 static HRESULT WINAPI test_stream_CopyTo(IStream *iface, IStream *dest, ULARGE_INTEGER size,
2244 ULARGE_INTEGER *read_size, ULARGE_INTEGER *write_size)
2246 ok(0, "Unexpected call.\n");
2247 return E_NOTIMPL;
2250 static HRESULT WINAPI test_stream_Commit(IStream *iface, DWORD flags)
2252 ok(0, "Unexpected call.\n");
2253 return E_NOTIMPL;
2256 static HRESULT WINAPI test_stream_Revert(IStream *iface)
2258 ok(0, "Unexpected call.\n");
2259 return E_NOTIMPL;
2262 static HRESULT WINAPI test_stream_LockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER size, DWORD type)
2264 ok(0, "Unexpected call.\n");
2265 return E_NOTIMPL;
2268 static HRESULT WINAPI test_stream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER size, DWORD type)
2270 ok(0, "Unexpected call.\n");
2271 return E_NOTIMPL;
2274 static HRESULT WINAPI test_stream_Stat(IStream *iface, STATSTG *stat, DWORD flags)
2276 memset(stat, 0, sizeof(STATSTG));
2277 stat->pwcsName = NULL;
2278 stat->type = STGTY_STREAM;
2279 stat->cbSize.QuadPart = 16;
2280 return S_OK;
2283 static HRESULT WINAPI test_stream_Clone(IStream *iface, IStream **out)
2285 ok(0, "Unexpected call.\n");
2286 return E_NOTIMPL;
2289 static const IStreamVtbl test_stream_vtbl =
2291 test_stream_QueryInterface,
2292 test_stream_AddRef,
2293 test_stream_Release,
2294 test_stream_Read,
2295 test_stream_Write,
2296 test_stream_Seek,
2297 test_stream_SetSize,
2298 test_stream_CopyTo,
2299 test_stream_Commit,
2300 test_stream_Revert,
2301 test_stream_LockRegion,
2302 test_stream_UnlockRegion,
2303 test_stream_Stat,
2304 test_stream_Clone,
2307 static HRESULT test_stream_create(IStream **out)
2309 struct test_stream *stream;
2311 if (!(stream = calloc(1, sizeof(*stream))))
2312 return E_OUTOFMEMORY;
2314 stream->IStream_iface.lpVtbl = &test_stream_vtbl;
2315 stream->refcount = 1;
2317 stream->read_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2318 stream->done_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2320 *out = &stream->IStream_iface;
2321 return S_OK;
2324 static DWORD test_stream_wait_read(IStream *iface, DWORD timeout)
2326 struct test_stream *stream = impl_from_IStream(iface);
2327 return WaitForSingleObject(stream->read_event, timeout);
2330 static void test_stream_complete_read(IStream *iface)
2332 struct test_stream *stream = impl_from_IStream(iface);
2333 SetEvent(stream->done_event);
2336 static void test_MFCreateMFByteStreamOnStream(void)
2338 struct test_callback *read_callback, *test_callback;
2339 IMFByteStream *bytestream;
2340 IMFByteStream *bytestream2;
2341 IStream *stream;
2342 IMFAttributes *attributes = NULL;
2343 IMFAsyncResult *result;
2344 DWORD caps, written;
2345 IUnknown *unknown;
2346 BYTE buffer[16];
2347 ULONG ref, size;
2348 DWORD res, len;
2349 HRESULT hr;
2350 UINT count;
2351 QWORD to;
2353 if(!pMFCreateMFByteStreamOnStream)
2355 win_skip("MFCreateMFByteStreamOnStream() not found\n");
2356 return;
2359 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2360 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2362 caps = 0xffff0000;
2363 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
2364 ok(hr == S_OK, "Failed to write, hr %#lx.\n", hr);
2366 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
2367 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2369 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
2370 (void **)&unknown);
2371 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2372 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2373 ref = IUnknown_Release(unknown);
2374 ok(ref == 1, "got %lu\n", ref);
2376 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
2377 (void **)&bytestream2);
2378 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2379 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2380 ref = IMFByteStream_Release(bytestream2);
2381 ok(ref == 1, "got %lu\n", ref);
2383 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2384 (void **)&attributes);
2385 ok(hr == S_OK ||
2386 /* w7pro64 */
2387 broken(hr == E_NOINTERFACE), "Unexpected hr %#lx.\n", hr);
2389 if (hr != S_OK)
2391 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
2392 IStream_Release(stream);
2393 IMFByteStream_Release(bytestream);
2394 return;
2397 ok(attributes != NULL, "got NULL\n");
2398 hr = IMFAttributes_GetCount(attributes, &count);
2399 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2400 ok(count == 0, "Unexpected attributes count %u.\n", count);
2402 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
2403 (void **)&unknown);
2404 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2405 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2406 ref = IUnknown_Release(unknown);
2407 ok(ref == 2, "got %lu\n", ref);
2409 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
2410 (void **)&bytestream2);
2411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2412 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2413 ref = IMFByteStream_Release(bytestream2);
2414 ok(ref == 2, "got %lu\n", ref);
2416 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2417 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2418 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2419 check_interface(bytestream, &IID_IMFGetService, FALSE);
2421 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2422 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2423 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2425 hr = IMFByteStream_Close(bytestream);
2426 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2428 hr = IMFByteStream_Close(bytestream);
2429 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2431 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2432 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2433 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2435 /* IMFByteStream maintains position separately from IStream */
2436 caps = 0;
2437 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2438 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2439 ok(size == 4, "Unexpected size.\n");
2440 ok(caps == 0xffff0000, "Unexpected content.\n");
2442 caps = 0;
2443 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2444 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2445 ok(size == 4, "Unexpected size.\n");
2446 ok(caps == 0xffff0000, "Unexpected content.\n");
2448 caps = 0;
2449 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2450 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2451 ok(size == 0, "Unexpected size.\n");
2452 ok(caps == 0, "Unexpected content.\n");
2454 hr = IMFByteStream_Seek(bytestream, msoBegin, 0, 0, &to);
2455 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2457 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2458 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2459 ok(size == 0, "Unexpected size.\n");
2460 ok(caps == 0, "Unexpected content.\n");
2462 caps = 0;
2463 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2464 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2465 ok(size == 4, "Unexpected size.\n");
2466 ok(caps == 0xffff0000, "Unexpected content.\n");
2468 caps = 0;
2469 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2470 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2471 ok(size == 0, "Unexpected size.\n");
2472 ok(caps == 0, "Unexpected content.\n");
2474 IMFAttributes_Release(attributes);
2475 IMFByteStream_Release(bytestream);
2476 IStream_Release(stream);
2479 /* test that BeginRead doesn't use MFASYNC_CALLBACK_QUEUE_STANDARD */
2481 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2482 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2484 read_callback = create_test_callback(&test_async_callback_result_vtbl);
2485 test_callback = create_test_callback(&test_async_callback_result_vtbl);
2487 hr = test_stream_create(&stream);
2488 ok(hr == S_OK, "got %#lx\n", hr);
2489 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
2490 ok(hr == S_OK, "got %#lx\n", hr);
2492 hr = IMFByteStream_BeginRead(bytestream, buffer, 1, &read_callback->IMFAsyncCallback_iface, NULL);
2493 ok(hr == S_OK, "got %#lx\n", hr);
2495 res = test_stream_wait_read(stream, 1000);
2496 ok(res == 0, "got %#lx\n", res);
2497 res = wait_async_callback_result(&read_callback->IMFAsyncCallback_iface, 10, &result);
2498 ok(res == WAIT_TIMEOUT, "got %#lx\n", res);
2500 /* MFASYNC_CALLBACK_QUEUE_STANDARD is not blocked */
2501 hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &test_callback->IMFAsyncCallback_iface, NULL);
2502 ok(hr == S_OK, "got %#lx\n", hr);
2503 res = wait_async_callback_result(&test_callback->IMFAsyncCallback_iface, 100, &result);
2504 ok(res == 0, "got %#lx\n", res);
2505 IMFAsyncResult_Release(result);
2507 test_stream_complete_read(stream);
2508 res = wait_async_callback_result(&read_callback->IMFAsyncCallback_iface, 1000, &result);
2509 ok(res == 0, "got %#lx\n", res);
2510 hr = IMFByteStream_EndRead(bytestream, result, &len);
2511 ok(hr == S_OK, "got %#lx\n", hr);
2512 ok(len == 1, "got %#lx\n", len);
2513 IMFAsyncResult_Release(result);
2515 IMFByteStream_Release(bytestream);
2516 IStream_Release(stream);
2518 IMFAsyncCallback_Release(&read_callback->IMFAsyncCallback_iface);
2519 IMFAsyncCallback_Release(&test_callback->IMFAsyncCallback_iface);
2521 hr = MFShutdown();
2522 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2525 static void test_file_stream(void)
2527 static const WCHAR newfilename[] = L"new.mp4";
2528 IMFByteStream *bytestream, *bytestream2;
2529 QWORD bytestream_length, position;
2530 IMFAttributes *attributes = NULL;
2531 MF_ATTRIBUTE_TYPE item_type;
2532 WCHAR pathW[MAX_PATH];
2533 WCHAR *filename;
2534 HRESULT hr;
2535 WCHAR *str;
2536 DWORD caps;
2537 UINT count;
2538 BOOL eos;
2540 filename = load_resource(L"test.mp4");
2542 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2543 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2545 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2546 MF_FILEFLAGS_NONE, filename, &bytestream);
2547 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2549 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2550 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2551 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2552 check_interface(bytestream, &IID_IMFGetService, TRUE);
2554 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2555 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2556 if (is_win8_plus)
2558 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
2559 "Unexpected caps %#lx.\n", caps);
2561 else
2562 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2564 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2565 (void **)&attributes);
2566 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2567 ok(attributes != NULL, "got NULL\n");
2569 hr = IMFAttributes_GetCount(attributes, &count);
2570 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2571 ok(count == 2, "Unexpected attributes count %u.\n", count);
2573 /* Original file name. */
2574 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
2575 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
2576 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
2577 CoTaskMemFree(str);
2579 /* Modification time. */
2580 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
2581 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
2582 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
2584 IMFAttributes_Release(attributes);
2586 /* Length. */
2587 hr = IMFByteStream_GetLength(bytestream, NULL);
2588 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2590 bytestream_length = 0;
2591 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
2592 ok(hr == S_OK, "Failed to get bytestream length, hr %#lx.\n", hr);
2593 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
2595 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
2596 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2598 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
2599 ok(hr == S_OK, "Failed query end of stream, hr %#lx.\n", hr);
2600 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
2602 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
2603 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2605 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
2606 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2608 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
2609 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2610 ok(position == 2 * bytestream_length, "Unexpected position.\n");
2612 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2613 MF_FILEFLAGS_NONE, filename, &bytestream2);
2614 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2615 IMFByteStream_Release(bytestream2);
2617 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2618 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2620 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2621 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2623 IMFByteStream_Release(bytestream);
2625 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2626 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2627 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
2629 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2630 MF_FILEFLAGS_NONE, filename, &bytestream);
2631 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "Unexpected hr %#lx.\n", hr);
2633 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2634 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2635 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2637 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2638 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2640 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2641 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2643 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2644 newfilename, &bytestream2);
2645 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2647 IMFByteStream_Release(bytestream);
2649 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2650 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
2651 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2653 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
2654 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2655 newfilename, &bytestream2);
2656 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2658 IMFByteStream_Release(bytestream);
2660 /* Explicit file: scheme */
2661 lstrcpyW(pathW, fileschemeW);
2662 lstrcatW(pathW, filename);
2663 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
2664 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2666 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream);
2667 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2668 ok(DeleteFileW(filename), "failed to delete file\n");
2669 IMFByteStream_Release(bytestream);
2671 hr = MFShutdown();
2672 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2674 DeleteFileW(newfilename);
2677 static void test_system_memory_buffer(void)
2679 IMFMediaBuffer *buffer;
2680 HRESULT hr;
2681 DWORD length, max;
2682 BYTE *data, *data2;
2684 hr = MFCreateMemoryBuffer(1024, NULL);
2685 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2687 hr = MFCreateMemoryBuffer(0, &buffer);
2688 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2689 if(buffer)
2691 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2692 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2693 ok(length == 0, "got %lu\n", length);
2695 IMFMediaBuffer_Release(buffer);
2698 hr = MFCreateMemoryBuffer(1024, &buffer);
2699 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2701 check_interface(buffer, &IID_IMFGetService, FALSE);
2703 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
2704 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2706 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2707 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2708 ok(length == 1024, "got %lu\n", length);
2710 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2711 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2713 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2714 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2716 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2717 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2719 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2720 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2721 ok(length == 10, "got %lu\n", length);
2723 length = 0;
2724 max = 0;
2725 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2726 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2727 ok(length == 0, "got %lu\n", length);
2728 ok(max == 0, "got %lu\n", length);
2730 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2732 ok(length == 10, "got %lu\n", length);
2733 ok(max == 1024, "got %lu\n", max);
2735 /* Attempt to lock the buffer twice */
2736 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2737 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2738 ok(data == data2, "Unexpected hr %#lx.\n", hr);
2740 hr = IMFMediaBuffer_Unlock(buffer);
2741 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2743 hr = IMFMediaBuffer_Unlock(buffer);
2744 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2746 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2747 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2749 hr = IMFMediaBuffer_Unlock(buffer);
2750 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2752 /* Extra Unlock */
2753 hr = IMFMediaBuffer_Unlock(buffer);
2754 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2756 IMFMediaBuffer_Release(buffer);
2759 static void test_system_memory_aligned_buffer(void)
2761 static const DWORD alignments[] =
2763 MF_16_BYTE_ALIGNMENT,
2764 MF_32_BYTE_ALIGNMENT,
2765 MF_64_BYTE_ALIGNMENT,
2766 MF_128_BYTE_ALIGNMENT,
2767 MF_256_BYTE_ALIGNMENT,
2768 MF_512_BYTE_ALIGNMENT,
2770 IMFMediaBuffer *buffer;
2771 DWORD length, max;
2772 unsigned int i;
2773 BYTE *data;
2774 HRESULT hr;
2776 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2777 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2779 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2780 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2782 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2783 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2784 ok(length == 0, "Unexpected current length %lu.\n", length);
2786 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2787 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2788 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2789 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2790 ok(length == 1, "Unexpected current length %lu.\n", length);
2792 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2793 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2794 ok(length == 201, "Unexpected max length %lu.\n", length);
2796 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2797 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2798 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2799 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2800 ok(length == 201, "Unexpected max length %lu.\n", length);
2801 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2802 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2804 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2805 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2806 ok(max == 201 && length == 10, "Unexpected length.\n");
2807 hr = IMFMediaBuffer_Unlock(buffer);
2808 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2810 IMFMediaBuffer_Release(buffer);
2812 for (i = 0; i < ARRAY_SIZE(alignments); ++i)
2814 hr = MFCreateAlignedMemoryBuffer(200, alignments[i], &buffer);
2815 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2817 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2818 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2819 ok(max == 200 && !length, "Unexpected length.\n");
2820 ok(!((uintptr_t)data & alignments[i]), "Data at %p is misaligned.\n", data);
2821 hr = IMFMediaBuffer_Unlock(buffer);
2822 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2824 IMFMediaBuffer_Release(buffer);
2827 hr = MFCreateAlignedMemoryBuffer(200, 0, &buffer);
2828 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2829 IMFMediaBuffer_Release(buffer);
2832 static void test_sample(void)
2834 static const DWORD test_pattern = 0x22222222;
2835 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2836 DWORD count, flags, length;
2837 IMFAttributes *attributes;
2838 IMFSample *sample;
2839 LONGLONG time;
2840 HRESULT hr;
2841 BYTE *data;
2843 hr = MFCreateSample( &sample );
2844 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2846 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2847 ok(hr == S_OK, "Failed to get attributes interface, hr %#lx.\n", hr);
2849 CHECK_ATTR_COUNT(attributes, 0);
2851 hr = IMFSample_GetBufferCount(sample, NULL);
2852 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2854 hr = IMFSample_GetBufferCount(sample, &count);
2855 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2856 ok(count == 0, "got %ld\n", count);
2858 hr = IMFSample_GetSampleFlags(sample, &flags);
2859 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2860 ok(!flags, "Unexpected flags %#lx.\n", flags);
2862 hr = IMFSample_SetSampleFlags(sample, 0x123);
2863 ok(hr == S_OK, "Failed to set sample flags, hr %#lx.\n", hr);
2864 hr = IMFSample_GetSampleFlags(sample, &flags);
2865 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2866 ok(flags == 0x123, "Unexpected flags %#lx.\n", flags);
2868 hr = IMFSample_GetSampleTime(sample, &time);
2869 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
2871 hr = IMFSample_GetSampleDuration(sample, &time);
2872 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
2874 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2875 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2877 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2878 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2880 hr = IMFSample_RemoveAllBuffers(sample);
2881 ok(hr == S_OK, "Failed to remove all, hr %#lx.\n", hr);
2883 hr = IMFSample_GetTotalLength(sample, &length);
2884 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2885 ok(!length, "Unexpected total length %lu.\n", length);
2887 hr = MFCreateMemoryBuffer(16, &buffer);
2888 ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr);
2890 hr = IMFSample_AddBuffer(sample, buffer);
2891 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2893 hr = IMFSample_AddBuffer(sample, buffer);
2894 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2896 hr = IMFSample_GetBufferCount(sample, &count);
2897 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2898 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2900 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2901 ok(hr == S_OK, "Failed to get buffer, hr %#lx.\n", hr);
2902 ok(buffer2 == buffer, "Unexpected object.\n");
2903 IMFMediaBuffer_Release(buffer2);
2905 hr = IMFSample_GetTotalLength(sample, &length);
2906 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2907 ok(!length, "Unexpected total length %lu.\n", length);
2909 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2910 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2912 hr = IMFSample_GetTotalLength(sample, &length);
2913 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2914 ok(length == 4, "Unexpected total length %lu.\n", length);
2916 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2917 ok(hr == S_OK, "Failed to remove buffer, hr %#lx.\n", hr);
2919 hr = IMFSample_GetTotalLength(sample, &length);
2920 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2921 ok(length == 2, "Unexpected total length %lu.\n", length);
2923 IMFMediaBuffer_Release(buffer);
2925 /* Duration */
2926 hr = IMFSample_SetSampleDuration(sample, 10);
2927 ok(hr == S_OK, "Failed to set duration, hr %#lx.\n", hr);
2928 CHECK_ATTR_COUNT(attributes, 0);
2929 hr = IMFSample_GetSampleDuration(sample, &time);
2930 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
2931 ok(time == 10, "Unexpected duration.\n");
2933 /* Timestamp */
2934 hr = IMFSample_SetSampleTime(sample, 1);
2935 ok(hr == S_OK, "Failed to set timestamp, hr %#lx.\n", hr);
2936 CHECK_ATTR_COUNT(attributes, 0);
2937 hr = IMFSample_GetSampleTime(sample, &time);
2938 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
2939 ok(time == 1, "Unexpected timestamp.\n");
2941 IMFAttributes_Release(attributes);
2942 IMFSample_Release(sample);
2944 /* CopyToBuffer() */
2945 hr = MFCreateSample(&sample);
2946 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2948 hr = MFCreateMemoryBuffer(16, &buffer2);
2949 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2951 /* Sample with no buffers. */
2952 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2953 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2954 hr = IMFSample_CopyToBuffer(sample, buffer2);
2955 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2956 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2957 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2958 ok(!length, "Unexpected length %lu.\n", length);
2960 /* Single buffer, larger destination. */
2961 hr = MFCreateMemoryBuffer(8, &buffer);
2962 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2964 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2965 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2966 *(DWORD *)data = 0x11111111;
2967 hr = IMFMediaBuffer_Unlock(buffer);
2968 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2969 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2970 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2972 hr = IMFSample_AddBuffer(sample, buffer);
2973 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2975 /* Existing content is overwritten. */
2976 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2977 ok(hr == S_OK, "Failed to set length, hr %#lx.\n", hr);
2979 hr = IMFSample_CopyToBuffer(sample, buffer2);
2980 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2982 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2983 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2984 ok(length == 4, "Unexpected buffer length %lu.\n", length);
2986 /* Multiple buffers, matching total size. */
2987 hr = IMFSample_AddBuffer(sample, buffer);
2988 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2990 hr = IMFSample_GetBufferCount(sample, &count);
2991 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2992 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2994 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2995 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2997 hr = IMFSample_CopyToBuffer(sample, buffer2);
2998 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
3000 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
3001 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
3002 ok(length == 16, "Unexpected buffer length %lu.\n", length);
3004 hr = IMFSample_AddBuffer(sample, buffer);
3005 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
3007 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
3008 ok(hr == S_OK, "Failed to set buffer length, hr %#lx.\n", hr);
3010 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
3011 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
3012 *(DWORD *)data = test_pattern;
3013 hr = IMFMediaBuffer_Unlock(buffer2);
3014 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
3016 hr = IMFSample_CopyToBuffer(sample, buffer2);
3017 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
3019 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
3020 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
3021 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#lx\n", *(DWORD *)data);
3022 hr = IMFMediaBuffer_Unlock(buffer2);
3023 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
3025 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
3026 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
3027 ok(!length, "Unexpected buffer length %lu.\n", length);
3029 IMFMediaBuffer_Release(buffer2);
3030 IMFSample_Release(sample);
3032 /* ConvertToContiguousBuffer() */
3033 hr = MFCreateSample(&sample);
3034 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
3036 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
3037 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3039 hr = MFCreateMemoryBuffer(16, &buffer);
3040 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
3042 hr = IMFSample_AddBuffer(sample, buffer);
3043 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
3045 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
3046 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
3047 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
3048 IMFMediaBuffer_Release(buffer2);
3050 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
3051 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
3053 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
3054 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
3055 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
3056 IMFMediaBuffer_Release(buffer2);
3058 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
3059 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3061 hr = MFCreateMemoryBuffer(16, &buffer2);
3062 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
3064 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
3065 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3067 hr = IMFSample_AddBuffer(sample, buffer2);
3068 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
3069 IMFMediaBuffer_Release(buffer2);
3071 hr = IMFSample_GetBufferCount(sample, &count);
3072 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
3073 ok(count == 2, "Unexpected buffer count %lu.\n", count);
3075 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
3076 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
3078 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
3079 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
3080 ok(length == 7, "Unexpected length %lu.\n", length);
3082 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
3083 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
3084 ok(length == 7, "Unexpected length %lu.\n", length);
3086 IMFMediaBuffer_Release(buffer3);
3088 hr = IMFSample_GetBufferCount(sample, &count);
3089 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
3090 ok(count == 1, "Unexpected buffer count %lu.\n", count);
3092 hr = IMFSample_AddBuffer(sample, buffer);
3093 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
3095 hr = IMFSample_GetBufferCount(sample, &count);
3096 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
3097 ok(count == 2, "Unexpected buffer count %lu.\n", count);
3099 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
3100 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
3102 hr = IMFSample_GetBufferCount(sample, &count);
3103 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
3104 ok(count == 1, "Unexpected buffer count %lu.\n", count);
3106 IMFMediaBuffer_Release(buffer);
3108 IMFSample_Release(sample);
3111 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
3113 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
3114 IMFMediaEventQueue *queue;
3115 IUnknown *state, *obj;
3116 HRESULT hr;
3118 ok(result != NULL, "Unexpected result object.\n");
3120 state = IMFAsyncResult_GetStateNoAddRef(result);
3121 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
3123 IMFMediaEvent *event = NULL, *event2;
3125 if (is_win8_plus)
3127 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3128 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
3130 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
3131 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
3133 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3134 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#lx.\n", hr);
3136 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
3137 ok(hr == E_FAIL, "Unexpected result, hr %#lx.\n", hr);
3139 if (event)
3140 IMFMediaEvent_Release(event);
3143 hr = IMFAsyncResult_GetObject(result, &obj);
3144 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3146 IMFMediaEventQueue_Release(queue);
3148 SetEvent(callback->event);
3151 return E_NOTIMPL;
3154 static const IMFAsyncCallbackVtbl testcallbackvtbl =
3156 testcallback_QueryInterface,
3157 testcallback_AddRef,
3158 testcallback_Release,
3159 testcallback_GetParameters,
3160 testcallback_Invoke,
3163 static void test_MFCreateAsyncResult(void)
3165 IMFAsyncResult *result, *result2;
3166 struct test_callback *callback;
3167 IUnknown *state, *object;
3168 MFASYNCRESULT *data;
3169 ULONG refcount;
3170 HANDLE event;
3171 DWORD flags;
3172 HRESULT hr;
3173 BOOL ret;
3175 callback = create_test_callback(NULL);
3177 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
3178 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
3180 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
3181 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3183 data = (MFASYNCRESULT *)result;
3184 ok(data->pCallback == NULL, "Unexpected callback value.\n");
3185 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
3186 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
3187 ok(data->hEvent == NULL, "Unexpected event.\n");
3189 hr = IMFAsyncResult_GetState(result, NULL);
3190 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3192 state = (void *)0xdeadbeef;
3193 hr = IMFAsyncResult_GetState(result, &state);
3194 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3195 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
3197 hr = IMFAsyncResult_GetStatus(result);
3198 ok(hr == S_OK, "Unexpected status %#lx.\n", hr);
3200 data->hrStatusResult = 123;
3201 hr = IMFAsyncResult_GetStatus(result);
3202 ok(hr == 123, "Unexpected status %#lx.\n", hr);
3204 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
3205 ok(hr == S_OK, "Failed to set status, hr %#lx.\n", hr);
3206 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#lx.\n", hr);
3208 hr = IMFAsyncResult_GetObject(result, NULL);
3209 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3211 object = (void *)0xdeadbeef;
3212 hr = IMFAsyncResult_GetObject(result, &object);
3213 ok(hr == E_POINTER, "Failed to get object, hr %#lx.\n", hr);
3214 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
3216 state = IMFAsyncResult_GetStateNoAddRef(result);
3217 ok(state == NULL, "Unexpected state.\n");
3219 /* Object. */
3220 hr = MFCreateAsyncResult((IUnknown *)result, &callback->IMFAsyncCallback_iface, NULL, &result2);
3221 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3223 data = (MFASYNCRESULT *)result2;
3224 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
3225 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
3226 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
3227 ok(data->hEvent == NULL, "Unexpected event.\n");
3229 object = NULL;
3230 hr = IMFAsyncResult_GetObject(result2, &object);
3231 ok(hr == S_OK, "Failed to get object, hr %#lx.\n", hr);
3232 ok(object == (IUnknown *)result, "Unexpected object.\n");
3233 IUnknown_Release(object);
3235 IMFAsyncResult_Release(result2);
3237 /* State object. */
3238 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, (IUnknown *)result, &result2);
3239 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3241 data = (MFASYNCRESULT *)result2;
3242 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
3243 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
3244 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
3245 ok(data->hEvent == NULL, "Unexpected event.\n");
3247 state = NULL;
3248 hr = IMFAsyncResult_GetState(result2, &state);
3249 ok(hr == S_OK, "Failed to get state object, hr %#lx.\n", hr);
3250 ok(state == (IUnknown *)result, "Unexpected state.\n");
3251 IUnknown_Release(state);
3253 state = IMFAsyncResult_GetStateNoAddRef(result2);
3254 ok(state == (IUnknown *)result, "Unexpected state.\n");
3256 refcount = IMFAsyncResult_Release(result2);
3257 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3258 refcount = IMFAsyncResult_Release(result);
3259 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3261 /* Event handle is closed on release. */
3262 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
3263 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3265 data = (MFASYNCRESULT *)result;
3266 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
3267 ok(data->hEvent != NULL, "Failed to create event.\n");
3268 ret = GetHandleInformation(event, &flags);
3269 ok(ret, "Failed to get handle info.\n");
3271 refcount = IMFAsyncResult_Release(result);
3272 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3273 ret = GetHandleInformation(event, &flags);
3274 ok(!ret, "Expected handle to be closed.\n");
3276 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3277 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3279 data = (MFASYNCRESULT *)result;
3280 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
3281 ok(data->hEvent != NULL, "Failed to create event.\n");
3282 ret = GetHandleInformation(event, &flags);
3283 ok(ret, "Failed to get handle info.\n");
3285 refcount = IMFAsyncResult_Release(result);
3286 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3287 ret = GetHandleInformation(event, &flags);
3288 ok(!ret, "Expected handle to be closed.\n");
3290 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3293 static void test_startup(void)
3295 DWORD queue;
3296 HRESULT hr;
3298 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
3299 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#lx.\n", hr);
3301 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3302 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3304 hr = MFAllocateWorkQueue(&queue);
3305 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3306 hr = MFUnlockWorkQueue(queue);
3307 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3309 hr = MFShutdown();
3310 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3312 hr = MFAllocateWorkQueue(&queue);
3313 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3315 /* Already shut down, has no effect. */
3316 hr = MFShutdown();
3317 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3319 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3320 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3322 hr = MFAllocateWorkQueue(&queue);
3323 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3324 hr = MFUnlockWorkQueue(queue);
3325 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3327 hr = MFShutdown();
3328 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3330 /* Platform lock. */
3331 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3332 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3334 hr = MFAllocateWorkQueue(&queue);
3335 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3336 hr = MFUnlockWorkQueue(queue);
3337 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3339 /* Unlocking implies shutdown. */
3340 hr = MFUnlockPlatform();
3341 ok(hr == S_OK, "Failed to unlock, %#lx.\n", hr);
3343 hr = MFAllocateWorkQueue(&queue);
3344 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3346 hr = MFLockPlatform();
3347 ok(hr == S_OK, "Failed to lock, %#lx.\n", hr);
3349 hr = MFAllocateWorkQueue(&queue);
3350 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3351 hr = MFUnlockWorkQueue(queue);
3352 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3354 hr = MFShutdown();
3355 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3358 static void test_allocate_queue(void)
3360 DWORD queue, queue2;
3361 HRESULT hr;
3363 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3364 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3366 hr = MFAllocateWorkQueue(&queue);
3367 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3368 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
3370 hr = MFUnlockWorkQueue(queue);
3371 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3373 hr = MFUnlockWorkQueue(queue);
3374 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
3376 hr = MFAllocateWorkQueue(&queue2);
3377 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3378 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
3380 hr = MFUnlockWorkQueue(queue2);
3381 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3383 /* Unlock in system queue range. */
3384 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
3385 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3387 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
3388 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3390 hr = MFUnlockWorkQueue(0x20);
3391 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3393 hr = MFShutdown();
3394 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3397 static void test_MFCopyImage(void)
3399 DWORD dest[4], src[4];
3400 HRESULT hr;
3402 if (!pMFCopyImage)
3404 win_skip("MFCopyImage() is not available.\n");
3405 return;
3408 memset(dest, 0xaa, sizeof(dest));
3409 memset(src, 0x11, sizeof(src));
3411 hr = pMFCopyImage((BYTE *)dest, 8, (const BYTE *)src, 8, 4, 1);
3412 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3413 ok(dest[0] == src[0] && dest[1] == 0xaaaaaaaa, "Unexpected buffer contents.\n");
3415 /* Negative destination stride. */
3416 memset(dest, 0xaa, sizeof(dest));
3418 src[0] = 0x11111111;
3419 src[1] = 0x22222222;
3420 src[2] = 0x33333333;
3421 src[3] = 0x44444444;
3423 hr = pMFCopyImage((BYTE *)(dest + 2), -8, (const BYTE *)src, 8, 4, 2);
3424 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3425 ok(dest[0] == 0x33333333, "Unexpected buffer contents %#lx.\n", dest[0]);
3426 ok(dest[1] == 0xaaaaaaaa, "Unexpected buffer contents %#lx.\n", dest[1]);
3427 ok(dest[2] == 0x11111111, "Unexpected buffer contents %#lx.\n", dest[2]);
3428 ok(dest[3] == 0xaaaaaaaa, "Unexpected buffer contents %#lx.\n", dest[3]);
3430 memset(dest, 0xaa, sizeof(dest));
3431 memset(src, 0x11, sizeof(src));
3433 hr = pMFCopyImage((BYTE *)dest, 8, (const BYTE *)src, 8, 16, 1);
3434 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3435 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3437 memset(dest, 0xaa, sizeof(dest));
3438 memset(src, 0x11, sizeof(src));
3440 hr = pMFCopyImage((BYTE *)dest, 8, (const BYTE *)src, 8, 8, 2);
3441 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3442 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3445 static void test_MFCreateCollection(void)
3447 IMFCollection *collection;
3448 IUnknown *element;
3449 DWORD count;
3450 HRESULT hr;
3452 hr = MFCreateCollection(NULL);
3453 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3455 hr = MFCreateCollection(&collection);
3456 ok(hr == S_OK, "Failed to create collection, hr %#lx.\n", hr);
3458 hr = IMFCollection_GetElementCount(collection, NULL);
3459 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3461 count = 1;
3462 hr = IMFCollection_GetElementCount(collection, &count);
3463 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3464 ok(count == 0, "Unexpected count %lu.\n", count);
3466 hr = IMFCollection_GetElement(collection, 0, NULL);
3467 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3469 element = (void *)0xdeadbeef;
3470 hr = IMFCollection_GetElement(collection, 0, &element);
3471 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3472 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3474 hr = IMFCollection_RemoveElement(collection, 0, NULL);
3475 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3477 element = (void *)0xdeadbeef;
3478 hr = IMFCollection_RemoveElement(collection, 0, &element);
3479 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#lx.\n", hr);
3480 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3482 hr = IMFCollection_RemoveAllElements(collection);
3483 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3485 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
3486 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3488 count = 0;
3489 hr = IMFCollection_GetElementCount(collection, &count);
3490 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3491 ok(count == 1, "Unexpected count %lu.\n", count);
3493 hr = IMFCollection_AddElement(collection, NULL);
3494 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3496 count = 0;
3497 hr = IMFCollection_GetElementCount(collection, &count);
3498 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3499 ok(count == 2, "Unexpected count %lu.\n", count);
3501 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
3502 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3504 count = 0;
3505 hr = IMFCollection_GetElementCount(collection, &count);
3506 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3507 ok(count == 11, "Unexpected count %lu.\n", count);
3509 hr = IMFCollection_GetElement(collection, 0, &element);
3510 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3511 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3512 IUnknown_Release(element);
3514 hr = IMFCollection_GetElement(collection, 1, &element);
3515 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3516 ok(!element, "Unexpected element.\n");
3518 hr = IMFCollection_GetElement(collection, 2, &element);
3519 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3520 ok(!element, "Unexpected element.\n");
3522 hr = IMFCollection_GetElement(collection, 10, &element);
3523 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3524 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3525 IUnknown_Release(element);
3527 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3528 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3530 hr = IMFCollection_GetElement(collection, 0, &element);
3531 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3533 hr = IMFCollection_RemoveAllElements(collection);
3534 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3536 count = 1;
3537 hr = IMFCollection_GetElementCount(collection, &count);
3538 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3539 ok(count == 0, "Unexpected count %lu.\n", count);
3541 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3542 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3544 IMFCollection_Release(collection);
3547 static void test_MFHeapAlloc(void)
3549 void *res;
3551 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
3552 ok(res != NULL, "MFHeapAlloc failed.\n");
3554 MFHeapFree(res);
3557 static void test_scheduled_items(void)
3559 struct test_callback *callback;
3560 IMFAsyncResult *result;
3561 MFWORKITEM_KEY key, key2;
3562 HRESULT hr;
3564 callback = create_test_callback(NULL);
3566 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3567 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3569 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3570 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3572 hr = MFCancelWorkItem(key);
3573 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3575 hr = MFCancelWorkItem(key);
3576 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#lx.\n", hr);
3578 if (!pMFPutWaitingWorkItem)
3580 win_skip("Waiting items are not supported.\n");
3581 return;
3584 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3585 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3587 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
3588 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3590 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
3591 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3593 hr = MFCancelWorkItem(key);
3594 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3596 hr = MFCancelWorkItem(key2);
3597 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3599 IMFAsyncResult_Release(result);
3601 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3602 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3604 hr = MFCancelWorkItem(key);
3605 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3607 hr = MFShutdown();
3608 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3610 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3613 static void test_serial_queue(void)
3615 static const DWORD queue_ids[] =
3617 MFASYNC_CALLBACK_QUEUE_STANDARD,
3618 MFASYNC_CALLBACK_QUEUE_RT,
3619 MFASYNC_CALLBACK_QUEUE_IO,
3620 MFASYNC_CALLBACK_QUEUE_TIMER,
3621 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
3622 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
3624 DWORD queue, serial_queue;
3625 unsigned int i;
3626 HRESULT hr;
3628 if (!pMFAllocateSerialWorkQueue)
3630 win_skip("Serial queues are not supported.\n");
3631 return;
3634 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3635 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3637 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
3639 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
3640 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
3642 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
3643 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
3644 "%u: failed to allocate a queue, hr %#lx.\n", i, hr);
3646 if (SUCCEEDED(hr))
3648 hr = MFUnlockWorkQueue(serial_queue);
3649 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#lx.\n", i, hr);
3653 /* Chain them together. */
3654 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
3655 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3657 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
3658 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3660 hr = MFUnlockWorkQueue(serial_queue);
3661 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3663 hr = MFUnlockWorkQueue(queue);
3664 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3666 hr = MFShutdown();
3667 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3670 static LONG periodic_counter;
3671 static void CALLBACK periodic_callback(IUnknown *context)
3673 InterlockedIncrement(&periodic_counter);
3676 static void test_periodic_callback(void)
3678 DWORD period, key;
3679 HRESULT hr;
3681 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3682 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3684 period = 0;
3685 hr = MFGetTimerPeriodicity(&period);
3686 ok(hr == S_OK, "Failed to get timer perdiod, hr %#lx.\n", hr);
3687 ok(period == 10, "Unexpected period %lu.\n", period);
3689 if (!pMFAddPeriodicCallback)
3691 win_skip("Periodic callbacks are not supported.\n");
3692 hr = MFShutdown();
3693 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3694 return;
3697 ok(periodic_counter == 0, "Unexpected counter value %lu.\n", periodic_counter);
3699 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
3700 ok(hr == S_OK, "Failed to add periodic callback, hr %#lx.\n", hr);
3701 ok(key != 0, "Unexpected key %#lx.\n", key);
3703 Sleep(10 * period);
3705 hr = pMFRemovePeriodicCallback(key);
3706 ok(hr == S_OK, "Failed to remove callback, hr %#lx.\n", hr);
3708 ok(periodic_counter > 0, "Unexpected counter value %lu.\n", periodic_counter);
3710 hr = MFShutdown();
3711 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3714 static void test_event_queue(void)
3716 struct test_callback *callback, *callback2;
3717 IMFMediaEvent *event, *event2;
3718 IMFMediaEventQueue *queue;
3719 IMFAsyncResult *result;
3720 HRESULT hr;
3721 DWORD ret;
3723 callback = create_test_callback(NULL);
3724 callback2 = create_test_callback(NULL);
3726 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3727 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3729 hr = MFCreateEventQueue(&queue);
3730 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3732 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3733 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
3735 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3736 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3738 if (is_win8_plus)
3740 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3741 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3743 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3744 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3745 ok(event2 == event, "Unexpected event object.\n");
3746 IMFMediaEvent_Release(event2);
3748 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3749 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3751 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3752 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3753 IMFMediaEvent_Release(event2);
3756 /* Async case. */
3757 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3758 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3760 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3761 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3763 /* Same callback, same state. */
3764 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3765 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3767 /* Same callback, different state. */
3768 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3769 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3771 /* Different callback, same state. */
3772 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)queue);
3773 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3775 /* Different callback, different state. */
3776 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3777 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3779 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3780 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3782 ret = WaitForSingleObject(callback->event, 500);
3783 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#lx.\n", ret);
3785 IMFMediaEvent_Release(event);
3787 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3788 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3790 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3791 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3793 /* Shutdown behavior. */
3794 hr = IMFMediaEventQueue_Shutdown(queue);
3795 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3797 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3798 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3800 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3801 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3802 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3803 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3804 IMFMediaEvent_Release(event);
3806 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3807 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3809 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3810 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3812 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3813 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3815 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3816 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3818 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3819 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3820 IMFAsyncResult_Release(result);
3822 /* Already shut down. */
3823 hr = IMFMediaEventQueue_Shutdown(queue);
3824 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3826 IMFMediaEventQueue_Release(queue);
3827 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3829 /* Release while subscribed. */
3830 callback = create_test_callback(NULL);
3832 hr = MFCreateEventQueue(&queue);
3833 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3835 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3836 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3837 EXPECT_REF(&callback->IMFAsyncCallback_iface, 2);
3839 IMFMediaEventQueue_Release(queue);
3840 ret = get_refcount(&callback->IMFAsyncCallback_iface);
3841 ok(ret == 1 || broken(ret == 2) /* Vista */,
3842 "Unexpected refcount %ld, expected 1.\n", ret);
3843 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3845 hr = MFShutdown();
3846 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3849 static void test_presentation_descriptor(void)
3851 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3852 IMFPresentationDescriptor *pd, *pd2;
3853 IMFMediaType *media_type;
3854 unsigned int i;
3855 BOOL selected;
3856 UINT64 value;
3857 DWORD count;
3858 HRESULT hr;
3860 hr = MFCreateMediaType(&media_type);
3861 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
3863 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3865 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3866 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3869 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3870 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr);
3872 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3873 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %lu.\n", count);
3875 for (i = 0; i < count; ++i)
3877 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3878 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3879 ok(!selected, "Unexpected selected state.\n");
3880 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3881 IMFStreamDescriptor_Release(stream_desc2);
3884 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3885 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3887 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3888 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3890 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3891 ok(hr == S_OK, "Failed to select a stream, hr %#lx.\n", hr);
3893 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3894 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3895 ok(!!selected, "Unexpected selected state.\n");
3896 IMFStreamDescriptor_Release(stream_desc2);
3898 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3899 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
3901 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3902 ok(hr == S_OK, "Failed to clone, hr %#lx.\n", hr);
3904 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3905 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3906 ok(!!selected, "Unexpected selected state.\n");
3907 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3908 IMFStreamDescriptor_Release(stream_desc2);
3910 value = 0;
3911 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3912 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
3913 ok(value == 1, "Unexpected attribute value.\n");
3915 IMFPresentationDescriptor_Release(pd2);
3916 IMFPresentationDescriptor_Release(pd);
3918 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3920 IMFStreamDescriptor_Release(stream_desc[i]);
3923 /* Partially initialized array. */
3924 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3925 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3926 stream_desc[0] = NULL;
3928 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3929 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3931 IMFStreamDescriptor_Release(stream_desc[1]);
3932 IMFMediaType_Release(media_type);
3935 enum clock_action
3937 CLOCK_START,
3938 CLOCK_STOP,
3939 CLOCK_PAUSE,
3940 CLOCK_RESTART,
3943 static void test_system_time_source(void)
3945 static const struct clock_state_test
3947 enum clock_action action;
3948 MFCLOCK_STATE state;
3949 BOOL is_invalid;
3951 clock_state_change[] =
3953 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3954 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3955 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3956 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3957 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3958 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3959 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3960 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3961 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3962 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3963 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3964 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3965 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3966 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3967 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3968 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3969 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3971 IMFPresentationTimeSource *time_source, *time_source2;
3972 IMFClockStateSink *statesink;
3973 IMFClock *clock, *clock2;
3974 MFCLOCK_PROPERTIES props;
3975 MFCLOCK_STATE state;
3976 unsigned int i;
3977 MFTIME systime;
3978 LONGLONG time;
3979 DWORD value;
3980 HRESULT hr;
3982 hr = MFCreateSystemTimeSource(&time_source);
3983 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3985 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3986 ok(hr == S_OK, "Failed to get flags, hr %#lx.\n", hr);
3987 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3988 "Unexpected flags %#lx.\n", value);
3990 value = 1;
3991 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3992 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3993 ok(value == 0, "Unexpected value %lu.\n", value);
3995 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3996 ok(hr == S_OK, "Failed to get state, hr %#lx.\n", hr);
3997 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3999 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
4000 ok(hr == S_OK, "Failed to get state sink, hr %#lx.\n", hr);
4002 /* State changes. */
4003 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
4005 switch (clock_state_change[i].action)
4007 case CLOCK_STOP:
4008 hr = IMFClockStateSink_OnClockStop(statesink, 0);
4009 break;
4010 case CLOCK_RESTART:
4011 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
4012 break;
4013 case CLOCK_PAUSE:
4014 hr = IMFClockStateSink_OnClockPause(statesink, 0);
4015 break;
4016 case CLOCK_START:
4017 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
4018 break;
4019 default:
4022 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#lx.\n", i, hr);
4023 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
4024 ok(hr == S_OK, "%u: failed to get state, hr %#lx.\n", i, hr);
4025 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
4028 IMFClockStateSink_Release(statesink);
4030 /* Properties. */
4031 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
4032 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4034 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
4035 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
4037 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
4038 wine_dbgstr_longlong(props.qwCorrelationRate));
4039 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
4040 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
4041 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
4042 wine_dbgstr_longlong(props.qwClockFrequency));
4043 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
4044 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
4046 /* Underlying clock. */
4047 hr = MFCreateSystemTimeSource(&time_source2);
4048 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
4049 EXPECT_REF(time_source2, 1);
4050 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
4051 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4052 EXPECT_REF(time_source2, 1);
4053 EXPECT_REF(clock2, 2);
4055 EXPECT_REF(time_source, 1);
4056 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
4057 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4058 EXPECT_REF(time_source, 1);
4059 EXPECT_REF(clock, 2);
4061 ok(clock != clock2, "Unexpected clock instance.\n");
4063 IMFPresentationTimeSource_Release(time_source2);
4064 IMFClock_Release(clock2);
4066 hr = IMFClock_GetClockCharacteristics(clock, &value);
4067 ok(hr == S_OK, "Failed to get clock flags, hr %#lx.\n", hr);
4068 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
4069 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#lx.\n", value);
4071 hr = IMFClock_GetContinuityKey(clock, &value);
4072 ok(hr == S_OK, "Failed to get clock key, hr %#lx.\n", hr);
4073 ok(value == 0, "Unexpected key value %lu.\n", value);
4075 hr = IMFClock_GetState(clock, 0, &state);
4076 ok(hr == S_OK, "Failed to get clock state, hr %#lx.\n", hr);
4077 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
4079 hr = IMFClock_GetProperties(clock, &props);
4080 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
4082 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
4083 wine_dbgstr_longlong(props.qwCorrelationRate));
4084 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
4085 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
4086 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
4087 wine_dbgstr_longlong(props.qwClockFrequency));
4088 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
4089 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
4091 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
4092 ok(hr == S_OK, "Failed to get clock time, hr %#lx.\n", hr);
4093 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
4095 IMFClock_Release(clock);
4097 /* Test returned time regarding specified rate and offset. */
4098 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
4099 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
4101 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
4102 ok(hr == S_OK, "Failed to get state %#lx.\n", hr);
4103 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
4105 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4106 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4107 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
4109 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
4110 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4112 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4113 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4114 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
4116 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
4117 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4119 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4120 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4121 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4122 wine_dbgstr_longlong(systime));
4124 hr = IMFClockStateSink_OnClockPause(statesink, 2);
4125 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4127 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4128 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4129 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
4131 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
4132 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
4134 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4135 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4136 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4137 wine_dbgstr_longlong(systime));
4139 hr = IMFClockStateSink_OnClockPause(statesink, 0);
4140 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4142 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4143 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4144 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4145 wine_dbgstr_longlong(systime));
4147 hr = IMFClockStateSink_OnClockStop(statesink, 123);
4148 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
4150 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4151 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4152 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
4154 /* Increased rate. */
4155 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
4156 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
4158 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
4159 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4161 hr = IMFClockStateSink_OnClockSetRate(statesink, 5, 2.0f);
4162 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
4164 hr = IMFClockStateSink_OnClockPause(statesink, 6);
4165 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4167 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4168 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4169 ok(time == 12 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4170 wine_dbgstr_longlong(systime));
4172 hr = IMFClockStateSink_OnClockRestart(statesink, 7);
4173 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
4175 hr = IMFClockStateSink_OnClockPause(statesink, 8);
4176 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4178 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4179 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4180 ok(time == 14 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4181 wine_dbgstr_longlong(systime));
4183 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
4184 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4186 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4187 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4188 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4189 wine_dbgstr_longlong(2 * systime));
4191 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
4192 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4194 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4195 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4196 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4197 wine_dbgstr_longlong(2 * systime));
4199 hr = IMFClockStateSink_OnClockPause(statesink, 2);
4200 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4202 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4203 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4204 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4205 wine_dbgstr_longlong(systime));
4207 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
4208 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
4210 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4211 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4212 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4213 wine_dbgstr_longlong(systime));
4215 hr = IMFClockStateSink_OnClockPause(statesink, 0);
4216 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4218 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4219 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4220 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4221 wine_dbgstr_longlong(systime));
4223 hr = IMFClockStateSink_OnClockStop(statesink, 123);
4224 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
4226 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4227 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4228 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
4230 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
4231 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4233 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4234 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4235 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4236 wine_dbgstr_longlong(2 * systime));
4238 hr = IMFClockStateSink_OnClockStop(statesink, 123);
4239 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
4241 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
4242 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4244 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4245 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4246 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4247 wine_dbgstr_longlong(2 * systime));
4249 hr = IMFClockStateSink_OnClockPause(statesink, 2);
4250 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4252 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4253 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4254 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4255 wine_dbgstr_longlong(systime));
4257 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
4258 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
4260 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4261 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4262 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4263 wine_dbgstr_longlong(systime));
4265 hr = IMFClockStateSink_OnClockPause(statesink, 0);
4266 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4268 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4269 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4270 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4271 wine_dbgstr_longlong(systime));
4273 IMFClockStateSink_Release(statesink);
4274 IMFPresentationTimeSource_Release(time_source);
4276 /* PRESENTATION_CURRENT_POSITION */
4277 hr = MFCreateSystemTimeSource(&time_source);
4278 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
4280 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
4281 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
4283 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4284 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4285 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4286 wine_dbgstr_longlong(systime));
4288 /* INVALID -> RUNNING */
4289 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
4290 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4292 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4293 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4294 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4295 wine_dbgstr_longlong(systime));
4297 /* RUNNING -> RUNNING */
4298 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
4299 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4301 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4302 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4303 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4304 wine_dbgstr_longlong(systime));
4306 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
4307 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4309 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4310 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4311 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4312 wine_dbgstr_longlong(systime));
4314 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
4315 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4317 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4318 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4319 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4320 wine_dbgstr_longlong(systime));
4322 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
4323 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4325 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4326 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4327 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4328 wine_dbgstr_longlong(systime));
4330 /* STOPPED -> RUNNING */
4331 hr = IMFClockStateSink_OnClockStop(statesink, 567);
4332 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
4334 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4335 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4336 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4337 wine_dbgstr_longlong(systime));
4339 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
4340 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4342 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4343 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4344 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4345 wine_dbgstr_longlong(systime));
4347 /* PAUSED -> RUNNING */
4348 hr = IMFClockStateSink_OnClockPause(statesink, 8);
4349 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4351 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4352 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4353 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4354 wine_dbgstr_longlong(systime));
4356 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
4357 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4359 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4360 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4361 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4362 wine_dbgstr_longlong(systime));
4364 hr = IMFClockStateSink_OnClockPause(statesink, 7);
4365 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
4367 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4368 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4369 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4370 wine_dbgstr_longlong(systime));
4372 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
4373 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
4375 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
4376 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
4377 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
4378 wine_dbgstr_longlong(systime));
4380 IMFClockStateSink_Release(statesink);
4381 IMFPresentationTimeSource_Release(time_source);
4384 static void test_MFInvokeCallback(void)
4386 struct test_callback *callback;
4387 IMFAsyncResult *result;
4388 MFASYNCRESULT *data;
4389 ULONG refcount;
4390 HRESULT hr;
4391 DWORD ret;
4393 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4394 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
4396 callback = create_test_callback(NULL);
4398 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
4399 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4401 data = (MFASYNCRESULT *)result;
4402 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
4403 ok(data->hEvent != NULL, "Failed to create event.\n");
4405 hr = MFInvokeCallback(result);
4406 ok(hr == S_OK, "Failed to invoke, hr %#lx.\n", hr);
4408 ret = WaitForSingleObject(data->hEvent, 100);
4409 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#lx.\n", ret);
4411 refcount = IMFAsyncResult_Release(result);
4412 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
4414 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4416 hr = MFShutdown();
4417 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4420 static void test_stream_descriptor(void)
4422 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
4423 IMFMediaTypeHandler *type_handler;
4424 IMFStreamDescriptor *stream_desc;
4425 GUID major_type;
4426 DWORD id, count;
4427 unsigned int i;
4428 HRESULT hr;
4430 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
4431 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4433 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4435 hr = MFCreateMediaType(&media_types[i]);
4436 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4439 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
4440 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4442 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4443 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4445 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
4446 ok(hr == S_OK, "Failed to get descriptor id, hr %#lx.\n", hr);
4447 ok(id == 123, "Unexpected id %#lx.\n", id);
4449 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4450 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4452 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4453 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4454 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4456 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
4457 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
4459 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4460 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4462 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4464 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
4465 ok(hr == S_OK, "Failed to get media type, hr %#lx.\n", hr);
4466 ok(media_type == media_types[i], "Unexpected object.\n");
4468 if (SUCCEEDED(hr))
4469 IMFMediaType_Release(media_type);
4472 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
4473 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#lx.\n", hr);
4475 /* IsMediaTypeSupported() */
4477 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
4478 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4480 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
4481 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4483 hr = MFCreateMediaType(&media_type);
4484 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4486 hr = MFCreateMediaType(&media_type3);
4487 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4489 media_type2 = (void *)0xdeadbeef;
4490 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4491 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4492 ok(!media_type2, "Unexpected pointer.\n");
4494 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
4495 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4497 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
4498 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4500 media_type2 = (void *)0xdeadbeef;
4501 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4502 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4503 ok(!media_type2, "Unexpected pointer.\n");
4505 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4506 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4508 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4509 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4511 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4512 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4513 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
4515 /* Mismatching major types. */
4516 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4517 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4519 media_type2 = (void *)0xdeadbeef;
4520 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4521 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4522 ok(!media_type2, "Unexpected pointer.\n");
4524 /* Subtype missing. */
4525 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4526 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4528 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4529 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4531 media_type2 = (void *)0xdeadbeef;
4532 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4533 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4534 ok(!media_type2, "Unexpected pointer.\n");
4536 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4537 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4539 media_type2 = (void *)0xdeadbeef;
4540 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4541 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4542 ok(!media_type2, "Unexpected pointer.\n");
4544 /* Mismatching subtype. */
4545 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4546 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4548 media_type2 = (void *)0xdeadbeef;
4549 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4550 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4551 ok(!media_type2, "Unexpected pointer.\n");
4553 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4554 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4555 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4557 IMFMediaTypeHandler_Release(type_handler);
4558 IMFStreamDescriptor_Release(stream_desc);
4560 /* IsMediaTypeSupported() for unset current type. */
4561 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4564 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4565 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4567 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
4568 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4570 /* Initialize one from initial type set. */
4571 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
4572 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4574 media_type2 = (void *)0xdeadbeef;
4575 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4576 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4577 ok(!media_type2, "Unexpected pointer.\n");
4579 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4580 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4582 media_type2 = (void *)0xdeadbeef;
4583 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4584 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4585 ok(!media_type2, "Unexpected pointer.\n");
4587 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4588 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4590 media_type2 = (void *)0xdeadbeef;
4591 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4592 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4593 ok(!media_type2, "Unexpected pointer.\n");
4595 /* Now set current type that's not compatible. */
4596 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4597 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4599 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4600 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4602 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
4603 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4605 media_type2 = (void *)0xdeadbeef;
4606 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4607 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4608 ok(!media_type2, "Unexpected pointer.\n");
4610 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
4611 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4613 media_type2 = (void *)0xdeadbeef;
4614 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4615 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4616 ok(!media_type2, "Unexpected pointer.\n");
4618 IMFMediaType_Release(media_type);
4619 IMFMediaType_Release(media_type3);
4621 IMFMediaTypeHandler_Release(type_handler);
4623 IMFStreamDescriptor_Release(stream_desc);
4625 /* Major type is returned for first entry. */
4626 hr = MFCreateMediaType(&media_types[0]);
4627 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4628 hr = MFCreateMediaType(&media_types[1]);
4629 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4631 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4632 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4633 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4634 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4636 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
4637 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4639 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4640 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4642 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4643 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4644 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4646 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4647 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4648 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4649 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4651 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4652 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4653 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4655 IMFMediaType_Release(media_types[0]);
4656 IMFMediaType_Release(media_types[1]);
4658 IMFMediaTypeHandler_Release(type_handler);
4659 IMFStreamDescriptor_Release(stream_desc);
4662 static const struct image_size_test
4664 const GUID *subtype;
4665 UINT32 width;
4666 UINT32 height;
4667 UINT32 size;
4668 UINT32 plane_size; /* Matches image size when 0. */
4669 UINT32 max_length;
4670 UINT32 contiguous_length;
4671 UINT32 pitch;
4673 image_size_tests[] =
4675 /* RGB */
4676 { &MFVideoFormat_RGB8, 3, 5, 20, 0, 320, 20, 64 },
4677 { &MFVideoFormat_RGB8, 1, 1, 4, 0, 64, 4, 64 },
4678 { &MFVideoFormat_RGB8, 320, 240, 76800, 0, 76800, 76800, 320 },
4679 { &MFVideoFormat_RGB555, 3, 5, 40, 0, 320, 40, 64 },
4680 { &MFVideoFormat_RGB555, 1, 1, 4, 0, 64, 4, 64 },
4681 { &MFVideoFormat_RGB555, 320, 240, 153600, 0, 153600, 153600, 640 },
4682 { &MFVideoFormat_RGB565, 3, 5, 40, 0, 320, 40, 64 },
4683 { &MFVideoFormat_RGB565, 1, 1, 4, 0, 64, 4, 64 },
4684 { &MFVideoFormat_RGB565, 320, 240, 153600, 0, 153600, 153600, 640 },
4685 { &MFVideoFormat_RGB24, 3, 5, 60, 0, 320, 60, 64 },
4686 { &MFVideoFormat_RGB24, 1, 1, 4, 0, 64, 4, 64 },
4687 { &MFVideoFormat_RGB24, 4, 3, 36, 0, 192, 36, 64 },
4688 { &MFVideoFormat_RGB24, 320, 240, 230400, 0, 230400, 230400, 960 },
4689 { &MFVideoFormat_RGB32, 3, 5, 60, 0, 320, 60, 64 },
4690 { &MFVideoFormat_RGB32, 1, 1, 4, 0, 64, 4, 64 },
4691 { &MFVideoFormat_RGB32, 320, 240, 307200, 0, 307200, 307200, 1280 },
4692 { &MFVideoFormat_ARGB32, 3, 5, 60, 0, 320, 60, 64 },
4693 { &MFVideoFormat_ARGB32, 1, 1, 4, 0, 64, 4, 64 },
4694 { &MFVideoFormat_ARGB32, 320, 240, 307200, 0, 307200, 307200, 1280 },
4695 { &MFVideoFormat_A2R10G10B10, 3, 5, 60, 0, 320, 60, 64 },
4696 { &MFVideoFormat_A2R10G10B10, 1, 1, 4, 0, 64, 4, 64 },
4697 { &MFVideoFormat_A2R10G10B10, 320, 240, 307200, 0, 307200, 307200, 1280 },
4698 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120, 0, 320, 120, 64 },
4699 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8, 0, 64, 8, 64 },
4700 { &MFVideoFormat_A16B16G16R16F, 320, 240, 614400, 0, 614400, 614400, 2560 },
4702 { &MEDIASUBTYPE_RGB8, 3, 5, 20 },
4703 { &MEDIASUBTYPE_RGB8, 1, 1, 4 },
4704 { &MEDIASUBTYPE_RGB555, 3, 5, 40 },
4705 { &MEDIASUBTYPE_RGB555, 1, 1, 4 },
4706 { &MEDIASUBTYPE_RGB565, 3, 5, 40 },
4707 { &MEDIASUBTYPE_RGB565, 1, 1, 4 },
4708 { &MEDIASUBTYPE_RGB24, 3, 5, 60 },
4709 { &MEDIASUBTYPE_RGB24, 1, 1, 4 },
4710 { &MEDIASUBTYPE_RGB24, 4, 3, 36 },
4711 { &MEDIASUBTYPE_RGB32, 3, 5, 60 },
4712 { &MEDIASUBTYPE_RGB32, 1, 1, 4 },
4714 /* YUV 4:4:4, 32 bpp, packed */
4715 { &MFVideoFormat_AYUV, 1, 1, 4, 0, 64, 4, 64 },
4716 { &MFVideoFormat_AYUV, 2, 1, 8, 0, 64, 8, 64 },
4717 { &MFVideoFormat_AYUV, 1, 2, 8, 0, 128, 8, 64 },
4718 { &MFVideoFormat_AYUV, 4, 3, 48, 0, 192, 48, 64 },
4719 { &MFVideoFormat_AYUV, 320, 240, 307200, 0, 307200, 307200, 1280 },
4721 /* YUV 4:2:2, 16 bpp, packed */
4722 { &MFVideoFormat_YUY2, 2, 1, 4, 0, 64, 4, 64 },
4723 { &MFVideoFormat_YUY2, 4, 3, 24, 0, 192, 24, 64 },
4724 { &MFVideoFormat_YUY2, 128, 128, 32768, 0, 32768, 32768, 256 },
4725 { &MFVideoFormat_YUY2, 320, 240, 153600, 0, 153600, 153600, 640 },
4727 { &MFVideoFormat_UYVY, 2, 1, 4, 0, 64, 4, 64 },
4728 { &MFVideoFormat_UYVY, 4, 3, 24, 0, 192, 24, 64 },
4729 { &MFVideoFormat_UYVY, 128, 128, 32768, 0, 32768, 32768, 256 },
4730 { &MFVideoFormat_UYVY, 320, 240, 153600, 0, 153600, 153600, 640 },
4732 /* YUV 4:2:0, 16 bpp, planar (the secondary plane has the same
4733 * height, half the width and the same stride as the primary
4734 * one) */
4735 { &MFVideoFormat_IMC1, 1, 1, 4, 0, 256, 8, 128 },
4736 { &MFVideoFormat_IMC1, 2, 1, 4, 0, 256, 8, 128 },
4737 { &MFVideoFormat_IMC1, 1, 2, 8, 0, 512, 16, 128 },
4738 { &MFVideoFormat_IMC1, 2, 2, 8, 0, 512, 16, 128 },
4739 { &MFVideoFormat_IMC1, 2, 4, 16, 0, 1024, 32, 128 },
4740 { &MFVideoFormat_IMC1, 4, 2, 16, 0, 512, 32, 128 },
4741 { &MFVideoFormat_IMC1, 4, 3, 24, 0, 768, 48, 128 },
4742 { &MFVideoFormat_IMC1, 320, 240, 153600, 0, 307200, 307200, 640 },
4744 { &MFVideoFormat_IMC3, 1, 1, 4, 0, 256, 8, 128 },
4745 { &MFVideoFormat_IMC3, 2, 1, 4, 0, 256, 8, 128 },
4746 { &MFVideoFormat_IMC3, 1, 2, 8, 0, 512, 16, 128 },
4747 { &MFVideoFormat_IMC3, 2, 2, 8, 0, 512, 16, 128 },
4748 { &MFVideoFormat_IMC3, 2, 4, 16, 0, 1024, 32, 128 },
4749 { &MFVideoFormat_IMC3, 4, 2, 16, 0, 512, 32, 128 },
4750 { &MFVideoFormat_IMC3, 4, 3, 24, 0, 768, 48, 128 },
4751 { &MFVideoFormat_IMC3, 320, 240, 153600, 0, 307200, 307200, 640 },
4753 /* YUV 4:2:0, 12 bpp, planar, full stride (the secondary plane has
4754 * half the height, the same width and the same stride as the
4755 * primary one) */
4756 { &MFVideoFormat_NV12, 1, 3, 9, 4, 288, 4, 64 },
4757 { &MFVideoFormat_NV12, 1, 2, 6, 3, 192, 3, 64 },
4758 { &MFVideoFormat_NV12, 2, 2, 6, 6, 192, 6, 64 },
4759 { &MFVideoFormat_NV12, 2, 4, 12, 0, 384, 12, 64 },
4760 { &MFVideoFormat_NV12, 3, 2, 12, 9, 192, 9, 64 },
4761 { &MFVideoFormat_NV12, 4, 2, 12, 0, 192, 12, 64 },
4762 { &MFVideoFormat_NV12, 320, 240, 115200, 0, 115200, 115200, 320 },
4764 /* YUV 4:2:0, 12 bpp, planar, half stride (the secondary plane has
4765 * the same height, half the width and half the stride of the
4766 * primary one) */
4767 { &MFVideoFormat_IMC2, 1, 1, 3, 1, 192, 1, 128 },
4768 { &MFVideoFormat_IMC2, 1, 2, 6, 3, 384, 2, 128 },
4769 { &MFVideoFormat_IMC2, 1, 3, 9, 4, 576, 3, 128 },
4770 { &MFVideoFormat_IMC2, 2, 1, 3, 0, 192, 3, 128 },
4771 { &MFVideoFormat_IMC2, 2, 2, 6, 6, 384, 6, 128 },
4772 { &MFVideoFormat_IMC2, 2, 4, 12, 0, 768, 12, 128 },
4773 { &MFVideoFormat_IMC2, 3, 2, 12, 9, 384, 8, 128 },
4774 { &MFVideoFormat_IMC2, 3, 5, 30, 22, 960, 20, 128 },
4775 { &MFVideoFormat_IMC2, 4, 2, 12, 0, 384, 12, 128 },
4776 { &MFVideoFormat_IMC2, 4, 3, 18, 0, 576, 18, 128 },
4777 { &MFVideoFormat_IMC2, 320, 240, 115200, 0, 138240, 115200, 384 },
4779 { &MFVideoFormat_IMC4, 1, 1, 3, 1, 192, 1, 128 },
4780 { &MFVideoFormat_IMC4, 1, 2, 6, 3, 384, 2, 128 },
4781 { &MFVideoFormat_IMC4, 1, 3, 9, 4, 576, 3, 128 },
4782 { &MFVideoFormat_IMC4, 2, 1, 3, 0, 192, 3, 128 },
4783 { &MFVideoFormat_IMC4, 2, 2, 6, 6, 384, 6, 128 },
4784 { &MFVideoFormat_IMC4, 2, 4, 12, 0, 768, 12, 128 },
4785 { &MFVideoFormat_IMC4, 3, 2, 12, 9, 384, 8, 128 },
4786 { &MFVideoFormat_IMC4, 3, 5, 30, 22, 960, 20, 128 },
4787 { &MFVideoFormat_IMC4, 4, 2, 12, 0, 384, 12, 128 },
4788 { &MFVideoFormat_IMC4, 4, 3, 18, 0, 576, 18, 128 },
4789 { &MFVideoFormat_IMC4, 320, 240, 115200, 0, 138240, 115200, 384 },
4791 /* YUV 4:1:1, 12 bpp, semi-planar */
4792 { &MFVideoFormat_NV11, 1, 3, 18, 4, 576, 3, 128 },
4793 { &MFVideoFormat_NV11, 1, 2, 12, 3, 384, 2, 128 },
4794 { &MFVideoFormat_NV11, 2, 2, 12, 6, 384, 6, 128 },
4795 { &MFVideoFormat_NV11, 2, 4, 24, 12, 768, 12, 128 },
4796 { &MFVideoFormat_NV11, 3, 2, 12, 9, 384, 8, 128 },
4797 { &MFVideoFormat_NV11, 4, 2, 12, 0, 384, 12, 128 },
4798 { &MFVideoFormat_NV11, 320, 240, 115200, 0, 138240, 115200, 384 },
4800 { &MFVideoFormat_YV12, 1, 1, 3, 1, 192, 1, 128 },
4801 { &MFVideoFormat_YV12, 1, 2, 6, 3, 384, 2, 128 },
4802 { &MFVideoFormat_YV12, 1, 3, 9, 4, 576, 3, 128 },
4803 { &MFVideoFormat_YV12, 2, 1, 3, 0, 192, 3, 128 },
4804 { &MFVideoFormat_YV12, 2, 2, 6, 6, 384, 6, 128 },
4805 { &MFVideoFormat_YV12, 2, 4, 12, 0, 768, 12, 128 },
4806 { &MFVideoFormat_YV12, 3, 2, 12, 9, 384, 8, 128 },
4807 { &MFVideoFormat_YV12, 3, 5, 30, 22, 960, 20, 128 },
4808 { &MFVideoFormat_YV12, 4, 2, 12, 0, 384, 12, 128 },
4809 { &MFVideoFormat_YV12, 4, 3, 18, 0, 576, 18, 128 },
4810 { &MFVideoFormat_YV12, 320, 240, 115200, 0, 138240, 115200, 384 },
4812 { &MFVideoFormat_I420, 1, 1, 3, 1, 192, 1, 128 },
4813 { &MFVideoFormat_I420, 1, 2, 6, 3, 384, 2, 128 },
4814 { &MFVideoFormat_I420, 1, 3, 9, 4, 576, 3, 128 },
4815 { &MFVideoFormat_I420, 2, 1, 3, 0, 192, 3, 128 },
4816 { &MFVideoFormat_I420, 2, 2, 6, 6, 384, 6, 128 },
4817 { &MFVideoFormat_I420, 2, 4, 12, 0, 768, 12, 128 },
4818 { &MFVideoFormat_I420, 3, 2, 12, 9, 384, 8, 128 },
4819 { &MFVideoFormat_I420, 3, 5, 30, 22, 960, 20, 128 },
4820 { &MFVideoFormat_I420, 4, 2, 12, 0, 384, 12, 128 },
4821 { &MFVideoFormat_I420, 4, 3, 18, 0, 576, 18, 128 },
4822 { &MFVideoFormat_I420, 320, 240, 115200, 0, 138240, 115200, 384 },
4824 { &MFVideoFormat_IYUV, 1, 1, 3, 1, 192, 1, 128 },
4825 { &MFVideoFormat_IYUV, 1, 2, 6, 3, 384, 2, 128 },
4826 { &MFVideoFormat_IYUV, 1, 3, 9, 4, 576, 3, 128 },
4827 { &MFVideoFormat_IYUV, 2, 1, 3, 0, 192, 3, 128 },
4828 { &MFVideoFormat_IYUV, 2, 2, 6, 6, 384, 6, 128 },
4829 { &MFVideoFormat_IYUV, 2, 4, 12, 0, 768, 12, 128 },
4830 { &MFVideoFormat_IYUV, 3, 2, 12, 9, 384, 8, 128 },
4831 { &MFVideoFormat_IYUV, 3, 5, 30, 22, 960, 20, 128 },
4832 { &MFVideoFormat_IYUV, 4, 2, 12, 0, 384, 12, 128 },
4833 { &MFVideoFormat_IYUV, 4, 3, 18, 0, 576, 18, 128 },
4834 { &MFVideoFormat_IYUV, 320, 240, 115200, 0, 138240, 115200, 384 },
4837 static void test_MFCalculateImageSize(void)
4839 unsigned int i;
4840 UINT32 size;
4841 HRESULT hr;
4843 size = 1;
4844 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
4845 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#lx.\n", hr);
4846 ok(size == 0, "Unexpected size %u.\n", size);
4848 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4850 const struct image_size_test *ptr = &image_size_tests[i];
4852 /* Those are supported since Win10. */
4853 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
4854 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
4856 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4857 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr);
4858 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4859 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4863 static void test_MFGetPlaneSize(void)
4865 unsigned int i;
4866 DWORD size;
4867 HRESULT hr;
4869 if (!pMFGetPlaneSize)
4871 win_skip("MFGetPlaneSize() is not available.\n");
4872 return;
4875 size = 1;
4876 hr = pMFGetPlaneSize(0xdeadbeef, 64, 64, &size);
4877 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4878 ok(size == 0, "Unexpected size %lu.\n", size);
4880 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4882 const struct image_size_test *ptr = &image_size_tests[i];
4883 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4884 if ((is_MEDIASUBTYPE_RGB(ptr->subtype)))
4885 continue;
4887 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4888 ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr);
4889 ok(size == plane_size, "%u: unexpected plane size %lu, expected %u. Size %u x %u, format %s.\n", i, size, plane_size,
4890 ptr->width, ptr->height, wine_dbgstr_an((char*)&ptr->subtype->Data1, 4));
4894 static void test_MFCompareFullToPartialMediaType(void)
4896 IMFMediaType *full_type, *partial_type;
4897 HRESULT hr;
4898 BOOL ret;
4900 hr = MFCreateMediaType(&full_type);
4901 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4903 hr = MFCreateMediaType(&partial_type);
4904 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4906 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4907 ok(!ret, "Unexpected result %d.\n", ret);
4909 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4910 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4912 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4913 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4915 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4916 ok(ret, "Unexpected result %d.\n", ret);
4918 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4919 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4921 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4922 ok(ret, "Unexpected result %d.\n", ret);
4924 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4925 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4927 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4928 ok(!ret, "Unexpected result %d.\n", ret);
4930 IMFMediaType_Release(full_type);
4931 IMFMediaType_Release(partial_type);
4934 static void test_attributes_serialization(void)
4936 static const UINT8 blob[] = {1,2,3};
4937 IMFAttributes *attributes, *dest;
4938 UINT32 size, count, value32;
4939 double value_dbl;
4940 UINT64 value64;
4941 UINT8 *buffer;
4942 IUnknown *obj;
4943 HRESULT hr;
4944 WCHAR *str;
4945 GUID guid;
4947 hr = MFCreateAttributes(&attributes, 0);
4948 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4950 hr = MFCreateAttributes(&dest, 0);
4951 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4953 hr = MFGetAttributesAsBlobSize(attributes, &size);
4954 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4955 ok(size == 8, "Got size %u.\n", size);
4957 buffer = malloc(size);
4959 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4960 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4962 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4963 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
4965 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4966 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4968 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4969 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4971 hr = MFInitAttributesFromBlob(dest, buffer, size);
4972 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4974 /* Previous items are cleared. */
4975 hr = IMFAttributes_GetCount(dest, &count);
4976 ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr);
4977 ok(count == 0, "Unexpected count %u.\n", count);
4979 free(buffer);
4981 /* Set some attributes of various types. */
4982 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4983 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4984 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4985 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4986 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4987 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4988 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4990 hr = MFGetAttributesAsBlobSize(attributes, &size);
4991 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4992 ok(size > 8, "Got unexpected size %u.\n", size);
4994 buffer = malloc(size);
4995 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4996 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4997 hr = MFInitAttributesFromBlob(dest, buffer, size);
4998 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4999 free(buffer);
5001 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
5002 ok(hr == S_OK, "Failed to get get uint32 value, hr %#lx.\n", hr);
5003 ok(value32 == 456, "Unexpected value %u.\n", value32);
5004 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
5005 ok(hr == S_OK, "Failed to get get uint64 value, hr %#lx.\n", hr);
5006 ok(value64 == 123, "Unexpected value.\n");
5007 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
5008 ok(hr == S_OK, "Failed to get get double value, hr %#lx.\n", hr);
5009 ok(value_dbl == 0.5, "Unexpected value.\n");
5010 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
5011 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
5012 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
5013 ok(hr == S_OK, "Failed to get guid value, hr %#lx.\n", hr);
5014 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
5015 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
5016 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
5017 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
5018 CoTaskMemFree(str);
5019 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
5020 ok(hr == S_OK, "Failed to get blob value, hr %#lx.\n", hr);
5021 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
5022 CoTaskMemFree(buffer);
5024 IMFAttributes_Release(attributes);
5025 IMFAttributes_Release(dest);
5028 static void test_wrapped_media_type(void)
5030 IMFMediaType *mediatype, *mediatype2;
5031 UINT32 count, type;
5032 HRESULT hr;
5033 GUID guid;
5035 hr = MFCreateMediaType(&mediatype);
5036 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
5038 hr = MFUnwrapMediaType(mediatype, &mediatype2);
5039 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
5041 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
5042 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
5043 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
5044 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
5046 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
5047 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
5049 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
5050 ok(hr == S_OK, "Failed to create wrapped media type, hr %#lx.\n", hr);
5052 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
5053 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
5054 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
5056 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
5057 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
5058 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
5060 hr = IMFMediaType_GetCount(mediatype2, &count);
5061 ok(hr == S_OK, "Failed to get item count, hr %#lx.\n", hr);
5062 ok(count == 3, "Unexpected count %u.\n", count);
5064 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
5065 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
5066 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
5068 IMFMediaType_Release(mediatype);
5070 hr = MFUnwrapMediaType(mediatype2, &mediatype);
5071 ok(hr == S_OK, "Failed to unwrap, hr %#lx.\n", hr);
5073 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
5074 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
5075 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
5077 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
5078 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
5080 IMFMediaType_Release(mediatype);
5081 IMFMediaType_Release(mediatype2);
5084 static void test_MFCreateWaveFormatExFromMFMediaType(void)
5086 static const struct wave_fmt_test
5088 const GUID *subtype;
5089 WORD format_tag;
5091 wave_fmt_tests[] =
5093 { &MFAudioFormat_PCM, WAVE_FORMAT_PCM, },
5094 { &MFAudioFormat_Float, WAVE_FORMAT_IEEE_FLOAT, },
5096 WAVEFORMATEXTENSIBLE *format_ext;
5097 IMFMediaType *mediatype;
5098 WAVEFORMATEX *format;
5099 UINT32 size, i;
5100 HRESULT hr;
5102 hr = MFCreateMediaType(&mediatype);
5103 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
5105 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
5106 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
5108 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
5109 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
5111 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
5112 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
5114 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
5115 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
5117 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
5118 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
5120 for (i = 0; i < ARRAY_SIZE(wave_fmt_tests); ++i)
5122 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, wave_fmt_tests[i].subtype);
5123 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
5125 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
5126 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
5127 ok(format != NULL, "Expected format structure.\n");
5128 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
5129 ok(format->wFormatTag == wave_fmt_tests[i].format_tag, "Expected tag %u, got %u.\n", wave_fmt_tests[i].format_tag, format->wFormatTag);
5130 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
5131 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format->nSamplesPerSec);
5132 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n", format->nAvgBytesPerSec);
5133 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
5134 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
5135 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
5136 CoTaskMemFree(format);
5138 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
5139 MFWaveFormatExConvertFlag_ForceExtensible);
5140 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
5141 ok(format_ext != NULL, "Expected format structure.\n");
5142 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
5143 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
5144 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
5145 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format_ext->Format.nSamplesPerSec);
5146 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n",
5147 format_ext->Format.nAvgBytesPerSec);
5148 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
5149 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
5150 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
5151 format_ext->Format.cbSize);
5152 CoTaskMemFree(format_ext);
5154 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
5155 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
5156 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
5157 CoTaskMemFree(format);
5160 IMFMediaType_Release(mediatype);
5163 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5165 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5166 IMFByteStream *stream;
5167 IUnknown *object;
5168 HRESULT hr;
5170 ok(!!result, "Unexpected result object.\n");
5172 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
5174 hr = IMFAsyncResult_GetObject(result, &object);
5175 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5177 hr = MFEndCreateFile(result, &stream);
5178 ok(hr == S_OK, "Failed to get file stream, hr %#lx.\n", hr);
5179 IMFByteStream_Release(stream);
5181 SetEvent(callback->event);
5183 return S_OK;
5186 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
5188 testcallback_QueryInterface,
5189 testcallback_AddRef,
5190 testcallback_Release,
5191 testcallback_GetParameters,
5192 test_create_file_callback_Invoke,
5195 static void test_async_create_file(void)
5197 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
5198 struct test_callback *callback;
5199 IUnknown *cancel_cookie;
5200 HRESULT hr;
5201 BOOL ret;
5203 callback = create_test_callback(&test_create_file_callback_vtbl);
5205 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5206 ok(hr == S_OK, "Fail to start up, hr %#lx.\n", hr);
5208 GetTempPathW(ARRAY_SIZE(pathW), pathW);
5209 GetTempFileNameW(pathW, NULL, 0, fileW);
5211 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
5212 &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface, &cancel_cookie);
5213 ok(hr == S_OK, "Async create request failed, hr %#lx.\n", hr);
5214 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
5216 WaitForSingleObject(callback->event, INFINITE);
5218 IUnknown_Release(cancel_cookie);
5220 hr = MFShutdown();
5221 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
5223 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
5225 ret = DeleteFileW(fileW);
5226 ok(ret, "Failed to delete test file.\n");
5229 struct activate_object
5231 IMFActivate IMFActivate_iface;
5232 LONG refcount;
5235 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
5237 if (IsEqualIID(riid, &IID_IMFActivate) ||
5238 IsEqualIID(riid, &IID_IMFAttributes) ||
5239 IsEqualIID(riid, &IID_IUnknown))
5241 *obj = iface;
5242 IMFActivate_AddRef(iface);
5243 return S_OK;
5246 *obj = NULL;
5247 return E_NOINTERFACE;
5250 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
5252 return 2;
5255 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
5257 return 1;
5260 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
5262 return E_NOTIMPL;
5265 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
5267 return E_NOTIMPL;
5270 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
5272 return E_NOTIMPL;
5275 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
5276 BOOL *result)
5278 return E_NOTIMPL;
5281 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
5283 return E_NOTIMPL;
5286 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
5288 return E_NOTIMPL;
5291 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
5293 return E_NOTIMPL;
5296 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
5298 return E_NOTIMPL;
5301 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
5303 return E_NOTIMPL;
5306 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
5307 UINT32 size, UINT32 *length)
5309 return E_NOTIMPL;
5312 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
5313 WCHAR **value, UINT32 *length)
5315 return E_NOTIMPL;
5318 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
5320 return E_NOTIMPL;
5323 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
5324 UINT32 bufsize, UINT32 *blobsize)
5326 return E_NOTIMPL;
5329 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
5331 return E_NOTIMPL;
5334 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
5336 return E_NOTIMPL;
5339 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
5341 return E_NOTIMPL;
5344 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
5346 return E_NOTIMPL;
5349 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
5351 return E_NOTIMPL;
5354 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
5356 return E_NOTIMPL;
5359 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
5361 return E_NOTIMPL;
5364 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
5366 return E_NOTIMPL;
5369 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
5371 return E_NOTIMPL;
5374 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
5376 return E_NOTIMPL;
5379 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
5381 return E_NOTIMPL;
5384 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
5386 return E_NOTIMPL;
5389 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
5391 return E_NOTIMPL;
5394 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
5396 return E_NOTIMPL;
5399 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
5401 return E_NOTIMPL;
5404 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
5406 return E_NOTIMPL;
5409 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
5411 return E_NOTIMPL;
5414 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
5416 return E_NOTIMPL;
5419 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
5421 return E_NOTIMPL;
5424 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
5426 return E_NOTIMPL;
5429 static const IMFActivateVtbl activate_object_vtbl =
5431 activate_object_QueryInterface,
5432 activate_object_AddRef,
5433 activate_object_Release,
5434 activate_object_GetItem,
5435 activate_object_GetItemType,
5436 activate_object_CompareItem,
5437 activate_object_Compare,
5438 activate_object_GetUINT32,
5439 activate_object_GetUINT64,
5440 activate_object_GetDouble,
5441 activate_object_GetGUID,
5442 activate_object_GetStringLength,
5443 activate_object_GetString,
5444 activate_object_GetAllocatedString,
5445 activate_object_GetBlobSize,
5446 activate_object_GetBlob,
5447 activate_object_GetAllocatedBlob,
5448 activate_object_GetUnknown,
5449 activate_object_SetItem,
5450 activate_object_DeleteItem,
5451 activate_object_DeleteAllItems,
5452 activate_object_SetUINT32,
5453 activate_object_SetUINT64,
5454 activate_object_SetDouble,
5455 activate_object_SetGUID,
5456 activate_object_SetString,
5457 activate_object_SetBlob,
5458 activate_object_SetUnknown,
5459 activate_object_LockStore,
5460 activate_object_UnlockStore,
5461 activate_object_GetCount,
5462 activate_object_GetItemByIndex,
5463 activate_object_CopyAllItems,
5464 activate_object_ActivateObject,
5465 activate_object_ShutdownObject,
5466 activate_object_DetachObject,
5469 static void test_local_handlers(void)
5471 IMFActivate local_activate = { &activate_object_vtbl };
5472 static const WCHAR localW[] = L"local";
5473 HRESULT hr;
5475 if (!pMFRegisterLocalSchemeHandler)
5477 win_skip("Local handlers are not supported.\n");
5478 return;
5481 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
5482 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5484 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
5485 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5487 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
5488 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5490 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5491 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5493 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
5494 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
5496 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
5497 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5499 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
5500 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5502 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
5503 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5505 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
5506 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5508 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
5509 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
5512 static void test_create_property_store(void)
5514 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
5515 IPropertyStore *store, *store2;
5516 PROPVARIANT value = {0};
5517 PROPERTYKEY key;
5518 ULONG refcount;
5519 DWORD count;
5520 HRESULT hr;
5522 hr = CreatePropertyStore(NULL);
5523 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5525 hr = CreatePropertyStore(&store);
5526 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5528 hr = CreatePropertyStore(&store2);
5529 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5530 ok(store2 != store, "Expected different store objects.\n");
5531 IPropertyStore_Release(store2);
5533 check_interface(store, &IID_IPropertyStoreCache, FALSE);
5534 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
5536 hr = IPropertyStore_GetCount(store, NULL);
5537 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5539 count = 0xdeadbeef;
5540 hr = IPropertyStore_GetCount(store, &count);
5541 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5542 ok(!count, "Unexpected count %lu.\n", count);
5544 hr = IPropertyStore_Commit(store);
5545 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5547 hr = IPropertyStore_GetAt(store, 0, &key);
5548 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5550 hr = IPropertyStore_GetValue(store, NULL, &value);
5551 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5553 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
5554 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5556 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5557 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5559 memset(&value, 0, sizeof(PROPVARIANT));
5560 value.vt = VT_I4;
5561 value.lVal = 0xdeadbeef;
5562 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5563 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5565 if (0)
5567 /* crashes on Windows */
5568 hr = IPropertyStore_SetValue(store, NULL, &value);
5569 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5572 hr = IPropertyStore_GetCount(store, &count);
5573 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5574 ok(count == 1, "Unexpected count %lu.\n", count);
5576 hr = IPropertyStore_Commit(store);
5577 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5579 hr = IPropertyStore_GetAt(store, 0, &key);
5580 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5581 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
5583 hr = IPropertyStore_GetAt(store, 1, &key);
5584 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5586 memset(&value, 0xcc, sizeof(PROPVARIANT));
5587 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5588 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5589 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
5590 ok(value.lVal == 0xdeadbeef, "Unexpected value %#lx.\n", value.lVal);
5592 memset(&value, 0, sizeof(PROPVARIANT));
5593 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5594 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5596 hr = IPropertyStore_GetCount(store, &count);
5597 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5598 ok(count == 1, "Unexpected count %lu.\n", count);
5600 memset(&value, 0xcc, sizeof(PROPVARIANT));
5601 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5603 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
5604 ok(!value.lVal, "Unexpected value %#lx.\n", value.lVal);
5606 refcount = IPropertyStore_Release(store);
5607 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
5610 struct test_thread_param
5612 IMFDXGIDeviceManager *manager;
5613 HANDLE handle;
5614 BOOL lock;
5617 static DWORD WINAPI test_device_manager_thread(void *arg)
5619 struct test_thread_param *param = arg;
5620 ID3D11Device *device;
5621 HRESULT hr;
5623 if (param->lock)
5625 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
5626 (void **)&device, FALSE);
5627 if (SUCCEEDED(hr))
5628 ID3D11Device_Release(device);
5630 else
5631 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
5633 return hr;
5636 static void test_dxgi_device_manager(void)
5638 IMFDXGIDeviceManager *manager, *manager2;
5639 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
5640 struct test_thread_param param;
5641 HANDLE handle1, handle, thread;
5642 UINT token, token2;
5643 IUnknown *unk;
5644 HRESULT hr;
5646 if (!pMFCreateDXGIDeviceManager)
5648 win_skip("MFCreateDXGIDeviceManager not found.\n");
5649 return;
5652 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
5653 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5655 token = 0;
5656 hr = pMFCreateDXGIDeviceManager(&token, NULL);
5657 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5658 ok(!token, "got wrong token: %u.\n", token);
5660 hr = pMFCreateDXGIDeviceManager(&token, &manager);
5661 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5662 EXPECT_REF(manager, 1);
5663 ok(!!token, "got wrong token: %u.\n", token);
5665 Sleep(50);
5666 token2 = 0;
5667 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
5668 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5669 EXPECT_REF(manager2, 1);
5670 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
5671 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
5672 EXPECT_REF(manager, 1);
5674 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5675 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5677 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5678 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5680 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
5681 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5683 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
5684 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
5685 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5686 EXPECT_REF(d3d11_dev, 1);
5688 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
5689 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5690 EXPECT_REF(d3d11_dev, 1);
5692 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
5693 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5695 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5696 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5697 EXPECT_REF(manager, 1);
5698 EXPECT_REF(d3d11_dev, 2);
5700 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
5701 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5702 EXPECT_REF(manager2, 1);
5703 EXPECT_REF(d3d11_dev, 2);
5705 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5706 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5707 EXPECT_REF(manager, 1);
5708 EXPECT_REF(d3d11_dev, 2);
5710 /* GetVideoService() on device change. */
5711 handle = NULL;
5712 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5713 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5714 ok(!!handle, "Unexpected handle value %p.\n", handle);
5716 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
5717 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
5718 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5719 EXPECT_REF(d3d11_dev2, 1);
5720 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
5721 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5722 EXPECT_REF(manager, 1);
5723 EXPECT_REF(d3d11_dev2, 2);
5724 EXPECT_REF(d3d11_dev, 1);
5726 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5727 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#lx.\n", hr);
5729 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5730 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5732 handle = NULL;
5733 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5734 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5735 ok(!!handle, "Unexpected handle value %p.\n", handle);
5737 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5738 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5740 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5741 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5742 IUnknown_Release(unk);
5744 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
5745 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5746 IUnknown_Release(unk);
5748 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
5749 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5750 IUnknown_Release(unk);
5752 handle1 = NULL;
5753 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5754 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5755 ok(handle != handle1, "Unexpected handle.\n");
5757 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5758 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5760 /* Already closed. */
5761 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5762 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5764 handle = NULL;
5765 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5766 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5768 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5769 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5771 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
5772 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5774 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5775 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5776 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
5777 ID3D11Device_Release(device);
5779 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5780 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5782 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5783 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5785 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
5786 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5788 /* Locked with one handle, unlock with another. */
5789 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5790 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5792 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5793 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5795 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5796 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5798 ID3D11Device_Release(device);
5800 /* Closing unlocks the device. */
5801 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5802 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5804 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5805 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5806 ID3D11Device_Release(device);
5808 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5809 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5811 /* Open two handles. */
5812 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5813 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5815 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5818 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5819 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5820 ID3D11Device_Release(device);
5822 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5823 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5824 ID3D11Device_Release(device);
5826 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5827 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5829 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5830 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5832 param.manager = manager;
5833 param.handle = handle;
5834 param.lock = TRUE;
5835 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5836 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5837 GetExitCodeThread(thread, (DWORD *)&hr);
5838 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#lx.\n", hr);
5839 CloseHandle(thread);
5841 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5842 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5844 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5845 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5847 /* Lock on main thread, unlock on another. */
5848 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5850 ID3D11Device_Release(device);
5852 param.manager = manager;
5853 param.handle = handle;
5854 param.lock = FALSE;
5855 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5856 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5857 GetExitCodeThread(thread, (DWORD *)&hr);
5858 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5859 CloseHandle(thread);
5861 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5862 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5864 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5865 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5867 IMFDXGIDeviceManager_Release(manager);
5868 EXPECT_REF(d3d11_dev2, 1);
5869 ID3D11Device_Release(d3d11_dev);
5870 ID3D11Device_Release(d3d11_dev2);
5871 IMFDXGIDeviceManager_Release(manager2);
5874 static void test_MFCreateTransformActivate(void)
5876 IMFActivate *activate;
5877 UINT32 count;
5878 HRESULT hr;
5880 if (!pMFCreateTransformActivate)
5882 win_skip("MFCreateTransformActivate() is not available.\n");
5883 return;
5886 hr = pMFCreateTransformActivate(&activate);
5887 ok(hr == S_OK, "Failed to create activator, hr %#lx.\n", hr);
5889 hr = IMFActivate_GetCount(activate, &count);
5890 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5891 ok(!count, "Unexpected attribute count %u.\n", count);
5893 IMFActivate_Release(activate);
5896 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5898 if (IsEqualIID(riid, &IID_IClassFactory) ||
5899 IsEqualIID(riid, &IID_IUnknown))
5901 *obj = iface;
5902 IClassFactory_AddRef(iface);
5903 return S_OK;
5906 *obj = NULL;
5907 return E_NOINTERFACE;
5910 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5912 return 2;
5915 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5917 return 1;
5920 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5922 ok(0, "Unexpected call.\n");
5923 return E_NOTIMPL;
5926 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5928 return S_OK;
5931 static const IClassFactoryVtbl test_mft_factory_vtbl =
5933 test_mft_factory_QueryInterface,
5934 test_mft_factory_AddRef,
5935 test_mft_factory_Release,
5936 test_mft_factory_CreateInstance,
5937 test_mft_factory_LockServer,
5940 static void test_MFTRegisterLocal(void)
5942 IClassFactory test_factory = { &test_mft_factory_vtbl };
5943 MFT_REGISTER_TYPE_INFO input_types[1], *in_types, *out_types;
5944 IMFAttributes *attributes;
5945 IMFActivate **activate;
5946 UINT32 count, count2;
5947 WCHAR *name;
5948 HRESULT hr;
5950 if (!pMFTRegisterLocal)
5952 win_skip("MFTRegisterLocal() is not available.\n");
5953 return;
5956 input_types[0].guidMajorType = MFMediaType_Audio;
5957 input_types[0].guidSubtype = MFAudioFormat_PCM;
5958 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5959 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5961 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5962 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5964 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5965 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5966 ok(count > 0, "Unexpected count %u.\n", count);
5967 CoTaskMemFree(activate);
5969 hr = pMFTUnregisterLocal(&test_factory);
5970 ok(hr == S_OK, "Failed to unregister MFT, hr %#lx.\n", hr);
5972 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5973 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5974 ok(count2 < count, "Unexpected count %u.\n", count2);
5975 CoTaskMemFree(activate);
5977 hr = pMFTUnregisterLocal(&test_factory);
5978 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5980 hr = pMFTUnregisterLocal(NULL);
5981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5983 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5984 0, NULL);
5985 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5987 hr = MFTGetInfo(MFT_CATEGORY_OTHER, &name, &in_types, &count, &out_types, &count2, &attributes);
5988 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5990 hr = pMFTUnregisterLocal(NULL);
5991 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5993 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5994 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5996 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5997 0, NULL);
5998 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
6000 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
6001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6004 static void test_queue_com(void)
6006 static int system_queues[] =
6008 MFASYNC_CALLBACK_QUEUE_STANDARD,
6009 MFASYNC_CALLBACK_QUEUE_RT,
6010 MFASYNC_CALLBACK_QUEUE_IO,
6011 MFASYNC_CALLBACK_QUEUE_TIMER,
6012 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
6013 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
6016 static int user_queues[] =
6018 MF_STANDARD_WORKQUEUE,
6019 MF_WINDOW_WORKQUEUE,
6020 MF_MULTITHREADED_WORKQUEUE,
6023 char path_name[MAX_PATH];
6024 PROCESS_INFORMATION info;
6025 STARTUPINFOA startup;
6026 char **argv;
6027 int i;
6029 if (!pCoGetApartmentType)
6031 win_skip("CoGetApartmentType() is not available.\n");
6032 return;
6035 winetest_get_mainargs(&argv);
6037 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
6039 memset(&startup, 0, sizeof(startup));
6040 startup.cb = sizeof(startup);
6041 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
6042 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
6043 "CreateProcess failed.\n" );
6044 wait_child_process(info.hProcess);
6045 CloseHandle(info.hProcess);
6046 CloseHandle(info.hThread);
6049 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
6051 memset(&startup, 0, sizeof(startup));
6052 startup.cb = sizeof(startup);
6053 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
6054 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
6055 "CreateProcess failed.\n" );
6056 wait_child_process(info.hProcess);
6057 CloseHandle(info.hProcess);
6058 CloseHandle(info.hThread);
6062 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
6064 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
6065 APTTYPEQUALIFIER qualifier;
6066 APTTYPE com_type;
6067 HRESULT hr;
6069 hr = pCoGetApartmentType(&com_type, &qualifier);
6070 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#lx.\n", hr);
6071 if (SUCCEEDED(hr))
6073 todo_wine {
6074 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
6075 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
6076 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
6077 else
6078 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
6079 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
6083 SetEvent(callback->event);
6084 return S_OK;
6087 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
6089 testcallback_QueryInterface,
6090 testcallback_AddRef,
6091 testcallback_Release,
6092 testcallback_GetParameters,
6093 test_queue_com_state_callback_Invoke,
6096 static void test_queue_com_state(const char *name)
6098 struct test_callback *callback;
6099 DWORD queue, queue_type;
6100 HRESULT hr;
6102 callback = create_test_callback(&test_queue_com_state_callback_vtbl);
6104 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
6105 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
6107 if (name[0] == 's')
6109 callback->param = name[1] - '0';
6110 hr = MFPutWorkItem(callback->param, &callback->IMFAsyncCallback_iface, NULL);
6111 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
6112 WaitForSingleObject(callback->event, INFINITE);
6114 else if (name[0] == 'u')
6116 queue_type = name[1] - '0';
6118 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
6119 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
6120 "Failed to allocate a queue of type %lu, hr %#lx.\n", queue_type, hr);
6122 if (SUCCEEDED(hr))
6124 callback->param = queue;
6125 hr = MFPutWorkItem(queue, &callback->IMFAsyncCallback_iface, NULL);
6126 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
6127 WaitForSingleObject(callback->event, INFINITE);
6129 hr = MFUnlockWorkQueue(queue);
6130 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
6134 hr = MFShutdown();
6135 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
6137 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
6140 static void test_MFGetStrideForBitmapInfoHeader(void)
6142 static const struct stride_test
6144 const GUID *subtype;
6145 unsigned int width;
6146 LONG stride;
6148 stride_tests[] =
6150 { &MFVideoFormat_RGB8, 3, -4 },
6151 { &MFVideoFormat_RGB8, 1, -4 },
6152 { &MFVideoFormat_RGB555, 3, -8 },
6153 { &MFVideoFormat_RGB555, 1, -4 },
6154 { &MFVideoFormat_RGB565, 3, -8 },
6155 { &MFVideoFormat_RGB565, 1, -4 },
6156 { &MFVideoFormat_RGB24, 3, -12 },
6157 { &MFVideoFormat_RGB24, 1, -4 },
6158 { &MFVideoFormat_RGB32, 3, -12 },
6159 { &MFVideoFormat_RGB32, 1, -4 },
6160 { &MFVideoFormat_ARGB32, 3, -12 },
6161 { &MFVideoFormat_ARGB32, 1, -4 },
6162 { &MFVideoFormat_A2R10G10B10, 3, -12 },
6163 { &MFVideoFormat_A2R10G10B10, 1, -4 },
6164 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
6165 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
6167 /* YUV */
6168 { &MFVideoFormat_NV12, 1, 1 },
6169 { &MFVideoFormat_NV12, 2, 2 },
6170 { &MFVideoFormat_NV12, 3, 3 },
6171 { &MFVideoFormat_AYUV, 1, 4 },
6172 { &MFVideoFormat_AYUV, 4, 16 },
6173 { &MFVideoFormat_AYUV, 5, 20 },
6174 { &MFVideoFormat_IMC1, 1, 4 },
6175 { &MFVideoFormat_IMC1, 2, 4 },
6176 { &MFVideoFormat_IMC1, 3, 8 },
6177 { &MFVideoFormat_IMC3, 1, 4 },
6178 { &MFVideoFormat_IMC3, 2, 4 },
6179 { &MFVideoFormat_IMC3, 3, 8 },
6180 { &MFVideoFormat_IMC2, 1, 1 },
6181 { &MFVideoFormat_IMC2, 2, 2 },
6182 { &MFVideoFormat_IMC2, 3, 3 },
6183 { &MFVideoFormat_IMC4, 1, 1 },
6184 { &MFVideoFormat_IMC4, 2, 2 },
6185 { &MFVideoFormat_IMC4, 3, 3 },
6186 { &MFVideoFormat_YV12, 1, 1 },
6187 { &MFVideoFormat_YV12, 2, 2 },
6188 { &MFVideoFormat_YV12, 3, 3 },
6189 { &MFVideoFormat_YV12, 320, 320 },
6190 { &MFVideoFormat_I420, 1, 1 },
6191 { &MFVideoFormat_I420, 2, 2 },
6192 { &MFVideoFormat_I420, 3, 3 },
6193 { &MFVideoFormat_I420, 320, 320 },
6194 { &MFVideoFormat_IYUV, 1, 1 },
6195 { &MFVideoFormat_IYUV, 2, 2 },
6196 { &MFVideoFormat_IYUV, 3, 3 },
6197 { &MFVideoFormat_IYUV, 320, 320 },
6198 { &MFVideoFormat_NV11, 1, 1 },
6199 { &MFVideoFormat_NV11, 2, 2 },
6200 { &MFVideoFormat_NV11, 3, 3 },
6202 unsigned int i;
6203 LONG stride;
6204 HRESULT hr;
6206 if (!pMFGetStrideForBitmapInfoHeader)
6208 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
6209 return;
6212 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
6213 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
6215 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
6217 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
6218 ok(hr == S_OK, "%u: failed to get stride, hr %#lx.\n", i, hr);
6219 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %ld, expected %ld.\n", i,
6220 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
6224 static void test_MFCreate2DMediaBuffer(void)
6226 static const char two_aas[] = { 0xaa, 0xaa };
6227 static const char eight_bbs[] = { 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb };
6228 DWORD max_length, length, length2;
6229 BYTE *buffer_start, *data, *data2;
6230 LONG pitch, pitch2, stride;
6231 IMF2DBuffer2 *_2dbuffer2;
6232 IMF2DBuffer *_2dbuffer;
6233 IMFMediaBuffer *buffer;
6234 int i, j, k;
6235 HRESULT hr;
6236 BOOL ret;
6238 if (!pMFCreate2DMediaBuffer)
6240 win_skip("MFCreate2DMediaBuffer() is not available.\n");
6241 return;
6244 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
6245 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
6247 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
6248 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
6250 /* YUV formats can't be bottom-up. */
6251 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
6252 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
6254 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
6255 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6257 check_interface(buffer, &IID_IMFGetService, TRUE);
6258 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6260 /* Full backing buffer size, with 64 bytes per row alignment. */
6261 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6262 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6263 ok(max_length > 0, "Unexpected length %lu.\n", max_length);
6265 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6266 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
6267 ok(!length, "Unexpected length.\n");
6269 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
6270 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
6272 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6273 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
6274 ok(length == 10, "Unexpected length.\n");
6276 /* Linear lock/unlock. */
6278 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
6279 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
6281 /* Linear locking call returns plane size.*/
6282 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
6283 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6284 ok(max_length == length, "Unexpected length.\n");
6286 memset(data, 0xaa, length);
6288 length = 0;
6289 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
6290 ok(max_length == length && length == 9, "Unexpected length %lu.\n", length);
6292 /* Already locked */
6293 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6294 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6295 ok(data2 == data, "Unexpected pointer.\n");
6297 hr = IMFMediaBuffer_Unlock(buffer);
6298 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6300 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6301 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6303 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6304 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6306 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6307 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6308 ok(length == 9, "Unexpected length %lu.\n", length);
6310 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
6311 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6313 /* 2D lock. */
6314 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6315 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
6317 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6318 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6320 hr = IMFMediaBuffer_Unlock(buffer);
6321 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6323 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6324 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6326 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
6327 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6329 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
6330 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6332 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
6333 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6335 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6336 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6337 ok(!!data, "Expected data pointer.\n");
6338 ok(pitch == 64, "Unexpected pitch %ld.\n", pitch);
6340 for (i = 0; i < 4; i++)
6341 ok(memcmp(&data[64 * i], two_aas, sizeof(two_aas)) == 0, "Invalid data instead of 0xaa.\n");
6342 memset(data, 0xbb, 194);
6344 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
6345 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6346 ok(data == data2, "Expected data pointer.\n");
6348 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
6349 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6351 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
6352 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6354 /* Active 2D lock */
6355 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6356 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6358 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6359 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6361 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6362 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6364 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6365 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6367 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6368 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6370 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6371 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6373 ok(memcmp(data, eight_bbs, sizeof(eight_bbs)) == 0, "Invalid data instead of 0xbb.\n");
6375 hr = IMFMediaBuffer_Unlock(buffer);
6376 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6378 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6379 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#lx.\n", hr);
6381 if (SUCCEEDED(hr))
6383 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6384 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6386 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
6387 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6389 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6390 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6392 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6393 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6395 /* Flags are ignored. */
6396 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
6397 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6399 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
6400 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6402 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6403 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6405 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6406 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6408 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
6409 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6411 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
6412 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6414 IMF2DBuffer2_Release(_2dbuffer2);
6416 else
6417 win_skip("IMF2DBuffer2 is not supported.\n");
6419 IMF2DBuffer_Release(_2dbuffer);
6421 IMFMediaBuffer_Release(buffer);
6423 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
6425 const struct image_size_test *ptr = &image_size_tests[i];
6427 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
6428 continue;
6430 winetest_push_context("%u, %u x %u, format %s", i, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6432 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
6433 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6435 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6436 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6437 ok(length == ptr->max_length, "Unexpected maximum length %lu.\n", length);
6439 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6440 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6442 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6443 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6445 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6446 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6447 ok(length == ptr->contiguous_length, "Unexpected contiguous length %lu.\n", length);
6449 data2 = malloc(ptr->contiguous_length + 16);
6450 ok(!!data2, "Failed to allocate buffer.\n");
6452 for (j = 0; j < ptr->contiguous_length + 16; j++)
6453 data2[j] = j & 0x7f;
6455 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length - 1);
6456 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6458 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6459 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6460 ok(length2 == ptr->contiguous_length, "Unexpected linear buffer length %lu.\n", length2);
6462 memset(data, 0xff, length2);
6464 hr = IMFMediaBuffer_Unlock(buffer);
6465 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6467 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length + 16);
6468 ok(hr == S_OK, "Failed to copy from contiguous buffer, hr %#lx.\n", hr);
6470 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6471 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6472 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6473 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6475 for (j = 0; j < ptr->contiguous_length; j++)
6477 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6479 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6480 continue;
6481 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6482 continue;
6484 if (data[j] != (j & 0x7f))
6485 break;
6487 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j);
6489 memset(data, 0xff, length2);
6491 hr = IMFMediaBuffer_Unlock(buffer);
6492 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6494 hr = IMF2DBuffer2_ContiguousCopyFrom(_2dbuffer2, data2, ptr->contiguous_length);
6495 ok(hr == S_OK, "Failed to copy from contiguous buffer, hr %#lx.\n", hr);
6497 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6498 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6499 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6500 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6502 for (j = 0; j < ptr->contiguous_length; j++)
6504 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6506 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6507 continue;
6508 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6509 continue;
6511 if (data[j] != (j & 0x7f))
6512 break;
6514 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data[j], j & 0x7f, j);
6516 hr = IMFMediaBuffer_Unlock(buffer);
6517 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6519 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length - 1);
6520 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6522 memset(data2, 0xff, ptr->contiguous_length + 16);
6524 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length + 16);
6525 ok(hr == S_OK, "Failed to copy to contiguous buffer, hr %#lx.\n", hr);
6527 for (j = 0; j < ptr->contiguous_length; j++)
6529 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6531 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6532 continue;
6533 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6534 continue;
6536 if (data2[j] != (j & 0x7f))
6537 break;
6539 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data2[j], j & 0x7f, j);
6541 memset(data2, 0xff, ptr->contiguous_length + 16);
6543 hr = IMF2DBuffer2_ContiguousCopyTo(_2dbuffer2, data2, ptr->contiguous_length);
6544 ok(hr == S_OK, "Failed to copy to contiguous buffer, hr %#lx.\n", hr);
6546 for (j = 0; j < ptr->contiguous_length; j++)
6548 if (IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC1) || IsEqualGUID(ptr->subtype, &MFVideoFormat_IMC3))
6550 if (j < ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width)
6551 continue;
6552 if (j >= ptr->height * ptr->pitch && j % ptr->pitch >= ptr->width / 2)
6553 continue;
6555 if (data2[j] != (j & 0x7f))
6556 break;
6558 ok(j == ptr->contiguous_length, "Unexpected byte %02x instead of %02x at position %u.\n", data2[j], j & 0x7f, j);
6560 free(data2);
6562 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
6563 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6564 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
6565 i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
6567 hr = pMFGetStrideForBitmapInfoHeader(ptr->subtype->Data1, ptr->width, &stride);
6568 ok(hr == S_OK, "Failed to get stride, hr %#lx.\n", hr);
6569 stride = abs(stride);
6571 /* primary plane */
6572 ok(ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6573 ptr->height * stride, length2);
6574 for (j = 0; j < ptr->height; j++)
6575 for (k = 0; k < stride; k++)
6576 data[j * stride + k] = ((j % 16) << 4) + (k % 16);
6578 data += ptr->height * stride;
6580 /* secondary planes */
6581 switch (ptr->subtype->Data1)
6583 case MAKEFOURCC('I','M','C','1'):
6584 case MAKEFOURCC('I','M','C','3'):
6585 ok(2 * ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6586 2 * ptr->height * stride, length2);
6587 for (j = 0; j < ptr->height; j++)
6588 for (k = 0; k < stride / 2; k++)
6589 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6590 break;
6592 case MAKEFOURCC('I','M','C','2'):
6593 case MAKEFOURCC('I','M','C','4'):
6594 case MAKEFOURCC('N','V','1','1'):
6595 case MAKEFOURCC('Y','V','1','2'):
6596 case MAKEFOURCC('I','4','2','0'):
6597 case MAKEFOURCC('I','Y','U','V'):
6598 ok(stride * 3 / 2 * ptr->height <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6599 stride * 3 / 2 * ptr->height, length2);
6600 for (j = 0; j < ptr->height; j++)
6601 for (k = 0; k < stride / 2; k++)
6602 data[j * (stride / 2) + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6603 break;
6605 case MAKEFOURCC('N','V','1','2'):
6606 ok(stride * ptr->height * 3 / 2 <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6607 stride * ptr->height * 3 / 2, length2);
6608 for (j = 0; j < ptr->height / 2; j++)
6609 for (k = 0; k < stride; k++)
6610 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6611 break;
6614 hr = IMFMediaBuffer_Unlock(buffer);
6615 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6617 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6618 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6620 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
6621 ok(hr == S_OK, "Failed to get scanline, hr %#lx.\n", hr);
6622 ok(data2 == data, "Unexpected data pointer.\n");
6623 ok(pitch == pitch2, "Unexpected pitch.\n");
6625 /* primary plane */
6626 for (j = 0; j < ptr->height; j++)
6627 for (k = 0; k < stride; k++)
6628 ok(data[j * pitch + k] == ((j % 16) << 4) + (k % 16),
6629 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6630 data[j * pitch + k], ((j % 16) << 4) + (k % 16), j, k);
6632 data += ptr->height * pitch;
6634 /* secondary planes */
6635 switch (ptr->subtype->Data1)
6637 case MAKEFOURCC('I','M','C','1'):
6638 case MAKEFOURCC('I','M','C','3'):
6639 for (j = 0; j < ptr->height; j++)
6640 for (k = 0; k < stride / 2; k++)
6641 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6642 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6643 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6644 break;
6646 case MAKEFOURCC('I','M','C','2'):
6647 case MAKEFOURCC('I','M','C','4'):
6648 case MAKEFOURCC('N','V','1','1'):
6649 case MAKEFOURCC('Y','V','1','2'):
6650 case MAKEFOURCC('I','4','2','0'):
6651 case MAKEFOURCC('I','Y','U','V'):
6652 for (j = 0; j < ptr->height; j++)
6653 for (k = 0; k < stride / 2; k++)
6654 ok(data[j * (pitch / 2) + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6655 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6656 data[j * (pitch / 2) + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6657 break;
6659 case MAKEFOURCC('N','V','1','2'):
6660 for (j = 0; j < ptr->height / 2; j++)
6661 for (k = 0; k < stride; k++)
6662 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6663 "Unexpected byte %02x instead of %02x at row %d column %d.\n",
6664 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), j + ptr->height, k);
6665 break;
6667 default:
6671 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6672 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6674 ok(pitch == ptr->pitch, "Unexpected pitch %ld, expected %d.\n", pitch, ptr->pitch);
6676 ret = TRUE;
6677 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
6678 ok(hr == S_OK, "Failed to get format flag, hr %#lx.\n", hr);
6679 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
6681 IMF2DBuffer_Release(_2dbuffer);
6682 IMF2DBuffer2_Release(_2dbuffer2);
6684 IMFMediaBuffer_Release(buffer);
6686 winetest_pop_context();
6689 /* Alignment tests */
6690 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
6692 const struct image_size_test *ptr = &image_size_tests[i];
6694 if (is_MEDIASUBTYPE_RGB(ptr->subtype))
6695 continue;
6697 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer);
6698 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6700 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6701 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6703 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6704 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6705 ok(((uintptr_t)data & MF_64_BYTE_ALIGNMENT) == 0, "Misaligned data at %p.\n", data);
6707 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6708 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6710 IMF2DBuffer_Release(_2dbuffer);
6711 IMFMediaBuffer_Release(buffer);
6715 static void test_MFCreateMediaBufferFromMediaType(void)
6717 static struct audio_buffer_test
6719 unsigned int duration;
6720 unsigned int min_length;
6721 unsigned int min_alignment;
6722 unsigned int block_alignment;
6723 unsigned int bytes_per_second;
6724 unsigned int buffer_length;
6725 } audio_tests[] =
6727 { 0, 0, 0, 4, 0, 20 },
6728 { 0, 16, 0, 4, 0, 20 },
6729 { 0, 0, 32, 4, 0, 36 },
6730 { 0, 64, 32, 4, 0, 64 },
6731 { 1, 0, 0, 4, 16, 36 },
6732 { 2, 0, 0, 4, 16, 52 },
6733 { 2, 0, 64, 4, 16, 68 },
6734 { 2, 0, 128, 4, 16,132 },
6736 IMFMediaType *media_type, *media_type2;
6737 unsigned int i, alignment;
6738 IMFMediaBuffer *buffer;
6739 DWORD length, max;
6740 BYTE *data;
6741 HRESULT hr;
6743 if (!pMFCreateMediaBufferFromMediaType)
6745 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
6746 return;
6749 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
6750 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6752 hr = MFCreateMediaType(&media_type);
6753 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6755 hr = MFCreateMediaType(&media_type2);
6756 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6758 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
6759 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6761 hr = IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)media_type2);
6762 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6764 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
6766 const struct audio_buffer_test *ptr = &audio_tests[i];
6768 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
6769 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6771 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
6772 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6774 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
6775 ptr->min_alignment, &buffer);
6776 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#lx.\n", hr);
6777 if (FAILED(hr))
6778 break;
6780 check_interface(buffer, &IID_IMFGetService, FALSE);
6782 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6783 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6784 ok(ptr->buffer_length == length, "%d: unexpected buffer length %lu, expected %u.\n", i, length, ptr->buffer_length);
6786 alignment = ptr->min_alignment ? ptr->min_alignment - 1 : MF_16_BYTE_ALIGNMENT;
6787 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6788 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6789 ok(ptr->buffer_length == max && !length, "Unexpected length.\n");
6790 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6791 hr = IMFMediaBuffer_Unlock(buffer);
6792 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6794 IMFMediaBuffer_Release(buffer);
6796 /* Only major type is set. */
6797 hr = pMFCreateMediaBufferFromMediaType(media_type2, ptr->duration * 10000000, ptr->min_length,
6798 ptr->min_alignment, &buffer);
6799 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6801 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6802 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6803 ok(ptr->min_length == length, "%u: unexpected buffer length %lu, expected %u.\n", i, length, ptr->min_length);
6805 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6806 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6807 ok(ptr->min_length == max && !length, "Unexpected length.\n");
6808 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6809 hr = IMFMediaBuffer_Unlock(buffer);
6810 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6812 IMFMediaBuffer_Release(buffer);
6815 IMFMediaType_Release(media_type);
6816 IMFMediaType_Release(media_type2);
6819 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
6821 GUID guid, subtype;
6822 UINT32 value;
6823 HRESULT hr;
6825 hr = IMFMediaType_GetMajorType(mediatype, &guid);
6826 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
6827 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
6829 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
6830 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
6832 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
6834 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
6835 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6837 if (fex->dwChannelMask)
6839 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
6840 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6841 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
6844 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
6846 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
6847 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6848 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
6851 else
6853 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
6854 subtype.Data1 = format->wFormatTag;
6855 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6857 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
6858 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6859 ok(value, "Unexpected value.\n");
6862 if (format->nChannels)
6864 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
6865 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6866 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
6869 if (format->nSamplesPerSec)
6871 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
6872 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6873 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
6876 if (format->nAvgBytesPerSec)
6878 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
6879 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6880 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
6883 if (format->nBlockAlign)
6885 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
6886 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6887 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
6890 if (format->wBitsPerSample)
6892 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
6893 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6894 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
6897 /* Only set for uncompressed formats. */
6898 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
6899 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
6900 IsEqualGUID(&guid, &MFAudioFormat_PCM))
6902 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6903 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
6905 else
6906 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
6909 static void test_MFInitMediaTypeFromWaveFormatEx(void)
6911 static const WAVEFORMATEX waveformatex_tests[] =
6913 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
6914 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
6915 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
6916 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
6917 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
6918 { 1234, 0, 0, 0, 0, 0 },
6919 { WAVE_FORMAT_ALAW },
6920 { WAVE_FORMAT_CREATIVE_ADPCM },
6921 { WAVE_FORMAT_MPEGLAYER3 },
6922 { WAVE_FORMAT_MPEG_ADTS_AAC },
6923 { WAVE_FORMAT_ALAC },
6924 { WAVE_FORMAT_AMR_NB },
6925 { WAVE_FORMAT_AMR_WB },
6926 { WAVE_FORMAT_AMR_WP },
6927 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
6928 { WAVE_FORMAT_DRM },
6929 { WAVE_FORMAT_DTS },
6930 { WAVE_FORMAT_FLAC },
6931 { WAVE_FORMAT_MPEG },
6932 { WAVE_FORMAT_WMAVOICE9 },
6933 { WAVE_FORMAT_OPUS },
6934 { WAVE_FORMAT_WMAUDIO2 },
6935 { WAVE_FORMAT_WMAUDIO3 },
6936 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
6937 { WAVE_FORMAT_WMASPDIF },
6940 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
6941 WAVEFORMATEXTENSIBLE waveformatext;
6942 MPEGLAYER3WAVEFORMAT mp3format;
6943 IMFMediaType *mediatype;
6944 unsigned int i, size;
6945 HRESULT hr;
6947 hr = MFCreateMediaType(&mediatype);
6948 ok(hr == S_OK, "Failed to create mediatype, hr %#lx.\n", hr);
6950 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
6952 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
6953 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#lx.\n", i, waveformatex_tests[i].wFormatTag, hr);
6955 validate_media_type(mediatype, &waveformatex_tests[i]);
6957 waveformatext.Format = waveformatex_tests[i];
6958 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
6959 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
6960 waveformatext.Samples.wSamplesPerBlock = 123;
6961 waveformatext.dwChannelMask = 0x8;
6962 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
6963 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
6965 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
6966 ok(hr == S_OK, "Failed to initialize media type, hr %#lx.\n", hr);
6968 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
6969 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
6971 validate_media_type(mediatype, &waveformatext.Format);
6974 /* MPEGLAYER3WAVEFORMAT */
6975 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
6976 mp3format.wfx.nChannels = 2;
6977 mp3format.wfx.nSamplesPerSec = 44100;
6978 mp3format.wfx.nAvgBytesPerSec = 16000;
6979 mp3format.wfx.nBlockAlign = 1;
6980 mp3format.wfx.wBitsPerSample = 0;
6981 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
6982 mp3format.wID = MPEGLAYER3_ID_MPEG;
6983 mp3format.fdwFlags = 0;
6984 mp3format.nBlockSize = 417;
6985 mp3format.nFramesPerBlock = 0;
6986 mp3format.nCodecDelay = 0;
6988 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
6989 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6991 validate_media_type(mediatype, &mp3format.wfx);
6992 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
6993 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6994 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
6995 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
6997 IMFMediaType_Release(mediatype);
7000 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
7002 MFVIDEOFORMAT *video_format;
7003 IMFMediaType *media_type;
7004 UINT32 size;
7005 HRESULT hr;
7007 hr = MFCreateMediaType(&media_type);
7008 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
7010 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
7011 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7012 ok(!!video_format, "Unexpected format.\n");
7013 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
7014 CoTaskMemFree(video_format);
7016 IMFMediaType_Release(media_type);
7019 static void test_MFCreateDXSurfaceBuffer(void)
7021 IDirect3DSurface9 *backbuffer = NULL, *surface;
7022 IDirect3DSwapChain9 *swapchain;
7023 D3DLOCKED_RECT locked_rect;
7024 DWORD length, max_length;
7025 IDirect3DDevice9 *device;
7026 IMF2DBuffer2 *_2dbuffer2;
7027 BOOL value, broken_test;
7028 IMFMediaBuffer *buffer;
7029 IMF2DBuffer *_2dbuffer;
7030 BYTE *data, *data2;
7031 IMFGetService *gs;
7032 IDirect3D9 *d3d;
7033 DWORD color;
7034 HWND window;
7035 HRESULT hr;
7036 LONG pitch;
7038 if (!pMFCreateDXSurfaceBuffer)
7040 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
7041 return;
7044 window = create_window();
7045 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7046 ok(!!d3d, "Failed to create a D3D object.\n");
7047 if (!(device = create_d3d9_device(d3d, window)))
7049 skip("Failed to create a D3D device, skipping tests.\n");
7050 goto done;
7053 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
7054 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08lx)\n", hr);
7056 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7057 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08lx)\n", hr);
7058 ok(backbuffer != NULL, "The back buffer is NULL\n");
7060 IDirect3DSwapChain9_Release(swapchain);
7062 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
7063 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7065 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
7066 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7068 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7069 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7070 check_interface(buffer, &IID_IMFGetService, TRUE);
7072 /* Surface is accessible. */
7073 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
7074 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7075 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
7076 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7077 ok(surface == backbuffer, "Unexpected surface pointer.\n");
7078 IDirect3DSurface9_Release(surface);
7079 IMFGetService_Release(gs);
7081 max_length = 0;
7082 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
7083 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7084 ok(!!max_length, "Unexpected length %lu.\n", max_length);
7086 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
7087 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7088 ok(!length, "Unexpected length %lu.\n", length);
7090 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
7091 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7093 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
7094 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7095 ok(length == 2 * max_length, "Unexpected length %lu.\n", length);
7097 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
7098 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
7100 /* Cannot lock while the surface is locked. */
7101 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
7102 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
7104 hr = IDirect3DSurface9_UnlockRect(backbuffer);
7105 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
7107 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
7108 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7109 /* Broken on Windows 8 and 10 v1507 */
7110 broken_test = length == 0;
7111 ok(length == max_length || broken(broken_test), "Unexpected length %lu instead of %lu.\n", length, max_length);
7113 /* You can lock the surface while the media buffer is locked. */
7114 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
7115 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
7117 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
7118 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7120 hr = IMFMediaBuffer_Unlock(buffer);
7121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7123 hr = IDirect3DSurface9_UnlockRect(backbuffer);
7124 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
7126 /* Unlock twice. */
7127 hr = IMFMediaBuffer_Unlock(buffer);
7128 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
7130 hr = IMFMediaBuffer_Unlock(buffer);
7131 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7133 /* Lock twice. */
7134 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7135 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7137 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
7138 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7139 ok(data == data2, "Unexpected pointer.\n");
7141 hr = IMFMediaBuffer_Unlock(buffer);
7142 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7144 hr = IMFMediaBuffer_Unlock(buffer);
7145 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
7147 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
7148 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7150 /* Unlocked. */
7151 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
7152 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7154 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
7155 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
7157 /* Cannot lock the buffer while the surface is locked. */
7158 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7159 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
7161 hr = IDirect3DSurface9_UnlockRect(backbuffer);
7162 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
7164 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7165 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7167 /* Cannot lock the surface once the buffer is locked. */
7168 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
7169 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
7171 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
7172 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7174 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
7175 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
7177 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7180 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
7181 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7183 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
7184 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7186 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
7187 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7189 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7190 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7192 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7193 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
7195 hr = IMFMediaBuffer_Unlock(buffer);
7196 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
7198 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
7199 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7200 ok(!value, "Unexpected return value %d.\n", value);
7202 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
7203 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7204 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
7205 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7206 ok(length == max_length, "Unexpected length %lu.\n", length);
7208 IMF2DBuffer_Release(_2dbuffer);
7210 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
7211 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7213 /* Lock flags are ignored, so writing is allowed when locking for
7214 * reading and viceversa. */
7215 put_d3d9_surface_color(backbuffer, 0, 0, 0xcdcdcdcd);
7216 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7217 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7218 ok(data == data2, "Unexpected scanline pointer.\n");
7219 ok(data[0] == 0xcd, "Unexpected leading byte.\n");
7220 memset(data, 0xab, 4);
7221 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7223 color = get_d3d9_surface_color(backbuffer, 0, 0);
7224 ok(color == 0xabababab, "Unexpected leading dword.\n");
7225 put_d3d9_surface_color(backbuffer, 0, 0, 0xefefefef);
7227 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7228 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7229 ok(data[0] == 0xef, "Unexpected leading byte.\n");
7230 memset(data, 0x89, 4);
7231 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7233 color = get_d3d9_surface_color(backbuffer, 0, 0);
7234 ok(color == 0x89898989, "Unexpected leading dword.\n");
7236 /* Also, flags incompatibilities are not taken into account even
7237 * if a buffer is already locked. */
7238 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7239 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7240 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7241 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7242 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7244 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7245 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7246 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7247 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7248 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7249 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7250 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7251 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7252 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7253 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7254 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7255 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7256 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7257 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7259 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7260 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7261 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7262 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7263 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7264 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7265 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7266 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7267 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7268 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7269 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7271 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7272 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7273 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7274 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7275 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7277 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7278 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7280 /* Except when originally locking for writing. */
7281 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7282 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7283 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7284 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7285 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7286 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7287 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7288 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7289 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
7290 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7291 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7293 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7294 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7296 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7297 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7299 IMF2DBuffer2_Release(_2dbuffer2);
7301 IMFMediaBuffer_Release(buffer);
7302 IDirect3DDevice9_Release(device);
7304 done:
7305 if (backbuffer)
7306 IDirect3DSurface9_Release(backbuffer);
7307 ok(!IDirect3D9_Release(d3d), "Unexpected refcount.\n");
7308 DestroyWindow(window);
7311 static void test_MFCreateTrackedSample(void)
7313 IMFTrackedSample *tracked_sample;
7314 IMFSample *sample;
7315 IUnknown *unk;
7316 HRESULT hr;
7318 if (!pMFCreateTrackedSample)
7320 win_skip("MFCreateTrackedSample() is not available.\n");
7321 return;
7324 hr = pMFCreateTrackedSample(&tracked_sample);
7325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7327 /* It's actually a sample. */
7328 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
7329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7331 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
7332 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7333 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
7334 IUnknown_Release(unk);
7336 IMFSample_Release(sample);
7338 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
7340 IMFTrackedSample_Release(tracked_sample);
7343 static void test_MFFrameRateToAverageTimePerFrame(void)
7345 static const struct frame_rate_test
7347 unsigned int numerator;
7348 unsigned int denominator;
7349 UINT64 avgtime;
7350 } frame_rate_tests[] =
7352 { 60000, 1001, 166833 },
7353 { 30000, 1001, 333667 },
7354 { 24000, 1001, 417188 },
7355 { 60, 1, 166667 },
7356 { 30, 1, 333333 },
7357 { 50, 1, 200000 },
7358 { 25, 1, 400000 },
7359 { 24, 1, 416667 },
7361 { 39, 1, 256410 },
7362 { 120, 1, 83333 },
7364 unsigned int i;
7365 UINT64 avgtime;
7366 HRESULT hr;
7368 avgtime = 1;
7369 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
7370 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7371 ok(!avgtime, "Unexpected frame time.\n");
7373 avgtime = 1;
7374 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
7375 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7376 ok(!avgtime, "Unexpected frame time.\n");
7378 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
7380 avgtime = 0;
7381 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
7382 frame_rate_tests[i].denominator, &avgtime);
7383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7384 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
7385 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
7389 static void test_MFAverageTimePerFrameToFrameRate(void)
7391 static const struct frame_rate_test
7393 unsigned int numerator;
7394 unsigned int denominator;
7395 UINT64 avgtime;
7396 } frame_rate_tests[] =
7398 { 60000, 1001, 166833 },
7399 { 30000, 1001, 333667 },
7400 { 24000, 1001, 417188 },
7401 { 60, 1, 166667 },
7402 { 30, 1, 333333 },
7403 { 50, 1, 200000 },
7404 { 25, 1, 400000 },
7405 { 24, 1, 416667 },
7407 { 1000000, 25641, 256410 },
7408 { 10000000, 83333, 83333 },
7409 { 1, 10, 100000000 },
7410 { 1, 10, 100000001 },
7411 { 1, 10, 200000000 },
7412 { 1, 1, 10000000 },
7413 { 1, 2, 20000000 },
7414 { 5, 1, 2000000 },
7415 { 10, 1, 1000000 },
7417 unsigned int i, numerator, denominator;
7418 HRESULT hr;
7420 numerator = denominator = 1;
7421 hr = MFAverageTimePerFrameToFrameRate(0, &numerator, &denominator);
7422 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7423 ok(!numerator && !denominator, "Unexpected output %u/%u.\n", numerator, denominator);
7425 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
7427 numerator = denominator = 12345;
7428 hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
7429 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7430 ok(numerator == frame_rate_tests[i].numerator && denominator == frame_rate_tests[i].denominator,
7431 "%u: unexpected %u/%u, expected %u/%u.\n", i, numerator, denominator, frame_rate_tests[i].numerator,
7432 frame_rate_tests[i].denominator);
7436 static void test_MFMapDXGIFormatToDX9Format(void)
7438 static const struct format_pair
7440 DXGI_FORMAT dxgi_format;
7441 DWORD d3d9_format;
7443 formats_map[] =
7445 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
7446 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
7447 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
7448 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
7449 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
7450 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
7451 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
7452 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
7453 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
7454 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
7455 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
7456 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
7457 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
7458 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
7459 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
7460 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
7461 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
7462 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
7463 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
7464 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
7465 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
7466 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
7467 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
7468 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
7469 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
7470 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
7471 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
7472 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
7473 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
7474 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
7475 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
7476 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
7477 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
7478 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
7479 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
7480 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
7481 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
7482 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
7483 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
7484 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
7485 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
7486 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
7487 { DXGI_FORMAT_P8, D3DFMT_P8 },
7488 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
7490 unsigned int i;
7491 DWORD format;
7493 if (!pMFMapDXGIFormatToDX9Format)
7495 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
7496 return;
7499 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
7501 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
7502 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
7506 static void test_MFMapDX9FormatToDXGIFormat(void)
7508 static const struct format_pair
7510 DXGI_FORMAT dxgi_format;
7511 DWORD d3d9_format;
7513 formats_map[] =
7515 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
7516 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
7517 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
7518 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
7519 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
7520 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
7521 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
7522 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
7523 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
7524 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
7525 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
7526 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
7527 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
7528 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
7529 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
7530 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
7531 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
7532 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
7533 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
7534 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
7535 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
7536 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
7537 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
7538 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
7539 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
7540 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
7541 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
7542 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
7543 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
7544 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
7545 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
7546 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
7547 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
7548 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
7549 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
7550 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
7551 { DXGI_FORMAT_P8, D3DFMT_P8 },
7552 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
7554 DXGI_FORMAT format;
7555 unsigned int i;
7557 if (!pMFMapDX9FormatToDXGIFormat)
7559 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
7560 return;
7563 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
7565 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
7566 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#lx.\n",
7567 format, formats_map[i].d3d9_format);
7571 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
7572 REFIID riid, void **obj)
7574 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
7575 IsEqualIID(riid, &IID_IUnknown))
7577 *obj = iface;
7578 IMFVideoSampleAllocatorNotify_AddRef(iface);
7579 return S_OK;
7582 *obj = NULL;
7583 return E_NOINTERFACE;
7586 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
7588 return 2;
7591 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
7593 return 1;
7596 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
7598 return E_NOTIMPL;
7601 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
7603 test_notify_callback_QueryInterface,
7604 test_notify_callback_AddRef,
7605 test_notify_callback_Release,
7606 test_notify_callback_NotifyRelease,
7609 static IMFMediaType * create_video_type(const GUID *subtype)
7611 IMFMediaType *video_type;
7612 HRESULT hr;
7614 hr = MFCreateMediaType(&video_type);
7615 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7617 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
7618 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7620 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
7621 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7623 return video_type;
7626 static ID3D11Device *create_d3d11_device(void)
7628 static const D3D_FEATURE_LEVEL default_feature_level[] =
7630 D3D_FEATURE_LEVEL_11_0,
7631 D3D_FEATURE_LEVEL_10_1,
7632 D3D_FEATURE_LEVEL_10_0,
7634 const D3D_FEATURE_LEVEL *feature_level;
7635 unsigned int feature_level_count;
7636 ID3D11Device *device;
7638 feature_level = default_feature_level;
7639 feature_level_count = ARRAY_SIZE(default_feature_level);
7641 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
7642 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7643 return device;
7644 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
7645 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7646 return device;
7647 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
7648 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
7649 return device;
7651 return NULL;
7654 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
7655 const BYTE *data, unsigned int src_pitch)
7657 ID3D11DeviceContext *immediate_context;
7658 ID3D11Device *device;
7660 ID3D11Texture2D_GetDevice(texture, &device);
7661 ID3D11Device_GetImmediateContext(device, &immediate_context);
7663 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
7664 sub_resource_idx, NULL, data, src_pitch, 0);
7666 ID3D11DeviceContext_Release(immediate_context);
7667 ID3D11Device_Release(device);
7670 static ID3D12Device *create_d3d12_device(void)
7672 ID3D12Device *device;
7673 HRESULT hr;
7675 if (!pD3D12CreateDevice) return NULL;
7677 hr = pD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
7678 if (FAILED(hr))
7679 return NULL;
7681 return device;
7684 static void test_d3d11_surface_buffer(void)
7686 DWORD max_length, cur_length, length, color;
7687 BYTE *data, *data2, *buffer_start;
7688 IMFDXGIBuffer *dxgi_buffer;
7689 D3D11_TEXTURE2D_DESC desc;
7690 IMF2DBuffer2 *_2dbuffer2;
7691 ID3D11Texture2D *texture;
7692 IMF2DBuffer *_2d_buffer;
7693 IMFMediaBuffer *buffer;
7694 ID3D11Device *device;
7695 BYTE buff[64 * 64 * 4];
7696 LONG pitch, pitch2;
7697 UINT index, size;
7698 IUnknown *obj;
7699 HRESULT hr;
7701 if (!pMFCreateDXGISurfaceBuffer)
7703 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
7704 return;
7707 /* d3d11 */
7708 if (!(device = create_d3d11_device()))
7710 skip("Failed to create a D3D11 device, skipping tests.\n");
7711 return;
7714 memset(&desc, 0, sizeof(desc));
7715 desc.Width = 64;
7716 desc.Height = 64;
7717 desc.ArraySize = 1;
7718 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7719 desc.SampleDesc.Count = 1;
7720 desc.SampleDesc.Quality = 0;
7722 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7723 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7725 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
7726 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7728 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7729 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7730 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7731 check_interface(buffer, &IID_IMFGetService, FALSE);
7733 max_length = 0;
7734 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
7735 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7736 ok(!!max_length, "Unexpected length %lu.\n", max_length);
7738 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7739 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7740 ok(!cur_length, "Unexpected length %lu.\n", cur_length);
7742 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
7743 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7745 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7746 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7747 ok(cur_length == 2 * max_length, "Unexpected length %lu.\n", cur_length);
7749 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7750 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7752 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
7753 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7754 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
7755 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7756 ok(length == max_length, "Unexpected length %lu.\n", length);
7757 IMF2DBuffer_Release(_2d_buffer);
7759 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7760 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7762 EXPECT_REF(texture, 2);
7763 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
7764 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7765 EXPECT_REF(texture, 3);
7766 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
7767 IUnknown_Release(obj);
7769 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
7770 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7772 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
7773 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7774 ok(index == 0, "Unexpected subresource index.\n");
7776 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7777 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7779 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7780 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7782 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7783 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#lx.\n", hr);
7785 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
7786 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7788 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
7789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7790 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
7791 IUnknown_Release(obj);
7793 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7794 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7796 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
7797 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7799 IMFDXGIBuffer_Release(dxgi_buffer);
7801 /* Texture updates. */
7802 color = get_d3d11_texture_color(texture, 0, 0);
7803 ok(!color, "Unexpected texture color %#lx.\n", color);
7805 max_length = cur_length = 0;
7806 data = NULL;
7807 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7808 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7809 ok(max_length && max_length == cur_length, "Unexpected length %lu.\n", max_length);
7810 if (data) *(DWORD *)data = ~0u;
7812 color = get_d3d11_texture_color(texture, 0, 0);
7813 ok(!color, "Unexpected texture color %#lx.\n", color);
7815 hr = IMFMediaBuffer_Unlock(buffer);
7816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7818 color = get_d3d11_texture_color(texture, 0, 0);
7819 ok(color == ~0u, "Unexpected texture color %#lx.\n", color);
7821 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7822 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7823 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#lx.\n", *(DWORD *)data);
7825 hr = IMFMediaBuffer_Unlock(buffer);
7826 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7828 /* Lock2D()/Unlock2D() */
7829 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7830 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7832 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7833 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7835 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7836 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7837 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7839 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7841 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7843 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7844 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7845 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7847 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7848 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
7850 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7851 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7853 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7854 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7856 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7857 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7859 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7860 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7862 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7863 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
7865 hr = IMFMediaBuffer_Unlock(buffer);
7866 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7868 IMF2DBuffer_Release(_2d_buffer);
7870 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
7871 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7873 /* Lock flags are honored, so reads and writes are discarded if
7874 * the flags are not correct. Also, previous content is discarded
7875 * when locking for writing and not for reading. */
7876 put_d3d11_texture_color(texture, 0, 0, 0xcdcdcdcd);
7877 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7878 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7879 ok(data == data2, "Unexpected scanline pointer.\n");
7880 ok(*(DWORD *)data == 0xcdcdcdcd, "Unexpected leading dword %#lx.\n", *(DWORD *)data);
7881 memset(data, 0xab, 4);
7882 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7884 color = get_d3d11_texture_color(texture, 0, 0);
7885 ok(color == 0xcdcdcdcd, "Unexpected leading dword %#lx.\n", color);
7886 put_d3d11_texture_color(texture, 0, 0, 0xefefefef);
7888 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7889 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7890 ok(*(DWORD *)data != 0xefefefef, "Unexpected leading dword.\n");
7891 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7893 color = get_d3d11_texture_color(texture, 0, 0);
7894 ok(color != 0xefefefef, "Unexpected leading dword.\n");
7896 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7897 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7898 ok(*(DWORD *)data != 0xefefefef, "Unexpected leading dword.\n");
7899 memset(data, 0x89, 4);
7900 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7902 color = get_d3d11_texture_color(texture, 0, 0);
7903 ok(color == 0x89898989, "Unexpected leading dword %#lx.\n", color);
7905 /* When relocking for writing, stores are committed even if they
7906 * were issued before relocking. */
7907 put_d3d11_texture_color(texture, 0, 0, 0xcdcdcdcd);
7908 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7909 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7910 memset(data, 0xab, 4);
7911 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7912 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7913 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7914 IMF2DBuffer2_Unlock2D(_2dbuffer2);
7916 color = get_d3d11_texture_color(texture, 0, 0);
7917 ok(color == 0xabababab, "Unexpected leading dword %#lx.\n", color);
7919 /* Flags incompatibilities. */
7920 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7921 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7922 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7923 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7924 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7925 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7926 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7927 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7928 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7929 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7930 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7932 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7933 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7934 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7935 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7936 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7937 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7938 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7939 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7941 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7942 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7943 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7944 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7945 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7946 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7947 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7948 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7949 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7950 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7951 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7952 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7953 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7955 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7956 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7957 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7958 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7959 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7960 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7962 /* Except when originally locking for writing. */
7963 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7964 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7965 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
7966 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7967 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
7968 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7969 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
7970 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7971 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7972 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_LOCKED), "Unexpected hr %#lx.\n", hr);
7973 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7974 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7975 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7976 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7978 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
7979 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7981 IMF2DBuffer2_Release(_2dbuffer2);
7982 IMFMediaBuffer_Release(buffer);
7984 /* Bottom up. */
7985 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
7986 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7988 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7989 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7991 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7992 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7993 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7995 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7996 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7997 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7999 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
8000 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8002 IMF2DBuffer_Release(_2d_buffer);
8003 IMFMediaBuffer_Release(buffer);
8005 ID3D11Texture2D_Release(texture);
8007 memset(&desc, 0, sizeof(desc));
8008 desc.Width = 64;
8009 desc.Height = 64;
8010 desc.ArraySize = 1;
8011 desc.MipLevels = 1;
8012 desc.Format = DXGI_FORMAT_NV12;
8013 desc.SampleDesc.Count = 1;
8014 desc.SampleDesc.Quality = 0;
8016 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
8017 if (SUCCEEDED(hr))
8019 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
8020 ok(hr == S_OK, "got %#lx.\n", hr);
8021 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
8022 ok(hr == S_OK, "got %#lx.\n", hr);
8024 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &buffer_start, &length);
8025 ok(hr == S_OK, "got %#lx.\n", hr);
8027 ok(pitch >= desc.Width, "got %ld.\n", pitch);
8028 ok(length == pitch * desc.Height * 3 / 2, "got %lu.\n", length);
8030 hr = IMF2DBuffer2_Unlock2D(_2dbuffer2);
8031 ok(hr == S_OK, "got %#lx.\n", hr);
8033 IMF2DBuffer2_Release(_2dbuffer2);
8034 IMFMediaBuffer_Release(buffer);
8035 ID3D11Texture2D_Release(texture);
8037 else
8039 win_skip("Failed to create NV12 texture, hr %#lx, skipping test.\n", hr);
8040 ID3D11Device_Release(device);
8041 return;
8044 /* Subresource index 1.
8045 * When WARP d3d11 device is used, this test leaves the device in a broken state, so it should
8046 * be kept last. */
8047 memset(&desc, 0, sizeof(desc));
8048 desc.Width = 64;
8049 desc.Height = 64;
8050 desc.ArraySize = 1;
8051 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
8052 desc.SampleDesc.Count = 1;
8053 desc.SampleDesc.Quality = 0;
8055 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
8056 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
8058 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
8059 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
8061 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
8062 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8064 /* Pitch reflects top level. */
8065 memset(buff, 0, sizeof(buff));
8066 *(DWORD *)buff = 0xff00ff00;
8067 update_d3d11_texture(texture, 1, buff, 64 * 4);
8069 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
8070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8071 ok(pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
8072 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#lx.\n", *(DWORD *)data);
8074 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
8075 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8077 IMF2DBuffer_Release(_2d_buffer);
8078 IMFMediaBuffer_Release(buffer);
8079 ID3D11Texture2D_Release(texture);
8081 ID3D11Device_Release(device);
8084 static void test_d3d12_surface_buffer(void)
8086 IMFDXGIBuffer *dxgi_buffer;
8087 D3D12_HEAP_PROPERTIES heap_props;
8088 D3D12_RESOURCE_DESC desc;
8089 ID3D12Resource *resource;
8090 IMFMediaBuffer *buffer;
8091 unsigned int refcount;
8092 ID3D12Device *device;
8093 IUnknown *obj;
8094 HRESULT hr;
8096 /* d3d12 */
8097 if (!(device = create_d3d12_device()))
8099 skip("Failed to create a D3D12 device, skipping tests.\n");
8100 return;
8103 memset(&heap_props, 0, sizeof(heap_props));
8104 heap_props.Type = D3D12_HEAP_TYPE_DEFAULT;
8106 memset(&desc, 0, sizeof(desc));
8107 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
8108 desc.Alignment = 0;
8109 desc.Width = 32;
8110 desc.Height = 32;
8111 desc.DepthOrArraySize = 1;
8112 desc.MipLevels = 1;
8113 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
8114 desc.SampleDesc.Count = 1;
8115 desc.SampleDesc.Quality = 0;
8116 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
8117 desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
8119 hr = ID3D12Device_CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE,
8120 &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&resource);
8121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8123 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D12Resource, (IUnknown *)resource, 0, FALSE, &buffer);
8124 if (hr == E_INVALIDARG)
8126 todo_wine
8127 win_skip("D3D12 resource buffers are not supported.\n");
8128 goto notsupported;
8130 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
8132 if (SUCCEEDED(hr))
8134 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8135 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8136 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8137 check_interface(buffer, &IID_IMFGetService, FALSE);
8139 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8140 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8142 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&obj);
8143 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8144 ok(obj == (IUnknown *)resource, "Unexpected resource pointer.\n");
8145 IUnknown_Release(obj);
8147 IMFDXGIBuffer_Release(dxgi_buffer);
8148 IMFMediaBuffer_Release(buffer);
8151 notsupported:
8152 ID3D12Resource_Release(resource);
8153 refcount = ID3D12Device_Release(device);
8154 ok(!refcount, "Unexpected device refcount %u.\n", refcount);
8157 static void test_sample_allocator_sysmem(void)
8159 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
8160 IMFMediaType *media_type, *video_type, *video_type2;
8161 IMFVideoSampleAllocatorCallback *allocator_cb;
8162 IMFVideoSampleAllocatorEx *allocatorex;
8163 IMFVideoSampleAllocator *allocator;
8164 IMFSample *sample, *sample2;
8165 IMFAttributes *attributes;
8166 IMFMediaBuffer *buffer;
8167 LONG refcount, count;
8168 DWORD buffer_count;
8169 IUnknown *unk;
8170 HRESULT hr;
8172 if (!pMFCreateVideoSampleAllocatorEx)
8173 return;
8175 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
8176 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8178 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
8179 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
8180 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
8182 IUnknown_Release(unk);
8184 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8185 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8187 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
8188 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8190 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
8191 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8193 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
8194 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8196 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
8197 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8199 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
8200 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8202 count = 10;
8203 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8204 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8205 ok(!count, "Unexpected count %ld.\n", count);
8207 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
8208 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8210 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8211 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
8213 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
8214 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8216 hr = MFCreateMediaType(&media_type);
8217 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8219 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
8220 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8222 video_type = create_video_type(&MFVideoFormat_RGB32);
8223 video_type2 = create_video_type(&MFVideoFormat_RGB32);
8225 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
8226 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
8228 /* Frame size is required. */
8229 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
8230 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8232 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
8233 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8235 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
8236 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8238 EXPECT_REF(video_type, 1);
8239 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8240 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8241 EXPECT_REF(video_type, 2);
8243 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
8244 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8246 /* Setting identical type does not replace it. */
8247 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
8248 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8249 EXPECT_REF(video_type, 2);
8250 EXPECT_REF(video_type2, 1);
8252 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8253 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8255 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
8256 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8257 EXPECT_REF(video_type2, 2);
8258 EXPECT_REF(video_type, 1);
8260 /* Modify referenced type. */
8261 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
8262 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8264 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8265 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8266 EXPECT_REF(video_type, 2);
8267 EXPECT_REF(video_type2, 1);
8269 count = 0;
8270 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8271 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8272 ok(count == 1, "Unexpected count %ld.\n", count);
8274 sample = NULL;
8275 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8277 refcount = get_refcount(sample);
8279 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8281 ok(!count, "Unexpected count %ld.\n", count);
8283 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
8284 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
8286 /* Reinitialize with active sample. */
8287 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
8288 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8289 ok(refcount == get_refcount(sample), "Unexpected refcount %lu.\n", get_refcount(sample));
8290 EXPECT_REF(video_type, 2);
8292 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8293 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8294 todo_wine
8295 ok(!count, "Unexpected count %ld.\n", count);
8297 check_interface(sample, &IID_IMFTrackedSample, TRUE);
8298 check_interface(sample, &IID_IMFDesiredSample, FALSE);
8300 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8303 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8304 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8305 check_interface(buffer, &IID_IMFGetService, TRUE);
8306 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
8308 IMFMediaBuffer_Release(buffer);
8310 hr = IMFSample_GetBufferCount(sample, &buffer_count);
8311 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8312 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
8314 IMFSample_Release(sample);
8316 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
8317 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8318 todo_wine
8319 EXPECT_REF(video_type, 2);
8321 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8322 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8323 ok(!count, "Unexpected count %ld.\n", count);
8325 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8326 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
8328 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
8329 IMFVideoSampleAllocator_Release(allocator);
8331 /* IMFVideoSampleAllocatorEx */
8332 hr = MFCreateAttributes(&attributes, 0);
8333 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8335 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8336 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8338 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
8339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8341 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
8342 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8344 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
8345 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8347 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8348 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
8350 EXPECT_REF(attributes, 1);
8351 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8352 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8353 EXPECT_REF(attributes, 2);
8355 count = 0;
8356 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
8357 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8358 ok(count == 1, "Unexpected count %ld.\n", count);
8360 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8361 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8363 hr = IMFSample_GetBufferCount(sample, &buffer_count);
8364 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8365 ok(buffer_count == 2, "Unexpected buffer count %lu.\n", buffer_count);
8367 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
8368 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
8370 /* Reinitialize with already allocated samples. */
8371 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
8372 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8373 EXPECT_REF(attributes, 1);
8375 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
8376 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8377 IMFSample_Release(sample2);
8379 IMFSample_Release(sample);
8381 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
8382 IMFVideoSampleAllocatorEx_Release(allocatorex);
8383 IMFAttributes_Release(attributes);
8386 static void test_sample_allocator_d3d9(void)
8388 IDirect3DDeviceManager9 *d3d9_manager;
8389 IMFVideoSampleAllocator *allocator;
8390 IDirect3DDevice9 *d3d9_device;
8391 IMFMediaType *video_type;
8392 IMFMediaBuffer *buffer;
8393 unsigned int token;
8394 IMFSample *sample;
8395 IDirect3D9 *d3d9;
8396 HWND window;
8397 HRESULT hr;
8399 if (!pMFCreateVideoSampleAllocatorEx)
8400 return;
8402 window = create_window();
8403 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8404 ok(!!d3d9, "Failed to create a D3D9 object.\n");
8405 if (!(d3d9_device = create_d3d9_device(d3d9, window)))
8407 skip("Failed to create a D3D9 device, skipping tests.\n");
8408 goto done;
8411 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
8412 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8414 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
8415 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8417 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8418 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8420 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
8421 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8423 video_type = create_video_type(&MFVideoFormat_RGB32);
8425 /* Frame size is required. */
8426 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8427 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8429 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8430 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8432 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8433 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8435 check_interface(sample, &IID_IMFTrackedSample, TRUE);
8436 check_interface(sample, &IID_IMFDesiredSample, FALSE);
8438 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8439 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8441 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8442 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8443 check_interface(buffer, &IID_IMFGetService, TRUE);
8444 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
8446 IMFSample_Release(sample);
8447 IMFMediaBuffer_Release(buffer);
8449 IMFVideoSampleAllocator_Release(allocator);
8450 IMFMediaType_Release(video_type);
8451 IDirect3DDeviceManager9_Release(d3d9_manager);
8452 IDirect3DDevice9_Release(d3d9_device);
8454 done:
8455 IDirect3D9_Release(d3d9);
8456 DestroyWindow(window);
8459 static void test_sample_allocator_d3d11(void)
8461 IMFMediaType *video_type;
8462 IMFVideoSampleAllocatorEx *allocatorex;
8463 IMFVideoSampleAllocator *allocator;
8464 unsigned int i, token;
8465 IMFDXGIDeviceManager *manager;
8466 IMFSample *sample;
8467 IMFDXGIBuffer *dxgi_buffer;
8468 IMFAttributes *attributes;
8469 D3D11_TEXTURE2D_DESC desc;
8470 ID3D11Texture2D *texture;
8471 IMFMediaBuffer *buffer;
8472 ID3D11Device *device;
8473 HRESULT hr;
8474 BYTE *data;
8475 static const unsigned int usage[] =
8477 D3D11_USAGE_DEFAULT,
8478 D3D11_USAGE_IMMUTABLE,
8479 D3D11_USAGE_DYNAMIC,
8480 D3D11_USAGE_STAGING,
8481 D3D11_USAGE_STAGING + 1,
8483 static const unsigned int sharing[] =
8485 D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
8486 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
8487 D3D11_RESOURCE_MISC_SHARED,
8490 if (!pMFCreateVideoSampleAllocatorEx)
8491 return;
8493 if (!(device = create_d3d11_device()))
8495 skip("Failed to create a D3D11 device, skipping tests.\n");
8496 return;
8499 hr = pMFCreateDXGIDeviceManager(&token, &manager);
8500 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
8502 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
8503 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
8505 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8506 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8508 EXPECT_REF(manager, 1);
8509 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
8510 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8511 EXPECT_REF(manager, 2);
8513 video_type = create_video_type(&MFVideoFormat_RGB32);
8514 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8517 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8518 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8520 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8521 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8523 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8526 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8527 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8528 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8529 check_interface(buffer, &IID_IMFGetService, FALSE);
8531 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8532 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8534 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8535 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8537 ID3D11Texture2D_GetDesc(texture, &desc);
8538 ok(desc.Width == 64, "Unexpected width %u.\n", desc.Width);
8539 ok(desc.Height == 64, "Unexpected height %u.\n", desc.Height);
8540 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
8541 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
8542 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
8543 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
8544 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
8545 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
8546 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
8547 desc.BindFlags);
8548 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8549 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
8551 ID3D11Texture2D_Release(texture);
8552 IMFDXGIBuffer_Release(dxgi_buffer);
8554 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
8555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8557 hr = IMFMediaBuffer_Unlock(buffer);
8558 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8560 IMFMediaBuffer_Release(buffer);
8561 IMFSample_Release(sample);
8563 IMFVideoSampleAllocator_Release(allocator);
8565 /* MF_SA_D3D11_USAGE */
8566 hr = MFCreateAttributes(&attributes, 1);
8567 ok(hr == S_OK, "Failed to create attributes, hr %#lx.\n", hr);
8569 for (i = 0; i < ARRAY_SIZE(usage); ++i)
8571 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8572 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8574 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
8575 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8577 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
8578 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8580 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8581 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
8583 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8584 IMFVideoSampleAllocatorEx_Release(allocatorex);
8585 continue;
8587 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", usage[i], hr);
8589 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
8590 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8592 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8593 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8595 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8598 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8599 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8601 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8602 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8604 ID3D11Texture2D_GetDesc(texture, &desc);
8605 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
8606 if (usage[i] == D3D11_USAGE_DEFAULT)
8608 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
8609 desc.BindFlags);
8610 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8612 else if (usage[i] == D3D11_USAGE_DYNAMIC)
8614 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
8615 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
8617 else if (usage[i] == D3D11_USAGE_STAGING)
8619 ok(!desc.BindFlags, "Unexpected bind flags %#x.\n", desc.BindFlags);
8620 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
8621 desc.CPUAccessFlags);
8623 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
8625 ID3D11Texture2D_Release(texture);
8626 IMFDXGIBuffer_Release(dxgi_buffer);
8627 IMFMediaBuffer_Release(buffer);
8629 IMFSample_Release(sample);
8631 IMFVideoSampleAllocatorEx_Release(allocatorex);
8634 /* MF_SA_D3D11_SHARED, MF_SA_D3D11_SHARED_WITHOUT_MUTEX */
8635 for (i = 0; i < ARRAY_SIZE(sharing); ++i)
8637 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
8638 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8640 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
8641 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8643 hr = IMFAttributes_DeleteAllItems(attributes);
8644 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8646 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
8647 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8649 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
8651 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED, TRUE);
8652 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8655 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED)
8657 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
8658 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
8661 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
8662 if (sharing[i] == (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED))
8664 todo_wine
8665 ok(hr == E_INVALIDARG, "%u: Unexpected hr %#lx.\n", i, hr);
8666 IMFVideoSampleAllocatorEx_Release(allocatorex);
8667 continue;
8669 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", i, hr);
8671 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
8672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8674 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8675 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8677 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8678 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8680 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
8681 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8683 ID3D11Texture2D_GetDesc(texture, &desc);
8684 ok(desc.MiscFlags == sharing[i], "%u: unexpected misc flags %#x.\n", i, desc.MiscFlags);
8686 ID3D11Texture2D_Release(texture);
8687 IMFDXGIBuffer_Release(dxgi_buffer);
8688 IMFMediaBuffer_Release(buffer);
8690 IMFSample_Release(sample);
8692 IMFVideoSampleAllocatorEx_Release(allocatorex);
8695 IMFAttributes_Release(attributes);
8697 IMFDXGIDeviceManager_Release(manager);
8698 ID3D11Device_Release(device);
8701 static void test_sample_allocator_d3d12(void)
8703 IMFVideoSampleAllocator *allocator = NULL;
8704 D3D12_HEAP_PROPERTIES heap_props;
8705 IMFDXGIDeviceManager *manager;
8706 D3D12_HEAP_FLAGS heap_flags;
8707 IMFDXGIBuffer *dxgi_buffer;
8708 IMFMediaType *video_type;
8709 ID3D12Resource *resource;
8710 D3D12_RESOURCE_DESC desc;
8711 IMFMediaBuffer *buffer;
8712 ID3D12Device *device;
8713 unsigned int token;
8714 IMFSample *sample;
8715 HRESULT hr;
8717 if (!(device = create_d3d12_device()))
8719 skip("Failed to create a D3D12 device, skipping tests.\n");
8720 return;
8723 hr = pMFCreateDXGIDeviceManager(&token, &manager);
8724 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
8726 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
8727 if (FAILED(hr))
8729 win_skip("Device manager does not support D3D12 devices.\n");
8730 goto done;
8732 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
8734 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
8735 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8737 EXPECT_REF(manager, 1);
8738 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
8739 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8740 EXPECT_REF(manager, 2);
8742 video_type = create_video_type(&MFVideoFormat_RGB32);
8743 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
8744 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8745 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_D3D_RESOURCE_VERSION, MF_D3D12_RESOURCE);
8746 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8748 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
8749 todo_wine
8750 ok(hr == S_OK || broken(hr == MF_E_UNEXPECTED) /* Some Win10 versions fail. */, "Unexpected hr %#lx.\n", hr);
8751 if (FAILED(hr)) goto done;
8753 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
8754 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8756 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
8757 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8759 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
8760 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
8761 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
8762 check_interface(buffer, &IID_IMFGetService, FALSE);
8764 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
8765 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
8767 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&resource);
8768 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
8770 resource->lpVtbl->GetDesc(resource, &desc);
8771 ok(desc.Width == 64, "Unexpected width.\n");
8772 ok(desc.Height == 64, "Unexpected height.\n");
8773 ok(desc.DepthOrArraySize == 1, "Unexpected array size %u.\n", desc.DepthOrArraySize);
8774 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
8775 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
8776 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
8777 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
8778 ok(!desc.Layout, "Unexpected layout %u.\n", desc.Layout);
8779 ok(!desc.Flags, "Unexpected flags %#x.\n", desc.Flags);
8781 hr = ID3D12Resource_GetHeapProperties(resource, &heap_props, &heap_flags);
8782 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8783 ok(heap_props.Type == D3D12_HEAP_TYPE_DEFAULT, "Unexpected heap type %u.\n", heap_props.Type);
8784 ok(heap_props.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN, "Unexpected page property %u.\n",
8785 heap_props.CPUPageProperty);
8786 ok(!heap_props.MemoryPoolPreference, "Unexpected pool preference %u.\n", heap_props.MemoryPoolPreference);
8787 ok(heap_flags == D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, "Unexpected heap flags %#x.\n", heap_flags);
8789 ID3D12Resource_Release(resource);
8790 IMFDXGIBuffer_Release(dxgi_buffer);
8791 IMFMediaBuffer_Release(buffer);
8792 IMFSample_Release(sample);
8794 done:
8795 if (allocator)
8796 IMFVideoSampleAllocator_Release(allocator);
8797 IMFDXGIDeviceManager_Release(manager);
8798 ID3D12Device_Release(device);
8801 static void test_MFLockSharedWorkQueue(void)
8803 DWORD taskid, queue, queue2;
8804 HRESULT hr;
8806 if (!pMFLockSharedWorkQueue)
8808 win_skip("MFLockSharedWorkQueue() is not available.\n");
8809 return;
8812 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
8813 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
8815 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
8816 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8818 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
8819 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
8821 taskid = 0;
8822 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
8823 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8825 queue = 0;
8826 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
8827 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
8829 queue2 = 0;
8830 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
8831 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8832 ok(queue == queue2, "Unexpected queue %#lx.\n", queue2);
8834 hr = MFUnlockWorkQueue(queue2);
8835 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8837 hr = MFUnlockWorkQueue(queue);
8838 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8840 hr = MFShutdown();
8841 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
8844 static void test_MFllMulDiv(void)
8846 /* (a * b + d) / c */
8847 static const struct muldivtest
8849 LONGLONG a;
8850 LONGLONG b;
8851 LONGLONG c;
8852 LONGLONG d;
8853 LONGLONG result;
8855 muldivtests[] =
8857 { 0, 0, 0, 0, _I64_MAX },
8858 { 1000000, 1000000, 2, 0, 500000000000 },
8859 { _I64_MAX, 3, _I64_MAX, 0, 3 },
8860 { _I64_MAX, 3, _I64_MAX, 1, 3 },
8861 { -10000, 3, 100, 0, -300 },
8862 { 2, 0, 3, 5, 1 },
8863 { 2, 1, 1, -3, -1 },
8864 /* a * b product does not fit in uint64_t */
8865 { _I64_MAX, 4, 8, 0, _I64_MAX / 2 },
8866 /* Large a * b product, large denominator */
8867 { _I64_MAX, 4, 0x100000000, 0, 0x1ffffffff },
8869 unsigned int i;
8871 for (i = 0; i < ARRAY_SIZE(muldivtests); ++i)
8873 LONGLONG result;
8875 result = MFllMulDiv(muldivtests[i].a, muldivtests[i].b, muldivtests[i].c, muldivtests[i].d);
8876 ok(result == muldivtests[i].result, "%u: unexpected result %s, expected %s.\n", i,
8877 wine_dbgstr_longlong(result), wine_dbgstr_longlong(muldivtests[i].result));
8881 static void test_shared_dxgi_device_manager(void)
8883 IMFDXGIDeviceManager *manager;
8884 HRESULT hr;
8885 UINT token;
8887 if (!pMFLockDXGIDeviceManager)
8889 win_skip("Shared DXGI device manager is not supported.\n");
8890 return;
8893 hr = pMFUnlockDXGIDeviceManager();
8894 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8896 manager = NULL;
8897 hr = pMFLockDXGIDeviceManager(NULL, &manager);
8898 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8899 ok(!!manager, "Unexpected instance.\n");
8901 hr = pMFLockDXGIDeviceManager(&token, &manager);
8902 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8904 EXPECT_REF(manager, 3);
8906 hr = pMFUnlockDXGIDeviceManager();
8907 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8909 EXPECT_REF(manager, 2);
8911 hr = pMFUnlockDXGIDeviceManager();
8912 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8915 static void check_video_format(const MFVIDEOFORMAT *format, unsigned int width, unsigned int height,
8916 DWORD d3dformat)
8918 unsigned int transfer_function;
8919 GUID guid;
8921 if (!d3dformat) d3dformat = D3DFMT_X8R8G8B8;
8923 switch (d3dformat)
8925 case D3DFMT_X8R8G8B8:
8926 case D3DFMT_R8G8B8:
8927 case D3DFMT_A8R8G8B8:
8928 case D3DFMT_R5G6B5:
8929 case D3DFMT_X1R5G5B5:
8930 case D3DFMT_A2B10G10R10:
8931 case D3DFMT_P8:
8932 transfer_function = MFVideoTransFunc_sRGB;
8933 break;
8934 default:
8935 transfer_function = MFVideoTransFunc_10;
8938 memcpy(&guid, &MFVideoFormat_Base, sizeof(guid));
8939 guid.Data1 = d3dformat;
8941 ok(format->dwSize == sizeof(*format), "Unexpected format size.\n");
8942 ok(format->videoInfo.dwWidth == width, "Unexpected width %lu.\n", format->videoInfo.dwWidth);
8943 ok(format->videoInfo.dwHeight == height, "Unexpected height %lu.\n", format->videoInfo.dwHeight);
8944 ok(format->videoInfo.PixelAspectRatio.Numerator == 1 &&
8945 format->videoInfo.PixelAspectRatio.Denominator == 1, "Unexpected PAR.\n");
8946 ok(format->videoInfo.SourceChromaSubsampling == MFVideoChromaSubsampling_Unknown, "Unexpected chroma subsampling.\n");
8947 ok(format->videoInfo.InterlaceMode == MFVideoInterlace_Progressive, "Unexpected interlace mode %u.\n",
8948 format->videoInfo.InterlaceMode);
8949 ok(format->videoInfo.TransferFunction == transfer_function, "Unexpected transfer function %u.\n",
8950 format->videoInfo.TransferFunction);
8951 ok(format->videoInfo.ColorPrimaries == MFVideoPrimaries_BT709, "Unexpected color primaries %u.\n",
8952 format->videoInfo.ColorPrimaries);
8953 ok(format->videoInfo.TransferMatrix == MFVideoTransferMatrix_Unknown, "Unexpected transfer matrix.\n");
8954 ok(format->videoInfo.SourceLighting == MFVideoLighting_office, "Unexpected source lighting %u.\n",
8955 format->videoInfo.SourceLighting);
8956 ok(format->videoInfo.FramesPerSecond.Numerator == 60 &&
8957 format->videoInfo.FramesPerSecond.Denominator == 1, "Unexpected frame rate %lu/%lu.\n",
8958 format->videoInfo.FramesPerSecond.Numerator, format->videoInfo.FramesPerSecond.Denominator);
8959 ok(format->videoInfo.NominalRange == MFNominalRange_Normal, "Unexpected nominal range %u.\n",
8960 format->videoInfo.NominalRange);
8961 ok(format->videoInfo.GeometricAperture.Area.cx == width && format->videoInfo.GeometricAperture.Area.cy == height,
8962 "Unexpected geometric aperture.\n");
8963 ok(!memcmp(&format->videoInfo.GeometricAperture, &format->videoInfo.MinimumDisplayAperture, sizeof(MFVideoArea)),
8964 "Unexpected minimum display aperture.\n");
8965 ok(format->videoInfo.PanScanAperture.Area.cx == 0 && format->videoInfo.PanScanAperture.Area.cy == 0,
8966 "Unexpected geometric aperture.\n");
8967 ok(format->videoInfo.VideoFlags == 0, "Unexpected video flags.\n");
8968 ok(IsEqualGUID(&format->guidFormat, &guid), "Unexpected format guid %s.\n", wine_dbgstr_guid(&format->guidFormat));
8969 ok(format->compressedInfo.AvgBitrate == 0, "Unexpected bitrate.\n");
8970 ok(format->compressedInfo.AvgBitErrorRate == 0, "Unexpected error bitrate.\n");
8971 ok(format->compressedInfo.MaxKeyFrameSpacing == 0, "Unexpected MaxKeyFrameSpacing.\n");
8972 ok(format->surfaceInfo.Format == d3dformat, "Unexpected format %lu.\n", format->surfaceInfo.Format);
8973 ok(format->surfaceInfo.PaletteEntries == 0, "Unexpected palette size %lu.\n", format->surfaceInfo.PaletteEntries);
8976 static void test_MFInitVideoFormat_RGB(void)
8978 static const DWORD formats[] =
8980 0, /* same D3DFMT_X8R8G8B8 */
8981 D3DFMT_X8R8G8B8,
8982 D3DFMT_R8G8B8,
8983 D3DFMT_A8R8G8B8,
8984 D3DFMT_R5G6B5,
8985 D3DFMT_X1R5G5B5,
8986 D3DFMT_A2B10G10R10,
8987 D3DFMT_P8,
8988 D3DFMT_L8,
8989 D3DFMT_YUY2,
8990 D3DFMT_DXT1,
8991 D3DFMT_D16,
8992 D3DFMT_L16,
8993 D3DFMT_A16B16G16R16F,
8995 MFVIDEOFORMAT format;
8996 unsigned int i;
8997 HRESULT hr;
8999 if (!pMFInitVideoFormat_RGB)
9001 win_skip("MFInitVideoFormat_RGB is not available.\n");
9002 return;
9005 hr = pMFInitVideoFormat_RGB(NULL, 64, 32, 0);
9006 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9008 for (i = 0; i < ARRAY_SIZE(formats); ++i)
9010 memset(&format, 0, sizeof(format));
9011 hr = pMFInitVideoFormat_RGB(&format, 64, 32, formats[i]);
9012 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9013 if (SUCCEEDED(hr))
9014 check_video_format(&format, 64, 32, formats[i]);
9018 static void test_MFCreateVideoMediaTypeFromVideoInfoHeader(void)
9020 IMFVideoMediaType *media_type;
9021 KS_VIDEOINFOHEADER vih;
9022 UINT32 value32;
9023 UINT64 value64;
9024 HRESULT hr;
9025 GUID guid;
9027 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(NULL, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
9028 todo_wine
9029 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9031 memset(&vih, 0, sizeof(vih));
9032 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, 0, 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
9033 todo_wine
9034 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9035 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
9036 todo_wine
9037 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9038 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
9039 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 0, 0, MFVideoInterlace_Unknown, 0, NULL, &media_type);
9040 todo_wine
9041 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9043 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
9044 vih.bmiHeader.biPlanes = 1;
9045 vih.bmiHeader.biWidth = 16;
9046 vih.bmiHeader.biHeight = 32;
9047 vih.bmiHeader.biBitCount = 32;
9049 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
9050 MFVideoFlag_AnalogProtected, &GUID_NULL, &media_type);
9051 todo_wine
9052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9053 if (FAILED(hr)) return;
9054 IMFVideoMediaType_Release(media_type);
9056 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
9057 MFVideoFlag_AnalogProtected, NULL, &media_type);
9058 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9060 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9061 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9062 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9063 hr = IMFVideoMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9064 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9065 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9066 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9067 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9068 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
9069 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9071 ok(value64 == ((UINT64)3 << 32 | 2), "Unexpected value %#I64x.\n", value64);
9072 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DRM_FLAGS, &value32);
9073 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9074 ok(value32 == MFVideoDRMFlag_AnalogProtected, "Unexpected value %#x.\n", value32);
9075 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9076 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9077 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9078 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9079 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9080 ok(value32 == 2048, "Unexpected value %u.\n", value32);
9081 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9082 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9083 ok(value32 == -64, "Unexpected value %d.\n", value32);
9084 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9085 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9086 ok(!!value32, "Unexpected value %#x.\n", value32);
9087 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9088 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9089 ok(!!value32, "Unexpected value %#x.\n", value32);
9091 IMFVideoMediaType_Release(media_type);
9093 /* Negative height. */
9094 vih.bmiHeader.biHeight = -32;
9095 hr = MFCreateVideoMediaTypeFromVideoInfoHeader(&vih, sizeof(vih), 3, 2, MFVideoInterlace_Progressive,
9096 MFVideoFlag_AnalogProtected, NULL, &media_type);
9097 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9098 hr = IMFVideoMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9100 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
9101 hr = IMFVideoMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9102 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9103 ok(value32 == 64, "Unexpected value %d.\n", value32);
9104 IMFVideoMediaType_Release(media_type);
9107 static void test_MFInitMediaTypeFromVideoInfoHeader(void)
9109 IMFMediaType *media_type;
9110 VIDEOINFOHEADER vih;
9111 UINT32 value32;
9112 UINT64 value64;
9113 HRESULT hr;
9114 GUID guid;
9116 hr = MFCreateMediaType(&media_type);
9117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9119 memset(&vih, 0, sizeof(vih));
9120 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, 0, NULL);
9121 todo_wine
9122 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9123 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
9124 todo_wine
9125 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
9127 vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
9128 vih.bmiHeader.biPlanes = 1;
9129 vih.bmiHeader.biWidth = 16;
9130 vih.bmiHeader.biHeight = 32;
9131 vih.bmiHeader.biBitCount = 32;
9133 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
9134 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9136 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9137 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9138 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9139 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9140 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9141 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
9142 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9143 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9144 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
9145 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9146 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9147 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9148 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9149 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9150 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9152 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9153 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9154 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9155 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9156 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9157 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9158 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9159 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9161 vih.bmiHeader.biHeight = -32;
9162 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), &GUID_NULL);
9163 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9164 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9165 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9166 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
9168 vih.bmiHeader.biHeight = 32;
9169 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
9170 todo_wine
9171 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9172 if (FAILED(hr)) goto failed;
9174 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9176 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9177 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9179 todo_wine
9180 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9181 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9182 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9183 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
9184 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9185 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9186 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9187 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9188 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9189 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9190 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9191 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9192 ok(value32 == 2048, "Unexpected value %u.\n", value32);
9193 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9194 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9195 ok(value32 == -64, "Unexpected value %d.\n", value32);
9196 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9197 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9198 ok(!!value32, "Unexpected value %#x.\n", value32);
9199 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9200 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9201 ok(!!value32, "Unexpected value %#x.\n", value32);
9203 /* Negative height. */
9204 vih.bmiHeader.biHeight = -32;
9205 hr = MFInitMediaTypeFromVideoInfoHeader(media_type, &vih, sizeof(vih), NULL);
9206 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9207 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9208 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9209 ok(value32 == 64, "Unexpected value %d.\n", value32);
9210 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9211 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9212 ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64);
9214 failed:
9215 IMFMediaType_Release(media_type);
9218 static void test_MFInitMediaTypeFromAMMediaType(void)
9220 IMFMediaType *media_type;
9221 AM_MEDIA_TYPE mt;
9222 UINT32 value32;
9223 UINT64 value64;
9224 HRESULT hr;
9225 GUID guid;
9226 VIDEOINFOHEADER vih =
9228 {0}, {0}, 0, 0, 0,
9229 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, 0xdeadbeef}
9231 static const struct guid_type_pair
9233 const GUID *am_type;
9234 const GUID *mf_type;
9235 } guid_types[] =
9237 { &MEDIASUBTYPE_I420, &MFVideoFormat_I420 },
9238 { &MEDIASUBTYPE_AYUV, &MFVideoFormat_AYUV },
9239 { &MEDIASUBTYPE_YV12, &MFVideoFormat_YV12 },
9240 { &MEDIASUBTYPE_YUY2, &MFVideoFormat_YUY2 },
9241 { &MEDIASUBTYPE_UYVY, &MFVideoFormat_UYVY },
9242 { &MEDIASUBTYPE_YVYU, &MFVideoFormat_YVYU },
9243 { &MEDIASUBTYPE_NV12, &MFVideoFormat_NV12 },
9244 { &MEDIASUBTYPE_ARGB32, &MFVideoFormat_ARGB32 },
9246 unsigned int i;
9248 hr = MFCreateMediaType(&media_type);
9249 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9251 memset(&mt, 0, sizeof(mt));
9252 mt.majortype = MEDIATYPE_Video;
9253 mt.formattype = FORMAT_VideoInfo;
9254 mt.cbFormat = sizeof(VIDEOINFOHEADER);
9255 mt.pbFormat = (BYTE *)&vih;
9257 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, 123);
9258 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9260 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9261 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9263 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9264 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9265 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9266 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9267 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9268 ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid));
9269 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9271 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9272 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9273 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9274 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9275 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9277 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9278 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9279 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9280 ok(!!value32, "Unexpected value %#x.\n", value32);
9282 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9283 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9284 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9285 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9286 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9287 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
9289 vih.bmiHeader.biHeight = -24;
9291 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9293 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9294 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9295 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9297 memcpy(&mt.subtype, &MEDIASUBTYPE_RGB32, sizeof(GUID));
9298 vih.bmiHeader.biHeight = 24;
9300 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9303 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9304 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9305 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9306 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9307 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9308 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9309 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9310 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9311 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9312 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9313 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9314 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9315 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9316 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9317 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9318 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9319 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9320 ok(value32 == 3072, "Unexpected value %u.\n", value32);
9321 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9322 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9323 ok(!!value32, "Unexpected value %#x.\n", value32);
9324 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9326 ok(!!value32, "Unexpected value %u.\n", value32);
9327 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9328 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9329 ok(value32 == -128, "Unexpected value %d.\n", value32);
9331 /* Negative height. */
9332 vih.bmiHeader.biHeight = -24;
9334 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9335 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9337 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9338 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9339 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9340 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9342 ok(IsEqualGUID(&guid, &MFVideoFormat_RGB32), "Unexpected guid %s.\n", debugstr_guid(&guid));
9343 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64);
9344 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9345 ok(value64 == ((UINT64)32 << 32 | 24), "Unexpected value %#I64x.\n", value64);
9346 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64);
9347 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9348 ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64);
9349 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32);
9350 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9351 ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32);
9352 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32);
9353 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9354 ok(value32 == 3072, "Unexpected value %u.\n", value32);
9355 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value32);
9356 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9357 ok(!!value32, "Unexpected value %#x.\n", value32);
9358 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value32);
9359 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9360 ok(!!value32, "Unexpected value %u.\n", value32);
9361 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32);
9362 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9363 ok(value32 == 128, "Unexpected value %d.\n", value32);
9365 vih.bmiHeader.biHeight = 24;
9366 for (i = 0; i < ARRAY_SIZE(guid_types); ++i)
9368 memcpy(&mt.subtype, guid_types[i].am_type, sizeof(GUID));
9370 hr = MFInitMediaTypeFromAMMediaType(media_type, &mt);
9371 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9373 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid);
9374 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9375 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid));
9376 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
9377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
9378 ok(IsEqualGUID(&guid, guid_types[i].mf_type), "Unexpected guid %s.\n", debugstr_guid(&guid));
9381 IMFMediaType_Release(media_type);
9384 static void test_MFCreatePathFromURL(void)
9386 static const struct
9388 const WCHAR *url;
9389 const WCHAR *path;
9390 HRESULT hr;
9392 tests[] =
9394 /* 0 leading slash */
9395 { L"file:c:/foo/bar", L"c:\\foo\\bar" },
9396 { L"file:c|/foo/bar", L"c:\\foo\\bar" },
9397 { L"file:cx|/foo/bar", L"cx|\\foo\\bar" },
9398 { L"file:c:foo/bar", L"c:foo\\bar" },
9399 { L"file:c|foo/bar", L"c:foo\\bar" },
9400 { L"file:c:/foo%20ba%2fr", L"c:\\foo ba/r" },
9401 { L"file:foo%20ba%2fr", L"foo ba/r" },
9402 { L"file:foo/bar/", L"foo\\bar\\" },
9404 /* 1 leading (back)slash */
9405 { L"file:/c:/foo/bar", L"c:\\foo\\bar" },
9406 { L"file:\\c:/foo/bar", L"c:\\foo\\bar" },
9407 { L"file:/c|/foo/bar", L"c:\\foo\\bar" },
9408 { L"file:/cx|/foo/bar", L"\\cx|\\foo\\bar" },
9409 { L"file:/c:foo/bar", L"c:foo\\bar" },
9410 { L"file:/c|foo/bar", L"c:foo\\bar" },
9411 { L"file:/c:/foo%20ba%2fr", L"c:\\foo ba/r" },
9412 { L"file:/foo%20ba%2fr", L"\\foo ba/r" },
9413 { L"file:/foo/bar/", L"\\foo\\bar\\" },
9415 /* 2 leading (back)slashes */
9416 { L"file://c:/foo/bar", L"c:\\foo\\bar" },
9417 { L"file://c:/d:/foo/bar", L"c:\\d:\\foo\\bar" },
9418 { L"file://c|/d|/foo/bar", L"c:\\d|\\foo\\bar" },
9419 { L"file://cx|/foo/bar", L"\\\\cx|\\foo\\bar" },
9420 { L"file://c:foo/bar", L"c:foo\\bar" },
9421 { L"file://c|foo/bar", L"c:foo\\bar" },
9422 { L"file://c:/foo%20ba%2fr", L"c:\\foo%20ba%2fr" },
9423 { L"file://c%3a/foo/../bar", L"\\\\c:\\foo\\..\\bar" },
9424 { L"file://c%7c/foo/../bar", L"\\\\c|\\foo\\..\\bar" },
9425 { L"file://foo%20ba%2fr", L"\\\\foo ba/r" },
9426 { L"file://localhost/c:/foo/bar", L"c:\\foo\\bar" },
9427 { L"file://localhost/c:/foo%20ba%5Cr", L"c:\\foo ba\\r" },
9428 { L"file://LocalHost/c:/foo/bar", L"c:\\foo\\bar" },
9429 { L"file:\\\\localhost\\c:\\foo\\bar", L"c:\\foo\\bar" },
9430 { L"file://incomplete", L"\\\\incomplete" },
9432 /* 3 leading (back)slashes (omitting hostname) */
9433 { L"file:///c:/foo/bar", L"c:\\foo\\bar" },
9434 { L"File:///c:/foo/bar", L"c:\\foo\\bar" },
9435 { L"file:///c:/foo%20ba%2fr", L"c:\\foo ba/r" },
9436 { L"file:///foo%20ba%2fr", L"\\foo ba/r" },
9437 { L"file:///foo/bar/", L"\\foo\\bar\\" },
9438 { L"file:///localhost/c:/foo/bar", L"\\localhost\\c:\\foo\\bar" },
9440 /* 4 leading (back)slashes */
9441 { L"file:////c:/foo/bar", L"c:\\foo\\bar" },
9442 { L"file:////c:/foo%20ba%2fr", L"c:\\foo%20ba%2fr" },
9443 { L"file:////foo%20ba%2fr", L"\\\\foo%20ba%2fr" },
9445 /* 5 and more leading (back)slashes */
9446 { L"file://///c:/foo/bar", L"\\\\c:\\foo\\bar" },
9447 { L"file://///c:/foo%20ba%2fr", L"\\\\c:\\foo ba/r" },
9448 { L"file://///foo%20ba%2fr", L"\\\\foo ba/r" },
9449 { L"file://////c:/foo/bar", L"\\\\c:\\foo\\bar" },
9451 /* Leading (back)slashes cannot be escaped */
9452 { L"file:%2f%2flocalhost%2fc:/foo/bar", L"//localhost/c:\\foo\\bar" },
9453 { L"file:%5C%5Clocalhost%5Cc:/foo/bar", L"\\\\localhost\\c:\\foo\\bar" },
9455 /* Hostname handling */
9456 { L"file://l%6fcalhost/c:/foo/bar", L"\\\\localhostc:\\foo\\bar" },
9457 { L"file://localhost:80/c:/foo/bar", L"\\\\localhost:80c:\\foo\\bar" },
9458 { L"file://host/c:/foo/bar", L"\\\\hostc:\\foo\\bar" },
9459 { L"file://host//c:/foo/bar", L"\\\\host\\\\c:\\foo\\bar" },
9460 { L"file://host/\\c:/foo/bar", L"\\\\host\\\\c:\\foo\\bar" },
9461 { L"file://host/c:foo/bar", L"\\\\hostc:foo\\bar" },
9462 { L"file://host/foo/bar", L"\\\\host\\foo\\bar" },
9463 { L"file:\\\\host\\c:\\foo\\bar", L"\\\\hostc:\\foo\\bar" },
9464 { L"file:\\\\host\\ca\\foo\\bar", L"\\\\host\\ca\\foo\\bar" },
9465 { L"file:\\\\host\\c|\\foo\\bar", L"\\\\hostc|\\foo\\bar" },
9466 { L"file:\\%5Chost\\c:\\foo\\bar", L"\\\\host\\c:\\foo\\bar" },
9467 { L"file:\\\\host\\cx:\\foo\\bar", L"\\\\host\\cx:\\foo\\bar" },
9468 { L"file:///host/c:/foo/bar", L"\\host\\c:\\foo\\bar" },
9470 /* Not file URLs */
9471 { L"c:\\foo\\bar", NULL, E_INVALIDARG },
9472 { L"foo/bar", NULL, E_INVALIDARG },
9473 { L"http://foo/bar", NULL, E_INVALIDARG },
9475 unsigned int i;
9476 WCHAR *path;
9477 HRESULT hr;
9479 if (!pMFCreatePathFromURL)
9481 win_skip("MFCreatePathFromURL() is not available.\n");
9482 return;
9485 hr = pMFCreatePathFromURL(NULL, NULL);
9486 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
9488 path = (void *)0xdeadbeef;
9489 hr = pMFCreatePathFromURL(NULL, &path);
9490 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
9491 ok(path == (void *)0xdeadbeef, "Unexpected pointer %p.\n", path);
9493 hr = pMFCreatePathFromURL(L"file://foo", NULL);
9494 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
9496 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9498 hr = pMFCreatePathFromURL(tests[i].url, &path);
9499 ok(hr == tests[i].hr, "Unexpected hr %#lx, expected %#lx.\n", hr, tests[i].hr);
9500 if (SUCCEEDED(hr))
9502 ok(!wcscmp(path, tests[i].path), "Unexpected path %s, expected %s.\n",
9503 debugstr_w(path), debugstr_w(tests[i].path));
9504 CoTaskMemFree(path);
9509 START_TEST(mfplat)
9511 char **argv;
9512 int argc;
9514 init_functions();
9516 argc = winetest_get_mainargs(&argv);
9517 if (argc >= 3)
9519 test_queue_com_state(argv[2]);
9520 return;
9523 if (!pMFCreateVideoSampleAllocatorEx)
9524 win_skip("MFCreateVideoSampleAllocatorEx() is not available. Some tests will be skipped.\n");
9526 if (!pD3D12CreateDevice)
9527 skip("Missing d3d12 support, some tests will be skipped.\n");
9529 CoInitialize(NULL);
9531 test_startup();
9532 test_register();
9533 test_media_type();
9534 test_MFCreateMediaEvent();
9535 test_attributes();
9536 test_sample();
9537 test_file_stream();
9538 test_MFCreateMFByteStreamOnStream();
9539 test_system_memory_buffer();
9540 test_system_memory_aligned_buffer();
9541 test_source_resolver();
9542 test_MFCreateAsyncResult();
9543 test_allocate_queue();
9544 test_MFLockSharedWorkQueue();
9545 test_MFCopyImage();
9546 test_MFCreateCollection();
9547 test_MFHeapAlloc();
9548 test_scheduled_items();
9549 test_serial_queue();
9550 test_periodic_callback();
9551 test_event_queue();
9552 test_presentation_descriptor();
9553 test_system_time_source();
9554 test_MFInvokeCallback();
9555 test_stream_descriptor();
9556 test_MFCalculateImageSize();
9557 test_MFGetPlaneSize();
9558 test_MFCompareFullToPartialMediaType();
9559 test_attributes_serialization();
9560 test_wrapped_media_type();
9561 test_MFCreateWaveFormatExFromMFMediaType();
9562 test_async_create_file();
9563 test_local_handlers();
9564 test_create_property_store();
9565 test_dxgi_device_manager();
9566 test_MFCreateTransformActivate();
9567 test_MFTRegisterLocal();
9568 test_queue_com();
9569 test_MFGetStrideForBitmapInfoHeader();
9570 test_MFCreate2DMediaBuffer();
9571 test_MFCreateMediaBufferFromMediaType();
9572 test_MFInitMediaTypeFromWaveFormatEx();
9573 test_MFCreateMFVideoFormatFromMFMediaType();
9574 test_MFCreateDXSurfaceBuffer();
9575 test_MFCreateTrackedSample();
9576 test_MFFrameRateToAverageTimePerFrame();
9577 test_MFAverageTimePerFrameToFrameRate();
9578 test_MFMapDXGIFormatToDX9Format();
9579 test_d3d11_surface_buffer();
9580 test_d3d12_surface_buffer();
9581 test_sample_allocator_sysmem();
9582 test_sample_allocator_d3d9();
9583 test_sample_allocator_d3d11();
9584 test_sample_allocator_d3d12();
9585 test_MFMapDX9FormatToDXGIFormat();
9586 test_MFllMulDiv();
9587 test_shared_dxgi_device_manager();
9588 test_MFInitVideoFormat_RGB();
9589 test_MFCreateVideoMediaTypeFromVideoInfoHeader();
9590 test_MFInitMediaTypeFromVideoInfoHeader();
9591 test_MFInitMediaTypeFromAMMediaType();
9592 test_MFCreatePathFromURL();
9594 CoUninitialize();