Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 62 +++++++++++++++++++++++++++++++++++--- dlls/mfplay/tests/mfplay.c | 37 ++++++++++++++++++++++- 2 files changed, 94 insertions(+), 5 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 6e0629ca0bc..7d9a4da8649 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1104,16 +1104,44 @@ static HRESULT WINAPI media_player_GetDuration(IMFPMediaPlayer *iface, REFGUID p
static HRESULT WINAPI media_player_SetRate(IMFPMediaPlayer *iface, float rate) { - FIXME("%p, %f.\n", iface, rate); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFRateControl *rate_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %f.\n", iface, rate); + + if (rate == 0.0f) + return MF_E_OUT_OF_RANGE; + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, + (void **)&rate_control))) + { + hr = IMFRateControl_SetRate(rate_control, FALSE, rate); + IMFRateControl_Release(rate_control); + } + + return hr; }
static HRESULT WINAPI media_player_GetRate(IMFPMediaPlayer *iface, float *rate) { - FIXME("%p, %p.\n", iface, rate); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFRateControl *rate_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, rate); + + if (!rate) + return E_POINTER; + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, + (void **)&rate_control))) + { + hr = IMFRateControl_GetRate(rate_control, NULL, rate); + IMFRateControl_Release(rate_control); + } + + return hr; }
static HRESULT WINAPI media_player_GetSupportedRates(IMFPMediaPlayer *iface, BOOL forward, @@ -2094,6 +2122,17 @@ static void media_player_playback_ended(struct media_player *player, HRESULT eve LeaveCriticalSection(&player->cs); }
+static void media_player_rate_changed(struct media_player *player, HRESULT event_status, + float rate, struct media_event **event) +{ + EnterCriticalSection(&player->cs); + + if (SUCCEEDED(media_event_create(player, MFP_EVENT_TYPE_RATE_SET, event_status, player->item, event))) + (*event)->u.rate_set.flRate = rate; + + LeaveCriticalSection(&player->cs); +} + static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { @@ -2106,6 +2145,7 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba IMFTopology *topology; unsigned int status; PROPVARIANT value; + float rate;
if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &session_event))) return S_OK; @@ -2160,6 +2200,20 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba
break;
+ case MESessionRateChanged: + + rate = 0.0f; + if (SUCCEEDED(IMFMediaEvent_GetValue(session_event, &value))) + { + if (value.vt == VT_R4) + rate = value.fltVal; + PropVariantClear(&value); + } + + media_player_rate_changed(player, event_status, rate, &event); + + break; + case MEBufferingStarted: case MEBufferingStopped: case MEExtendedType: diff --git a/dlls/mfplay/tests/mfplay.c b/dlls/mfplay/tests/mfplay.c index 12825ba29da..50ecb1b09b9 100644 --- a/dlls/mfplay/tests/mfplay.c +++ b/dlls/mfplay/tests/mfplay.c @@ -171,10 +171,10 @@ static void test_create_player(void) static void test_shutdown(void) { SIZE size, min_size, max_size; + float slowest, fastest, rate; MFP_MEDIAPLAYER_STATE state; MFVideoNormalizedRect rect; IMFPMediaPlayer *player; - float slowest, fastest; IMFPMediaItem *item; PROPVARIANT propvar; COLORREF color; @@ -263,6 +263,15 @@ static void test_shutdown(void) hr = IMFPMediaPlayer_GetPosition(player, &MFP_POSITIONTYPE_100NS, &propvar); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+ hr = IMFPMediaPlayer_SetRate(player, 2.0f); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + + hr = IMFPMediaPlayer_GetRate(player, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IMFPMediaPlayer_GetRate(player, &rate); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + hr = IMFPMediaPlayer_Shutdown(player); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
@@ -548,6 +557,31 @@ static void test_duration(void) IMFPMediaPlayer_Release(player); }
+static void test_playback_rate(void) +{ + IMFPMediaPlayer *player; + float rate; + HRESULT hr; + + hr = MFPCreateMediaPlayer(NULL, FALSE, 0, NULL, NULL, &player); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFPMediaPlayer_SetRate(player, 0.0f); + ok(hr == MF_E_OUT_OF_RANGE, "Unexpected hr %#lx.\n", hr); + + hr = IMFPMediaPlayer_SetRate(player, 2.0f); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFPMediaPlayer_GetRate(player, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IMFPMediaPlayer_GetRate(player, &rate); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(rate == 1.0f, "Unexpected rate %f.\n", rate); + + IMFPMediaPlayer_Release(player); +} + START_TEST(mfplay) { test_create_player(); @@ -555,4 +589,5 @@ START_TEST(mfplay) test_media_item(); test_video_control(); test_duration(); + test_playback_rate(); }
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=108056
Your paranoid android.
=== debian11 (32 bit report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit Arabic:Morocco report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit German report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit French report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit Hebrew:Israel report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit Hindi:India report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit Japanese:Japan report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit Chinese:China report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (32 bit WoW report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
=== debian11 (64 bit WoW report) ===
mfplay: mfplay.c:573: Test failed: Unexpected hr 0x80004001.
Sorry, that depends on first 3 patches that are already on the list.