[PATCH 3/5] winegstreamer: Reimplement COM registration and vending locally.

Zebediah Figura z.figura12 at gmail.com
Sat Mar 7 10:00:23 CST 2020


From: Zebediah Figura <z.figura12 at gmail.com>

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/winegstreamer/Makefile.in                |   4 +-
 dlls/winegstreamer/gst_private.h              |  17 +-
 dlls/winegstreamer/gstdemux.c                 |  69 +--
 dlls/winegstreamer/main.c                     | 484 +++++++++---------
 dlls/winegstreamer/mfplat.c                   |  11 +-
 .../{mfplat.idl => winegstreamer_classes.idl} |  36 +-
 6 files changed, 320 insertions(+), 301 deletions(-)
 rename dlls/winegstreamer/{mfplat.idl => winegstreamer_classes.idl} (55%)

diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index 2050a44b132..2364ac84dc5 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -5,7 +5,6 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
 PARENTSRC = ../strmbase
 
 C_SRCS = \
-	dllfunc.c \
 	filter.c \
 	gst_cbs.c \
 	gstdemux.c \
@@ -16,7 +15,8 @@ C_SRCS = \
 	qualitycontrol.c \
 	seeking.c
 
-IDL_SRCS = mfplat.idl
+IDL_SRCS = \
+	winegstreamer_classes.idl
 
 RC_SRCS = \
 	rsrc.rc
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 353ff0bbd5b..e6fb841fc87 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -22,8 +22,14 @@
 #define __GST_PRIVATE_INCLUDED__
 
 #include <stdarg.h>
+#include <stdio.h>
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/audio/audio.h>
 
 #define COBJMACROS
+#define NONAMELESSSTRUCT
+#define NONAMELESSUNION
 #include "windef.h"
 #include "winbase.h"
 #include "wtypes.h"
@@ -35,16 +41,17 @@
 
 #define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
 
-IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN;
-IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN;
-IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr);
-IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN;
+extern LONG object_locks;
+
+HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT gstdemux_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT wave_parser_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
 
 BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
 
 void start_dispatch_thread(void) DECLSPEC_HIDDEN;
 
 extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
-extern HRESULT mfplat_can_unload_now(void) DECLSPEC_HIDDEN;
 
 #endif /* __GST_PRIVATE_INCLUDED__ */
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 30f3a590006..a51354b13c7 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -20,11 +20,6 @@
  */
 
 #include "config.h"
-
-#include <gst/gst.h>
-#include <gst/video/video.h>
-#include <gst/audio/audio.h>
-
 #include "gst_private.h"
 #include "gst_guids.h"
 #include "gst_cbs.h"
@@ -1719,23 +1714,17 @@ static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin,
     return VFW_S_NO_MORE_ITEMS;
 }
 
-IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
+HRESULT gstdemux_create(IUnknown *outer, IUnknown **out)
 {
     struct gstdemux *object;
 
     if (!init_gstreamer())
-    {
-        *phr = E_FAIL;
-        return NULL;
-    }
+        return E_FAIL;
 
     mark_wine_thread();
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
-    {
-        *phr = E_OUTOFMEMORY;
-        return NULL;
-    }
+        return E_OUTOFMEMORY;
 
     strmbase_filter_init(&object->filter, outer, &CLSID_Gstreamer_Splitter, &filter_ops);
     strmbase_sink_init(&object->sink, &object->filter, wcsInputPinName, &sink_ops, NULL);
@@ -1745,10 +1734,10 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
     object->init_gst = gstdecoder_init_gst;
     object->source_query_accept = gstdecoder_source_query_accept;
     object->source_get_media_type = gstdecoder_source_get_media_type;
-    *phr = S_OK;
 
     TRACE("Created GStreamer demuxer %p.\n", object);
-    return &object->filter.IUnknown_inner;
+    *out = &object->filter.IUnknown_inner;
+    return S_OK;
 }
 
 static struct gstdemux *impl_from_IAMStreamSelect(IAMStreamSelect *iface)
@@ -2422,24 +2411,18 @@ static HRESULT wave_parser_source_get_media_type(struct gstdemux_source *pin,
     return S_OK;
 }
 
-IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr)
+HRESULT wave_parser_create(IUnknown *outer, IUnknown **out)
 {
     static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
     struct gstdemux *object;
 
     if (!init_gstreamer())
-    {
-        *phr = E_FAIL;
-        return NULL;
-    }
+        return E_FAIL;
 
     mark_wine_thread();
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
-    {
-        *phr = E_OUTOFMEMORY;
-        return NULL;
-    }
+        return E_OUTOFMEMORY;
 
     strmbase_filter_init(&object->filter, outer, &CLSID_WAVEParser, &filter_ops);
     strmbase_sink_init(&object->sink, &object->filter, sink_name, &wave_parser_sink_ops, NULL);
@@ -2447,10 +2430,10 @@ IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr)
     object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL);
     object->source_query_accept = wave_parser_source_query_accept;
     object->source_get_media_type = wave_parser_source_get_media_type;
-    *phr = S_OK;
 
     TRACE("Created WAVE parser %p.\n", object);
-    return &object->filter.IUnknown_inner;
+    *out = &object->filter.IUnknown_inner;
+    return S_OK;
 }
 
 static HRESULT avi_splitter_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
@@ -2543,24 +2526,18 @@ static HRESULT avi_splitter_source_get_media_type(struct gstdemux_source *pin,
     return S_OK;
 }
 
-IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
+HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out)
 {
     static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
     struct gstdemux *object;
 
     if (!init_gstreamer())
-    {
-        *phr = E_FAIL;
-        return NULL;
-    }
+        return E_FAIL;
 
     mark_wine_thread();
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
-    {
-        *phr = E_OUTOFMEMORY;
-        return NULL;
-    }
+        return E_OUTOFMEMORY;
 
     strmbase_filter_init(&object->filter, outer, &CLSID_AviSplitter, &filter_ops);
     strmbase_sink_init(&object->sink, &object->filter, sink_name, &avi_splitter_sink_ops, NULL);
@@ -2569,10 +2546,10 @@ IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
     object->init_gst = avi_splitter_init_gst;
     object->source_query_accept = avi_splitter_source_query_accept;
     object->source_get_media_type = avi_splitter_source_get_media_type;
-    *phr = S_OK;
 
     TRACE("Created AVI splitter %p.\n", object);
-    return &object->filter.IUnknown_inner;
+    *out = &object->filter.IUnknown_inner;
+    return S_OK;
 }
 
 static HRESULT mpeg_splitter_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
@@ -2701,24 +2678,18 @@ static const struct strmbase_filter_ops mpeg_splitter_ops =
     .filter_wait_state = gstdemux_wait_state,
 };
 
-IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
+HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out)
 {
     static const WCHAR sink_name[] = {'I','n','p','u','t',0};
     struct gstdemux *object;
 
     if (!init_gstreamer())
-    {
-        *phr = E_FAIL;
-        return NULL;
-    }
+        return E_FAIL;
 
     mark_wine_thread();
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
-    {
-        *phr = E_OUTOFMEMORY;
-        return NULL;
-    }
+        return E_OUTOFMEMORY;
 
     strmbase_filter_init(&object->filter, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops);
     strmbase_sink_init(&object->sink, &object->filter, sink_name, &mpeg_splitter_sink_ops, NULL);
@@ -2730,8 +2701,8 @@ IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
     object->source_query_accept = mpeg_splitter_source_query_accept;
     object->source_get_media_type = mpeg_splitter_source_get_media_type;
     object->enum_sink_first = TRUE;
-    *phr = S_OK;
 
     TRACE("Created MPEG-1 splitter %p.\n", object);
-    return &object->filter.IUnknown_inner;
+    *out = &object->filter.IUnknown_inner;
+    return S_OK;
 }
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 59c2bd974d4..2872710b3e2 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -18,12 +18,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-#include <stdarg.h>
-#include <stdio.h>
-
-#include <gst/gst.h>
-
 #include "gst_private.h"
 #include "rpcproxy.h"
 #include "wine/debug.h"
@@ -32,7 +26,8 @@
 #include "initguid.h"
 #include "gst_guids.h"
 
-static HINSTANCE hInst = NULL;
+static HINSTANCE winegstreamer_instance;
+LONG object_locks;
 
 WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
 
@@ -45,249 +40,130 @@ static const WCHAR avi_splitterW[] =
 static const WCHAR mpeg_splitterW[] =
 {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0};
 
