From 74dc0c5df9c3094352caedda8ebe14ed2dfd615e Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Sun, 8 Mar 2020 14:05:09 -0500 Subject: [PATCH] winegstreamer: Reimplement COM registration and vending locally. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/winegstreamer/Makefile.in | 4 +- dlls/winegstreamer/gst_private.h | 17 +- dlls/winegstreamer/gstdemux.c | 69 +-- dlls/winegstreamer/main.c | 526 +++++++++--------- dlls/winegstreamer/mfplat.c | 11 +- .../{mfplat.idl => winegstreamer_classes.idl} | 36 +- 6 files changed, 341 insertions(+), 322 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 +#include +#include +#include +#include #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 -#include -#include - #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 -#include - -#include - #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 - }, +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) +{ + if (reason == DLL_PROCESS_ATTACH) { - wNull, - FALSE, TRUE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTaudio - }, - { - 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 -}; - -static const AMOVIESETUP_MEDIATYPE wave_parser_sink_type_data[] = -{ - {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE}, - {&MEDIATYPE_Stream, &MEDIASUBTYPE_AU}, - {&MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF}, -}; - -static const AMOVIESETUP_MEDIATYPE wave_parser_source_type_data[] = -{ - {&MEDIATYPE_Audio, &GUID_NULL}, -}; - -static const AMOVIESETUP_PIN wave_parser_pin_data[] = -{ - { - 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, - }, -}; - -static const AMOVIESETUP_FILTER wave_parser_filter_data = -{ - &CLSID_WAVEParser, - wave_parserW, - MERIT_UNLIKELY, - ARRAY_SIZE(wave_parser_pin_data), - wave_parser_pin_data, -}; - -static const AMOVIESETUP_MEDIATYPE avi_splitter_sink_type_data[] = -{ - {&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi}, -}; - -static const AMOVIESETUP_PIN avi_splitter_pin_data[] = -{ - { - 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, - }, -}; - -static const AMOVIESETUP_FILTER avi_splitter_filter_data = -{ - &CLSID_AviSplitter, - avi_splitterW, - 0x5ffff0, - ARRAY_SIZE(avi_splitter_pin_data), - avi_splitter_pin_data, -}; - -static const AMOVIESETUP_MEDIATYPE mpeg_splitter_sink_type_data[] = -{ - {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio}, - {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video}, - {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System}, - {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD}, -}; - -static const AMOVIESETUP_MEDIATYPE mpeg_splitter_audio_type_data[] = -{ - {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet}, - {&MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload}, -}; - -static const AMOVIESETUP_MEDIATYPE mpeg_splitter_video_type_data[] = -{ - {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet}, - {&MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload}, -}; - -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, - }, -}; - -static const AMOVIESETUP_FILTER mpeg_splitter_filter_data = -{ - &CLSID_MPEG1Splitter, - mpeg_splitterW, - 0x5ffff0, - ARRAY_SIZE(mpeg_splitter_pin_data), - mpeg_splitter_pin_data, -}; - -FactoryTemplate const g_Templates[] = { - { - wGstreamer_Splitter, - &CLSID_Gstreamer_Splitter, - Gstreamer_Splitter_create, - NULL, - &amfSplitter, - }, - { - 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); - -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - hInst = hInstDLL; - return STRMBASE_DllMain(hInstDLL, fdwReason, lpv); + return TRUE; } -/*********************************************************************** - * DllCanUnloadNow - */ HRESULT WINAPI DllCanUnloadNow(void) { - HRESULT hr = STRMBASE_DllCanUnloadNow(); + TRACE(".\n"); - if (hr == S_OK) - hr = mfplat_can_unload_now(); + return object_locks ? S_FALSE : S_OK; +} +struct class_factory +{ + IClassFactory IClassFactory_iface; + HRESULT (*create_instance)(IUnknown *outer, IUnknown **out); +}; + +static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface); +} + +static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory)) + { + *out = iface; + IClassFactory_AddRef(iface); + return S_OK; + } + + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI class_factory_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI class_factory_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out) +{ + struct class_factory *factory = impl_from_IClassFactory(iface); + IUnknown *unk; + HRESULT hr; + + TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out); + + if (outer && !IsEqualGUID(iid, &IID_IUnknown)) + return E_NOINTERFACE; + + *out = NULL; + if (SUCCEEDED(hr = factory->create_instance(outer, &unk))) + { + hr = IUnknown_QueryInterface(unk, iid, out); + IUnknown_Release(unk); + } return hr; } -/*********************************************************************** - * DllGetClassObject - */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock) { + TRACE("iface %p, lock %d.\n", iface, lock); + + if (lock) + InterlockedIncrement(&object_locks); + else + InterlockedDecrement(&object_locks); + return S_OK; +} + +static const IClassFactoryVtbl class_factory_vtbl = +{ + class_factory_QueryInterface, + class_factory_AddRef, + class_factory_Release, + class_factory_CreateInstance, + class_factory_LockServer, +}; + +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}; + +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 = ®_avi_splitter_sink_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .nMediaTypes = 1, + .lpMediaType = ®_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 = ®_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 = ®_stream_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .nMediaTypes = 1, + .lpMediaType = ®_audio_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .nMediaTypes = 1, + .lpMediaType = ®_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, ®_avi_splitter); + IFilterMapper2_RegisterFilter(mapper, &CLSID_Gstreamer_Splitter, + wGstreamer_Splitter, NULL, NULL, NULL, ®_gstdemux); + IFilterMapper2_RegisterFilter(mapper, &CLSID_MPEG1Splitter, mpeg_splitterW, NULL, NULL, NULL, ®_mpeg_splitter); + IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, wave_parserW, NULL, NULL, NULL, ®_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 -#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 @@ -18,9 +21,36 @@ #pragma makedep register +[ + helpstring("AVI Splitter"), + threading(both), + 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 {}