l3codeca.acm: Avoid mpg123 functions with suffix.
[wine.git] / dlls / mfmediaengine / tests / mfmediaengine.c
blob008ee58849c65010b26ee981828bc9076e4c4cf3
1 /*
2 * Copyright 2019 Jactry Zeng for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
26 #include "mfapi.h"
27 #include "mfidl.h"
28 #include "mfmediaengine.h"
29 #include "mferror.h"
30 #include "dxgi.h"
31 #include "initguid.h"
32 #include "mmdeviceapi.h"
33 #include "audiosessiontypes.h"
35 #include "wine/test.h"
37 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
39 static IMFMediaEngineClassFactory *factory;
41 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
42 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
44 ULONG rc;
45 IUnknown_AddRef(obj);
46 rc = IUnknown_Release(obj);
47 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %ld, expected %ld.\n", rc, ref);
50 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
51 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
53 IUnknown *iface = iface_ptr;
54 HRESULT hr, expected_hr;
55 IUnknown *unk;
57 expected_hr = supported ? S_OK : E_NOINTERFACE;
59 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
60 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
61 if (SUCCEEDED(hr))
62 IUnknown_Release(unk);
65 static void init_functions(void)
67 HMODULE mod = GetModuleHandleA("mfplat.dll");
69 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
70 X(MFCreateDXGIDeviceManager);
71 #undef X
74 struct media_engine_notify
76 IMFMediaEngineNotify IMFMediaEngineNotify_iface;
77 LONG refcount;
80 static inline struct media_engine_notify *impl_from_IMFMediaEngineNotify(IMFMediaEngineNotify *iface)
82 return CONTAINING_RECORD(iface, struct media_engine_notify, IMFMediaEngineNotify_iface);
85 static HRESULT WINAPI media_engine_notify_QueryInterface(IMFMediaEngineNotify *iface, REFIID riid, void **obj)
87 if (IsEqualIID(riid, &IID_IMFMediaEngineNotify) ||
88 IsEqualIID(riid, &IID_IUnknown))
90 *obj = iface;
91 IMFMediaEngineNotify_AddRef(iface);
92 return S_OK;
95 *obj = NULL;
96 return E_NOINTERFACE;
99 static ULONG WINAPI media_engine_notify_AddRef(IMFMediaEngineNotify *iface)
101 struct media_engine_notify *notify = impl_from_IMFMediaEngineNotify(iface);
102 return InterlockedIncrement(&notify->refcount);
105 static ULONG WINAPI media_engine_notify_Release(IMFMediaEngineNotify *iface)
107 struct media_engine_notify *notify = impl_from_IMFMediaEngineNotify(iface);
108 ULONG refcount = InterlockedDecrement(&notify->refcount);
110 if (!refcount)
111 free(notify);
113 return refcount;
116 static HRESULT WINAPI media_engine_notify_EventNotify(IMFMediaEngineNotify *iface, DWORD event, DWORD_PTR param1, DWORD param2)
118 return S_OK;
121 static IMFMediaEngineNotifyVtbl media_engine_notify_vtbl =
123 media_engine_notify_QueryInterface,
124 media_engine_notify_AddRef,
125 media_engine_notify_Release,
126 media_engine_notify_EventNotify,
129 static struct media_engine_notify *create_callback(void)
131 struct media_engine_notify *object;
133 object = calloc(1, sizeof(*object));
135 object->IMFMediaEngineNotify_iface.lpVtbl = &media_engine_notify_vtbl;
136 object->refcount = 1;
138 return object;
141 static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback)
143 IMFDXGIDeviceManager *manager;
144 IMFMediaEngine *media_engine;
145 IMFAttributes *attributes;
146 UINT token;
147 HRESULT hr;
149 hr = pMFCreateDXGIDeviceManager(&token, &manager);
150 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
152 hr = MFCreateAttributes(&attributes, 3);
153 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
155 hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, (IUnknown *)callback);
156 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
157 hr = IMFAttributes_SetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_UNKNOWN);
158 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
160 hr = IMFMediaEngineClassFactory_CreateInstance(factory, 0, attributes, &media_engine);
161 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
163 IMFAttributes_Release(attributes);
164 IMFDXGIDeviceManager_Release(manager);
166 return media_engine;
169 static IMFMediaEngineEx *create_media_engine_ex(IMFMediaEngineNotify *callback)
171 IMFMediaEngine *engine = create_media_engine(callback);
172 IMFMediaEngineEx *engine_ex = NULL;
174 if (engine)
176 IMFMediaEngine_QueryInterface(engine, &IID_IMFMediaEngineEx, (void **)&engine_ex);
177 IMFMediaEngine_Release(engine);
180 return engine_ex;
183 static void test_factory(void)
185 IMFMediaEngineClassFactory *factory, *factory2;
186 struct media_engine_notify *notify;
187 IMFDXGIDeviceManager *manager;
188 IMFMediaEngine *media_engine;
189 IMFAttributes *attributes;
190 UINT token;
191 HRESULT hr;
193 hr = CoCreateInstance(&CLSID_MFMediaEngineClassFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IMFMediaEngineClassFactory,
194 (void **)&factory);
195 ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /* pre-win8 */, "Failed to create class factory, hr %#lx.\n", hr);
196 if (FAILED(hr))
198 win_skip("Media Engine is not supported.\n");
199 return;
202 notify = create_callback();
204 /* Aggregation is not supported. */
205 hr = CoCreateInstance(&CLSID_MFMediaEngineClassFactory, (IUnknown *)factory, CLSCTX_INPROC_SERVER,
206 &IID_IMFMediaEngineClassFactory, (void **)&factory2);
207 ok(hr == CLASS_E_NOAGGREGATION, "Unexpected hr %#lx.\n", hr);
209 hr = pMFCreateDXGIDeviceManager(&token, &manager);
210 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
211 hr = MFCreateAttributes(&attributes, 3);
212 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
214 hr = IMFMediaEngineClassFactory_CreateInstance(factory, MF_MEDIA_ENGINE_WAITFORSTABLE_STATE, attributes, &media_engine);
215 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
217 hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_OPM_HWND, NULL);
218 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
219 hr = IMFMediaEngineClassFactory_CreateInstance(factory, MF_MEDIA_ENGINE_WAITFORSTABLE_STATE, attributes, &media_engine);
220 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
222 IMFAttributes_DeleteAllItems(attributes);
223 hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, (IUnknown *)&notify->IMFMediaEngineNotify_iface);
224 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
225 hr = IMFAttributes_SetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_UNKNOWN);
226 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
227 EXPECT_REF(factory, 1);
228 hr = IMFMediaEngineClassFactory_CreateInstance(factory, MF_MEDIA_ENGINE_WAITFORSTABLE_STATE, attributes, &media_engine);
229 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
230 EXPECT_REF(factory, 1);
232 IMFMediaEngine_Release(media_engine);
233 IMFAttributes_Release(attributes);
234 IMFDXGIDeviceManager_Release(manager);
235 IMFMediaEngineClassFactory_Release(factory);
236 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
239 static void test_CreateInstance(void)
241 struct media_engine_notify *notify;
242 IMFMediaEngineEx *media_engine_ex;
243 IMFDXGIDeviceManager *manager;
244 IMFMediaEngine *media_engine;
245 IMFAttributes *attributes;
246 IUnknown *unk;
247 UINT token;
248 HRESULT hr;
249 BOOL ret;
251 notify = create_callback();
253 hr = pMFCreateDXGIDeviceManager(&token, &manager);
254 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
256 hr = MFCreateAttributes(&attributes, 3);
257 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
259 hr = IMFMediaEngineClassFactory_CreateInstance(factory, MF_MEDIA_ENGINE_WAITFORSTABLE_STATE,
260 attributes, &media_engine);
261 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
263 hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_OPM_HWND, NULL);
264 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
266 hr = IMFMediaEngineClassFactory_CreateInstance(factory, MF_MEDIA_ENGINE_WAITFORSTABLE_STATE,
267 attributes, &media_engine);
268 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
270 IMFAttributes_DeleteAllItems(attributes);
272 hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, (IUnknown *)&notify->IMFMediaEngineNotify_iface);
273 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
274 hr = IMFAttributes_SetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_UNKNOWN);
275 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
277 hr = IMFMediaEngineClassFactory_CreateInstance(factory, MF_MEDIA_ENGINE_REAL_TIME_MODE
278 | MF_MEDIA_ENGINE_WAITFORSTABLE_STATE, attributes, &media_engine);
279 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
281 check_interface(media_engine, &IID_IMFMediaEngine, TRUE);
283 hr = IMFMediaEngine_QueryInterface(media_engine, &IID_IMFGetService, (void **)&unk);
284 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* supported since win10 */, "Unexpected hr %#lx.\n", hr);
285 if (SUCCEEDED(hr))
286 IUnknown_Release(unk);
288 if (SUCCEEDED(IMFMediaEngine_QueryInterface(media_engine, &IID_IMFMediaEngineEx, (void **)&media_engine_ex)))
290 hr = IMFMediaEngineEx_GetRealTimeMode(media_engine_ex, &ret);
291 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
292 ok(ret, "Unexpected value.\n");
294 hr = IMFMediaEngineEx_SetRealTimeMode(media_engine_ex, FALSE);
295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
297 hr = IMFMediaEngineEx_GetRealTimeMode(media_engine_ex, &ret);
298 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
299 ok(!ret, "Unexpected value.\n");
301 hr = IMFMediaEngineEx_SetRealTimeMode(media_engine_ex, TRUE);
302 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
304 hr = IMFMediaEngineEx_GetRealTimeMode(media_engine_ex, &ret);
305 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
306 ok(ret, "Unexpected value.\n");
308 IMFMediaEngineEx_Release(media_engine_ex);
311 IMFMediaEngine_Release(media_engine);
312 IMFAttributes_Release(attributes);
313 IMFDXGIDeviceManager_Release(manager);
314 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
317 static void test_Shutdown(void)
319 struct media_engine_notify *notify;
320 IMFMediaEngineEx *media_engine_ex;
321 IMFMediaTimeRange *time_range;
322 IMFMediaEngine *media_engine;
323 PROPVARIANT propvar;
324 DWORD flags, cx, cy;
325 unsigned int state;
326 UINT32 value;
327 double val;
328 HRESULT hr;
329 BSTR str;
330 BOOL ret;
332 notify = create_callback();
334 media_engine = create_media_engine(&notify->IMFMediaEngineNotify_iface);
336 hr = IMFMediaEngine_Shutdown(media_engine);
337 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
339 hr = IMFMediaEngine_Shutdown(media_engine);
340 ok(hr == MF_E_SHUTDOWN || broken(hr == S_OK) /* before win10 */, "Unexpected hr %#lx.\n", hr);
342 hr = IMFMediaEngine_SetSource(media_engine, NULL);
343 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
345 hr = IMFMediaEngine_GetCurrentSource(media_engine, &str);
346 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
348 state = IMFMediaEngine_GetNetworkState(media_engine);
349 ok(!state, "Unexpected state %d.\n", state);
351 /* Preload mode is still accessible. */
352 state = IMFMediaEngine_GetPreload(media_engine);
353 ok(!state, "Unexpected state %d.\n", state);
355 hr = IMFMediaEngine_SetPreload(media_engine, MF_MEDIA_ENGINE_PRELOAD_AUTOMATIC);
356 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
358 state = IMFMediaEngine_GetPreload(media_engine);
359 ok(state == MF_MEDIA_ENGINE_PRELOAD_AUTOMATIC, "Unexpected state %d.\n", state);
361 hr = IMFMediaEngine_SetPreload(media_engine, 100);
362 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
364 state = IMFMediaEngine_GetPreload(media_engine);
365 ok(state == 100, "Unexpected state %d.\n", state);
367 hr = IMFMediaEngine_GetBuffered(media_engine, &time_range);
368 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
370 hr = IMFMediaEngine_Load(media_engine);
371 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
373 str = SysAllocString(L"video/mp4");
374 hr = IMFMediaEngine_CanPlayType(media_engine, str, &state);
375 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
376 SysFreeString(str);
378 state = IMFMediaEngine_GetReadyState(media_engine);
379 ok(!state, "Unexpected state %d.\n", state);
381 state = IMFMediaEngine_IsSeeking(media_engine);
382 ok(!state, "Unexpected state %d.\n", state);
384 val = IMFMediaEngine_GetCurrentTime(media_engine);
385 ok(val == 0.0, "Unexpected time %f.\n", val);
387 hr = IMFMediaEngine_SetCurrentTime(media_engine, 1.0);
388 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
390 val = IMFMediaEngine_GetStartTime(media_engine);
391 ok(val == 0.0, "Unexpected time %f.\n", val);
393 state = IMFMediaEngine_IsPaused(media_engine);
394 ok(!!state, "Unexpected state %d.\n", state);
396 val = IMFMediaEngine_GetDefaultPlaybackRate(media_engine);
397 ok(val == 1.0, "Unexpected rate %f.\n", val);
399 hr = IMFMediaEngine_SetDefaultPlaybackRate(media_engine, 2.0);
400 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
402 val = IMFMediaEngine_GetPlaybackRate(media_engine);
403 ok(val == 1.0, "Unexpected rate %f.\n", val);
405 hr = IMFMediaEngine_GetPlayed(media_engine, &time_range);
406 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
408 hr = IMFMediaEngine_GetSeekable(media_engine, &time_range);
409 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
411 state = IMFMediaEngine_IsEnded(media_engine);
412 ok(!state, "Unexpected state %d.\n", state);
414 /* Autoplay mode is still accessible. */
415 state = IMFMediaEngine_GetAutoPlay(media_engine);
416 ok(!state, "Unexpected state.\n");
418 hr = IMFMediaEngine_SetAutoPlay(media_engine, TRUE);
419 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
421 state = IMFMediaEngine_GetAutoPlay(media_engine);
422 ok(!!state, "Unexpected state.\n");
424 /* Loop mode is still accessible. */
425 state = IMFMediaEngine_GetLoop(media_engine);
426 ok(!state, "Unexpected state.\n");
428 hr = IMFMediaEngine_SetLoop(media_engine, TRUE);
429 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
431 state = IMFMediaEngine_GetLoop(media_engine);
432 ok(!!state, "Unexpected state.\n");
434 hr = IMFMediaEngine_Play(media_engine);
435 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
437 hr = IMFMediaEngine_Pause(media_engine);
438 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
440 state = IMFMediaEngine_GetMuted(media_engine);
441 ok(!state, "Unexpected state.\n");
443 hr = IMFMediaEngine_SetMuted(media_engine, TRUE);
444 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
446 val = IMFMediaEngine_GetVolume(media_engine);
447 ok(val == 1.0, "Unexpected value %f.\n", val);
449 hr = IMFMediaEngine_SetVolume(media_engine, 2.0);
450 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
452 state = IMFMediaEngine_HasVideo(media_engine);
453 ok(!state, "Unexpected state.\n");
455 state = IMFMediaEngine_HasAudio(media_engine);
456 ok(!state, "Unexpected state.\n");
458 hr = IMFMediaEngine_GetNativeVideoSize(media_engine, &cx, &cy);
459 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
461 hr = IMFMediaEngine_GetVideoAspectRatio(media_engine, &cx, &cy);
462 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
464 if (SUCCEEDED(IMFMediaEngine_QueryInterface(media_engine, &IID_IMFMediaEngineEx, (void **)&media_engine_ex)))
466 hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine_ex, NULL, NULL);
467 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
469 hr = IMFMediaEngineEx_GetAudioStreamCategory(media_engine_ex, &value);
470 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
472 hr = IMFMediaEngineEx_GetAudioEndpointRole(media_engine_ex, &value);
473 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
475 hr = IMFMediaEngineEx_SetAudioStreamCategory(media_engine_ex, AudioCategory_ForegroundOnlyMedia);
476 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
478 hr = IMFMediaEngineEx_SetAudioEndpointRole(media_engine_ex, eConsole);
479 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
481 hr = IMFMediaEngineEx_GetResourceCharacteristics(media_engine_ex, NULL);
482 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
484 hr = IMFMediaEngineEx_GetResourceCharacteristics(media_engine_ex, &flags);
485 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
487 hr = IMFMediaEngineEx_GetRealTimeMode(media_engine_ex, NULL);
488 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
490 hr = IMFMediaEngineEx_GetRealTimeMode(media_engine_ex, &ret);
491 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
493 hr = IMFMediaEngineEx_SetRealTimeMode(media_engine_ex, TRUE);
494 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
496 hr = IMFMediaEngineEx_GetPresentationAttribute(media_engine_ex, &MF_PD_DURATION, &propvar);
497 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
499 hr = IMFMediaEngineEx_GetStreamAttribute(media_engine_ex, 0, &MF_SD_PROTECTED, &propvar);
500 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
502 IMFMediaEngineEx_Release(media_engine_ex);
505 IMFMediaEngine_Release(media_engine);
506 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
509 static void test_Play(void)
511 struct media_engine_notify *notify;
512 IMFMediaTimeRange *range, *range1;
513 IMFMediaEngine *media_engine;
514 LONGLONG pts;
515 DWORD count;
516 HRESULT hr;
517 BOOL ret;
519 notify = create_callback();
521 media_engine = create_media_engine(&notify->IMFMediaEngineNotify_iface);
523 hr = IMFMediaEngine_GetBuffered(media_engine, &range);
524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
525 hr = IMFMediaEngine_GetBuffered(media_engine, &range1);
526 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
527 ok(range != range1, "Unexpected pointer.\n");
529 count = IMFMediaTimeRange_GetLength(range);
530 ok(!count, "Unexpected count %lu.\n", count);
532 IMFMediaTimeRange_Release(range);
533 IMFMediaTimeRange_Release(range1);
535 ret = IMFMediaEngine_IsPaused(media_engine);
536 ok(ret, "Unexpected state %d.\n", ret);
538 hr = IMFMediaEngine_OnVideoStreamTick(media_engine, NULL);
539 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
541 pts = 0;
542 hr = IMFMediaEngine_OnVideoStreamTick(media_engine, &pts);
543 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
544 ok(pts == MINLONGLONG, "Unexpected timestamp.\n");
546 hr = IMFMediaEngine_Play(media_engine);
547 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
549 ret = IMFMediaEngine_IsPaused(media_engine);
550 ok(!ret, "Unexpected state %d.\n", ret);
552 hr = IMFMediaEngine_Play(media_engine);
553 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
555 hr = IMFMediaEngine_Shutdown(media_engine);
556 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
558 hr = IMFMediaEngine_OnVideoStreamTick(media_engine, NULL);
559 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
561 hr = IMFMediaEngine_OnVideoStreamTick(media_engine, &pts);
562 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
564 ret = IMFMediaEngine_IsPaused(media_engine);
565 ok(!ret, "Unexpected state %d.\n", ret);
567 IMFMediaEngine_Release(media_engine);
569 /* Play -> Pause */
570 media_engine = create_media_engine(&notify->IMFMediaEngineNotify_iface);
572 hr = IMFMediaEngine_Play(media_engine);
573 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
575 ret = IMFMediaEngine_IsPaused(media_engine);
576 ok(!ret, "Unexpected state %d.\n", ret);
578 hr = IMFMediaEngine_Pause(media_engine);
579 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
581 ret = IMFMediaEngine_IsPaused(media_engine);
582 ok(!!ret, "Unexpected state %d.\n", ret);
584 IMFMediaEngine_Release(media_engine);
585 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
588 static void test_playback_rate(void)
590 struct media_engine_notify *notify;
591 IMFMediaEngine *media_engine;
592 double rate;
593 HRESULT hr;
595 notify = create_callback();
597 media_engine = create_media_engine(&notify->IMFMediaEngineNotify_iface);
599 rate = IMFMediaEngine_GetDefaultPlaybackRate(media_engine);
600 ok(rate == 1.0, "Unexpected default rate.\n");
602 rate = IMFMediaEngine_GetPlaybackRate(media_engine);
603 ok(rate == 1.0, "Unexpected default rate.\n");
605 hr = IMFMediaEngine_SetPlaybackRate(media_engine, 0.0);
606 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
608 rate = IMFMediaEngine_GetPlaybackRate(media_engine);
609 ok(rate == 0.0, "Unexpected default rate.\n");
611 hr = IMFMediaEngine_SetDefaultPlaybackRate(media_engine, 0.0);
612 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
614 IMFMediaEngine_Release(media_engine);
615 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
618 static void test_mute(void)
620 struct media_engine_notify *notify;
621 IMFMediaEngine *media_engine;
622 HRESULT hr;
623 BOOL ret;
625 notify = create_callback();
627 media_engine = create_media_engine(&notify->IMFMediaEngineNotify_iface);
629 ret = IMFMediaEngine_GetMuted(media_engine);
630 ok(!ret, "Unexpected state.\n");
632 hr = IMFMediaEngine_SetMuted(media_engine, TRUE);
633 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
635 ret = IMFMediaEngine_GetMuted(media_engine);
636 ok(ret, "Unexpected state.\n");
638 hr = IMFMediaEngine_Shutdown(media_engine);
639 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
641 ret = IMFMediaEngine_GetMuted(media_engine);
642 ok(ret, "Unexpected state.\n");
644 IMFMediaEngine_Release(media_engine);
645 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
648 static void test_error(void)
650 struct media_engine_notify *notify;
651 IMFMediaEngine *media_engine;
652 IMFMediaError *eo, *eo2;
653 unsigned int code;
654 HRESULT hr;
656 notify = create_callback();
658 media_engine = create_media_engine(&notify->IMFMediaEngineNotify_iface);
660 eo = (void *)0xdeadbeef;
661 hr = IMFMediaEngine_GetError(media_engine, &eo);
662 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
663 ok(!eo, "Unexpected instance.\n");
665 hr = IMFMediaEngine_SetErrorCode(media_engine, MF_MEDIA_ENGINE_ERR_ENCRYPTED + 1);
666 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
668 hr = IMFMediaEngine_SetErrorCode(media_engine, MF_MEDIA_ENGINE_ERR_ABORTED);
669 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
671 eo = NULL;
672 hr = IMFMediaEngine_GetError(media_engine, &eo);
673 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
674 ok(!!eo, "Unexpected instance.\n");
676 eo2 = NULL;
677 hr = IMFMediaEngine_GetError(media_engine, &eo2);
678 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
679 ok(eo2 != eo, "Unexpected instance.\n");
681 IMFMediaError_Release(eo2);
682 IMFMediaError_Release(eo);
684 hr = IMFMediaEngine_SetErrorCode(media_engine, MF_MEDIA_ENGINE_ERR_NOERROR);
685 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
687 eo = (void *)0xdeadbeef;
688 hr = IMFMediaEngine_GetError(media_engine, &eo);
689 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
690 ok(!eo, "Unexpected instance.\n");
692 hr = IMFMediaEngine_Shutdown(media_engine);
693 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
695 eo = (void *)0xdeadbeef;
696 hr = IMFMediaEngine_GetError(media_engine, &eo);
697 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
698 ok(!eo, "Unexpected instance.\n");
700 hr = IMFMediaEngine_SetErrorCode(media_engine, MF_MEDIA_ENGINE_ERR_NOERROR);
701 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
703 IMFMediaEngine_Release(media_engine);
705 /* Error object. */
706 hr = IMFMediaEngineClassFactory_CreateError(factory, &eo);
707 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
709 code = IMFMediaError_GetErrorCode(eo);
710 ok(code == MF_MEDIA_ENGINE_ERR_NOERROR, "Unexpected code %u.\n", code);
712 hr = IMFMediaError_GetExtendedErrorCode(eo);
713 ok(hr == S_OK, "Unexpected code %#lx.\n", hr);
715 hr = IMFMediaError_SetErrorCode(eo, MF_MEDIA_ENGINE_ERR_ENCRYPTED + 1);
716 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
718 hr = IMFMediaError_SetErrorCode(eo, MF_MEDIA_ENGINE_ERR_ABORTED);
719 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
721 code = IMFMediaError_GetErrorCode(eo);
722 ok(code == MF_MEDIA_ENGINE_ERR_ABORTED, "Unexpected code %u.\n", code);
724 hr = IMFMediaError_SetExtendedErrorCode(eo, E_FAIL);
725 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
727 hr = IMFMediaError_GetExtendedErrorCode(eo);
728 ok(hr == E_FAIL, "Unexpected code %#lx.\n", hr);
730 IMFMediaError_Release(eo);
731 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
734 static void test_time_range(void)
736 IMFMediaTimeRange *range;
737 double start, end;
738 DWORD count;
739 HRESULT hr;
740 BOOL ret;
742 hr = IMFMediaEngineClassFactory_CreateTimeRange(factory, &range);
743 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
745 /* Empty ranges. */
746 hr = IMFMediaTimeRange_Clear(range);
747 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
749 ret = IMFMediaTimeRange_ContainsTime(range, 10.0);
750 ok(!ret, "Unexpected return value %d.\n", ret);
752 count = IMFMediaTimeRange_GetLength(range);
753 ok(!count, "Unexpected range count.\n");
755 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
756 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
758 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
759 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
761 /* Add a range. */
762 hr = IMFMediaTimeRange_AddRange(range, 10.0, 1.0);
763 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
765 count = IMFMediaTimeRange_GetLength(range);
766 ok(count == 1, "Unexpected range count.\n");
768 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
769 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
770 ok(start == 10.0, "Unexpected start %.e.\n", start);
772 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
773 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
774 ok(end == 1.0, "Unexpected end %.e.\n", end);
776 hr = IMFMediaTimeRange_AddRange(range, 2.0, 3.0);
777 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
779 count = IMFMediaTimeRange_GetLength(range);
780 ok(count == 1, "Unexpected range count.\n");
782 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
783 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
784 ok(start == 2.0, "Unexpected start %.8e.\n", start);
786 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
787 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
788 ok(end == 3.0, "Unexpected end %.8e.\n", end);
790 hr = IMFMediaTimeRange_AddRange(range, 10.0, 9.0);
791 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
793 count = IMFMediaTimeRange_GetLength(range);
794 ok(count == 2, "Unexpected range count.\n");
796 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
797 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
798 ok(start == 2.0, "Unexpected start %.8e.\n", start);
800 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
801 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
802 ok(end == 3.0, "Unexpected end %.8e.\n", end);
804 start = 0.0;
805 hr = IMFMediaTimeRange_GetStart(range, 1, &start);
806 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
807 ok(start == 10.0, "Unexpected start %.8e.\n", start);
809 hr = IMFMediaTimeRange_GetEnd(range, 1, &end);
810 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
811 ok(end == 9.0, "Unexpected end %.8e.\n", end);
813 hr = IMFMediaTimeRange_AddRange(range, 2.0, 9.1);
814 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
816 count = IMFMediaTimeRange_GetLength(range);
817 ok(count == 2, "Unexpected range count.\n");
819 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
820 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
821 ok(start == 2.0, "Unexpected start %.8e.\n", start);
823 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
824 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
825 ok(end == 9.1, "Unexpected end %.8e.\n", end);
827 hr = IMFMediaTimeRange_GetStart(range, 1, &start);
828 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
829 ok(start == 10.0, "Unexpected start %.8e.\n", start);
831 hr = IMFMediaTimeRange_GetEnd(range, 1, &end);
832 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
833 ok(end == 9.0, "Unexpected end %.8e.\n", end);
835 hr = IMFMediaTimeRange_AddRange(range, 8.5, 2.5);
836 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
838 count = IMFMediaTimeRange_GetLength(range);
839 ok(count == 2, "Unexpected range count.\n");
841 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
842 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
843 ok(start == 2.0, "Unexpected start %.8e.\n", start);
845 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
846 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
847 ok(end == 9.1, "Unexpected end %.8e.\n", end);
849 hr = IMFMediaTimeRange_AddRange(range, 20.0, 20.0);
850 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
852 count = IMFMediaTimeRange_GetLength(range);
853 ok(count == 3, "Unexpected range count.\n");
855 hr = IMFMediaTimeRange_Clear(range);
856 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
858 count = IMFMediaTimeRange_GetLength(range);
859 ok(!count, "Unexpected range count.\n");
861 /* Intersect */
862 hr = IMFMediaTimeRange_AddRange(range, 5.0, 10.0);
863 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
865 hr = IMFMediaTimeRange_AddRange(range, 6.0, 12.0);
866 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
868 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
869 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
870 ok(start == 5.0, "Unexpected start %.8e.\n", start);
872 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
873 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
874 ok(end == 12.0, "Unexpected end %.8e.\n", end);
876 count = IMFMediaTimeRange_GetLength(range);
877 ok(count == 1, "Unexpected range count.\n");
879 hr = IMFMediaTimeRange_AddRange(range, 4.0, 6.0);
880 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
882 count = IMFMediaTimeRange_GetLength(range);
883 ok(count == 1, "Unexpected range count.\n");
885 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
886 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
887 ok(start == 4.0, "Unexpected start %.8e.\n", start);
889 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
890 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
891 ok(end == 12.0, "Unexpected end %.8e.\n", end);
893 hr = IMFMediaTimeRange_AddRange(range, 5.0, 3.0);
894 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
896 count = IMFMediaTimeRange_GetLength(range);
897 ok(count == 1, "Unexpected range count.\n");
899 hr = IMFMediaTimeRange_GetStart(range, 0, &start);
900 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
901 ok(start == 4.0, "Unexpected start %.8e.\n", start);
903 hr = IMFMediaTimeRange_GetEnd(range, 0, &end);
904 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
905 ok(end == 12.0, "Unexpected end %.8e.\n", end);
907 IMFMediaTimeRange_Release(range);
910 static void test_SetSourceFromByteStream(void)
912 struct media_engine_notify *notify;
913 IMFMediaEngineEx *media_engine;
914 PROPVARIANT propvar;
915 DWORD flags;
916 HRESULT hr;
918 notify = create_callback();
920 media_engine = create_media_engine_ex(&notify->IMFMediaEngineNotify_iface);
921 if (!media_engine)
923 win_skip("IMFMediaEngineEx is not supported.\n");
924 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
925 return;
928 hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine, NULL, NULL);
929 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
931 hr = IMFMediaEngineEx_GetResourceCharacteristics(media_engine, NULL);
932 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
934 hr = IMFMediaEngineEx_GetResourceCharacteristics(media_engine, &flags);
935 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
937 hr = IMFMediaEngineEx_GetPresentationAttribute(media_engine, &MF_PD_DURATION, &propvar);
938 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
940 hr = IMFMediaEngineEx_GetStreamAttribute(media_engine, 0, &MF_SD_PROTECTED, &propvar);
941 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
943 IMFMediaEngineEx_Release(media_engine);
944 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
947 static void test_audio_configuration(void)
949 struct media_engine_notify *notify;
950 IMFMediaEngineEx *media_engine;
951 UINT32 value;
952 HRESULT hr;
954 notify = create_callback();
956 media_engine = create_media_engine_ex(&notify->IMFMediaEngineNotify_iface);
957 if (!media_engine)
959 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
960 return;
963 hr = IMFMediaEngineEx_GetAudioStreamCategory(media_engine, &value);
964 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
965 ok(value == AudioCategory_Other, "Unexpected value %u.\n", value);
967 hr = IMFMediaEngineEx_GetAudioEndpointRole(media_engine, &value);
968 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
969 ok(value == eMultimedia, "Unexpected value %u.\n", value);
971 IMFMediaEngineEx_Release(media_engine);
972 IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
975 START_TEST(mfmediaengine)
977 HRESULT hr;
979 CoInitialize(NULL);
981 hr = CoCreateInstance(&CLSID_MFMediaEngineClassFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IMFMediaEngineClassFactory,
982 (void **)&factory);
983 if (FAILED(hr))
985 win_skip("Media Engine is not supported.\n");
986 CoUninitialize();
987 return;
990 init_functions();
992 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
993 ok(hr == S_OK, "MFStartup failed: %#lx.\n", hr);
995 test_factory();
996 test_CreateInstance();
997 test_Shutdown();
998 test_Play();
999 test_playback_rate();
1000 test_mute();
1001 test_error();
1002 test_time_range();
1003 test_SetSourceFromByteStream();
1004 test_audio_configuration();
1006 IMFMediaEngineClassFactory_Release(factory);
1008 CoUninitialize();
1010 MFShutdown();