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
28 #include "mfmediaengine.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
)
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
;
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
);
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
);
74 struct media_engine_notify
76 IMFMediaEngineNotify IMFMediaEngineNotify_iface
;
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
))
91 IMFMediaEngineNotify_AddRef(iface
);
99 static ULONG WINAPI
media_engine_notify_AddRef(IMFMediaEngineNotify
*iface
)
101 struct media_engine_notify
*notify
= impl_from_IMFMediaEngineNotify(iface
);
102 return InterlockedIncrement(¬ify
->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(¬ify
->refcount
);
116 static HRESULT WINAPI
media_engine_notify_EventNotify(IMFMediaEngineNotify
*iface
, DWORD event
, DWORD_PTR param1
, DWORD param2
)
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;
141 static IMFMediaEngine
*create_media_engine(IMFMediaEngineNotify
*callback
)
143 IMFDXGIDeviceManager
*manager
;
144 IMFMediaEngine
*media_engine
;
145 IMFAttributes
*attributes
;
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
);
169 static IMFMediaEngineEx
*create_media_engine_ex(IMFMediaEngineNotify
*callback
)
171 IMFMediaEngine
*engine
= create_media_engine(callback
);
172 IMFMediaEngineEx
*engine_ex
= NULL
;
176 IMFMediaEngine_QueryInterface(engine
, &IID_IMFMediaEngineEx
, (void **)&engine_ex
);
177 IMFMediaEngine_Release(engine
);
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
;
193 hr
= CoCreateInstance(&CLSID_MFMediaEngineClassFactory
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFMediaEngineClassFactory
,
195 ok(hr
== S_OK
|| broken(hr
== REGDB_E_CLASSNOTREG
) /* pre-win8 */, "Failed to create class factory, hr %#lx.\n", hr
);
198 win_skip("Media Engine is not supported.\n");
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
*)¬ify
->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(¬ify
->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
;
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
*)¬ify
->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
);
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(¬ify
->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
;
332 notify
= create_callback();
334 media_engine
= create_media_engine(¬ify
->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
);
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(¬ify
->IMFMediaEngineNotify_iface
);
509 static void test_Play(void)
511 struct media_engine_notify
*notify
;
512 IMFMediaTimeRange
*range
, *range1
;
513 IMFMediaEngine
*media_engine
;
519 notify
= create_callback();
521 media_engine
= create_media_engine(¬ify
->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
);
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
);
570 media_engine
= create_media_engine(¬ify
->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(¬ify
->IMFMediaEngineNotify_iface
);
588 static void test_playback_rate(void)
590 struct media_engine_notify
*notify
;
591 IMFMediaEngine
*media_engine
;
595 notify
= create_callback();
597 media_engine
= create_media_engine(¬ify
->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(¬ify
->IMFMediaEngineNotify_iface
);
618 static void test_mute(void)
620 struct media_engine_notify
*notify
;
621 IMFMediaEngine
*media_engine
;
625 notify
= create_callback();
627 media_engine
= create_media_engine(¬ify
->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(¬ify
->IMFMediaEngineNotify_iface
);
648 static void test_error(void)
650 struct media_engine_notify
*notify
;
651 IMFMediaEngine
*media_engine
;
652 IMFMediaError
*eo
, *eo2
;
656 notify
= create_callback();
658 media_engine
= create_media_engine(¬ify
->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
);
672 hr
= IMFMediaEngine_GetError(media_engine
, &eo
);
673 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
674 ok(!!eo
, "Unexpected instance.\n");
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
);
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(¬ify
->IMFMediaEngineNotify_iface
);
734 static void test_time_range(void)
736 IMFMediaTimeRange
*range
;
742 hr
= IMFMediaEngineClassFactory_CreateTimeRange(factory
, &range
);
743 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
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
);
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
);
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");
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
;
918 notify
= create_callback();
920 media_engine
= create_media_engine_ex(¬ify
->IMFMediaEngineNotify_iface
);
923 win_skip("IMFMediaEngineEx is not supported.\n");
924 IMFMediaEngineNotify_Release(¬ify
->IMFMediaEngineNotify_iface
);
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(¬ify
->IMFMediaEngineNotify_iface
);
947 static void test_audio_configuration(void)
949 struct media_engine_notify
*notify
;
950 IMFMediaEngineEx
*media_engine
;
954 notify
= create_callback();
956 media_engine
= create_media_engine_ex(¬ify
->IMFMediaEngineNotify_iface
);
959 IMFMediaEngineNotify_Release(¬ify
->IMFMediaEngineNotify_iface
);
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(¬ify
->IMFMediaEngineNotify_iface
);
975 START_TEST(mfmediaengine
)
981 hr
= CoCreateInstance(&CLSID_MFMediaEngineClassFactory
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFMediaEngineClassFactory
,
985 win_skip("Media Engine is not supported.\n");
992 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
993 ok(hr
== S_OK
, "MFStartup failed: %#lx.\n", hr
);
996 test_CreateInstance();
999 test_playback_rate();
1003 test_SetSourceFromByteStream();
1004 test_audio_configuration();
1006 IMFMediaEngineClassFactory_Release(factory
);