[PATCH v5 1/6] wmp: Implement playback via quartz

Anton Romanov theli.ua at gmail.com
Tue Mar 27 23:00:52 CDT 2018


Signed-off-by: Anton Romanov <theli.ua at gmail.com>
---
 dlls/wmp/player.c          |  91 +++++++++++++++++++++++++++++++---
 dlls/wmp/tests/Makefile.in |   2 +-
 dlls/wmp/tests/av.mp4      | Bin 1493 -> 0 bytes
 dlls/wmp/tests/media.c     | 120 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/wmp/tests/oleobj.c    |   6 +--
 dlls/wmp/tests/rsrc.rc     |   5 +-
 dlls/wmp/tests/test.mp3    | Bin 0 -> 240333 bytes
 dlls/wmp/wmp_private.h     |   8 ++-
 8 files changed, 217 insertions(+), 15 deletions(-)
 delete mode 100644 dlls/wmp/tests/av.mp4
 create mode 100644 dlls/wmp/tests/media.c
 create mode 100644 dlls/wmp/tests/test.mp3

diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c
index 4a0d0742fd..5effc75743 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,62 @@ static HRESULT WINAPI WMPControls_get_isAvailable(IWMPControls *iface, BSTR bstr
 
 static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
 {
+    HRESULT hres = S_OK;
     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 = 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,
+                CLSCTX_INPROC_SERVER,
+                &IID_IGraphBuilder,
+                (void **)&This->filter_graph);
+        if (SUCCEEDED(hres))
+            hres = IGraphBuilder_RenderFile(This->filter_graph, media->url, NULL);
+        if (SUCCEEDED(hres))
+            hres = IGraphBuilder_QueryInterface(This->filter_graph, &IID_IMediaControl,
+                    (void**)&This->media_control);
+    }
+
+    if (SUCCEEDED(hres))
+        hres = IMediaControl_Run(This->media_control);
+
+    if (hres == S_FALSE) {
+        hres = S_OK; /* S_FALSE will mean that graph is transitioning and that is fine */
+    }
+    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->filter_graph) {
+        return NS_S_WMPCORE_COMMAND_NOT_AVAILABLE;
+    }
+    if (This->media_control) {
+        hres = IMediaControl_Stop(This->media_control);
+        IMediaControl_Release(This->media_control);
+    }
+    if (!This->filter_graph) {
+        IGraphBuilder_Release(This->filter_graph);
+    }
+    This->filter_graph = NULL;
+    This->media_control = NULL;
+    return hres;
 }
 
 static HRESULT WINAPI WMPControls_pause(IWMPControls *iface)
@@ -1741,16 +1796,36 @@ 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){
+WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface)
+{
+    if (iface->lpVtbl == &WMPMediaVtbl) {
+        return CONTAINING_RECORD(iface, WMPMedia, IWMPMedia_iface);
+    }
+    return NULL;
+}
 
+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;
 