-static WCHAR wNull[] = {'\0'};
-
-static const AMOVIESETUP_MEDIATYPE amfMTstream[] =
-{   { &MEDIATYPE_Stream, &WINESUBTYPE_Gstreamer },
-    { &MEDIATYPE_Stream, &MEDIASUBTYPE_NULL },
-};
-
-static const AMOVIESETUP_MEDIATYPE amfMTaudio[] =
-{   { &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL } };
-
-static const AMOVIESETUP_MEDIATYPE amfMTvideo[] =
-{   { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL } };
-
-static const AMOVIESETUP_PIN amfSplitPin[] =
-{   {   wNull,
-        FALSE, FALSE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        2,
-        amfMTstream
-    },
-    {
-        wNull,
-        FALSE, TRUE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        1,
-        amfMTaudio
-    },
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
+{
+    if (reason == DLL_PROCESS_ATTACH)
     {
-        wNull,
-        FALSE, TRUE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        1,
-        amfMTvideo
+        winegstreamer_instance = instance;
+        DisableThreadLibraryCalls(instance);
     }
-};
-
-static const AMOVIESETUP_FILTER amfSplitter =
-{   &CLSID_Gstreamer_Splitter,
-    wGstreamer_Splitter,
-    MERIT_PREFERRED,
-    3,
-    amfSplitPin
-};
+    return TRUE;
+}
 
-static const AMOVIESETUP_MEDIATYPE wave_parser_sink_type_data[] =
+HRESULT WINAPI DllCanUnloadNow(void)
 {
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_AU},
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF},
-};
+    TRACE(".\n");
 
-static const AMOVIESETUP_MEDIATYPE wave_parser_source_type_data[] =
-{
-    {&MEDIATYPE_Audio, &GUID_NULL},
-};
+    return object_locks ? S_FALSE : S_OK;
+}
 
-static const AMOVIESETUP_PIN wave_parser_pin_data[] =
+struct class_factory
 {
-    {
-        NULL,
-        FALSE, FALSE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        ARRAY_SIZE(wave_parser_sink_type_data),
-        wave_parser_sink_type_data,
-    },
-    {
-        NULL,
-        FALSE, TRUE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        ARRAY_SIZE(wave_parser_source_type_data),
-        wave_parser_source_type_data,
-    },
+    IClassFactory IClassFactory_iface;
+    HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
 };
 
-static const AMOVIESETUP_FILTER wave_parser_filter_data =
+static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
 {
-    &CLSID_WAVEParser,
-    wave_parserW,
-    MERIT_UNLIKELY,
-    ARRAY_SIZE(wave_parser_pin_data),
-    wave_parser_pin_data,
-};
+    return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
+}
 
-static const AMOVIESETUP_MEDIATYPE avi_splitter_sink_type_data[] =
+static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
 {
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi},
-};
+    TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
 
-static const AMOVIESETUP_PIN avi_splitter_pin_data[] =
-{
+    if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
     {
-        NULL,
-        FALSE, FALSE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        ARRAY_SIZE(avi_splitter_sink_type_data),
-        avi_splitter_sink_type_data,
-    },
-    {
-        NULL,
-        FALSE, TRUE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        ARRAY_SIZE(amfMTvideo),
-        amfMTvideo,
-    },
-};
+        *out = iface;
+        IClassFactory_AddRef(iface);
+        return S_OK;
+    }
 
-static const AMOVIESETUP_FILTER avi_splitter_filter_data =
-{
-    &CLSID_AviSplitter,
-    avi_splitterW,
-    0x5ffff0,
-    ARRAY_SIZE(avi_splitter_pin_data),
-    avi_splitter_pin_data,
-};
+    *out = NULL;
+    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
 
-static const AMOVIESETUP_MEDIATYPE mpeg_splitter_sink_type_data[] =
+static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
 {
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio},
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video},
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System},
-    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD},
-};
+    return 2;
+}
 
-static const AMOVIESETUP_MEDIATYPE mpeg_splitter_audio_type_data[] =
+static ULONG WINAPI class_factory_Release(IClassFactory *iface)
 {
-    {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet},
-    {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload},
-};
+    return 1;
+}
 
-static const AMOVIESETUP_MEDIATYPE mpeg_splitter_video_type_data[] =
+static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out)
 {
-    {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet},
-    {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload},
-};
+    struct class_factory *factory = impl_from_IClassFactory(iface);
+    IUnknown *unk;
+    HRESULT hr;
 
-static const AMOVIESETUP_PIN mpeg_splitter_pin_data[] =
-{
-    {
-        NULL,
-        FALSE, FALSE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        ARRAY_SIZE(mpeg_splitter_sink_type_data),
-        mpeg_splitter_sink_type_data,
-    },
-    {
-        NULL,
-        FALSE, TRUE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        ARRAY_SIZE(mpeg_splitter_audio_type_data),
-        mpeg_splitter_audio_type_data,
-    },
-    {
-        NULL,
-        FALSE, TRUE, FALSE, FALSE,
-        &GUID_NULL,
-        NULL,
-        ARRAY_SIZE(mpeg_splitter_video_type_data),
-        mpeg_splitter_video_type_data,
-    },
-};
+    TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
 
