[PATCH v3 4/6] wmp: Add seeking and duration

Anton Romanov theli.ua at gmail.com
Thu Mar 15 23:26:03 CDT 2018


Signed-off-by: Anton Romanov <theli.ua at gmail.com>
---
 dlls/wmp/player.c      | 60 +++++++++++++++++++++++++++++++++++++++++++-------
 dlls/wmp/tests/media.c | 33 +++++++++++++++++++++++++++
 dlls/wmp/wmp_private.h |  3 +++
 3 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c
index 799de2c4f1..cbd84356ab 100644
--- a/dlls/wmp/player.c
+++ b/dlls/wmp/player.c
@@ -1377,8 +1377,22 @@ static HRESULT WINAPI WMPControls_Invoke(IWMPControls *iface, DISPID dispIdMembe
 static HRESULT WINAPI WMPControls_get_isAvailable(IWMPControls *iface, BSTR bstrItem, VARIANT_BOOL *pIsAvailable)
 {
     WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
-    FIXME("(%p)->(%s)\n", This, debugstr_w(bstrItem));
-    return E_NOTIMPL;
+    static const WCHAR currentPosition[] = {'c','u','r','r','e','n','t','P','o','s','i','t','i','o','n',0};
+    TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrItem), pIsAvailable);
+    *pIsAvailable = VARIANT_FALSE;
+    if (!This->pFilterGraph) {
+        *pIsAvailable = VARIANT_FALSE;
+    } else if (strcmpW(currentPosition, bstrItem) == 0) {
+        DWORD capabilities;
+        IMediaSeeking_GetCapabilities(This->media_seeking, &capabilities);
+        *pIsAvailable = (capabilities & AM_SEEKING_CanSeekAbsolute) ?
+            VARIANT_TRUE : VARIANT_FALSE;
+    } else {
+        FIXME("%s not implemented\n", debugstr_w(bstrItem));
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
@@ -1408,6 +1422,11 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
         if (SUCCEEDED(hres))
             hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl,
                     (void**)&This->media_control);
+        if (SUCCEEDED(hres))
+            hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaSeeking,
+                    (void**)&This->media_seeking);
+        if (SUCCEEDED(hres))
+            hres = IMediaSeeking_SetTimeFormat(This->media_seeking, &TIME_FORMAT_MEDIA_TIME);
         update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN);
         if (SUCCEEDED(hres))
             hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaEvent,
@@ -1426,7 +1445,10 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
     }
 
     if (SUCCEEDED(hres)) {
+        LONGLONG duration;
         update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_PLAYING);
+        if (SUCCEEDED(IMediaSeeking_GetDuration(This->media_seeking, &duration)))
+            media->duration = (DOUBLE)duration / 10000000.0f;
     } else {
         update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_UNDEFINED);
     }
@@ -1450,6 +1472,7 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface)
     IGraphBuilder_Release(This->pFilterGraph);
     IMediaControl_Release(This->media_control);
     IMediaEvent_Release(This->media_event);
+    IMediaSeeking_Release(This->media_seeking);
 
     This->pFilterGraph = NULL;
     This->media_control = NULL;
