wmp: Improve media items handling.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2018-08-17 18:05:16 +03:00 committed by Alexandre Julliard
parent 31cbe190f7
commit cd1c681ee7
3 changed files with 144 additions and 51 deletions

View file

@ -129,14 +129,17 @@ static HRESULT WINAPI WMPPlayer4_close(IWMPPlayer4 *iface)
return E_NOTIMPL;
}
static HRESULT WINAPI WMPPlayer4_get_URL(IWMPPlayer4 *iface, BSTR *pbstrURL)
static HRESULT WINAPI WMPPlayer4_get_URL(IWMPPlayer4 *iface, BSTR *url)
{
WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
TRACE("(%p)->(%p)\n", This, pbstrURL);
if(This->wmpmedia == NULL) {
TRACE("(%p)->(%p)\n", This, url);
if(This->media == NULL) {
return S_FALSE;
}
return IWMPMedia_get_sourceURL(This->wmpmedia, pbstrURL);
return return_bstr(This->media->url, url);
}
static HRESULT WINAPI WMPPlayer4_put_URL(IWMPPlayer4 *iface, BSTR url)
@ -149,7 +152,7 @@ static HRESULT WINAPI WMPPlayer4_put_URL(IWMPPlayer4 *iface, BSTR url)
return E_POINTER;
}
hres = create_media_from_url(url, &media);
hres = create_media_from_url(url, 0.0, &media);
if (SUCCEEDED(hres)) {
update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsTransitioning);
@ -202,16 +205,18 @@ static HRESULT WINAPI WMPPlayer4_get_settings(IWMPPlayer4 *iface, IWMPSettings *
return S_OK;
}
static HRESULT WINAPI WMPPlayer4_get_currentMedia(IWMPPlayer4 *iface, IWMPMedia **ppMedia)
static HRESULT WINAPI WMPPlayer4_get_currentMedia(IWMPPlayer4 *iface, IWMPMedia **media)
{
WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
TRACE("(%p)->(%p)\n", This, ppMedia);
if(This->wmpmedia == NULL) {
TRACE("(%p)->(%p)\n", This, media);
*media = NULL;
if (This->media == NULL)
return S_FALSE;
}
IWMPMedia_AddRef(This->wmpmedia);
*ppMedia = This->wmpmedia;
return S_OK;
return create_media_from_url(This->media->url, This->media->duration, media);
}
static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia *pMedia)
@ -223,15 +228,15 @@ static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia
return E_POINTER;
}
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistChanging);
if(This->wmpmedia != NULL) {
if(This->media != NULL) {
IWMPControls_stop(&This->IWMPControls_iface);
IWMPMedia_Release(This->wmpmedia);
IWMPMedia_Release(&This->media->IWMPMedia_iface);
}
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistChanged);
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistOpenNoMedia);
IWMPMedia_AddRef(pMedia);
This->wmpmedia = pMedia;
This->media = unsafe_impl_from_IWMPMedia(pMedia);
return S_OK;
}
@ -259,8 +264,7 @@ static HRESULT WINAPI WMPPlayer4_get_versionInfo(IWMPPlayer4 *iface, BSTR *versi
if (!version)
return E_POINTER;
*version = SysAllocString(versionW);
return *version ? S_OK : E_OUTOFMEMORY;
return return_bstr(versionW, version);
}
static HRESULT WINAPI WMPPlayer4_launchURL(IWMPPlayer4 *iface, BSTR url)
@ -343,11 +347,13 @@ static HRESULT WINAPI WMPPlayer4_newPlaylist(IWMPPlayer4 *iface, BSTR name, BSTR
return E_NOTIMPL;
}
static HRESULT WINAPI WMPPlayer4_newMedia(IWMPPlayer4 *iface, BSTR url, IWMPMedia **ppMedia)
static HRESULT WINAPI WMPPlayer4_newMedia(IWMPPlayer4 *iface, BSTR url, IWMPMedia **media)
{
WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
FIXME("(%p)->(%p)\n", This, ppMedia);
return E_NOTIMPL;
TRACE("(%p)->(%s %p)\n", This, debugstr_w(url), media);
return create_media_from_url(url, 0.0, media);
}
static HRESULT WINAPI WMPPlayer4_get_enabled(IWMPPlayer4 *iface, VARIANT_BOOL *pbEnabled)
@ -1450,20 +1456,13 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
{
HRESULT hres = S_OK;
WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
WMPMedia *media;
TRACE("(%p)\n", This);
if (!This->wmpmedia) {
if (!This->media) {
return NS_S_WMPCORE_COMMAND_NOT_AVAILABLE;
}
media = unsafe_impl_from_IWMPMedia(This->wmpmedia);
if (!media) {
FIXME("No support for non-builtin IWMPMedia implementations\n");
return E_INVALIDARG;
}
if (!This->filter_graph) {
hres = CoCreateInstance(&CLSID_FilterGraph,
NULL,
@ -1473,7 +1472,7 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposOpeningUnknownURL);
if (SUCCEEDED(hres))
hres = IGraphBuilder_RenderFile(This->filter_graph, media->url, NULL);
hres = IGraphBuilder_RenderFile(This->filter_graph, This->media->url, NULL);
if (SUCCEEDED(hres))
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposMediaOpen);
if (SUCCEEDED(hres))
@ -1517,7 +1516,7 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
LONGLONG duration;
update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsPlaying);
if (SUCCEEDED(IMediaSeeking_GetDuration(This->media_seeking, &duration)))
media->duration = (DOUBLE)duration / 10000000.0f;
This->media->duration = (DOUBLE)duration / 10000000.0f;
} else {
update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsUndefined);
}
@ -1781,24 +1780,23 @@ static HRESULT WINAPI WMPMedia_get_isIdentical(IWMPMedia *iface, IWMPMedia *othe
return E_NOTIMPL;
}
static HRESULT WINAPI WMPMedia_get_sourceURL(IWMPMedia *iface, BSTR *pbstrSourceUrl)
static HRESULT WINAPI WMPMedia_get_sourceURL(IWMPMedia *iface, BSTR *url)
{
WMPMedia *This = impl_from_IWMPMedia(iface);
BSTR url;
TRACE("(%p)->(%p)\n", This, pbstrSourceUrl);
url = SysAllocString(This->url);
if (url) {
*pbstrSourceUrl = url;
return S_OK;
}
return E_OUTOFMEMORY;
TRACE("(%p)->(%p)\n", This, url);
return return_bstr(This->url, url);
}
static HRESULT WINAPI WMPMedia_get_name(IWMPMedia *iface, BSTR *pbstrName)
static HRESULT WINAPI WMPMedia_get_name(IWMPMedia *iface, BSTR *name)
{
WMPMedia *This = impl_from_IWMPMedia(iface);
FIXME("(%p)->(%p)\n", This, pbstrName);
return E_NOTIMPL;
FIXME("(%p)->(%p)\n", This, name);
/* FIXME: this should be a display name */
return return_bstr(This->url, name);
}
static HRESULT WINAPI WMPMedia_put_name(IWMPMedia *iface, BSTR pbstrName)
@ -2012,8 +2010,8 @@ BOOL init_player(WindowsMediaPlayer *wmp)
void destroy_player(WindowsMediaPlayer *wmp)
{
IWMPControls_stop(&wmp->IWMPControls_iface);
if(wmp->wmpmedia)
IWMPMedia_Release(wmp->wmpmedia);
if (wmp->media)
IWMPMedia_Release(&wmp->media->IWMPMedia_iface);
DestroyWindow(wmp->msg_window);
}
@ -2025,16 +2023,18 @@ WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface)
return NULL;
}
HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia)
HRESULT create_media_from_url(BSTR url, double duration, IWMPMedia **ppMedia)
{
WMPMedia *media = heap_alloc_zero(sizeof(WMPMedia));
static const WCHAR emptyW[] = {0};
WMPMedia *media;
if (!media) {
media = heap_alloc_zero(sizeof(*media));
if (!media)
return E_OUTOFMEMORY;
}
media->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl;
media->url = heap_strdupW(url);
media->url = url ? heap_strdupW(url) : heap_strdupW(emptyW);
media->duration = duration;
media->ref = 1;
if (media->url) {

View file

@ -487,6 +487,81 @@ playback_skip:
return test_ran;
}
static void test_media_item(void)
{
static const WCHAR testW[] = {'t','e','s','t',0};
IWMPMedia *media, *media2;
IWMPPlayer4 *player;
HRESULT hr;
BSTR str;
hr = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IWMPPlayer4, (void **)&player);
if (hr == REGDB_E_CLASSNOTREG)
{
win_skip("CLSID_WindowsMediaPlayer is not registered.\n");
return;
}
ok(hr == S_OK, "Failed to create media player instance, hr %#x.\n", hr);
hr = IWMPPlayer4_newMedia(player, NULL, &media);
ok(hr == S_OK, "Failed to create a media item, hr %#x.\n", hr);
hr = IWMPMedia_get_name(media, &str);
ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr);
ok(*str == 0, "Unexpected name %s.\n", wine_dbgstr_w(str));
SysFreeString(str);
media2 = (void *)0xdeadbeef;
hr = IWMPPlayer4_get_currentMedia(player, &media2);
ok(hr == S_FALSE, "Failed to get current media, hr %#x.\n", hr);
ok(media2 == NULL, "Unexpected media instance.\n");
hr = IWMPPlayer4_put_currentMedia(player, media);
ok(hr == S_OK, "Failed to set current media, hr %#x.\n", hr);
hr = IWMPPlayer4_get_currentMedia(player, &media2);
ok(hr == S_OK, "Failed to get current media, hr %#x.\n", hr);
ok(media2 != NULL && media != media2, "Unexpected media instance.\n");
IWMPMedia_Release(media2);
IWMPMedia_Release(media);
str = SysAllocStringLen(NULL, 0);
hr = IWMPPlayer4_newMedia(player, str, &media);
ok(hr == S_OK, "Failed to create a media item, hr %#x.\n", hr);
SysFreeString(str);
hr = IWMPMedia_get_name(media, &str);
ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr);
ok(*str == 0, "Unexpected name %s.\n", wine_dbgstr_w(str));
SysFreeString(str);
IWMPMedia_Release(media);
str = SysAllocString(mp3file);
hr = IWMPPlayer4_newMedia(player, str, &media);
ok(hr == S_OK, "Failed to create a media item, hr %#x.\n", hr);
SysFreeString(str);
hr = IWMPMedia_get_name(media, &str);
ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr);
todo_wine
ok(!lstrcmpW(str, testW), "Unexpected name %s.\n", wine_dbgstr_w(str));
SysFreeString(str);
hr = IWMPPlayer4_put_currentMedia(player, media);
ok(hr == S_OK, "Failed to set current media, hr %#x.\n", hr);
IWMPMedia_Release(media);
hr = IWMPPlayer4_get_currentMedia(player, &media2);
ok(hr == S_OK, "Failed to get current media, hr %#x.\n", hr);
ok(media2 != NULL, "Unexpected media instance.\n");
hr = IWMPMedia_get_name(media2, &str);
ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr);
todo_wine
ok(!lstrcmpW(str, testW), "Unexpected name %s.\n", wine_dbgstr_w(str));
SysFreeString(str);
IWMPMedia_Release(media2);
IWMPPlayer4_Release(player);
}
START_TEST(media)
{
CoInitialize(NULL);
@ -494,6 +569,8 @@ START_TEST(media)
main_thread_id = GetCurrentThreadId();
playing_event = CreateEventW(NULL, FALSE, FALSE, NULL);
completed_event = CreateEventW(NULL, FALSE, FALSE, NULL);
test_media_item();
if (test_wmp()) {
test_completion_event();
} else {

View file

@ -73,7 +73,7 @@ struct WindowsMediaPlayer {
ConnectionPoint *wmpocx;
IWMPMedia *wmpmedia;
WMPMedia *media;
/* DirectShow stuff */
IGraphBuilder* filter_graph;
@ -89,7 +89,7 @@ struct WindowsMediaPlayer {
BOOL init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface) DECLSPEC_HIDDEN;
HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) DECLSPEC_HIDDEN;
HRESULT create_media_from_url(BSTR url, double duration, 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;
@ -116,3 +116,19 @@ static inline WCHAR *heap_strdupW(const WCHAR *str)
return ret;
}
static inline HRESULT return_bstr(const WCHAR *value, BSTR *p)
{
if(!p)
return E_INVALIDARG;
if(value) {
*p = SysAllocString(value);
if(!*p)
return E_OUTOFMEMORY;
}else {
*p = NULL;
}
return S_OK;
}