-static const AMOVIESETUP_FILTER mpeg_splitter_filter_data =
-{
-    &CLSID_MPEG1Splitter,
-    mpeg_splitterW,
-    0x5ffff0,
-    ARRAY_SIZE(mpeg_splitter_pin_data),
-    mpeg_splitter_pin_data,
-};
+    if (outer && !IsEqualGUID(iid, &IID_IUnknown))
+        return E_NOINTERFACE;
 
-FactoryTemplate const g_Templates[] = {
-    {
-        wGstreamer_Splitter,
-        &CLSID_Gstreamer_Splitter,
-        Gstreamer_Splitter_create,
-        NULL,
-        &amfSplitter,
-    },
+    *out = NULL;
+    if (SUCCEEDED(hr = factory->create_instance(outer, &unk)))
     {
-        wave_parserW,
-        &CLSID_WAVEParser,
-        wave_parser_create,
-        NULL,
-        &wave_parser_filter_data,
-    },
-    {
-        avi_splitterW,
-        &CLSID_AviSplitter,
-        avi_splitter_create,
-        NULL,
-        &avi_splitter_filter_data,
-    },
-    {
-        mpeg_splitterW,
-        &CLSID_MPEG1Splitter,
-        mpeg_splitter_create,
-        NULL,
-        &mpeg_splitter_filter_data,
-    },
-};
-
-const int g_cTemplates = ARRAY_SIZE(g_Templates);
+        hr = IUnknown_QueryInterface(unk, iid, out);
+        IUnknown_Release(unk);
+    }
+    return hr;
+}
 
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock)
 {
-    if (fdwReason == DLL_PROCESS_ATTACH)
-        hInst = hInstDLL;
-    return STRMBASE_DllMain(hInstDLL, fdwReason, lpv);
+    TRACE("iface %p, lock %d.\n", iface, lock);
+
+    if (lock)
+        InterlockedIncrement(&object_locks);
+    else
+        InterlockedDecrement(&object_locks);
+    return S_OK;
 }
 
-/***********************************************************************
- *    DllCanUnloadNow
- */
-HRESULT WINAPI DllCanUnloadNow(void)
+static const IClassFactoryVtbl class_factory_vtbl =
 {
-    HRESULT hr = STRMBASE_DllCanUnloadNow();
+    class_factory_QueryInterface,
+    class_factory_AddRef,
+    class_factory_Release,
+    class_factory_CreateInstance,
+    class_factory_LockServer,
+};
 
-    if (hr == S_OK)
-        hr = mfplat_can_unload_now();
+static struct class_factory avi_splitter_cf = {{&class_factory_vtbl}, avi_splitter_create};
+static struct class_factory gstdemux_cf = {{&class_factory_vtbl}, gstdemux_create};
+static struct class_factory mpeg_splitter_cf = {{&class_factory_vtbl}, mpeg_splitter_create};
+static struct class_factory wave_parser_cf = {{&class_factory_vtbl}, wave_parser_create};
 
-    return hr;
-}
-
-/***********************************************************************
- *    DllGetClassObject
- */
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
 {
+    struct class_factory *factory;
     HRESULT hr;
 
-    if (FAILED(hr = mfplat_get_class_object(rclsid, riid, ppv)))
-        hr = STRMBASE_DllGetClassObject( rclsid, riid, ppv );
+    TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out);
 
-    return hr;
+    if (SUCCEEDED(hr = mfplat_get_class_object(clsid, iid, out)))
+        return hr;
+
+    if (IsEqualGUID(clsid, &CLSID_AviSplitter))
+        factory = &avi_splitter_cf;
+    else if (IsEqualGUID(clsid, &CLSID_Gstreamer_Splitter))
+        factory = &gstdemux_cf;
+    else if (IsEqualGUID(clsid, &CLSID_MPEG1Splitter))
+        factory = &mpeg_splitter_cf;
+    else if (IsEqualGUID(clsid, &CLSID_WAVEParser))
+        factory = &wave_parser_cf;
+    else
+    {
+        FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid));
+        return CLASS_E_CLASSNOTAVAILABLE;
+    }
+
+    return IClassFactory_QueryInterface(&factory->IClassFactory_iface, iid, out);
 }
 
 static BOOL CALLBACK init_gstreamer_proc(INIT_ONCE *once, void *param, void **ctx)
