Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/main.c | 60 ++++++++++++++++++++---- dlls/mfmediaengine/tests/mfmediaengine.c | 32 +++++++++++-- 2 files changed, 81 insertions(+), 11 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index fcef1be048f..b9bf3c7027b 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -76,6 +76,8 @@ struct media_engine IMFDXGIDeviceManager *dxgi_manager; enum media_engine_mode mode; unsigned int flags; + double playback_rate; + double default_playback_rate; IMFMediaSession *session; CRITICAL_SECTION cs; }; @@ -344,30 +346,70 @@ static BOOL WINAPI media_engine_IsPaused(IMFMediaEngine *iface)
static double WINAPI media_engine_GetDefaultPlaybackRate(IMFMediaEngine *iface) { - FIXME("(%p): stub.\n", iface); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + double rate;
- return 0.0; + TRACE("%p.\n", iface); + + EnterCriticalSection(&engine->cs); + rate = engine->default_playback_rate; + LeaveCriticalSection(&engine->cs); + + return rate; }
static HRESULT WINAPI media_engine_SetDefaultPlaybackRate(IMFMediaEngine *iface, double rate) { - FIXME("(%p, %f): stub.\n", iface, rate); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %f.\n", iface, rate); + + EnterCriticalSection(&engine->cs); + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else if (engine->default_playback_rate != rate) + { + engine->default_playback_rate = rate; + IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_RATECHANGE, 0, 0); + } + LeaveCriticalSection(&engine->cs); + + return hr; }
static double WINAPI media_engine_GetPlaybackRate(IMFMediaEngine *iface) { - FIXME("(%p): stub.\n", iface); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + double rate;
- return 0.0; + TRACE("%p.\n", iface); + + EnterCriticalSection(&engine->cs); + rate = engine->playback_rate; + LeaveCriticalSection(&engine->cs); + + return rate; }
static HRESULT WINAPI media_engine_SetPlaybackRate(IMFMediaEngine *iface, double rate) { - FIXME("(%p, %f): stub.\n", iface, rate); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %f.\n", iface, rate); + + EnterCriticalSection(&engine->cs); + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else if (engine->playback_rate != rate) + { + engine->playback_rate = rate; + IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_RATECHANGE, 0, 0); + } + LeaveCriticalSection(&engine->cs); + + return hr; }
static HRESULT WINAPI media_engine_GetPlayed(IMFMediaEngine *iface, IMFMediaTimeRange **played) @@ -672,6 +714,8 @@ static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct engine->session_events.lpVtbl = &media_engine_session_events_vtbl; engine->refcount = 1; engine->flags = (flags & MF_MEDIA_ENGINE_CREATEFLAGS_MASK) | FLAGS_ENGINE_PAUSED; + engine->default_playback_rate = 1.0; + engine->playback_rate = 1.0; InitializeCriticalSection(&engine->cs);
hr = IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, &IID_IMFMediaEngineNotify, diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index a3db611e9fc..4079e9aa70f 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -310,15 +310,12 @@ todo_wine ok(!!state, "Unexpected state %d.\n", state);
val = IMFMediaEngine_GetDefaultPlaybackRate(media_engine); -todo_wine ok(val == 1.0, "Unexpected rate %f.\n", val);
hr = IMFMediaEngine_SetDefaultPlaybackRate(media_engine, 2.0); -todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
val = IMFMediaEngine_GetPlaybackRate(media_engine); -todo_wine ok(val == 1.0, "Unexpected rate %f.\n", val);
hr = IMFMediaEngine_GetPlayed(media_engine, &time_range); @@ -440,6 +437,34 @@ static void test_Play(void) IMFMediaEngine_Release(media_engine); }
+static void test_playback_rate(void) +{ + struct media_engine_notify notify_impl = {{&media_engine_notify_vtbl}, 1}; + IMFMediaEngineNotify *callback = ¬ify_impl.IMFMediaEngineNotify_iface; + IMFMediaEngine *media_engine; + double rate; + HRESULT hr; + + media_engine = create_media_engine(callback); + + rate = IMFMediaEngine_GetDefaultPlaybackRate(media_engine); + ok(rate == 1.0, "Unexpected default rate.\n"); + + rate = IMFMediaEngine_GetPlaybackRate(media_engine); + ok(rate == 1.0, "Unexpected default rate.\n"); + + hr = IMFMediaEngine_SetPlaybackRate(media_engine, 0.0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + rate = IMFMediaEngine_GetPlaybackRate(media_engine); + ok(rate == 0.0, "Unexpected default rate.\n"); + + hr = IMFMediaEngine_SetDefaultPlaybackRate(media_engine, 0.0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMFMediaEngine_Release(media_engine); +} + START_TEST(mfmediaengine) { HRESULT hr; @@ -464,6 +489,7 @@ START_TEST(mfmediaengine) test_CreateInstance(); test_Shutdown(); test_Play(); + test_playback_rate();
IMFMediaEngineClassFactory_Release(factory);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/main.c | 29 ++++++++++++++++++--- dlls/mfmediaengine/tests/mfmediaengine.c | 32 ++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index b9bf3c7027b..731bccb581d 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -63,6 +63,7 @@ enum media_engine_flags FLAGS_ENGINE_LOOP = 0x80, FLAGS_ENGINE_PAUSED = 0x100, FLAGS_ENGINE_WAITING = 0x200, + FLAGS_ENGINE_MUTED = 0x400, };
struct media_engine @@ -542,16 +543,36 @@ static HRESULT WINAPI media_engine_Pause(IMFMediaEngine *iface)
static BOOL WINAPI media_engine_GetMuted(IMFMediaEngine *iface) { - FIXME("(%p): stub.\n", iface); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + BOOL ret;
- return FALSE; + TRACE("%p.\n", iface); + + EnterCriticalSection(&engine->cs); + ret = !!(engine->flags & FLAGS_ENGINE_MUTED); + LeaveCriticalSection(&engine->cs); + + return ret; }
static HRESULT WINAPI media_engine_SetMuted(IMFMediaEngine *iface, BOOL muted) { - FIXME("(%p, %d): stub.\n", iface, muted); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %d.\n", iface, muted); + + EnterCriticalSection(&engine->cs); + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else if (!!(engine->flags & FLAGS_ENGINE_MUTED) ^ !!muted) + { + media_engine_set_flag(engine, FLAGS_ENGINE_MUTED, muted); + IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE, 0, 0); + } + LeaveCriticalSection(&engine->cs); + + return hr; }
static double WINAPI media_engine_GetVolume(IMFMediaEngine *iface) diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 4079e9aa70f..0839d1d4451 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -361,14 +361,13 @@ todo_wine ok(!state, "Unexpected state.\n");
hr = IMFMediaEngine_SetMuted(media_engine, TRUE); -todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
val = IMFMediaEngine_GetVolume(media_engine); todo_wine ok(val == 1.0, "Unexpected value %f.\n", val);
- val = IMFMediaEngine_SetVolume(media_engine, 2.0); + hr = IMFMediaEngine_SetVolume(media_engine, 2.0); todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
@@ -465,6 +464,34 @@ static void test_playback_rate(void) IMFMediaEngine_Release(media_engine); }
+static void test_mute(void) +{ + struct media_engine_notify notify_impl = {{&media_engine_notify_vtbl}, 1}; + IMFMediaEngineNotify *callback = ¬ify_impl.IMFMediaEngineNotify_iface; + IMFMediaEngine *media_engine; + HRESULT hr; + BOOL ret; + + media_engine = create_media_engine(callback); + + ret = IMFMediaEngine_GetMuted(media_engine); + ok(!ret, "Unexpected state.\n"); + + hr = IMFMediaEngine_SetMuted(media_engine, TRUE); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + ret = IMFMediaEngine_GetMuted(media_engine); + ok(ret, "Unexpected state.\n"); + + hr = IMFMediaEngine_Shutdown(media_engine); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + ret = IMFMediaEngine_GetMuted(media_engine); + ok(ret, "Unexpected state.\n"); + + IMFMediaEngine_Release(media_engine); +} + START_TEST(mfmediaengine) { HRESULT hr; @@ -490,6 +517,7 @@ START_TEST(mfmediaengine) test_Shutdown(); test_Play(); test_playback_rate(); + test_mute();
IMFMediaEngineClassFactory_Release(factory);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/main.c | 30 ++++++++++++++++++++---- dlls/mfmediaengine/tests/mfmediaengine.c | 2 -- 2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index 731bccb581d..59006e64ca7 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -79,6 +79,7 @@ struct media_engine unsigned int flags; double playback_rate; double default_playback_rate; + double volume; IMFMediaSession *session; CRITICAL_SECTION cs; }; @@ -577,16 +578,36 @@ static HRESULT WINAPI media_engine_SetMuted(IMFMediaEngine *iface, BOOL muted)
static double WINAPI media_engine_GetVolume(IMFMediaEngine *iface) { - FIXME("(%p): stub.\n", iface); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + double volume;
- return 0.0; + TRACE("%p.\n", iface); + + EnterCriticalSection(&engine->cs); + volume = engine->volume; + LeaveCriticalSection(&engine->cs); + + return volume; }
static HRESULT WINAPI media_engine_SetVolume(IMFMediaEngine *iface, double volume) { - FIXME("(%p, %f): stub.\n", iface, volume); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %f.\n", iface, volume); + + EnterCriticalSection(&engine->cs); + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else if (volume != engine->volume) + { + engine->volume = volume; + IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE, 0, 0); + } + LeaveCriticalSection(&engine->cs); + + return hr; }
static BOOL WINAPI media_engine_HasVideo(IMFMediaEngine *iface) @@ -737,6 +758,7 @@ static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct engine->flags = (flags & MF_MEDIA_ENGINE_CREATEFLAGS_MASK) | FLAGS_ENGINE_PAUSED; engine->default_playback_rate = 1.0; engine->playback_rate = 1.0; + engine->volume = 1.0; InitializeCriticalSection(&engine->cs);
hr = IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, &IID_IMFMediaEngineNotify, diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 0839d1d4451..a5b80ef25f4 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -364,11 +364,9 @@ todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
val = IMFMediaEngine_GetVolume(media_engine); -todo_wine ok(val == 1.0, "Unexpected value %f.\n", val);
hr = IMFMediaEngine_SetVolume(media_engine, 2.0); -todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
state = IMFMediaEngine_HasVideo(media_engine);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index 59006e64ca7..5ec179614d0 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -762,9 +762,9 @@ static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct InitializeCriticalSection(&engine->cs);
hr = IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, &IID_IMFMediaEngineNotify, - (void **)&engine->callback); + (void **)&engine->callback); if (FAILED(hr)) - return MF_E_ATTRIBUTENOTFOUND; + return hr;
if (FAILED(hr = MFCreateMediaSession(NULL, &engine->session))) return hr;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/Makefile.in | 2 +- dlls/mfmediaengine/main.c | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/dlls/mfmediaengine/Makefile.in b/dlls/mfmediaengine/Makefile.in index 2278e87a645..cb593cb7edf 100644 --- a/dlls/mfmediaengine/Makefile.in +++ b/dlls/mfmediaengine/Makefile.in @@ -1,6 +1,6 @@ MODULE = mfmediaengine.dll IMPORTLIB = mfmediaengine -IMPORTS = mf mfuuid uuid +IMPORTS = mfplat mf mfuuid uuid
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index 5ec179614d0..2a390cbd77f 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -72,9 +72,7 @@ struct media_engine IMFAsyncCallback session_events; LONG refcount; IMFMediaEngineNotify *callback; - UINT64 playback_hwnd; - DXGI_FORMAT output_format; - IMFDXGIDeviceManager *dxgi_manager; + IMFAttributes *attributes; enum media_engine_mode mode; unsigned int flags; double playback_rate; @@ -192,10 +190,10 @@ static void free_media_engine(struct media_engine *engine) { if (engine->callback) IMFMediaEngineNotify_Release(engine->callback); - if (engine->dxgi_manager) - IMFDXGIDeviceManager_Release(engine->dxgi_manager); if (engine->session) IMFMediaSession_Release(engine->session); + if (engine->attributes) + IMFAttributes_Release(engine->attributes); DeleteCriticalSection(&engine->cs); heap_free(engine); } @@ -750,6 +748,8 @@ static ULONG WINAPI media_engine_factory_Release(IMFMediaEngineClassFactory *ifa
static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct media_engine *engine) { + DXGI_FORMAT output_format; + UINT64 playback_hwnd; HRESULT hr;
engine->IMFMediaEngine_iface.lpVtbl = &media_engine_vtbl; @@ -772,11 +772,15 @@ static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct if (FAILED(hr = IMFMediaSession_BeginGetEvent(engine->session, &engine->session_events, NULL))) return hr;
- IMFAttributes_GetUINT64(attributes, &MF_MEDIA_ENGINE_PLAYBACK_HWND, &engine->playback_hwnd); - IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_DXGI_MANAGER, &IID_IMFDXGIDeviceManager, - (void **)&engine->dxgi_manager); - hr = IMFAttributes_GetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, &engine->output_format); - if (engine->playback_hwnd) /* FIXME: handle MF_MEDIA_ENGINE_PLAYBACK_VISUAL */ + if (FAILED(hr = MFCreateAttributes(&engine->attributes, 0))) + return hr; + + if (FAILED(hr = IMFAttributes_CopyAllItems(attributes, engine->attributes))) + return hr; + + IMFAttributes_GetUINT64(attributes, &MF_MEDIA_ENGINE_PLAYBACK_HWND, &playback_hwnd); + hr = IMFAttributes_GetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, &output_format); + if (playback_hwnd) /* FIXME: handle MF_MEDIA_ENGINE_PLAYBACK_VISUAL */ engine->mode = MEDIA_ENGINE_RENDERING_MODE; else {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=72627
Your paranoid android.
=== debiant (build log) ===
/home/winetest/tools/testbot/var/wine-win32/dlls/mfmediaengine/../../../wine/dlls/mfmediaengine/main.c:775: undefined reference to `MFCreateAttributes' collect2: error: ld returned 1 exit status Task: The win32 Wine build failed
=== debiant (build log) ===
/home/winetest/tools/testbot/var/wine-wow32/dlls/mfmediaengine/../../../wine/dlls/mfmediaengine/main.c:775: undefined reference to `MFCreateAttributes' collect2: error: ld returned 1 exit status Task: The wow32 Wine build failed
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/main.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index 2a390cbd77f..80226f9d22a 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -136,10 +136,32 @@ static HRESULT WINAPI media_engine_session_events_Invoke(IMFAsyncCallback *iface { struct media_engine *engine = impl_from_session_events_IMFAsyncCallback(iface); IMFMediaEvent *event = NULL; + MediaEventType event_type; HRESULT hr;
if (FAILED(hr = IMFMediaSession_EndGetEvent(engine->session, result, &event))) + { WARN("Failed to get session event, hr %#x.\n", hr); + goto failed; + } + + if (FAILED(hr = IMFMediaEvent_GetType(event, &event_type))) + { + WARN("Failed to get event type, hr %#x.\n", hr); + goto failed; + } + + switch (event_type) + { + case MEBufferingStarted: + case MEBufferingStopped: + + IMFMediaEngineNotify_EventNotify(engine->callback, event_type == MEBufferingStarted ? + MF_MEDIA_ENGINE_EVENT_BUFFERINGSTARTED : MF_MEDIA_ENGINE_EVENT_BUFFERINGENDED, 0, 0); + break; + } + +failed:
if (event) IMFMediaEvent_Release(event);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=72628
Your paranoid android.
=== debiant (build log) ===
/home/winetest/tools/testbot/var/wine-win32/dlls/mfmediaengine/../../../wine/dlls/mfmediaengine/main.c:797: undefined reference to `MFCreateAttributes' collect2: error: ld returned 1 exit status Task: The win32 Wine build failed
=== debiant (build log) ===
/home/winetest/tools/testbot/var/wine-wow32/dlls/mfmediaengine/../../../wine/dlls/mfmediaengine/main.c:797: undefined reference to `MFCreateAttributes' collect2: error: ld returned 1 exit status Task: The wow32 Wine build failed