[PATCH v13 1/3] wmp: Add seeking and duration

Anton Romanov theli.ua at gmail.com
Tue Apr 17 00:52:08 CDT 2018


Signed-off-by: Anton Romanov <theli.ua at gmail.com>
---

Changed test media file that works now consistently across all windows VMs 
as far as duration goes. Hopefully this'll help different versions of
gstreamer as well.
Removed all but 60 as accepted duration in tests.

 dlls/wmp/player.c       |  65 +++++++++++++++++++++++++++++++++-------
 dlls/wmp/tests/media.c  |  37 +++++++++++++++++++++++
 dlls/wmp/tests/rsrc.rc  |   2 +-
 dlls/wmp/tests/test.mp3 | Bin 240333 -> 240333 bytes
 dlls/wmp/wmp_private.h  |   3 ++
 5 files changed, 96 insertions(+), 11 deletions(-)

diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c
index f4ce62a447..8448916a80 100644
--- a/dlls/wmp/player.c
+++ b/dlls/wmp/player.c
@@ -1396,8 +1396,21 @@ 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);
+    if (!This->filter_graph) {
+        *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)
@@ -1428,11 +1441,16 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
 
         if (SUCCEEDED(hres))
             hres = IGraphBuilder_RenderFile(This->filter_graph, media->url, NULL);
+        if (SUCCEEDED(hres))
+            update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposMediaOpen);
         if (SUCCEEDED(hres))
             hres = IGraphBuilder_QueryInterface(This->filter_graph, &IID_IMediaControl,
                     (void**)&This->media_control);
         if (SUCCEEDED(hres))
-            update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposMediaOpen);
+            hres = IGraphBuilder_QueryInterface(This->filter_graph, &IID_IMediaSeeking,
+                    (void**)&This->media_seeking);
+        if (SUCCEEDED(hres))
+            hres = IMediaSeeking_SetTimeFormat(This->media_seeking, &TIME_FORMAT_MEDIA_TIME);
         if (SUCCEEDED(hres))
             hres = IGraphBuilder_QueryInterface(This->filter_graph, &IID_IMediaEvent,
                     (void**)&This->media_event);
@@ -1459,7 +1477,10 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
     }
 
     if (SUCCEEDED(hres)) {
+        LONGLONG duration;
         update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsPlaying);
+        if (SUCCEEDED(IMediaSeeking_GetDuration(This->media_seeking, &duration)))
+            media->duration = (DOUBLE)duration / 10000000.0f;
     } else {
         update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsUndefined);
     }
@@ -1482,11 +1503,14 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface)
     if (This->media_event) {
         IMediaEvent_Release(This->media_event);
     }
-
+    if (This->media_seeking) {
+        IMediaSeeking_Release(This->media_seeking);
+    }
     IGraphBuilder_Release(This->filter_graph);
     This->filter_graph = NULL;
     This->media_control = NULL;
     This->media_event = NULL;
+    This->media_seeking = NULL;
 
     update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistOpenNoMedia);
     update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsStopped);
@@ -1517,15 +1541,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)
@@ -1762,9 +1804,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 c2cd1cf941..f242ac90a5 100644
--- a/dlls/wmp/tests/media.c
+++ b/dlls/wmp/tests/media.c
@@ -303,6 +303,11 @@ static BOOL test_wmp(void)
     static DWORD dw = 100;
     IWMPSettings *settings;
     BOOL test_ran = TRUE;
+    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) {
@@ -338,6 +343,10 @@ static BOOL 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);
 
@@ -380,6 +389,33 @@ static BOOL test_wmp(void)
     /* MediaOpening happens only on xp, 2003 */
     CLEAR_CALLED(OPENSTATE, wmposMediaOpening);
 
+    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);
+
+    duration = 15.0;
+    hres = IWMPControls_put_currentPosition(controls, duration);
+    ok(hres == S_OK, "IWMPControls_put_currentPosition failed: %08x\n", hres);
+
+    duration = 0.0;
+    hres = IWMPControls_get_currentPosition(controls, &duration);
+    ok(hres == S_OK, "IWMPControls_get_currentPosition failed: %08x\n", hres);
+    /* builtin quartz does not handle this currently and resets to 0.0, works
+     * with native quartz */
+    todo_wine ok((int)duration >= 15.0, "unexpected value %f\n", duration);
+
+    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, "unexpected value: %f\n", duration);
+    IWMPMedia_Release(media);
+
     SET_EXPECT(PLAYSTATE, wmppsStopped);
     /* The following happens on wine only since we close media on stop */
     SET_EXPECT(OPENSTATE, wmposPlaylistOpenNoMedia);