@@ -316,9 +192,9 @@ static BOOL CALLBACK init_gstreamer_proc(INIT_ONCE *once, void *param, void **ct
         /* Unloading glib is a bad idea.. it installs atexit handlers,
          * so never unload the dll after loading */
         GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
-                (LPCWSTR)hInst, &handle);
+                (LPCWSTR)winegstreamer_instance, &handle);
         if (!handle)
-            ERR("Failed to pin module %p.\n", hInst);
+            ERR("Failed to pin module %p.\n", winegstreamer_instance);
 
         start_dispatch_thread();
     }
@@ -341,32 +217,176 @@ BOOL init_gstreamer(void)
     return status;
 }
 
-/***********************************************************************
- *      DllRegisterServer
- */
+static const REGPINTYPES reg_audio_mt = {&MEDIATYPE_Audio, &GUID_NULL};
+static const REGPINTYPES reg_stream_mt = {&MEDIATYPE_Stream, &GUID_NULL};
+static const REGPINTYPES reg_video_mt = {&MEDIATYPE_Video, &GUID_NULL};
+
+static const REGPINTYPES reg_avi_splitter_sink_mt = {&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi};
+
+static const REGFILTERPINS2 reg_avi_splitter_pins[2] =
+{
+    {
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_avi_splitter_sink_mt,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_OUTPUT,
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_video_mt,
+    },
+};
+
+static const REGFILTER2 reg_avi_splitter =
+{
+    .dwVersion = 2,
+    .dwMerit = MERIT_NORMAL,
+    .u.s2.cPins2 = 2,
+    .u.s2.rgPins2 = reg_avi_splitter_pins,
+};
+
+static const REGPINTYPES reg_mpeg_splitter_sink_mts[4] =
+{
+    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio},
+    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video},
+    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System},
+    {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD},
+};
+
+static const REGPINTYPES reg_mpeg_splitter_audio_mts[2] =
+{
+    {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet},
+    {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload},
+};
+
+static const REGPINTYPES reg_mpeg_splitter_video_mts[2] =
+{
+    {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet},
+    {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload},
+};
+
+static const REGFILTERPINS2 reg_mpeg_splitter_pins[3] =
+{
+    {
+        .nMediaTypes = 4,
+        .lpMediaType = reg_mpeg_splitter_sink_mts,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_ZERO | REG_PINFLAG_B_OUTPUT,
+        .nMediaTypes = 2,
+        .lpMediaType = reg_mpeg_splitter_audio_mts,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_ZERO | REG_PINFLAG_B_OUTPUT,
+        .nMediaTypes = 2,
+        .lpMediaType = reg_mpeg_splitter_video_mts,
+    },
+};
+
+static const REGFILTER2 reg_mpeg_splitter =
+{
+    .dwVersion = 2,
+    .dwMerit = MERIT_NORMAL,
+    .u.s2.cPins2 = 3,
+    .u.s2.rgPins2 = reg_mpeg_splitter_pins,
+};
+
+static const REGPINTYPES reg_wave_parser_sink_mts[3] =
+{
+    {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
+    {&MEDIATYPE_Stream, &MEDIASUBTYPE_AU},
+    {&MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF},
+};
+
+static const REGFILTERPINS2 reg_wave_parser_pins[2] =
+{
+    {
+        .nMediaTypes = 3,
+        .lpMediaType = reg_wave_parser_sink_mts,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_OUTPUT,
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_audio_mt,
+    },
+};
+
+static const REGFILTER2 reg_wave_parser =
+{
+    .dwVersion = 2,
+    .dwMerit = MERIT_UNLIKELY,
+    .u.s2.cPins2 = 2,
+    .u.s2.rgPins2 = reg_wave_parser_pins,
+};
+
+static const REGFILTERPINS2 reg_gstdemux_pins[3] =
+{
+    {
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_stream_mt,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_OUTPUT,
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_audio_mt,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_OUTPUT,
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_video_mt,
+    },
+};
+
+static const REGFILTER2 reg_gstdemux =
+{
+    .dwVersion = 2,
+    .dwMerit = MERIT_PREFERRED,
+    .u.s2.cPins2 = 3,
+    .u.s2.rgPins2 = reg_gstdemux_pins,
+};
+
 HRESULT WINAPI DllRegisterServer(void)
 {
+    IFilterMapper2 *mapper;
     HRESULT hr;
 
-    TRACE("\n");
+    TRACE(".\n");
 
-    hr = AMovieDllRegisterServer2(TRUE);
-    if (SUCCEEDED(hr))
-        hr = __wine_register_resources(hInst);
-    return hr;
+    if (FAILED(hr = __wine_register_resources(winegstreamer_instance)))
+        return hr;
+
+    if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IFilterMapper2, (void **)&mapper)))
+        return hr;
+
+    IFilterMapper2_RegisterFilter(mapper, &CLSID_AviSplitter, avi_splitterW, NULL, NULL, NULL, &reg_avi_splitter);
+    IFilterMapper2_RegisterFilter(mapper, &CLSID_Gstreamer_Splitter,
+            wGstreamer_Splitter, NULL, NULL, NULL, &reg_gstdemux);
+    IFilterMapper2_RegisterFilter(mapper, &CLSID_MPEG1Splitter, mpeg_splitterW, NULL, NULL, NULL, &reg_mpeg_splitter);
+    IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, wave_parserW, NULL, NULL, NULL, &reg_wave_parser);
+
+    IFilterMapper2_Release(mapper);
+    return S_OK;
 }
 
