Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 6c68240fa8..987d189515 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1577,9 +1577,14 @@ static HRESULT WINAPI WMPMedia_get_isIdentical(IWMPMedia *iface, IWMPMedia *othe static HRESULT WINAPI WMPMedia_get_sourceURL(IWMPMedia *iface, BSTR *pbstrSourceUrl) { WMPMedia *This = impl_from_IWMPMedia(iface); + BSTR url; TRACE("(%p)->(%p)\n", This, pbstrSourceUrl); - *pbstrSourceUrl = SysAllocString(This->url); - return S_OK; + url = SysAllocString(This->url); + if (url) { + *pbstrSourceUrl = url; + return S_OK; + } + return E_FAIL; }
static HRESULT WINAPI WMPMedia_get_name(IWMPMedia *iface, BSTR *pbstrName)
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 71 +++++++++++++++++++++++++---- dlls/wmp/tests/Makefile.in | 2 +- dlls/wmp/tests/media.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ dlls/wmp/tests/oleobj.c | 2 +- dlls/wmp/wmp_private.h | 7 ++- 5 files changed, 181 insertions(+), 12 deletions(-) create mode 100644 dlls/wmp/tests/media.c
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 987d189515..a36fa36eed 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -19,6 +19,7 @@ #include "wmp_private.h"
#include "wine/debug.h" +#include <nserror.h>
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
@@ -119,12 +120,20 @@ static HRESULT WINAPI WMPPlayer4_put_URL(IWMPPlayer4 *iface, BSTR url) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); IWMPMedia *media; + HRESULT hres; TRACE("(%p)->(%s)\n", This, debugstr_w(url)); if(url == NULL) { return E_POINTER; } - media = create_media_from_url(url); - return IWMPPlayer4_put_currentMedia(iface, media); + hres = create_media_from_url(url, &media); + if (SUCCEEDED(hres)) { + hres = IWMPPlayer4_put_currentMedia(iface, media); + IWMPMedia_Release(media); /* put will addref */ + } + if (SUCCEEDED(hres) && This->auto_start) { + hres = IWMPControls_play(&This->IWMPControls_iface); + } + return hres; }
static HRESULT WINAPI WMPPlayer4_get_openState(IWMPPlayer4 *iface, WMPOpenState *pwmpos) @@ -1357,16 +1366,53 @@ static HRESULT WINAPI WMPControls_get_isAvailable(IWMPControls *iface, BSTR bstr
static HRESULT WINAPI WMPControls_play(IWMPControls *iface) { + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPControls(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + WMPMedia *media; + TRACE("(%p)\n", This); + if (!This->wmpmedia) { + return NS_S_WMPCORE_COMMAND_NOT_AVAILABLE; + } + media = impl_from_IWMPMedia(This->wmpmedia); + if (!This->pFilterGraph) { + hres = CoCreateInstance(&CLSID_FilterGraph, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IGraphBuilder, + (void **)&This->pFilterGraph); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_RenderFile(This->pFilterGraph, media->url, NULL); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl, + (void**)&This->media_control); + } + hres = IMediaControl_Run(This->media_control); + if (hres == S_FALSE) { + OAFilterState fs; + hres = IMediaControl_GetState(This->media_control, 1000, &fs); + if (hres != S_OK || fs != State_Running) { + hres = S_FALSE; + } + } + return hres; }
static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) { + HRESULT hres = S_OK; WindowsMediaPlayer *This = impl_from_IWMPControls(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + TRACE("(%p)\n", This); + if (!This->pFilterGraph) { + return NS_S_WMPCORE_COMMAND_NOT_AVAILABLE; + } + hres = IMediaControl_Stop(This->media_control); + if(This->pFilterGraph) + IGraphBuilder_Release(This->pFilterGraph); + if(This->media_control) + IMediaControl_Release(This->media_control); + This->pFilterGraph = NULL; + This->media_control = NULL; + return hres; }
static HRESULT WINAPI WMPControls_pause(IWMPControls *iface) @@ -1741,16 +1787,23 @@ void init_player(WindowsMediaPlayer *wmp)
void destroy_player(WindowsMediaPlayer *wmp) { + IWMPControls_stop(&wmp->IWMPControls_iface); if(wmp->wmpmedia) IWMPMedia_Release(wmp->wmpmedia); }
-IWMPMedia* create_media_from_url(BSTR url){ - +HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) +{ WMPMedia *media = heap_alloc_zero(sizeof(WMPMedia)); media->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; media->url = heap_strdupW(url); media->ref = 1;
- return &media->IWMPMedia_iface; + if (media->url) { + *ppMedia = &media->IWMPMedia_iface; + + return S_OK; + } + IWMPMedia_Release(&media->IWMPMedia_iface); + return E_OUTOFMEMORY; } diff --git a/dlls/wmp/tests/Makefile.in b/dlls/wmp/tests/Makefile.in index dded3a4a7e..b4ecf3ffda 100644 --- a/dlls/wmp/tests/Makefile.in +++ b/dlls/wmp/tests/Makefile.in @@ -1,7 +1,7 @@ TESTDLL = wmp.dll IMPORTS = ole32 oleaut32 user32 gdi32
-C_SRCS = oleobj.c +C_SRCS = oleobj.c media.c
RC_SRCS = \ rsrc.rc diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c new file mode 100644 index 0000000000..191ed6547e --- /dev/null +++ b/dlls/wmp/tests/media.c @@ -0,0 +1,111 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WIN32_LEAN_AND_MEAN +#define COBJMACROS +#include <wmp.h> +#include <olectl.h> +#include <nserror.h> + +#include "wine/test.h" + +static const WCHAR mp4file[] = {'a','v','.','m','p','4',0}; +static inline WCHAR *load_resource(const WCHAR *name) +{ + static WCHAR pathW[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW); + lstrcatW(pathW, name); + + file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW), + GetLastError()); + + res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA); + ok( res != 0, "couldn't find resource\n" ); + ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); + WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); + ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); + CloseHandle( file ); + + return pathW; +} + +static void test_wmp(void) +{ + IWMPPlayer4 *player4; + IWMPControls *controls; + HRESULT hres; + BSTR filename; + + IOleObject *oleobj; + + hres = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IOleObject, (void**)&oleobj); + if(hres == REGDB_E_CLASSNOTREG) { + win_skip("CLSID_WindowsMediaPlayer not registered\n"); + return; + } + ok(hres == S_OK, "Could not create CLSID_WindowsMediaPlayer instance: %08x\n", hres); + + hres = IOleObject_QueryInterface(oleobj, &IID_IWMPPlayer4, (void**)&player4); + ok(hres == S_OK, "Could not get IWMPPlayer4 iface: %08x\n", hres); + + controls = NULL; + hres = IWMPPlayer4_get_controls(player4, &controls); + ok(hres == S_OK, "get_controls failed: %08x\n", hres); + ok(controls != NULL, "controls = NULL\n"); + + hres = IWMPControls_play(controls); + ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_play is available: %08x\n", hres); + + filename = SysAllocString(load_resource(mp4file)); + + hres = IWMPPlayer4_put_URL(player4, filename); + ok(hres == S_OK, "IWMPPlayer4_put_URL failed: %08x\n", hres); + + hres = IWMPControls_play(controls); + todo_wine + ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_play is available: %08x\n", hres); + + hres = IWMPControls_stop(controls); + ok(hres == S_OK, "IWMPControls_stop failed: %08x\n", hres); + + /* Already Stopped */ + hres = IWMPControls_stop(controls); + ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_stop is available: %08x\n", hres); + + hres = IWMPControls_play(controls); + ok(hres == S_OK, "IWMPControls_play failed: %08x\n", hres); + + IWMPControls_Release(controls); + IWMPPlayer4_Release(player4); + IOleObject_Release(oleobj); + DeleteFileW(filename); + SysFreeString(filename); +} + +START_TEST(media) +{ + CoInitialize(NULL); + + test_wmp(); + + CoUninitialize(); +} diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c index 937960cbaf..85ff148103 100644 --- a/dlls/wmp/tests/oleobj.c +++ b/dlls/wmp/tests/oleobj.c @@ -944,7 +944,6 @@ static void test_wmp_ifaces(IOleObject *oleobj)
filename = SysAllocString(load_resource(mp4file));
- SET_EXPECT(GetContainer); SET_EXPECT(Invoke_USERMODE); hres = IWMPPlayer4_put_URL(player4, filename); @@ -1039,6 +1038,7 @@ static void test_wmp_ifaces(IOleObject *oleobj)
IWMPSettings_Release(settings); IWMPPlayer_Release(player); + DeleteFileW(filename); SysFreeString(filename); }
diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index e95b194d77..240a91803c 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -22,6 +22,7 @@ #include "wine/heap.h" #include "wine/unicode.h" #include "ole2.h" +#include "dshow.h" #include "wmp.h"
typedef struct { @@ -70,11 +71,15 @@ struct WindowsMediaPlayer { ConnectionPoint *wmpocx;
IWMPMedia *wmpmedia; + + /* DirectShow stuff */ + IGraphBuilder* pFilterGraph; + IMediaControl* media_control; };
void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; -IWMPMedia* create_media_from_url(BSTR url); +HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia); void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN; void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN;
Hi,
While running your changed tests on Windows, 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=36690
Your paranoid android.
=== wxppro (32 bit media) === media.c:95: Test failed: IWMPControls_play failed: 000d1103
=== w2003std (32 bit media) === media.c:95: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64 (32 bit media) === media.c:95: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64_zh_CN (32 bit media) === media.c:95: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64_fr (32 bit media) === media.c:95: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64_he (32 bit media) === media.c:95: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64 (64 bit media) === media.c:95: Test failed: IWMPControls_play failed: 000d1103
On 12/03/18 23:34, Anton Romanov wrote:
static HRESULT WINAPI WMPPlayer4_get_openState(IWMPPlayer4 *iface, WMPOpenState *pwmpos) @@ -1357,16 +1366,53 @@ static HRESULT WINAPI WMPControls_get_isAvailable(IWMPControls *iface, BSTR bstr
static HRESULT WINAPI WMPControls_play(IWMPControls *iface) {
- HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
- WMPMedia *media;
- TRACE("(%p)\n", This);
- if (!This->wmpmedia) {
return NS_S_WMPCORE_COMMAND_NOT_AVAILABLE;
- }
- media = impl_from_IWMPMedia(This->wmpmedia);
- if (!This->pFilterGraph) {
hres = CoCreateInstance(&CLSID_FilterGraph,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IGraphBuilder,
(void **)&This->pFilterGraph);
if (SUCCEEDED(hres))
hres = IGraphBuilder_RenderFile(This->pFilterGraph, media->url, NULL);
if (SUCCEEDED(hres))
hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl,
(void**)&This->media_control);
- }
- hres = IMediaControl_Run(This->media_control);
This will crash if either of the above calls fail.
- if (hres == S_FALSE) {
OAFilterState fs;
hres = IMediaControl_GetState(This->media_control, 1000, &fs);
if (hres != S_OK || fs != State_Running) {
hres = S_FALSE;
}
- }
1 second seems arbitrary, especially given that IWMPControls has no similar method to force a state change.
- return hres;
}
This function on the whole (and several others in the file) could use some spacing.
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/events.c | 11 ++++ dlls/wmp/oleobj.c | 2 +- dlls/wmp/player.c | 44 ++++++++++++++ dlls/wmp/tests/media.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++-- dlls/wmp/wmp_main.c | 1 + dlls/wmp/wmp_private.h | 3 +- include/wmpids.h | 63 ++++++++++++++++++++ 7 files changed, 269 insertions(+), 7 deletions(-) create mode 100644 include/wmpids.h
diff --git a/dlls/wmp/events.c b/dlls/wmp/events.c index a908834010..412eb307d1 100644 --- a/dlls/wmp/events.c +++ b/dlls/wmp/events.c @@ -400,3 +400,14 @@ void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) { ConnectionPoint_Destroy(wmp->wmpocx); } + +void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams) +{ + DWORD i; + + for(i=0; i<This->sinks_size; i++) { + if(This->sinks[i]) + IDispatch_Invoke(This->sinks[i], dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT, + DISPATCH_METHOD, dispparams, NULL, NULL, NULL); + } +} diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c index cc0e9a9d98..cbf183c1f6 100644 --- a/dlls/wmp/oleobj.c +++ b/dlls/wmp/oleobj.c @@ -307,8 +307,8 @@ static ULONG WINAPI OleObject_Release(IOleObject *iface)
if(!ref) { release_client_site(This); - ConnectionPointContainer_Destroy(This); destroy_player(This); + ConnectionPointContainer_Destroy(This); heap_free(This); }
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index a36fa36eed..81ce9f2969 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -20,9 +20,12 @@
#include "wine/debug.h" #include <nserror.h> +#include "wmpids.h"
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
+static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state); + static inline WMPMedia *impl_from_IWMPMedia(IWMPMedia *iface) { return CONTAINING_RECORD(iface, WMPMedia, IWMPMedia_iface); @@ -125,14 +128,20 @@ static HRESULT WINAPI WMPPlayer4_put_URL(IWMPPlayer4 *iface, BSTR url) if(url == NULL) { return E_POINTER; } + hres = create_media_from_url(url, &media); + if (SUCCEEDED(hres)) { + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); hres = IWMPPlayer4_put_currentMedia(iface, media); IWMPMedia_Release(media); /* put will addref */ + + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_READY); } if (SUCCEEDED(hres) && This->auto_start) { hres = IWMPControls_play(&This->IWMPControls_iface); } + return hres; }
@@ -191,9 +200,13 @@ static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia if(pMedia == NULL) { return E_POINTER; } + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGING); if(This->wmpmedia != NULL) { IWMPMedia_Release(This->wmpmedia); } + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGED); + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA); + This->wmpmedia = pMedia; IWMPMedia_AddRef(This->wmpmedia); return S_OK; @@ -1380,12 +1393,16 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (void **)&This->pFilterGraph); + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_OPENING_UNKNOWN_URL); + if (SUCCEEDED(hres)) hres = IGraphBuilder_RenderFile(This->pFilterGraph, media->url, NULL); if (SUCCEEDED(hres)) hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl, (void**)&This->media_control); + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN); } + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); hres = IMediaControl_Run(This->media_control); if (hres == S_FALSE) { OAFilterState fs; @@ -1394,6 +1411,12 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) hres = S_FALSE; } } + if (SUCCEEDED(hres)) { + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_PLAYING); + } else { + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_UNDEFINED); + } + return hres; }
@@ -1405,6 +1428,8 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) if (!This->pFilterGraph) { return NS_S_WMPCORE_COMMAND_NOT_AVAILABLE; } + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_CHANGING); hres = IMediaControl_Stop(This->media_control); if(This->pFilterGraph) IGraphBuilder_Release(This->pFilterGraph); @@ -1412,6 +1437,8 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) IMediaControl_Release(This->media_control); This->pFilterGraph = NULL; This->media_control = NULL; + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA); + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED); return hres; }
@@ -1807,3 +1834,20 @@ HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) IWMPMedia_Release(&media->IWMPMedia_iface); return E_OUTOFMEMORY; } + +static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state) +{ + DISPPARAMS dispparams; + VARIANTARG params[1]; + + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = params; + + V_VT(params) = VT_UI4; + V_UI4(params) = state; + + call_sink(wmp->wmpocx, type, + &dispparams); +} diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index 191ed6547e..a6ed14b316 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -19,9 +19,31 @@ #include <wmp.h> #include <olectl.h> #include <nserror.h> +#include <wmpids.h>
#include "wine/test.h"
+#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + expect_ ## func = TRUE + +#define CHECK_EXPECT(func) \ + do { \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +DEFINE_EXPECT(PLAYSTATE_CHANGE); +DEFINE_EXPECT(OPENSTATE_CHANGE); + static const WCHAR mp4file[] = {'a','v','.','m','p','4',0}; static inline WCHAR *load_resource(const WCHAR *name) { @@ -48,14 +70,101 @@ static inline WCHAR *load_resource(const WCHAR *name) return pathW; }
+static ULONG WINAPI Dispatch_AddRef(IDispatch *iface) +{ + return 2; +} + +static ULONG WINAPI Dispatch_Release(IDispatch *iface) +{ + return 1; +} + +static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPOCXEvents_QueryInterface(IDispatch *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID__WMPOCXEvents, riid) || IsEqualGUID(&IID_IDispatch, riid)) { + *ppv = iface; + return S_OK; + } + + ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); + return E_NOINTERFACE; +} + +static HRESULT WINAPI WMPOCXEvents_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + switch(dispIdMember) { + /* Uncomment below traces to debug wmp events */ + case DISPID_WMPCOREEVENT_OPENSTATECHANGE: + CHECK_EXPECT(OPENSTATE_CHANGE); + /*trace("DISPID_WMPCOREEVENT_OPENSTATECHANGE, %d\n", V_UI4(pDispParams->rgvarg));*/ + break; + case DISPID_WMPCOREEVENT_PLAYSTATECHANGE: + CHECK_EXPECT(PLAYSTATE_CHANGE); + /*trace("DISPID_WMPCOREEVENT_PLAYSTATECHANGE, %d\n", V_UI4(pDispParams->rgvarg));*/ + break; + case DISPID_WMPCOREEVENT_MEDIACHANGE: + /*trace("DISPID_WMPCOREEVENT_MEDIACHANGE\n");*/ + break; + case DISPID_WMPCOREEVENT_CURRENTITEMCHANGE: + /*trace("DISPID_WMPCOREEVENT_CURRENTITEMCHANGE\n");*/ + break; + default: + /*trace("event: %d\n", dispIdMember);*/ + break; + } + + return E_NOTIMPL; +} + +static IDispatchVtbl WMPOcxEventsVtbl = { + WMPOCXEvents_QueryInterface, + Dispatch_AddRef, + Dispatch_Release, + Dispatch_GetTypeInfoCount, + Dispatch_GetTypeInfo, + Dispatch_GetIDsOfNames, + WMPOCXEvents_Invoke, +}; + +static IDispatch WMPOCXEvents = { &WMPOcxEventsVtbl }; + + static void test_wmp(void) { IWMPPlayer4 *player4; IWMPControls *controls; HRESULT hres; BSTR filename; - + IConnectionPointContainer *container; + IConnectionPoint *point; IOleObject *oleobj; + static DWORD dw = 100; + IWMPSettings *settings;
hres = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IOleObject, (void**)&oleobj); if(hres == REGDB_E_CLASSNOTREG) { @@ -64,9 +173,30 @@ static void test_wmp(void) } ok(hres == S_OK, "Could not create CLSID_WindowsMediaPlayer instance: %08x\n", hres);
+ hres = IOleObject_QueryInterface(oleobj, &IID_IConnectionPointContainer, (void**)&container); + ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres); + if(FAILED(hres)) + return; + + hres = IConnectionPointContainer_FindConnectionPoint(container, &IID__WMPOCXEvents, &point); + IConnectionPointContainer_Release(container); + ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres); + + hres = IConnectionPoint_Advise(point, (IUnknown*)&WMPOCXEvents, &dw); + ok(hres == S_OK, "Advise failed: %08x\n", hres); + hres = IOleObject_QueryInterface(oleobj, &IID_IWMPPlayer4, (void**)&player4); ok(hres == S_OK, "Could not get IWMPPlayer4 iface: %08x\n", hres);
+ settings = NULL; + hres = IWMPPlayer4_get_settings(player4, &settings); + ok(hres == S_OK, "get_settings failed: %08x\n", hres); + ok(settings != NULL, "settings = NULL\n"); + + 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); ok(hres == S_OK, "get_controls failed: %08x\n", hres); @@ -77,23 +207,35 @@ static void test_wmp(void)
filename = SysAllocString(load_resource(mp4file));
+ SET_EXPECT(OPENSTATE_CHANGE); + SET_EXPECT(PLAYSTATE_CHANGE); hres = IWMPPlayer4_put_URL(player4, filename); ok(hres == S_OK, "IWMPPlayer4_put_URL failed: %08x\n", hres); + CHECK_CALLED(OPENSTATE_CHANGE); + CHECK_CALLED(PLAYSTATE_CHANGE);
+ SET_EXPECT(OPENSTATE_CHANGE); + SET_EXPECT(PLAYSTATE_CHANGE); hres = IWMPControls_play(controls); - todo_wine - ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_play is available: %08x\n", hres); + ok(hres == S_OK, "IWMPControls_play failed: %08x\n", hres); + CHECK_CALLED(OPENSTATE_CHANGE); + CHECK_CALLED(PLAYSTATE_CHANGE);
+ SET_EXPECT(OPENSTATE_CHANGE); + SET_EXPECT(PLAYSTATE_CHANGE); hres = IWMPControls_stop(controls); ok(hres == S_OK, "IWMPControls_stop failed: %08x\n", hres); + CHECK_CALLED(OPENSTATE_CHANGE); + CHECK_CALLED(PLAYSTATE_CHANGE);
/* Already Stopped */ hres = IWMPControls_stop(controls); ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_stop is available: %08x\n", hres);
- hres = IWMPControls_play(controls); - ok(hres == S_OK, "IWMPControls_play failed: %08x\n", hres); + hres = IConnectionPoint_Unadvise(point, dw); + ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
+ IConnectionPoint_Release(point); IWMPControls_Release(controls); IWMPPlayer4_Release(player4); IOleObject_Release(oleobj); diff --git a/dlls/wmp/wmp_main.c b/dlls/wmp/wmp_main.c index 29b096f7fd..9a33b2762b 100644 --- a/dlls/wmp/wmp_main.c +++ b/dlls/wmp/wmp_main.c @@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
HINSTANCE wmp_instance; +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) { diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 240a91803c..b2077fe77d 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -79,9 +79,10 @@ struct WindowsMediaPlayer {
void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; -HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia); +HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) DECLSPEC_HIDDEN; void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN; void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN; +void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams) DECLSPEC_HIDDEN;
HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
diff --git a/include/wmpids.h b/include/wmpids.h new file mode 100644 index 0000000000..2b47f7fc55 --- /dev/null +++ b/include/wmpids.h @@ -0,0 +1,63 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +/* play state */ +#define WMP_PLAY_STATE_UNDEFINED 0 +#define WMP_PLAY_STATE_STOPPED 1 +#define WMP_PLAY_STATE_PAUSED 2 +#define WMP_PLAY_STATE_PLAYING 3 +#define WMP_PLAY_STATE_SCAN_FORWARD 4 +#define WMP_PLAY_STATE_SCAN_REVERSE 5 +#define WMP_PLAY_STATE_BUFFERING 6 +#define WMP_PLAY_STATE_WAITING 7 +#define WMP_PLAY_STATE_MEDIA_ENDED 8 +#define WMP_PLAY_STATE_TRANSITIONING 9 +#define WMP_PLAY_STATE_READY 10 +#define WMP_PLAY_STATE_RECONNECTING 11 + +/* open state */ +#define WMP_OPEN_STATE_UNDEFINED 0 +#define WMP_OPEN_STATE_PLAYLIST_CHANGING 1 +#define WMP_OPEN_STATE_PLAYLIST_LOCATING 2 +#define WMP_OPEN_STATE_PLAYLIST_CONNECTING 3 +#define WMP_OPEN_STATE_PLAYLIST_LOADING 4 +#define WMP_OPEN_STATE_PLAYLIST_OPENGING 5 +#define WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA 6 +#define WMP_OPEN_STATE_PLAYLIST_CHANGED 7 +#define WMP_OPEN_STATE_MEDIA_CHANGING 8 +#define WMP_OPEN_STATE_MEDIA_LOCATING 9 +#define WMP_OPEN_STATE_MEDIA_CONNECTING 10 +#define WMP_OPEN_STATE_MEDIA_LOADING 11 +#define WMP_OPEN_STATE_MEDIA_OPENING 12 +#define WMP_OPEN_STATE_MEDIA_OPEN 13 +#define WMP_OPEN_STATE_BEGIN_CODEC_ACQUISITION 14 +#define WMP_OPEN_STATE_END_CODEC_ACQUISITION 15 +#define WMP_OPEN_STATE_BEGIN_LICENSE_ACQUISITION 16 +#define WMP_OPEN_STATE_END_LICENSE_ACQUISITION 17 +#define WMP_OPEN_STATE_BEGIN_INDIVIDUALIZATION 18 +#define WMP_OPEN_STATE_END_INDIVIDUALIZATION 19 +#define WMP_OPEN_STATE_MEDIA_WAITING 20 +#define WMP_OPEN_STATE_OPENING_UNKNOWN_URL 21 + +/* WMPCoreEvents */ +#define DISPID_WMPCOREEVENT_OPENSTATECHANGE 5001 +#define DISPID_WMPCOREEVENT_STATUSCHANGE 5002 + +#define DISPID_WMPCOREEVENT_PLAYSTATECHANGE 5101 + +#define DISPID_WMPCOREEVENT_MEDIACHANGE 5802 +#define DISPID_WMPCOREEVENT_CURRENTITEMCHANGE 5806
Hi,
While running your changed tests on Windows, 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=36691
Your paranoid android.
=== wxppro (32 bit media) === media.c:220: Test failed: IWMPControls_play failed: 000d1103
=== w2003std (32 bit media) === media.c:220: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64 (32 bit media) === media.c:220: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64_zh_CN (32 bit media) === media.c:220: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64_fr (32 bit media) === media.c:220: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64_he (32 bit media) === media.c:220: Test failed: IWMPControls_play failed: 000d1103
=== wvistau64 (64 bit media) === media.c:220: Test failed: IWMPControls_play failed: 000d1103
On 12/03/18 23:34, Anton Romanov wrote:
- switch(dispIdMember) {
/* Uncomment below traces to debug wmp events */
case DISPID_WMPCOREEVENT_OPENSTATECHANGE:
CHECK_EXPECT(OPENSTATE_CHANGE);
/*trace("DISPID_WMPCOREEVENT_OPENSTATECHANGE, %d\n", V_UI4(pDispParams->rgvarg));*/
break;
case DISPID_WMPCOREEVENT_PLAYSTATECHANGE:
CHECK_EXPECT(PLAYSTATE_CHANGE);
/*trace("DISPID_WMPCOREEVENT_PLAYSTATECHANGE, %d\n", V_UI4(pDispParams->rgvarg));*/
break;
case DISPID_WMPCOREEVENT_MEDIACHANGE:
/*trace("DISPID_WMPCOREEVENT_MEDIACHANGE\n");*/
break;
case DISPID_WMPCOREEVENT_CURRENTITEMCHANGE:
/*trace("DISPID_WMPCOREEVENT_CURRENTITEMCHANGE\n");*/
break;
default:
/*trace("event: %d\n", dispIdMember);*/
break;
- }
I would use "if (winetest_debug > 1) trace(...);", but that's just personal preference.
- settings = NULL;
- hres = IWMPPlayer4_get_settings(player4, &settings);
- ok(hres == S_OK, "get_settings failed: %08x\n", hres);
- ok(settings != NULL, "settings = NULL\n");
- hres = IWMPSettings_put_autoStart(settings, VARIANT_FALSE);
- ok(hres == S_OK, "Could not put autoStart in IWMPSettings: %08x\n", hres);
- IWMPSettings_Release(settings);
This seems like it should be part of the previous patch.
-HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia); +HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) DECLSPEC_HIDDEN;
Similarly here.
+#define WMP_OPEN_STATE_PLAYLIST_OPENGING 5
You seem to have introduced a typo here.
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/wmp_private.h | 5 ++++ 2 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 81ce9f2969..42ee06315a 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state); +static DWORD CALLBACK WMP_event_thread(LPVOID parm);
static inline WMPMedia *impl_from_IWMPMedia(IWMPMedia *iface) { @@ -197,18 +198,20 @@ static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); TRACE("(%p)->(%p)\n", This, pMedia); + if(pMedia == NULL) { return E_POINTER; } update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGING); if(This->wmpmedia != NULL) { + IWMPControls_stop(&This->IWMPControls_iface); IWMPMedia_Release(This->wmpmedia); } update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGED); update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA);
+ IWMPMedia_AddRef(pMedia); This->wmpmedia = pMedia; - IWMPMedia_AddRef(This->wmpmedia); return S_OK; }
@@ -1401,6 +1404,11 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl, (void**)&This->media_control); update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaEvent, + (void**)&This->media_event); + This->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); + This->event_thread = CreateThread(NULL, 0, WMP_event_thread, This, 0, NULL); } update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); hres = IMediaControl_Run(This->media_control); @@ -1435,8 +1443,14 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) IGraphBuilder_Release(This->pFilterGraph); if(This->media_control) IMediaControl_Release(This->media_control); + if (This->media_event) + IMediaEvent_Release(This->media_event); This->pFilterGraph = NULL; This->media_control = NULL; + This->media_event = NULL; + SetEvent(This->stop_event); + WaitForSingleObject(This->event_thread, INFINITE); + CloseHandle(This->event_thread); update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA); update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED); return hres; @@ -1810,6 +1824,7 @@ void init_player(WindowsMediaPlayer *wmp)
wmp->invoke_urls = VARIANT_TRUE; wmp->auto_start = VARIANT_TRUE; + wmp->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); }
void destroy_player(WindowsMediaPlayer *wmp) @@ -1817,11 +1832,18 @@ void destroy_player(WindowsMediaPlayer *wmp) IWMPControls_stop(&wmp->IWMPControls_iface); if(wmp->wmpmedia) IWMPMedia_Release(wmp->wmpmedia); + CloseHandle(wmp->stop_event); + }
HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) { WMPMedia *media = heap_alloc_zero(sizeof(WMPMedia)); + + if (!media) { + return E_OUTOFMEMORY; + } + media->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; media->url = heap_strdupW(url); media->ref = 1; @@ -1851,3 +1873,47 @@ static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state) call_sink(wmp->wmpocx, type, &dispparams); } + +static DWORD CALLBACK WMP_event_thread(LPVOID parm) +{ + WindowsMediaPlayer* wmp = (WindowsMediaPlayer *)parm; + HRESULT hr; + HANDLE handle[2]; + DWORD n = 0, ret = 0; + + handle[n++] = wmp->stop_event; + IMediaEvent_GetEventHandle(wmp->media_event, (OAEVENT *)&handle[n++]); + for (;;) { + DWORD r; + + r = WaitForMultipleObjects(n, handle, FALSE, INFINITE); + if (r == WAIT_OBJECT_0) { + TRACE("got stop event\n"); + break; + } + else if (r == WAIT_OBJECT_0+1) { + LONG event_code; + LONG_PTR p1, p2; + do { + hr = IMediaEvent_GetEvent(wmp->media_event, &event_code, &p1, &p2, 0); + if (SUCCEEDED(hr)) { + TRACE("got event_code = 0x%02x\n", event_code); + /* For now we only handle EC_COMPLETE */ + if (event_code == EC_COMPLETE) { + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_MEDIA_ENDED); + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED); + } + + IMediaEvent_FreeEventParams(wmp->media_event, event_code, p1, p2); + } + } while (hr == S_OK); + } + else { + TRACE("Unknown error (%d)\n", (int)r); + break; + } + } + + return ret; +} diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index b2077fe77d..1ffc36c74c 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -75,6 +75,11 @@ struct WindowsMediaPlayer { /* DirectShow stuff */ IGraphBuilder* pFilterGraph; IMediaControl* media_control; + IMediaEvent* media_event; + + /* Async event notification */ + HANDLE event_thread; + HANDLE stop_event; };
void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
On 12/03/18 23:34, Anton Romanov wrote:
Signed-off-by: Anton Romanov theli.ua@gmail.com
dlls/wmp/player.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/wmp_private.h | 5 ++++ 2 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 81ce9f2969..42ee06315a 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state); +static DWORD CALLBACK WMP_event_thread(LPVOID parm);
static inline WMPMedia *impl_from_IWMPMedia(IWMPMedia *iface) { @@ -197,18 +198,20 @@ static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); TRACE("(%p)->(%p)\n", This, pMedia);
if(pMedia == NULL) { return E_POINTER; } update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGING); if(This->wmpmedia != NULL) {
IWMPControls_stop(&This->IWMPControls_iface); IWMPMedia_Release(This->wmpmedia);
} update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGED); update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA);
IWMPMedia_AddRef(pMedia); This->wmpmedia = pMedia;
- IWMPMedia_AddRef(This->wmpmedia); return S_OK;
}
@@ -1401,6 +1404,11 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl, (void**)&This->media_control); update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN);
if (SUCCEEDED(hres))
hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaEvent,
(void**)&This->media_event);
This->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
This->event_thread = CreateThread(NULL, 0, WMP_event_thread, This, 0, NULL);
This->stop_event will be leaked here if it was already set; probably you want to close it in WMPControls_stop() instead.
HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) { WMPMedia *media = heap_alloc_zero(sizeof(WMPMedia));
- if (!media) {
return E_OUTOFMEMORY;
- }
- media->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; media->url = heap_strdupW(url); media->ref = 1;
This belongs in the same patch where this function was added.
@@ -1851,3 +1873,47 @@ static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state) call_sink(wmp->wmpocx, type, &dispparams); }
+static DWORD CALLBACK WMP_event_thread(LPVOID parm) +{
- WindowsMediaPlayer* wmp = (WindowsMediaPlayer *)parm;
- HRESULT hr;
- HANDLE handle[2];
- DWORD n = 0, ret = 0;
- handle[n++] = wmp->stop_event;
- IMediaEvent_GetEventHandle(wmp->media_event, (OAEVENT *)&handle[n++]);
- for (;;) {
DWORD r;
r = WaitForMultipleObjects(n, handle, FALSE, INFINITE);
if (r == WAIT_OBJECT_0) {
TRACE("got stop event\n");
break;
}
else if (r == WAIT_OBJECT_0+1) {
LONG event_code;
LONG_PTR p1, p2;
do {
hr = IMediaEvent_GetEvent(wmp->media_event, &event_code, &p1, &p2, 0);
if (SUCCEEDED(hr)) {
TRACE("got event_code = 0x%02x\n", event_code);
/* For now we only handle EC_COMPLETE */
if (event_code == EC_COMPLETE) {
update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_MEDIA_ENDED);
update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING);
update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED);
}
IMediaEvent_FreeEventParams(wmp->media_event, event_code, p1, p2);
}
} while (hr == S_OK);
}
else {
TRACE("Unknown error (%d)\n", (int)r);
break;
}
- }
This probably deserves an ERR more than a TRACE.
- return ret;
+} diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index b2077fe77d..1ffc36c74c 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -75,6 +75,11 @@ struct WindowsMediaPlayer { /* DirectShow stuff */ IGraphBuilder* pFilterGraph; IMediaControl* media_control;
- IMediaEvent* media_event;
- /* Async event notification */
- HANDLE event_thread;
- HANDLE stop_event;
};
void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 61 +++++++++++++++++++++++++++++++++++++++++++------- dlls/wmp/tests/media.c | 27 ++++++++++++++++++++++ dlls/wmp/wmp_private.h | 3 +++ 3 files changed, 83 insertions(+), 8 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 42ee06315a..d3c67a3820 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1376,8 +1376,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) @@ -1403,6 +1417,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, @@ -1420,7 +1439,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); } @@ -1445,6 +1467,8 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) IMediaControl_Release(This->media_control); if (This->media_event) IMediaEvent_Release(This->media_event); + if (This->media_seeking) + IMediaSeeking_Release(This->media_seeking); This->pFilterGraph = NULL; This->media_control = NULL; This->media_event = NULL; @@ -1480,15 +1504,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) @@ -1725,9 +1767,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 a6ed14b316..4af5078857 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -165,6 +165,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) { @@ -202,6 +207,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);
@@ -221,6 +230,23 @@ 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"); + + hres = IWMPControls_get_currentPosition(controls, &duration); + ok(hres == S_OK, "IWMPControls_get_currentPosition failed: %08x\n", hres); + ok(duration == 0.0, "unexpected value\n"); + + 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(duration == 0.047, "unexpected value: %f\n", duration); + SET_EXPECT(OPENSTATE_CHANGE); SET_EXPECT(PLAYSTATE_CHANGE); hres = IWMPControls_stop(controls); @@ -241,6 +267,7 @@ static void test_wmp(void) 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 1ffc36c74c..07fc0e1d9f 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;
Hi,
While running your changed tests on Windows, 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=36692
Your paranoid android.
=== wxppro (32 bit media) === media.c:229: Test failed: IWMPControls_play failed: 000d1103 media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w2003std (32 bit media) === media.c:229: Test failed: IWMPControls_play failed: 000d1103 media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== wvistau64 (32 bit media) === media.c:229: Test failed: IWMPControls_play failed: 000d1103 media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== wvistau64_zh_CN (32 bit media) === media.c:229: Test failed: IWMPControls_play failed: 000d1103 media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== wvistau64_fr (32 bit media) === media.c:229: Test failed: IWMPControls_play failed: 000d1103 media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== wvistau64_he (32 bit media) === media.c:229: Test failed: IWMPControls_play failed: 000d1103 media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w7u (32 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w7pro64 (32 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w8 (32 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w864 (32 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w1064 (32 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== wvistau64 (64 bit media) === media.c:229: Test failed: IWMPControls_play failed: 000d1103 media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w7pro64 (64 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w864 (64 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
=== w1064 (64 bit media) === media.c:235: Test failed: unexpected value media.c:248: Test failed: unexpected value: 0.000000
On 12/03/18 23:34, Anton Romanov wrote:
Signed-off-by: Anton Romanov theli.ua@gmail.com
dlls/wmp/player.c | 61 +++++++++++++++++++++++++++++++++++++++++++------- dlls/wmp/tests/media.c | 27 ++++++++++++++++++++++ dlls/wmp/wmp_private.h | 3 +++ 3 files changed, 83 insertions(+), 8 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 42ee06315a..d3c67a3820 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1376,8 +1376,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);
debugstr_variant(pIsAvailable);
Zebediah Figura z.figura12@gmail.com wrote:
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);
debugstr_variant(pIsAvailable);
That doesn't seem to be a valid suggestion.
On 13/03/18 10:48, Dmitry Timoshkov wrote:
Zebediah Figura z.figura12@gmail.com wrote:
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);
debugstr_variant(pIsAvailable);
That doesn't seem to be a valid suggestion.
Whoops, my bad, I wasn't paying attention. Please ignore that one then.
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 22 ++++++++++++++++++---- dlls/wmp/tests/media.c | 13 +++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index d3c67a3820..ddee6667f4 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1130,8 +1130,15 @@ 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->pFilterGraph) { + return S_FALSE; + } + /* Ideally we would use IAMOpenProgress but we don't have it in wine (yet) */ + FIXME("stub: Returning buffering progress 100\n"); + *plBufferingProgress = 100; + + return S_OK; }
static HRESULT WINAPI WMPNetwork_get_bufferingTime(IWMPNetwork *iface, LONG *plBufferingTime) @@ -1256,8 +1263,15 @@ 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->pFilterGraph) { + return S_FALSE; + } + /* Ideally we would use IAMOpenProgress but we don't have it in wine (yet) */ + 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 4af5078857..9e1853ecfe 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -165,8 +165,10 @@ static void test_wmp(void) IOleObject *oleobj; static DWORD dw = 100; IWMPSettings *settings; + 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); @@ -247,6 +249,17 @@ static void test_wmp(void) ok(hres == S_OK, "IWMPMedia_get_duration failed: %08x\n", hres); ok(duration == 0.047, "unexpected value: %f\n", duration);
+ network = NULL; + hres = IWMPPlayer4_get_network(player4, &network); + ok(hres == S_OK, "get_network failed: %08x\n", hres); + ok(network != NULL, "network = NULL\n"); + hres = IWMPNetwork_get_bufferingProgress(network, &progress); + ok(hres == S_OK, "IWMPNetwork_get_bufferingProgress failed: %08x\n", hres); + ok(progress == 100, "unexpected value: %d\n", progress); + 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); + SET_EXPECT(OPENSTATE_CHANGE); SET_EXPECT(PLAYSTATE_CHANGE); hres = IWMPControls_stop(controls);
Hi,
While running your changed tests on Windows, 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=36693
Your paranoid android.
=== wxppro (32 bit media) === media.c:231: Test failed: IWMPControls_play failed: 000d1103 media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w2003std (32 bit media) === media.c:231: Test failed: IWMPControls_play failed: 000d1103 media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64 (32 bit media) === media.c:231: Test failed: IWMPControls_play failed: 000d1103 media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64_zh_CN (32 bit media) === media.c:231: Test failed: IWMPControls_play failed: 000d1103 media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64_fr (32 bit media) === media.c:231: Test failed: IWMPControls_play failed: 000d1103 media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64_he (32 bit media) === media.c:231: Test failed: IWMPControls_play failed: 000d1103 media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w7u (32 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w7pro64 (32 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w8 (32 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w864 (32 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w1064 (32 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64 (64 bit media) === media.c:231: Test failed: IWMPControls_play failed: 000d1103 media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w7pro64 (64 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w864 (64 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w1064 (64 bit media) === media.c:237: Test failed: unexpected value media.c:250: Test failed: unexpected value: 0.000000 media.c:257: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:260: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
On 12/03/18 23:34, Anton Romanov wrote:
Signed-off-by: Anton Romanov theli.ua@gmail.com
dlls/wmp/player.c | 22 ++++++++++++++++++---- dlls/wmp/tests/media.c | 13 +++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index d3c67a3820..ddee6667f4 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1130,8 +1130,15 @@ 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->pFilterGraph) {
return S_FALSE;
- }
- /* Ideally we would use IAMOpenProgress but we don't have it in wine (yet) */
- FIXME("stub: Returning buffering progress 100\n");
- *plBufferingProgress = 100;
- return S_OK;
Note that not all sources support IAMOpenProgress anyway—in particular the async file reader doesn't. Which is to say that this behaviour is not necessarily wrong.
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 29 +++++++++++++++++++++++++---- dlls/wmp/tests/media.c | 8 +++++++- dlls/wmp/wmp_private.h | 1 + 3 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index ddee6667f4..1e63c44b38 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -937,16 +937,32 @@ static HRESULT WINAPI WMPSettings_put_balance(IWMPSettings *iface, LONG v)
static HRESULT WINAPI WMPSettings_get_volume(IWMPSettings *iface, LONG *p) { + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + if (!This->pFilterGraph) { + return S_FALSE; + } + hres = IBasicAudio_get_Volume(This->basic_audio, p); + /* IBasicAudio - [-10000, 0], wmp - [0, 100] */ + if (SUCCEEDED(hres)) + *p = (*p + 10000) * 100 / 10000; + return hres; }
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); + if (!This->pFilterGraph) { + return S_FALSE; + } + /* IBasicAudio - [-10000, 0], wmp - [0, 100] */ + v = 10000 * v / 100 - 10000; + hres = IBasicAudio_put_Volume(This->basic_audio, v); + TRACE("ret: %d", hres); + return hres; }
static HRESULT WINAPI WMPSettings_getMode(IWMPSettings *iface, BSTR mode, VARIANT_BOOL *p) @@ -1440,6 +1456,9 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) if (SUCCEEDED(hres)) hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaEvent, (void**)&This->media_event); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IBasicAudio, (void**)&This->basic_audio); + This->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); This->event_thread = CreateThread(NULL, 0, WMP_event_thread, This, 0, NULL); } @@ -1483,6 +1502,8 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) IMediaEvent_Release(This->media_event); if (This->media_seeking) IMediaSeeking_Release(This->media_seeking); + if (This->basic_audio) + IBasicAudio_Release(This->basic_audio); This->pFilterGraph = NULL; This->media_control = NULL; This->media_event = NULL; diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index 9e1853ecfe..e72e78a20b 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -202,7 +202,6 @@ static void 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); @@ -232,6 +231,12 @@ static void test_wmp(void) CHECK_CALLED(OPENSTATE_CHANGE); CHECK_CALLED(PLAYSTATE_CHANGE);
+ 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); + 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"); @@ -274,6 +279,7 @@ static void test_wmp(void) hres = IConnectionPoint_Unadvise(point, dw); ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
+ IWMPSettings_Release(settings); IConnectionPoint_Release(point); IWMPControls_Release(controls); IWMPPlayer4_Release(player4); diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 07fc0e1d9f..8b95c534a8 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -79,6 +79,7 @@ struct WindowsMediaPlayer { IMediaControl* media_control; IMediaEvent* media_event; IMediaSeeking* media_seeking; + IBasicAudio* basic_audio;
/* Async event notification */ HANDLE event_thread;
Hi,
While running your changed tests on Windows, 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=36694
Your paranoid android.
=== wxppro (32 bit media) === media.c:230: Test failed: IWMPControls_play failed: 000d1103 media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w2003std (32 bit media) === media.c:230: Test failed: IWMPControls_play failed: 000d1103 media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64 (32 bit media) === media.c:230: Test failed: IWMPControls_play failed: 000d1103 media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64_zh_CN (32 bit media) === media.c:230: Test failed: IWMPControls_play failed: 000d1103 media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64_fr (32 bit media) === media.c:230: Test failed: IWMPControls_play failed: 000d1103 media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64_he (32 bit media) === media.c:230: Test failed: IWMPControls_play failed: 000d1103 media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w7u (32 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w7pro64 (32 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w8 (32 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w864 (32 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w1064 (32 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== wvistau64 (64 bit media) === media.c:230: Test failed: IWMPControls_play failed: 000d1103 media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w7pro64 (64 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w864 (64 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
=== w1064 (64 bit media) === media.c:242: Test failed: unexpected value media.c:255: Test failed: unexpected value: 0.000000 media.c:262: Test failed: IWMPNetwork_get_bufferingProgress failed: 00000001 media.c:265: Test failed: IWMPNetwork_get_downloadProgress failed: 00000001
On 12/03/18 23:34, Anton Romanov wrote:
Signed-off-by: Anton Romanov theli.ua@gmail.com
dlls/wmp/player.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 6c68240fa8..987d189515 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1577,9 +1577,14 @@ static HRESULT WINAPI WMPMedia_get_isIdentical(IWMPMedia *iface, IWMPMedia *othe static HRESULT WINAPI WMPMedia_get_sourceURL(IWMPMedia *iface, BSTR *pbstrSourceUrl) { WMPMedia *This = impl_from_IWMPMedia(iface);
- BSTR url; TRACE("(%p)->(%p)\n", This, pbstrSourceUrl);
- *pbstrSourceUrl = SysAllocString(This->url);
- return S_OK;
- url = SysAllocString(This->url);
- if (url) {
*pbstrSourceUrl = url;
return S_OK;
- }
- return E_FAIL;
}
static HRESULT WINAPI WMPMedia_get_name(IWMPMedia *iface, BSTR *pbstrName)
I think E_OUTOFMEMORY would be better here.