[PATCH 2/7] wmp: Implement playback via quartz
Anton Romanov
theli.ua at gmail.com
Mon Mar 12 23:34:50 CDT 2018
Signed-off-by: Anton Romanov <theli.ua at 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;
--
2.16.2
More information about the wine-devel
mailing list