-/***********************************************************************
- *      DllUnregisterServer
- */
 HRESULT WINAPI DllUnregisterServer(void)
 {
+    IFilterMapper2 *mapper;
     HRESULT hr;
 
-    TRACE("\n");
+    TRACE(".\n");
 
-    hr = AMovieDllRegisterServer2(FALSE);
-    if (SUCCEEDED(hr))
-        hr = __wine_unregister_resources(hInst);
-    return hr;
+    if (FAILED(hr = __wine_unregister_resources(winegstreamer_instance)))
+        return hr;
+
+    if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IFilterMapper2, (void **)&mapper)))
+        return hr;
+
+    IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_AviSplitter);
+    IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_Gstreamer_Splitter);
+    IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_MPEG1Splitter);
+    IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_WAVEParser);
+
+    IFilterMapper2_Release(mapper);
+    return S_OK;
 }
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 2233bbe1593..55b9b088765 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -18,9 +18,7 @@
 
 #include <stdarg.h>
 
-#define COBJMACROS
-#define NONAMELESSUNION
-
+#include "gst_private.h"
 #include "mfapi.h"
 #include "mfidl.h"
 
@@ -29,8 +27,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
 
-static LONG object_locks;
-
 struct video_processor
 {
     IMFTransform IMFTransform_iface;
@@ -437,8 +433,3 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
 
     return CLASS_E_CLASSNOTAVAILABLE;
 }
-
-HRESULT mfplat_can_unload_now(void)
-{
-    return !object_locks ? S_OK : S_FALSE;
-}
diff --git a/dlls/winegstreamer/mfplat.idl b/dlls/winegstreamer/winegstreamer_classes.idl
similarity index 55%
rename from dlls/winegstreamer/mfplat.idl
rename to dlls/winegstreamer/winegstreamer_classes.idl
index 05a75bdb8ed..fa0e1784057 100644
--- a/dlls/winegstreamer/mfplat.idl
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
@@ -1,5 +1,8 @@
 /*
- * Copyright 2019 Nikolay Sivov for CodeWeavers
+ * COM classes for winegstreamer
+ *
+ * Copyright 2019 Nikolay Sivov
+ * Copyright 2019 Zebediah Figura
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,8 +22,35 @@
 #pragma makedep register
 
 [
+    helpstring("AVI Splitter"),
     threading(both),
-    uuid(88753b26-5b24-49bd-b2e7-0c445c78c982)
+    uuid(1b544c20-fd0b-11ce-8c63-00aa0044b51e)
+]
+coclass AviSplitter {}
+
+[
+    helpstring("MPEG-I Stream Splitter"),
+    threading(both),
+    uuid(336475d0-942a-11ce-a870-00aa002feab5)
+]
+coclass MPEG1Splitter {}
+
+[
+    helpstring("Wave Parser"),
+    threading(both),
+    uuid(d51bd5a1-7548-11cf-a520-0080c77ef58a)
+]
+coclass WAVEParser {}
 
+[
+    helpstring("GStreamer splitter"),
+    threading(both),
+    uuid(f9d8d64e-a144-47dc-8ee0-f53498372c29)
+]
+coclass Gstreamer_Splitter {}
+
+[
+    threading(both),
+    uuid(88753b26-5b24-49bd-b2e7-0c445c78c982)
 ]
-coclass VideoProcessorMFT { }
+coclass VideoProcessorMFT {}
-- 
2.25.1




More information about the wine-devel mailing list