Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 65 +++++++++++++++++++++++++++++++++++------- dlls/wmp/tests/media.c | 41 ++++++++++++++++++++++++++ dlls/wmp/wmp_private.h | 3 ++ 3 files changed, 99 insertions(+), 10 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, ¤tPosition); + *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..ff6331bd86 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,37 @@ 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 || + broken(round(duration) == 30) || + broken(round(duration) == 57), + "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 +454,7 @@ playback_skip: IOleObject_Release(oleobj); DeleteFileW(filename); SysFreeString(filename); + SysFreeString(bstrcurrentPosition);
return test_ran; } 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;
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 27 +++++++++++++++++++++++---- dlls/wmp/tests/media.c | 16 ++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 8448916a80..e5bf1c7964 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1150,8 +1150,17 @@ static HRESULT WINAPI WMPNetwork_get_bufferingCount(IWMPNetwork *iface, LONG *pl static HRESULT WINAPI WMPNetwork_get_bufferingProgress(IWMPNetwork *iface, LONG *plBufferingProgress) { WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); - FIXME("(%p)->(%p)\n", This, plBufferingProgress); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, plBufferingProgress); + if (!This->filter_graph) { + return S_FALSE; + } + /* Ideally we would use IAMOpenProgress for URL reader but we don't have it in wine (yet) + * For file sources FileAsyncReader->Length should work + * */ + FIXME("stub: Returning buffering progress 100\n"); + *plBufferingProgress = 100; + + return S_OK; }
static HRESULT WINAPI WMPNetwork_get_bufferingTime(IWMPNetwork *iface, LONG *plBufferingTime) @@ -1276,8 +1285,18 @@ static HRESULT WINAPI WMPNetwork_put_maxBandwidth(IWMPNetwork *iface, LONG lMaxB static HRESULT WINAPI WMPNetwork_get_downloadProgress(IWMPNetwork *iface, LONG *plDownloadProgress) { WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); - FIXME("(%p)->(%p)\n", This, plDownloadProgress); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, plDownloadProgress); + if (!This->filter_graph) { + return S_FALSE; + } + /* Ideally we would use IAMOpenProgress for URL reader but we don't have it in wine (yet) + * For file sources FileAsyncReader->Length could work or it should just be + * 100 + * */ + FIXME("stub: Returning download progress 100\n"); + *plDownloadProgress = 100; + + return S_OK; }
static HRESULT WINAPI WMPNetwork_get_encodedFrameRate(IWMPNetwork *iface, LONG *plFrameRate) diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index ff6331bd86..a42afa1ad3 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -303,8 +303,10 @@ static BOOL test_wmp(void) static DWORD dw = 100; IWMPSettings *settings; BOOL test_ran = TRUE; + IWMPNetwork *network; DOUBLE duration; VARIANT_BOOL vbool; + LONG progress; 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); @@ -420,6 +422,20 @@ static BOOL test_wmp(void) "unexpected value: %f\n", duration); IWMPMedia_Release(media);
+ network = NULL; + hres = IWMPPlayer4_get_network(player4, &network); + ok(hres == S_OK, "get_network failed: %08x\n", hres); + ok(network != NULL, "network = NULL\n"); + progress = 0; + hres = IWMPNetwork_get_bufferingProgress(network, &progress); + ok(hres == S_OK || broken(hres == S_FALSE), "IWMPNetwork_get_bufferingProgress failed: %08x\n", hres); + ok(progress == 100, "unexpected value: %d\n", progress); + progress = 0; + hres = IWMPNetwork_get_downloadProgress(network, &progress); + ok(hres == S_OK, "IWMPNetwork_get_downloadProgress failed: %08x\n", hres); + ok(progress == 100, "unexpected value: %d\n", progress); + IWMPNetwork_Release(network); + SET_EXPECT(PLAYSTATE, wmppsStopped); /* The following happens on wine only since we close media on stop */ SET_EXPECT(OPENSTATE, wmposPlaylistOpenNoMedia);
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 29 +++++++++++++++++++++++++---- dlls/wmp/tests/media.c | 17 ++++++++++++++++- dlls/wmp/wmp_private.h | 2 ++ 3 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index e5bf1c7964..ad0e478b10 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -958,15 +958,27 @@ static HRESULT WINAPI WMPSettings_put_balance(IWMPSettings *iface, LONG v) static HRESULT WINAPI WMPSettings_get_volume(IWMPSettings *iface, LONG *p) { WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + if (!p) + return E_POINTER; + *p = This->volume; + return S_OK; }
static HRESULT WINAPI WMPSettings_put_volume(IWMPSettings *iface, LONG v) { + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); - FIXME("(%p)->(%d)\n", This, v); - return E_NOTIMPL; + TRACE("(%p)->(%d)\n", This, v); + This->volume = v; + if (!This->filter_graph) { + hres = S_OK; + } else { + /* IBasicAudio - [-10000, 0], wmp - [0, 100] */ + v = 10000 * v / 100 - 10000; + hres = IBasicAudio_put_Volume(This->basic_audio, v); + } + return hres; }
static HRESULT WINAPI WMPSettings_getMode(IWMPSettings *iface, BSTR mode, VARIANT_BOOL *p) @@ -1484,6 +1496,10 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) IMediaEventEx_Release(media_event_ex); } } + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(This->filter_graph, &IID_IBasicAudio, (void**)&This->basic_audio); + if (SUCCEEDED(hres)) + hres = IWMPSettings_put_volume(&This->IWMPSettings_iface, This->volume); }
update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsTransitioning); @@ -1525,11 +1541,15 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) if (This->media_seeking) { IMediaSeeking_Release(This->media_seeking); } + if (This->basic_audio) { + IBasicAudio_Release(This->basic_audio); + } IGraphBuilder_Release(This->filter_graph); This->filter_graph = NULL; This->media_control = NULL; This->media_event = NULL; This->media_seeking = NULL; + This->basic_audio = NULL;
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistOpenNoMedia); update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsStopped); @@ -1983,6 +2003,7 @@ BOOL init_player(WindowsMediaPlayer *wmp)
wmp->invoke_urls = VARIANT_TRUE; wmp->auto_start = VARIANT_TRUE; + wmp->volume = 100; return TRUE; }
diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index a42afa1ad3..e2fa2ac55d 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -338,7 +338,6 @@ static BOOL test_wmp(void)
hres = IWMPSettings_put_autoStart(settings, VARIANT_FALSE); ok(hres == S_OK, "Could not put autoStart in IWMPSettings: %08x\n", hres); - IWMPSettings_Release(settings);
controls = NULL; hres = IWMPPlayer4_get_controls(player4, &controls); @@ -352,6 +351,12 @@ static BOOL test_wmp(void) hres = IWMPControls_play(controls); ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_play is available: %08x\n", hres);
+ hres = IWMPSettings_put_volume(settings, 36); + ok(hres == S_OK, "IWMPSettings_put_volume failed: %08x\n", hres); + hres = IWMPSettings_get_volume(settings, &progress); + ok(hres == S_OK, "IWMPSettings_get_volume failed: %08x\n", hres); + ok(progress == 36, "unexpected value: %d\n", progress); + filename = SysAllocString(load_resource(mp3file));
SET_EXPECT(OPENSTATE, wmposPlaylistChanging); @@ -464,7 +469,17 @@ playback_skip: hres = IConnectionPoint_Unadvise(point, dw); ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
+ hres = IWMPSettings_get_volume(settings, &progress); + ok(hres == S_OK, "IWMPSettings_get_volume failed: %08x\n", hres); + ok(progress == 36, "unexpected value: %d\n", progress); + hres = IWMPSettings_put_volume(settings, 99); + ok(hres == S_OK, "IWMPSettings_put_volume failed: %08x\n", hres); + hres = IWMPSettings_get_volume(settings, &progress); + ok(hres == S_OK, "IWMPSettings_get_volume failed: %08x\n", hres); + ok(progress == 99, "unexpected value: %d\n", progress); + IConnectionPoint_Release(point); + IWMPSettings_Release(settings); IWMPControls_Release(controls); IWMPPlayer4_Release(player4); IOleObject_Release(oleobj); diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index e8d534803f..b0861dd302 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -69,6 +69,7 @@ struct WindowsMediaPlayer { VARIANT_BOOL auto_start; VARIANT_BOOL invoke_urls; VARIANT_BOOL enable_error_dialogs; + LONG volume;
ConnectionPoint *wmpocx;
@@ -79,6 +80,7 @@ struct WindowsMediaPlayer { IMediaControl* media_control; IMediaEvent* media_event; IMediaSeeking* media_seeking; + IBasicAudio* basic_audio;
/* Async event notification */ HWND msg_window;
Signed-off-by: Jacek Caban jacek@codeweavers.com
Anton Romanov theli.ua@gmail.com writes:
Signed-off-by: Anton Romanov theli.ua@gmail.com
dlls/wmp/player.c | 65 +++++++++++++++++++++++++++++++++++------- dlls/wmp/tests/media.c | 41 ++++++++++++++++++++++++++ dlls/wmp/wmp_private.h | 3 ++ 3 files changed, 99 insertions(+), 10 deletions(-)
It doesn't work here:
../../../tools/runtest -q -P wine -T ../../.. -M wmp.dll -p wmp_test.exe.so media && touch media.ok media.c:416: Test failed: unexpected value: 30.036000 Makefile:185: recipe for target 'media.ok' failed make: *** [media.ok] Error 1
On Mon, Apr 16, 2018 at 12:54 PM, Alexandre Julliard julliard@winehq.org wrote:
Anton Romanov theli.ua@gmail.com writes:
Signed-off-by: Anton Romanov theli.ua@gmail.com
dlls/wmp/player.c | 65 +++++++++++++++++++++++++++++++++++------- dlls/wmp/tests/media.c | 41 ++++++++++++++++++++++++++ dlls/wmp/wmp_private.h | 3 ++ 3 files changed, 99 insertions(+), 10 deletions(-)
It doesn't work here:
../../../tools/runtest -q -P wine -T ../../.. -M wmp.dll -p wmp_test.exe.so media && touch media.ok media.c:416: Test failed: unexpected value: 30.036000 Makefile:185: recipe for target 'media.ok' failed make: *** [media.ok] Error 1
-- Alexandre Julliard julliard@winehq.org
What gstreamer version do you have there? Media file is 60 seconds long. Quartz/winegstreamer returns 60 for me. Though on some systems WMP does return 30 for whatever reasons.