-    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/av.mp4 b/dlls/wmp/tests/av.mp4
deleted file mode 100644
index 1431e98dd3f5bb28c282d3d732a3a1fc13cf3d63..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1493
zcmeHHO-sW-5Z$D$cn}OyK`=rq^=7}c+G`IUJa`ik#7o*uZD_U$*=<2j`7uHf{1GDl
z1OJ2v!Gm5r>6;{NZ56!et&eVJ_RZ{@-Py2=F|(~MeMfqNF`bdc*b#oM${1U02eu9V
zMQ}^yjZE%({o at Y&97zZ2!~blBKX3W>_ST2tck=HTAD{cZ at Vo&eT`}nJY3bAx=4GZa
z`b{u30X;KsOfrA+Qdsb;0;`MQx#~tW!HuCOUU|%5K~!R<&M$QfHdhiFrtM0VXpus!
z8w+y59SdAe at Y%E99^ge_ClAreVu!myqQRus?~Q!2$C&d&tH)iNa<paP^xAL?DW*gV
zJmyUv*c2zwHkSH<n at jvhshTeQ3#sJjGAQR1Zxn5mK=T+nGsvN>0=u^4bYPYW!*CPt
zTN*aoSS3n(!+3qqfYDcs1sIL`ye3uDqbLP`;L_xqDBmInpmH=QpDe|$U`GJ2p{zzd
z&Pvttk^tpyV>J6*S+Hlqjx2 at qU;BwW2rS>HV~<gE;!E4QQ633y;7KMC5 at ko$puM+W
Ks#QwWO7#=93TT)B

diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c
new file mode 100644
index 0000000000..6e4a0c170f
--- /dev/null
+++ b/dlls/wmp/tests/media.c
@@ -0,0 +1,120 @@
+/*
+ * 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 mp3file[] = {'t','e','s','t','.','m','p','3',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;
+    IWMPSettings *settings;
+
+    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);
+
+    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);
+    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(mp3file));
+
+    hres = IWMPPlayer4_put_URL(player4, filename);
+    ok(hres == S_OK, "IWMPPlayer4_put_URL failed: %08x\n", hres);
+
+    hres = IWMPControls_play(controls);
+    ok(hres == S_OK, "IWMPControls_play failed: %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 e4c2294436..41179dae5d 100644
--- a/dlls/wmp/tests/oleobj.c
+++ b/dlls/wmp/tests/oleobj.c
@@ -70,7 +70,7 @@ DEFINE_EXPECT(GetWindowContext);
 DEFINE_EXPECT(ShowObject);
 DEFINE_EXPECT(OnShowWindow_FALSE);
 
-static const WCHAR mp4file[] = {'a','v','.','m','p','4',0};
+static const WCHAR mp3file[] = {'t','e','s','t','.','m','p','3',0};
 static inline WCHAR *load_resource(const WCHAR *name)
 {
     static WCHAR pathW[MAX_PATH];
@@ -942,8 +942,7 @@ static void test_wmp_ifaces(IOleObject *oleobj)
     ok(hres == S_FALSE, "get_currentMedia SUCCEEDED\n");
     ok(media == NULL, "media != NULL\n");
 
-    filename = SysAllocString(load_resource(mp4file));
-
+    filename = SysAllocString(load_resource(mp3file));
 
     SET_EXPECT(GetContainer);
     SET_EXPECT(Invoke_USERMODE);
@@ -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/tests/rsrc.rc b/dlls/wmp/tests/rsrc.rc
index fb30ae6940..f33acc1256 100644
--- a/dlls/wmp/tests/rsrc.rc
+++ b/dlls/wmp/tests/rsrc.rc
@@ -18,5 +18,6 @@
 
 #include "windef.h"
 
-/* @makedep: av.mp4 */
-av.mp4 RCDATA "av.mp4"
+/* ffmpeg -ar 48000 -t 60 -f s16le -acodec pcm_s16le -ac 2 -i /dev/zero -acodec libmp3lame -aq 4 output.mp3 */
+/* @makedep: test.mp3 */
+test.mp3 RCDATA "test.mp3"
diff --git a/dlls/wmp/tests/test.mp3 b/dlls/wmp/tests/test.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..149a2cd346ee52ae179c46198ce290a5dd4d6251
GIT binary patch
literal 240333
zcmeI%f23Xo0LJlCcd=qF8IkluD<ZR5KSsq;mzGVmT``eqrkEu$6EP~1m`IVNlq5-1
zBqA}9NQp$^ij2req${`gz5Vg*;oRHE``_o9?faaU<K1!gx#zyyedmr1!}ROw{rmPU
zO#Yl7hPgclj~%}8=B+z-Y~8+X+v=<T{<gBb|Ex8hyN at 1zWb(@7G#8#4=H7X2n7d%(
zMVsa?-h9cWmtAqymTRxOe(UxfH|@OTwq18D+;#Wfd+yzT-+}udIC$vrLr0E2`q;7K
zk3VtZ$)}%r_PLYKzwpw_ue|#D8*jb+?tAZl at X^PgeEQkvr at r{|tFOQL?)x8p{Auau
zUrzt}+nL}0`17y7r|)F)o*$gN=j~^|-(k!7yQZ&A-^a=|Pn}*_-h617KQjyuPmXOI
zhD}!v!+DcmZ%*bUZ#Xdw8}{73cVYGKy*To<?u(0y)AL{cALk!AYYv^m`EQ-^`47za
z{Ksc}{ugI_{tst-{%>b|{-u-a-~YK8N9r8zPv at VaIdbhLho(NbKCaLB-7z`p-`9pU
zug&xY*T?no{mb{4wUFQgANarrKCJoq##)zV^*BHI$xnW+g#;h?zz06?!SmI~J>c{0
z_5SnF=l?#x9XvmHe(?M-^1WmAke at I3zz06?!Os^X_kf=-{CqKTTjY at E2hR_lA3Q%q
zgf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8gT7@h=@PQ9}hzMPL
z-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1eBc8g_z)4g_`nA~
z at S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIUKJXzTbn$@?eBeW?
zki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE724}9Q5MCjrJANatBRw0WI
zeBc8gB0?7*_`nA~v<g{#-~%7{5D~igzz06?p;gG at 10VRnhltR{2R`tD53NELANarr
zK175rKJbALd}tN2_`nA~@F5~}@qrI~;6tmB#Rop{fe#U(iw}I at 10Pz2EI#mo4}6FS
zU3}mJANbHJWbuIyeBeVw=;8w(_`ru&A&U=u-~%5bLKh$Szz06G3R!&M10VPh5xV%m
z2R`tjRmkE4ANatBh|t9cKJbALtwI(b_`nA~M1(Fr at PQ9}Xce;fzz06?AtH3~fe(D(
zL#vR*2R`tD4-uh at 4}9PQA6kVhKJbALe255LeBc8g_|Ph3 at qrI~;6p^{;sYP}z=u{L
ziw}I at 10Nzn7a#b*2R^h4S$yCFANUXvy7<5cKJcMc$l?PZ_`rvV(8UKn at PQAlLKYwR
zzz04=gf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8gT7@h=@PQ9}
zhzMPL-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1eBc8g_z)4g
z_`nA~@S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIUKJXzTbn$@?
zeBeW?ki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE724}9Q5MCjrJANatB
zRw0WIeBc8gB0?7*_`nA~v<g{#-~%7{5D~igzz06?p;gG at 10VRnhltR{2R`tD53NEL
zANarrK175rKJbALd}tN2_`nA~@F5~}@qrI~;6tmB#Rop{fe#U(iw}I at 10Pz2EI#mo
z4}6FSU3}mJANbHJWbuIyeBeVw=;8w(_`ru&A&U=u-~%5bLKh$Szz06G3R!&M10VPh
z5xV%m2R`tjRmkE4ANatBh|t9cKJbALtwI(b_`nA~M1(Fr at PQ9}Xce;fzz06?AtH3~
zfe(D(L#vR*2R`tD4-uh at 4}9PQA6kVhKJbALe255LeBc8g_|Ph3 at qrI~;6p^{;sYP}
zz=u{Liw}I at 10Nzn7a#b*2R^h4S$yCFANUXvy7<5cKJcMc$l?PZ_`rvV(8UKn at PQAl
zLKYwRzz04=gf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8gT7@h=
z at PQ9}hzMPL-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1eBc8g
z_z)4g_`nA~@S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIUKJXzT
zbn$@?eBeW?ki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE724}9Q5MCjrJ
zANatBRw0WIeBc8gB0?7*_`nA~v<g{#-~%7{5D~igzz06?p;gG at 10VRnhltR{2R`tD
z53NELANarrK175rKJbALd}tN2_`nA~@F5~}@qrI~;6tmB#Rop{fe#U(iw}I at 10Pz2
zEI#mo4}6FSU3}mJANbHJWbuIyeBeVw=;8w(_`ru&A&U=u-~%5bLKh$Szz06G3R!&M
z10VPh5xV%m2R`tjRmkE4ANatBh|t9cKJbALtwI(b_`nA~M1(Fr at PQ9}Xce;fzz06?
zAtH3~fe(D(L#vR*2R`tD4-uh at 4}9PQA6kVhKJbALe255LeBc8g_|Ph3 at qrI~;6p^{
z;sYP}z=u{Liw}I at 10Nzn7a#b*2R^h4S$yCFANUXvy7<5cKJcMc$l?PZ_`rvV(8UKn
z at PQAlLKYwRzz04=gf2etfe(CW6|(ri2R`s2B6RVA4}9Q5tB}P9KJbAL5uu9 at eBc8g
zT7 at h=@PQ9}hzMPL-~%7{&?;o{fe(D(LqzD}10VRnhgKnr4}9PQA0k2*ANarrKC}v1
zeBc8g_z)4g_`nA~@S#=6;sYP}z=w#?#Rop{fe)=h79aS)2R=lEE<W&q4}549viQIU
zKJXzTbn$@?eBeW?ki`c+ at PQ8zp^FcE-~%68g)Bbsfe(C$2wi;O10VR%DrE725C6x9
d+)1Ogvb_1wlJk#Vo9RK<XU$8q`ogTQ&p*pvqh$a9

literal 0
HcmV?d00001

diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
index e95b194d77..05ad5889e2 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,16 @@ struct WindowsMediaPlayer {
     ConnectionPoint *wmpocx;
 
     IWMPMedia *wmpmedia;
+
+    /* DirectShow stuff */
+    IGraphBuilder* filter_graph;
+    IMediaControl* media_control;
 };
 
 void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
 void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
-IWMPMedia* create_media_from_url(BSTR url);
+WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface) DECLSPEC_HIDDEN;
+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;
 
-- 
2.16.2




More information about the wine-devel mailing list