@@ -414,6 +450,7 @@ playback_skip:
     IOleObject_Release(oleobj);
     DeleteFileW(filename);
     SysFreeString(filename);
+    SysFreeString(bstrcurrentPosition);
 
     return test_ran;
 }
diff --git a/dlls/wmp/tests/rsrc.rc b/dlls/wmp/tests/rsrc.rc
index a92079e798..7ce8c4b687 100644
--- a/dlls/wmp/tests/rsrc.rc
+++ b/dlls/wmp/tests/rsrc.rc
@@ -18,7 +18,7 @@
 
 #include "windef.h"
 
-/* ffmpeg -ar 48000 -t 60 -f s16le -acodec pcm_s16le -ac 2 -i /dev/zero -acodec libmp3lame -aq 4 output.mp3 */
+/* ffmpeg -f lavfi -i anullsrc=r=48000:cl=4 -t 60 -acodec libmp3lame -aq 4 dlls/wmp/tests/test.mp3 */
 /* @makedep: test.mp3 */
 test.mp3 RCDATA "test.mp3"
 /* ffmpeg -ar 48000 -t 1 -f s16le -acodec pcm_s16le -ac 2 -i /dev/zero -acodec libmp3lame -aq 4 test1s.mp3 */
diff --git a/dlls/wmp/tests/test.mp3 b/dlls/wmp/tests/test.mp3
index 149a2cd346ee52ae179c46198ce290a5dd4d6251..a8f22ce279cda0861cefe6851dcae0bced1372ad 100644
GIT binary patch
literal 240333
zcmeIxVWgdP9Ki9X?nXsMMod)NB697zTaCn0m$o+1ZbrsTx%MKf#3W)&WJV%Il2WE6
ziHzBlD@`Oa#*{=N5s5^ataI*ObidzMn|9cX at AKk0|L^mh=YM|Z<D4xI%&r*5$8GaF
zcFc`lR}I6|wmth7Hr_qGX?A*M{raW57f$ET%`Yy?3(GD07M>cdM$cV)YMA=q?O|%=
zHP>Cg>W0-fuDR*vTi4!x$DPwNvv+N}=ibft&po(x`@@gS?|f|6?mbT|?0s_IGtcgS
z?)euE9DMPmLx*2}<<-~Uc=N4y-aYdEhaY|X$+6=nK3)9$)R$j<{mtn!XTSaahaZ3X
z`IldR`~8nU|N8r%@h6Xle0((I%<=(;wO4N*-y6?y^t0)mOY8qm=g+PFVwhSSu6l2D
z?UrHKa9|i#Y`bs!+|n0)bbPRuE?xX-y#Km`+MkdA at BJV0{FizErzbrBYZIRT<b>z{
zZo>1oKY!56YyAJpXSoR1`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCF
zMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCF
zMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCF
zMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCF
zMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCF
zMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCF
zMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCF
zMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|
z(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3a
zk44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(
z`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at I
zm5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk
z*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!
z!<COk*!j at Im5)W(`Ow3ak44z|(8HCFMcDb!!<COk*!j at Im5)W(`Ow3ak44z|(8F~F
X_;{pC>Wi5FlJ at hP+utJWN&EZ at Ay;|i

literal 240333
zcmeI%f23Xo0LJlCcd=qF8IkluD<ZR5KSsq;mzGVmT``eqrkEu$6EP~1m`IVNlq5-1
zBqA}9NQp$^ij2req${`gz5Vg*;oRHE``_o9?faaU<K1!gx#zyyedmr1!}ROw{rmPU
zO#Yl7hPgclj~%}8=B+z-Y~8+X+v=<T{<gBb|Ex8hyN at 1zWb(@7G#8#4=H7X2n7d%(
zMVsa?-h9cWmtAqymTRxOe(UxfH|@OTwq18D+;#Wfd+yzT-+}udIC$vrLr0E2`q;7K
zk3VtZ$)}%r_PLYKzwpw_ue|#D8*jb+?tAZl at X^PgeEQkvr at r{|tFOQL?)x8p{Auau
zUrzt}+nL}0`17y7r|)F)o*$gN=j~^|-(k!7yQZ&A-^a=|Pn}*_-h617KQjyuPmXOI
zhD}!v!+DcmZ%*bUZ#Xdw8}{73cVYGKy*To<?u(0y)AL{cALk!AYYv^m`EQ-^`47za
z{Ksc}{ugI_{tst-{%>b|{-u-a-~YK8N9r8zPv at VaIdbhLho(NbKCaLB-7z`p-`9pU
zug&xY*T?no{mb{4wUFQgANarrKCJoq##)zV^*BHI$xnW+g#;h?zz06?!SmI~J>c{0
z_5SnF=l?#x9XvmHe(?M-^1WmAke at I3zz06?!Os^X_kf=-{CqKTTjY at E2hR_lA3Q%q
zgf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8gT7@h=@PQ9}hzMPL
z-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1eBc8g_z)4g_`nA~
z at S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIUKJXzTbn$@?eBeW?
zki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE724}9Q5MCjrJANatBRw0WI
zeBc8gB0?7*_`nA~v<g{#-~%7{5D~igzz06?p;gG at 10VRnhltR{2R`tD53NELANarr
zK175rKJbALd}tN2_`nA~@F5~}@qrI~;6tmB#Rop{fe#U(iw}I at 10Pz2EI#mo4}6FS
zU3}mJANbHJWbuIyeBeVw=;8w(_`ru&A&U=u-~%5bLKh$Szz06G3R!&M10VPh5xV%m
z2R`tjRmkE4ANatBh|t9cKJbALtwI(b_`nA~M1(Fr at PQ9}Xce;fzz06?AtH3~fe(D(
zL#vR*2R`tD4-uh at 4}9PQA6kVhKJbALe255LeBc8g_|Ph3 at qrI~;6p^{;sYP}z=u{L
ziw}I at 10Nzn7a#b*2R^h4S$yCFANUXvy7<5cKJcMc$l?PZ_`rvV(8UKn at PQAlLKYwR
zzz04=gf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8gT7@h=@PQ9}
zhzMPL-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1eBc8g_z)4g
z_`nA~@S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIUKJXzTbn$@?
zeBeW?ki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE724}9Q5MCjrJANatB
zRw0WIeBc8gB0?7*_`nA~v<g{#-~%7{5D~igzz06?p;gG at 10VRnhltR{2R`tD53NEL
zANarrK175rKJbALd}tN2_`nA~@F5~}@qrI~;6tmB#Rop{fe#U(iw}I at 10Pz2EI#mo
z4}6FSU3}mJANbHJWbuIyeBeVw=;8w(_`ru&A&U=u-~%5bLKh$Szz06G3R!&M10VPh
z5xV%m2R`tjRmkE4ANatBh|t9cKJbALtwI(b_`nA~M1(Fr at PQ9}Xce;fzz06?AtH3~
zfe(D(L#vR*2R`tD4-uh at 4}9PQA6kVhKJbALe255LeBc8g_|Ph3 at qrI~;6p^{;sYP}
zz=u{Liw}I at 10Nzn7a#b*2R^h4S$yCFANUXvy7<5cKJcMc$l?PZ_`rvV(8UKn at PQAl
zLKYwRzz04=gf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8gT7@h=
z at PQ9}hzMPL-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1eBc8g
z_z)4g_`nA~@S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIUKJXzT
zbn$@?eBeW?ki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE724}9Q5MCjrJ
zANatBRw0WIeBc8gB0?7*_`nA~v<g{#-~%7{5D~igzz06?p;gG at 10VRnhltR{2R`tD
z53NELANarrK175rKJbALd}tN2_`nA~@F5~}@qrI~;6tmB#Rop{fe#U(iw}I at 10Pz2
zEI#mo4}6FSU3}mJANbHJWbuIyeBeVw=;8w(_`ru&A&U=u-~%5bLKh$Szz06G3R!&M
z10VPh5xV%m2R`tjRmkE4ANatBh|t9cKJbALtwI(b_`nA~M1(Fr at PQ9}Xce;fzz06?
zAtH3~fe(D(L#vR*2R`tD4-uh at 4}9PQA6kVhKJbALe255LeBc8g_|Ph3 at qrI~;6p^{
z;sYP}z=u{Liw}I at 10Nzn7a#b*2R^h4S$yCFANUXvy7<5cKJcMc$l?PZ_`rvV(8UKn
z at PQAlLKYwRzz04=gf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8g
zT7 at h=@PQ9}hzMPL-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1
zeBc8g_z)4g_`nA~@S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIU
zKJXzTbn$@?eBeW?ki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE725C6x9
d+)1Ogvb_1wlJk#Vo9RK<XU$8q`ogTQ&p*pvqh$a9

diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
index 3792e52abd..e8d534803f 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* filter_graph;
     IMediaControl* media_control;
     IMediaEvent* media_event;
+    IMediaSeeking* media_seeking;
 
     /* Async event notification */
     HWND msg_window;
-- 
2.17.0




More information about the wine-devel mailing list