[PATCH] wmp: Improve media items handling.
Nikolay Sivov
nsivov at codeweavers.com
Fri Aug 17 10:05:16 CDT 2018
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/wmp/player.c | 98 +++++++++++++++++++++---------------------
dlls/wmp/tests/media.c | 77 +++++++++++++++++++++++++++++++++
dlls/wmp/wmp_private.h | 20 ++++++++-
3 files changed, 144 insertions(+), 51 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c
index 56b408f5b1..fd8c17d60f 100644
--- a/dlls/wmp/player.c
+++ b/dlls/wmp/player.c
@@ -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) {
diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c
index aeca6180b0..bd9aefc975 100644
--- a/dlls/wmp/tests/media.c
+++ b/dlls/wmp/tests/media.c
@@ -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 {
diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
index b0861dd302..9617be0c7f 100644
--- a/dlls/wmp/wmp_private.h
+++ b/dlls/wmp/wmp_private.h
@@ -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;
+}
--
2.18.0
More information about the wine-devel
mailing list