@@ -1488,15 +1511,33 @@ static HRESULT WINAPI WMPControls_fastReverse(IWMPControls *iface)
 static HRESULT WINAPI WMPControls_get_currentPosition(IWMPControls *iface, DOUBLE *pdCurrentPosition)
 {
     WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
-    FIXME("(%p)->(%p)\n", This, pdCurrentPosition);
-    return E_NOTIMPL;
+    HRESULT hres;
+    LONGLONG currentPosition;
+
+    TRACE("(%p)->(%p)\n", This, pdCurrentPosition);
+    if (!This->media_seeking)
+        return S_FALSE;
+
+    hres = IMediaSeeking_GetCurrentPosition(This->media_seeking, &currentPosition);
+    *pdCurrentPosition = (DOUBLE) currentPosition / 10000000.0f;
+    TRACE("hres: %d, pos: %f\n", hres, *pdCurrentPosition);
+    return hres;
 }
 
 static HRESULT WINAPI WMPControls_put_currentPosition(IWMPControls *iface, DOUBLE dCurrentPosition)
 {
+    LONGLONG Current;
+    HRESULT hres;
     WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
-    FIXME("(%p)->(%f)\n", This, dCurrentPosition);
-    return E_NOTIMPL;
+    TRACE("(%p)->(%f)\n", This, dCurrentPosition);
+    if (!This->media_seeking)
+        return S_FALSE;
+
+    Current = 10000000 * dCurrentPosition;
+    hres = IMediaSeeking_SetPositions(This->media_seeking, &Current,
+            AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+
+    return hres;
 }
 
 static HRESULT WINAPI WMPControls_get_currentPositionString(IWMPControls *iface, BSTR *pbstrCurrentPosition)
@@ -1733,9 +1774,12 @@ static HRESULT WINAPI WMPMedia_getMarkerName(IWMPMedia *iface, LONG MarkerNum, B
 
 static HRESULT WINAPI WMPMedia_get_duration(IWMPMedia *iface, DOUBLE *pDuration)
 {
+    /* MSDN: If this property is used with a media item other than the one 
+     * specified in Player.currentMedia, it may not contain a valid value. */
     WMPMedia *This = impl_from_IWMPMedia(iface);
-    FIXME("(%p)->(%p)\n", This, pDuration);
-    return E_NOTIMPL;
+    TRACE("(%p)->(%p)\n", This, pDuration);
+    *pDuration = This->duration;
+    return S_OK;
 }
 
 static HRESULT WINAPI WMPMedia_get_durationString(IWMPMedia *iface, BSTR *pbstrDuration)
diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c
index f98a60fbfd..b6849b0657 100644
--- a/dlls/wmp/tests/media.c
+++ b/dlls/wmp/tests/media.c
@@ -190,6 +190,11 @@ static void test_wmp(void)
     IOleObject *oleobj;
     static DWORD dw = 100;
     IWMPSettings *settings;
+    DOUBLE duration;
+    VARIANT_BOOL vbool;
+    IWMPMedia *media;
+    static const WCHAR currentPosition[] = {'c','u','r','r','e','n','t','P','o','s','i','t','i','o','n',0};
+    BSTR bstrcurrentPosition = SysAllocString(currentPosition);
 
     hres = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IOleObject, (void**)&oleobj);
     if(hres == REGDB_E_CLASSNOTREG) {
@@ -227,6 +232,10 @@ static void test_wmp(void)
     ok(hres == S_OK, "get_controls failed: %08x\n", hres);
     ok(controls != NULL, "controls = NULL\n");
 
+    hres = IWMPControls_get_isAvailable(controls, bstrcurrentPosition, &vbool);
+    ok(hres == S_OK, "IWMPControls_get_isAvailable failed: %08x\n", hres);
+    ok(vbool == VARIANT_FALSE, "unexpected value\n");
+
     hres = IWMPControls_play(controls);
     ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_play is available: %08x\n", hres);
 
@@ -274,6 +283,29 @@ static void test_wmp(void)
     CHECK_CALLED(OPENSTATE_CHANGE);
     CHECK_CALLED(PLAYSTATE_CHANGE);
 
+    hres = IWMPControls_get_isAvailable(controls, bstrcurrentPosition, &vbool);
+    ok(hres == S_OK, "IWMPControls_get_isAvailable failed: %08x\n", hres);
+    ok(vbool == VARIANT_TRUE, "unexpected value\n");
+
+    duration = 0.0;
+    hres = IWMPControls_get_currentPosition(controls, &duration);
+    ok(hres == S_OK, "IWMPControls_get_currentPosition failed: %08x\n", hres);
+    ok((int)duration == 0, "unexpected value %f\n", duration);
+
+    hres = IWMPControls_put_currentPosition(controls, duration);
+    ok(hres == S_OK, "IWMPControls_put_currentPosition failed: %08x\n", hres);
+
+    hres = IWMPPlayer4_get_currentMedia(player4, &media);
+    ok(hres == S_OK, "IWMPPlayer4_get_currentMedia failed: %08x\n", hres);
+    hres = IWMPMedia_get_duration(media, &duration);
+    ok(hres == S_OK, "IWMPMedia_get_duration failed: %08x\n", hres);
+    ok(
+            round(duration) == 60 ||
+            broken(round(duration) == 30) ||
+            broken(round(duration) == 57)
+            , "unexpected value: %f\n", duration);
+    IWMPMedia_Release(media);
+
     SET_EXPECT(OPENSTATE_CHANGE); todo_wine ok(FALSE || broken(TRUE), "WMP in wine changes open state when stopping\n");
     SET_EXPECT(PLAYSTATE_CHANGE);
     hres = IWMPControls_stop(controls);
@@ -301,6 +333,7 @@ playback_skip:
     IOleObject_Release(oleobj);
     DeleteFileW(filename);
     SysFreeString(filename);
+    SysFreeString(bstrcurrentPosition);
 }
 
 START_TEST(media)
diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
index c7575b4919..0737b5d857 100644
--- a/dlls/wmp/wmp_private.h
+++ b/dlls/wmp/wmp_private.h
@@ -42,6 +42,8 @@ typedef struct {
     LONG ref;
 
     WCHAR *url;
+
+    DOUBLE duration;
 } WMPMedia;
 
 struct WindowsMediaPlayer {
@@ -76,6 +78,7 @@ struct WindowsMediaPlayer {
     IGraphBuilder* pFilterGraph;
     IMediaControl* media_control;
     IMediaEvent*  media_event;
+    IMediaSeeking*  media_seeking;
 
     /* Async event notification */
     HANDLE event_thread;
-- 
2.16.2




More information about the wine-devel mailing list