From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/main.c | 77 +++++++++++++++++++++++++++++++++++++- dlls/qedit/qedit_private.h | 3 +- dlls/quartz/regsvr.c | 12 ------ 3 files changed, 77 insertions(+), 15 deletions(-)
diff --git a/dlls/qedit/main.c b/dlls/qedit/main.c index a271f9adb79..3797d96dcf3 100644 --- a/dlls/qedit/main.c +++ b/dlls/qedit/main.c @@ -192,12 +192,71 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return S_OK; }
+static const REGPINTYPES reg_null_mt = {&GUID_NULL, &GUID_NULL}; + +static const REGFILTERPINS2 reg_sample_grabber_pins[2] = +{ + { + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_null_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_null_mt, + }, +}; + +static const REGFILTER2 reg_sample_grabber = +{ + .dwVersion = 2, + .dwMerit = MERIT_DO_NOT_USE, + .u.s2.cPins2 = 2, + .u.s2.rgPins2 = reg_sample_grabber_pins, +}; + +static const REGFILTERPINS2 reg_null_renderer_pins[1] = +{ + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_null_mt, + }, +}; + +static const REGFILTER2 reg_null_renderer = +{ + .dwVersion = 2, + .dwMerit = MERIT_DO_NOT_USE, + .u.s2.cPins2 = 1, + .u.s2.rgPins2 = reg_null_renderer_pins, +}; + /*********************************************************************** * DllRegisterServer (QEDIT.@) */ HRESULT WINAPI DllRegisterServer(void) { - return __wine_register_resources( instance ); + IFilterMapper2 *mapper; + HRESULT hr; + + if (FAILED(hr = __wine_register_resources( instance ))) + return hr; + + if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper2, (void **)&mapper))) + return hr; + + IFilterMapper2_RegisterFilter(mapper, &CLSID_SampleGrabber, L"SampleGrabber", + NULL, NULL, NULL, ®_sample_grabber); + IFilterMapper2_RegisterFilter(mapper, &CLSID_NullRenderer, L"Null Renderer", + NULL, NULL, NULL, ®_null_renderer); + + IFilterMapper2_Release(mapper); + return S_OK; }
/*********************************************************************** @@ -205,5 +264,19 @@ HRESULT WINAPI DllRegisterServer(void) */ HRESULT WINAPI DllUnregisterServer(void) { - return __wine_unregister_resources( instance ); + IFilterMapper2 *mapper; + HRESULT hr; + + if (FAILED(hr = __wine_unregister_resources( 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_SampleGrabber); + IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_NullRenderer); + + IFilterMapper2_Release(mapper); + return S_OK; } diff --git a/dlls/qedit/qedit_private.h b/dlls/qedit/qedit_private.h index 344656d7d87..96f21bcb3ba 100644 --- a/dlls/qedit/qedit_private.h +++ b/dlls/qedit/qedit_private.h @@ -23,7 +23,8 @@ #include <stdarg.h>
#define COBJMACROS - +#define NONAMELESSSTRUCT +#define NONAMELESSUNION #include "windef.h" #include "winbase.h" #include "wtypes.h" diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c index ff5db662f04..7196f79a54c 100644 --- a/dlls/quartz/regsvr.c +++ b/dlls/quartz/regsvr.c @@ -174,18 +174,6 @@ static HRESULT unregister_filters(struct regsvr_filter const *list) */
static struct regsvr_filter const filter_list[] = { - { &CLSID_NullRenderer, - &CLSID_LegacyAmFilterCategory, - L"Null Renderer", - 0x200000, - { { REG_PINFLAG_B_RENDERER, - { { &MEDIATYPE_NULL, &GUID_NULL }, - { NULL } - }, - }, - { 0xFFFFFFFF }, - } - }, { &CLSID_VideoRenderer, &CLSID_LegacyAmFilterCategory, L"Video Renderer",
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/Makefile.in | 4 +- dlls/qcap/audiorecord.c | 24 ++- dlls/qcap/avico.c | 25 ++- dlls/qcap/avimux.c | 17 +- dlls/qcap/capturegraph.c | 40 ++--- dlls/qcap/qcap_classes.idl | 71 ++++++++ dlls/qcap/qcap_main.c | 321 +++++++++++++++++++++++-------------- dlls/qcap/qcap_main.h | 19 +-- dlls/qcap/smartteefilter.c | 16 +- dlls/qcap/vfwcapture.c | 11 +- 10 files changed, 341 insertions(+), 207 deletions(-) create mode 100644 dlls/qcap/qcap_classes.idl
diff --git a/dlls/qcap/Makefile.in b/dlls/qcap/Makefile.in index d10075aea08..981a0dc3f39 100644 --- a/dlls/qcap/Makefile.in +++ b/dlls/qcap/Makefile.in @@ -8,7 +8,6 @@ C_SRCS = \ avico.c \ avimux.c \ capturegraph.c \ - dllfunc.c \ filter.c \ mediatype.c \ pin.c \ @@ -18,3 +17,6 @@ C_SRCS = \ vfwcapture.c
RC_SRCS = version.rc + +IDL_SRCS = \ + qcap_classes.idl diff --git a/dlls/qcap/audiorecord.c b/dlls/qcap/audiorecord.c index 3c15734e894..48be64b63f5 100644 --- a/dlls/qcap/audiorecord.c +++ b/dlls/qcap/audiorecord.c @@ -154,22 +154,18 @@ static const IPersistPropertyBagVtbl PersistPropertyBagVtbl = PPB_Save };
-IUnknown* WINAPI QCAP_createAudioCaptureFilter(IUnknown *outer, HRESULT *phr) +HRESULT audio_record_create(IUnknown *outer, IUnknown **out) { - AudioRecord *This = NULL; + AudioRecord *object;
- FIXME("(%p, %p): the entire CLSID_AudioRecord implementation is just stubs\n", outer, phr); + if (!(object = CoTaskMemAlloc(sizeof(*object)))) + return E_OUTOFMEMORY; + memset(object, 0, sizeof(*object));
- This = CoTaskMemAlloc(sizeof(*This)); - if (This == NULL) { - *phr = E_OUTOFMEMORY; - return NULL; - } - memset(This, 0, sizeof(*This)); - This->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl; - - strmbase_filter_init(&This->filter, outer, &CLSID_AudioRecord, &filter_ops); + object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl; + strmbase_filter_init(&object->filter, outer, &CLSID_AudioRecord, &filter_ops);
- *phr = S_OK; - return &This->filter.IUnknown_inner; + TRACE("Created audio recorder %p.\n", object); + *out = &object->filter.IUnknown_inner; + return S_OK; } diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c index 53b8526f449..fc5826b16fe 100644 --- a/dlls/qcap/avico.c +++ b/dlls/qcap/avico.c @@ -480,25 +480,22 @@ static const struct strmbase_source_ops source_ops = .pfnDecideAllocator = AVICompressorOut_DecideAllocator, };
-IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr) +HRESULT avi_compressor_create(IUnknown *outer, IUnknown **out) { static const WCHAR source_name[] = {'O','u','t',0}; static const WCHAR sink_name[] = {'I','n',0}; - AVICompressor *compressor; + AVICompressor *object;
- compressor = heap_alloc_zero(sizeof(*compressor)); - if(!compressor) { - *phr = E_NOINTERFACE; - return NULL; - } - - strmbase_filter_init(&compressor->filter, outer, &CLSID_AVICo, &filter_ops); + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY;
- compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl; + strmbase_filter_init(&object->filter, outer, &CLSID_AVICo, &filter_ops); + object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
- strmbase_sink_init(&compressor->sink, &compressor->filter, sink_name, &sink_ops, NULL); - strmbase_source_init(&compressor->source, &compressor->filter, source_name, &source_ops); + strmbase_sink_init(&object->sink, &object->filter, sink_name, &sink_ops, NULL); + strmbase_source_init(&object->source, &object->filter, source_name, &source_ops);
- *phr = S_OK; - return &compressor->filter.IUnknown_inner; + TRACE("Created AVI compressor %p.\n", object); + *out = &object->filter.IUnknown_inner; + return S_OK; } diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c index 91a0b17f8e1..f1e703bfb60 100644 --- a/dlls/qcap/avimux.c +++ b/dlls/qcap/avimux.c @@ -1835,7 +1835,7 @@ static HRESULT create_input_pin(AviMux *avimux) return S_OK; }
-IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr) +HRESULT avi_mux_create(IUnknown *outer, IUnknown **out) { static const WCHAR output_name[] = {'A','V','I',' ','O','u','t',0};
@@ -1843,11 +1843,8 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr) PIN_INFO info; HRESULT hr;
- avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux)); - if(!avimux) { - *phr = E_OUTOFMEMORY; - return NULL; - } + if (!(avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux)))) + return E_OUTOFMEMORY;
strmbase_filter_init(&avimux->filter, outer, &CLSID_AviDest, &filter_ops); avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl; @@ -1870,13 +1867,13 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr) strmbase_source_cleanup(&avimux->source); strmbase_filter_cleanup(&avimux->filter); HeapFree(GetProcessHeap(), 0, avimux); - *phr = hr; - return NULL; + return hr; }
avimux->interleave = 10000000;
+ TRACE("Created AVI mux %p.\n", avimux); ObjectRefCount(TRUE); - *phr = S_OK; - return &avimux->filter.IUnknown_inner; + *out = &avimux->filter.IUnknown_inner; + return S_OK; } diff --git a/dlls/qcap/capturegraph.c b/dlls/qcap/capturegraph.c index 894d4f61e9c..33b0ecfaa11 100644 --- a/dlls/qcap/capturegraph.c +++ b/dlls/qcap/capturegraph.c @@ -74,33 +74,27 @@ static inline CaptureGraphImpl *impl_from_ICaptureGraphBuilder2(ICaptureGraphBui }
-IUnknown * CALLBACK QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter, - HRESULT *phr) +HRESULT capture_graph_create(IUnknown *outer, IUnknown **out) { - CaptureGraphImpl * pCapture = NULL; + CaptureGraphImpl *object;
- TRACE("(%p, %p)\n", pUnkOuter, phr); + if (outer) + return CLASS_E_NOAGGREGATION;
- *phr = CLASS_E_NOAGGREGATION; - if (pUnkOuter) - { - return NULL; - } - *phr = E_OUTOFMEMORY; + if (!(object = CoTaskMemAlloc(sizeof(*object)))) + return E_OUTOFMEMORY;
- pCapture = CoTaskMemAlloc(sizeof(CaptureGraphImpl)); - if (pCapture) - { - pCapture->ICaptureGraphBuilder2_iface.lpVtbl = &builder2_Vtbl; - pCapture->ICaptureGraphBuilder_iface.lpVtbl = &builder_Vtbl; - pCapture->ref = 1; - pCapture->mygraph = NULL; - InitializeCriticalSection(&pCapture->csFilter); - pCapture->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CaptureGraphImpl.csFilter"); - *phr = S_OK; - ObjectRefCount(TRUE); - } - return (IUnknown *)&pCapture->ICaptureGraphBuilder_iface; + object->ICaptureGraphBuilder2_iface.lpVtbl = &builder2_Vtbl; + object->ICaptureGraphBuilder_iface.lpVtbl = &builder_Vtbl; + object->ref = 1; + object->mygraph = NULL; + InitializeCriticalSection(&object->csFilter); + object->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CaptureGraphImpl.csFilter"); + + TRACE("Created capture graph builder %p.\n", object); + ObjectRefCount(TRUE); + *out = (IUnknown *)&object->ICaptureGraphBuilder_iface; + return S_OK; }
static HRESULT WINAPI diff --git a/dlls/qcap/qcap_classes.idl b/dlls/qcap/qcap_classes.idl new file mode 100644 index 00000000000..ac1ec9a21b9 --- /dev/null +++ b/dlls/qcap/qcap_classes.idl @@ -0,0 +1,71 @@ +/* + * COM classes for qcap + * + * 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 + * 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 + */ + +#pragma makedep register + +[ + helpstring("Audio Capture Filter"), + threading(both), + uuid(e30629d2-27e5-11ce-875d-00608cb78066) +] +coclass AudioRecord {} + +[ + helpstring("Audio Capture Filter"), + threading(both), + uuid(d76e2820-1563-11cf-ac98-00aa004c0fa9) +] +coclass AVICo {} + +[ + helpstring("AVI mux"), + threading(both), + uuid(e2510970-f137-11ce-8b67-00aa00a3f1a6) +] +coclass AviDest {} + +[ + helpstring("Capture Graph Builder"), + threading(both), + uuid(bf87b6e0-8c27-11d0-b3f0-00aa003761c5) +] +coclass CaptureGraphBuilder {} + +[ + helpstring("Capture Graph Builder 2"), + threading(both), + uuid(bf87b6e1-8c27-11d0-b3f0-00aa003761c5) +] +coclass CaptureGraphBuilder2 {} + +[ + helpstring("Smart Tee Filter"), + threading(both), + uuid(cc58e280-8aa1-11d1-b3f1-00aa003761c5) +] +coclass SmartTee {} + +[ + helpstring("VFW Capture Filter"), + threading(both), + uuid(1b544c22-fd0b-11ce-8c63-00aa0044b51e) +] +coclass VfwCapture {} + diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c index c5b4931c907..2b9850cb329 100644 --- a/dlls/qcap/qcap_main.c +++ b/dlls/qcap/qcap_main.c @@ -1,8 +1,9 @@ /* - * Qcap implementation, dllentry points + * DirectShow capture * * Copyright (C) 2003 Dominik Strasser * Copyright (C) 2005 Rolf Kalbermatter + * Copyright (C) 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 @@ -25,7 +26,8 @@ #include <stdarg.h>
#define COBJMACROS - +#define NONAMELESSSTRUCT +#define NONAMELESSUNION #include "windef.h" #include "winbase.h" #include "wingdi.h" @@ -33,6 +35,7 @@ #include "objbase.h" #include "uuids.h" #include "strmif.h" +#include "rpcproxy.h"
#include "qcap_main.h"
@@ -41,132 +44,207 @@
WINE_DEFAULT_DEBUG_CHANNEL(qcap);
+static HINSTANCE qcap_instance; + static LONG objects_ref = 0;
-static const WCHAR wAudioCaptureFilter[] = -{'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0}; -static const WCHAR wAVICompressor[] = -{'A','V','I',' ','C','o','m','p','r','e','s','s','o','r',0}; -static const WCHAR wVFWCaptFilter[] = -{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0}; -static const WCHAR wVFWCaptFilterProp[] = -{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',' ', - 'P','r','o','p','e','r','t','y',' ','P','a','g','e',0}; -static const WCHAR wAVIMux[] = -{'A','V','I',' ','m','u','x',0}; -static const WCHAR wAVIMuxPropPage[] = -{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e',0}; -static const WCHAR wAVIMuxPropPage1[] = -{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e','1',0}; -static const WCHAR wFileWriter[] = -{'F','i','l','e',' ','W','r','i','t','e','r',0}; -static const WCHAR wCaptGraphBuilder[] = -{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r',0}; -static const WCHAR wCaptGraphBuilder2[] = -{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r','2',0}; -static const WCHAR wInfPinTeeFilter[] = -{'I','n','f','i','n','i','t','e',' ','P','i','n',' ','T','e','e',' ','F','i', - 'l','t','e','r',0}; -static const WCHAR wSmartTeeFilter[] = -{'S','m','a','r','t',' ','T','e','e',' ','F','i','l','t','e','r',0}; -static const WCHAR wAudioInMixerProp[] = -{'A','u','d','i','o','I','n','p','u','t','M','i','x','e','r',' ','P','r','o', - 'p','e','r','t','y',' ','P','a','g','e',0}; - -FactoryTemplate const g_Templates[] = { +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))) { - wAudioCaptureFilter, - &CLSID_AudioRecord, - QCAP_createAudioCaptureFilter, - NULL - },{ - wAVICompressor, - &CLSID_AVICo, - QCAP_createAVICompressor, - NULL - },{ - wVFWCaptFilter, - &CLSID_VfwCapture, - QCAP_createVFWCaptureFilter, - NULL - },{ - wVFWCaptFilterProp, - &CLSID_CaptureProperties, - NULL, /* FIXME: Implement QCAP_createVFWCaptureFilterPropertyPage */ - NULL - },{ - wAVIMux, - &CLSID_AviDest, - QCAP_createAVIMux, - NULL - },{ - wAVIMuxPropPage, - &CLSID_AviMuxProptyPage, - NULL, /* FIXME: Implement QCAP_createAVIMuxPropertyPage */ - NULL - },{ - wAVIMuxPropPage1, - &CLSID_AviMuxProptyPage1, - NULL, /* FIXME: Implement QCAP_createAVIMuxPropertyPage1 */ - NULL - },{ - wFileWriter, - &CLSID_FileWriter, - NULL, /* FIXME: Implement QCAP_createFileWriter */ - NULL - },{ - wCaptGraphBuilder, - &CLSID_CaptureGraphBuilder, - QCAP_createCaptureGraphBuilder2, - NULL - },{ - wCaptGraphBuilder2, - &CLSID_CaptureGraphBuilder2, - QCAP_createCaptureGraphBuilder2, - NULL - },{ - wInfPinTeeFilter, - &CLSID_InfTee, - NULL, /* FIXME: Implement QCAP_createInfinitePinTeeFilter */ - NULL - },{ - wSmartTeeFilter, - &CLSID_SmartTee, - QCAP_createSmartTeeFilter, - NULL - },{ - wAudioInMixerProp, - &CLSID_AudioInputMixerProperties, - NULL, /* FIXME: Implement QCAP_createAudioInputMixerPropertyPage */ - NULL + hr = IUnknown_QueryInterface(unk, iid, out); + IUnknown_Release(unk); } + return hr; +} + +static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock) +{ + TRACE("iface %p, lock %d.\n", iface, lock); + + if (lock) + InterlockedIncrement(&objects_ref); + else + InterlockedDecrement(&objects_ref); + return S_OK; +} + +static const IClassFactoryVtbl class_factory_vtbl = +{ + class_factory_QueryInterface, + class_factory_AddRef, + class_factory_Release, + class_factory_CreateInstance, + class_factory_LockServer, };
-const int g_cTemplates = ARRAY_SIZE(g_Templates); +static struct class_factory audio_record_cf = {{&class_factory_vtbl}, audio_record_create}; +static struct class_factory avi_compressor_cf = {{&class_factory_vtbl}, avi_compressor_create}; +static struct class_factory avi_mux_cf = {{&class_factory_vtbl}, avi_mux_create}; +static struct class_factory capture_graph_cf = {{&class_factory_vtbl}, capture_graph_create}; +static struct class_factory smart_tee_cf = {{&class_factory_vtbl}, smart_tee_create}; +static struct class_factory vfw_capture_cf = {{&class_factory_vtbl}, vfw_capture_create};
-/*********************************************************************** - * Dll EntryPoint (QCAP.@) - */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { - return STRMBASE_DllMain(hInstDLL,fdwReason,lpv); + if (reason == DLL_PROCESS_ATTACH) + { + qcap_instance = instance; + DisableThreadLibraryCalls(instance); + } + return TRUE; }
-/*********************************************************************** - * DllGetClassObject - */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) { - return STRMBASE_DllGetClassObject( rclsid, riid, ppv ); + struct class_factory *factory; + + TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out); + + if (IsEqualGUID(clsid, &CLSID_AudioRecord)) + factory = &audio_record_cf; + else if (IsEqualGUID(clsid, &CLSID_AVICo)) + factory = &avi_compressor_cf; + else if (IsEqualGUID(clsid, &CLSID_AviDest)) + factory = &avi_mux_cf; + else if (IsEqualGUID(clsid, &CLSID_CaptureGraphBuilder)) + factory = &capture_graph_cf; + else if (IsEqualGUID(clsid, &CLSID_CaptureGraphBuilder2)) + factory = &capture_graph_cf; + else if (IsEqualGUID(clsid, &CLSID_SmartTee)) + factory = &smart_tee_cf; + else if (IsEqualGUID(clsid, &CLSID_VfwCapture)) + factory = &vfw_capture_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 const REGPINTYPES reg_avi_mux_sink_mt = {&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi}; + +static const REGFILTERPINS2 reg_avi_mux_pins[1] = +{ + { + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_avi_mux_sink_mt, + }, +}; + +static const REGFILTER2 reg_avi_mux = +{ + .dwVersion = 2, + .dwMerit = MERIT_DO_NOT_USE, + .u.s2.cPins2 = 1, + .u.s2.rgPins2 = reg_avi_mux_pins, +}; + +static const REGPINTYPES reg_video_mt = {&MEDIATYPE_Video, &GUID_NULL}; + +static const REGFILTERPINS2 reg_smart_tee_pins[3] = +{ + { + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_video_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_video_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_video_mt, + }, +}; + +static const REGFILTER2 reg_smart_tee = +{ + .dwVersion = 2, + .dwMerit = MERIT_DO_NOT_USE, + .u.s2.cPins2 = 3, + .u.s2.rgPins2 = reg_smart_tee_pins, +}; + /*********************************************************************** * DllRegisterServer (QCAP.@) */ HRESULT WINAPI DllRegisterServer(void) { - TRACE("()\n"); - return AMovieDllRegisterServer2(TRUE); + static const WCHAR avi_muxW[] = {'A','V','I',' ','M','u','x',0}; + static const WCHAR smart_teeW[] = {'S','m','a','r','t',' ','T','e','e',0}; + IFilterMapper2 *mapper; + HRESULT hr; + + if (FAILED(hr = __wine_register_resources( qcap_instance ))) + return hr; + + if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper2, (void **)&mapper))) + return hr; + + IFilterMapper2_RegisterFilter(mapper, &CLSID_AviDest, avi_muxW, + NULL, NULL, NULL, ®_avi_mux); + IFilterMapper2_RegisterFilter(mapper, &CLSID_SmartTee, smart_teeW, + NULL, NULL, NULL, ®_smart_tee); + + IFilterMapper2_Release(mapper); + return S_OK; }
/*********************************************************************** @@ -174,8 +252,21 @@ HRESULT WINAPI DllRegisterServer(void) */ HRESULT WINAPI DllUnregisterServer(void) { - TRACE("\n"); - return AMovieDllRegisterServer2(FALSE); + IFilterMapper2 *mapper; + HRESULT hr; + + if (FAILED(hr = __wine_unregister_resources( qcap_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_SampleGrabber); + IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_NullRenderer); + + IFilterMapper2_Release(mapper); + return S_OK; }
/*********************************************************************** @@ -183,11 +274,9 @@ HRESULT WINAPI DllUnregisterServer(void) */ HRESULT WINAPI DllCanUnloadNow(void) { - TRACE("\n"); + TRACE(".\n");
- if (STRMBASE_DllCanUnloadNow() == S_OK && objects_ref == 0) - return S_OK; - return S_FALSE; + return objects_ref ? S_FALSE : S_OK; }
DWORD ObjectRefCount(BOOL increment) diff --git a/dlls/qcap/qcap_main.h b/dlls/qcap/qcap_main.h index ab02dbb9ab5..58c7a26f9e1 100644 --- a/dlls/qcap/qcap_main.h +++ b/dlls/qcap/qcap_main.h @@ -25,18 +25,11 @@
extern DWORD ObjectRefCount(BOOL increment) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAudioCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createAVICompressor(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createVFWCaptureFilterPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createAVICompressor(IUnknown*,HRESULT*) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createAVIMuxPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createAVIMuxPropertyPage1(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createFileWriter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createInfinitePinTeeFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createSmartTeeFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; -extern IUnknown * WINAPI QCAP_createAudioInputMixerPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; +HRESULT audio_record_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; +HRESULT avi_compressor_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; +HRESULT avi_mux_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; +HRESULT capture_graph_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; +HRESULT smart_tee_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; +HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
#endif /* _QCAP_MAIN_H_DEFINED */ diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c index 5339cb5134f..46ec09ca7e4 100644 --- a/dlls/qcap/smartteefilter.c +++ b/dlls/qcap/smartteefilter.c @@ -321,7 +321,7 @@ static const struct strmbase_source_ops preview_ops = .pfnDecideAllocator = SmartTeeFilterPreview_DecideAllocator, };
-IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr) +HRESULT smart_tee_create(IUnknown *outer, IUnknown **out) { static const WCHAR captureW[] = {'C','a','p','t','u','r','e',0}; static const WCHAR previewW[] = {'P','r','e','v','i','e','w',0}; @@ -330,10 +330,7 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr) HRESULT hr;
if (!(object = CoTaskMemAlloc(sizeof(*object)))) - { - *phr = E_OUTOFMEMORY; - return NULL; - } + return E_OUTOFMEMORY; memset(object, 0, sizeof(*object));
strmbase_filter_init(&object->filter, outer, &CLSID_SmartTee, &filter_ops); @@ -342,14 +339,15 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr) &IID_IMemAllocator, (void **)&object->sink.pAllocator); if (FAILED(hr)) { - *phr = hr; strmbase_filter_cleanup(&object->filter); - return NULL; + CoTaskMemFree(object); + return hr; }
strmbase_source_init(&object->capture, &object->filter, captureW, &capture_ops); strmbase_source_init(&object->preview, &object->filter, previewW, &preview_ops);
- *phr = S_OK; - return &object->filter.IUnknown_inner; + TRACE("Created smart tee %p.\n", object); + *out = &object->filter.IUnknown_inner; + return S_OK; } diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index 6cd4a84d2e1..d2acf9eda43 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -559,16 +559,13 @@ static const struct strmbase_source_ops source_ops = .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator, };
-IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr) +HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out) { static const WCHAR source_name[] = {'O','u','t','p','u','t',0}; VfwCapture *object;
if (!(object = CoTaskMemAlloc(sizeof(*object)))) - { - *phr = E_OUTOFMEMORY; - return NULL; - } + return E_OUTOFMEMORY;
strmbase_filter_init(&object->filter, outer, &CLSID_VfwCapture, &filter_ops);
@@ -583,6 +580,6 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
TRACE("Created VFW capture filter %p.\n", object); ObjectRefCount(TRUE); - *phr = S_OK; - return &object->filter.IUnknown_inner; + *out = &object->filter.IUnknown_inner; + return S_OK; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=66604
Your paranoid android.
=== debiant (64 bit WoW report) ===
quartz: filtergraph: Timeout
March 7, 2020 10:01 AM, "Zebediah Figura" z.figura12@gmail.com wrote:
diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c index c5b4931c907..2b9850cb329 100644 --- a/dlls/qcap/qcap_main.c +++ b/dlls/qcap/qcap_main.c @@ -174,8 +252,21 @@ HRESULT WINAPI DllRegisterServer(void) */ HRESULT WINAPI DllUnregisterServer(void) {
- TRACE("\n");
- return AMovieDllRegisterServer2(FALSE);
- IFilterMapper2 *mapper;
- HRESULT hr;
- if (FAILED(hr = __wine_unregister_resources( qcap_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_SampleGrabber);
- IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_NullRenderer);
Looks like a copy-pasto from patch 1.
- IFilterMapper2_Release(mapper);
- return S_OK;
}
/***********************************************************************
Chip
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@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 = ®_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 <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 {}
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- Not compile-tested.
dlls/wineqtdecoder/Makefile.in | 4 +- dlls/wineqtdecoder/main.c | 292 ++++++++++++------- dlls/wineqtdecoder/qtsplitter.c | 16 +- dlls/wineqtdecoder/qtvdecoder.c | 20 +- dlls/wineqtdecoder/wineqtdecoder_classes.idl | 37 +++ 5 files changed, 234 insertions(+), 135 deletions(-) create mode 100644 dlls/wineqtdecoder/wineqtdecoder_classes.idl
diff --git a/dlls/wineqtdecoder/Makefile.in b/dlls/wineqtdecoder/Makefile.in index bdd387432e5..b7db9b7c243 100644 --- a/dlls/wineqtdecoder/Makefile.in +++ b/dlls/wineqtdecoder/Makefile.in @@ -4,7 +4,6 @@ EXTRALIBS = $(QUICKTIME_LIBS) PARENTSRC = ../strmbase
C_SRCS = \ - dllfunc.c \ filter.c \ main.c \ mediatype.c \ @@ -20,3 +19,6 @@ C_SRCS = \
RC_SRCS = \ rsrc.rc + +IDL_SRCS = \ + wineqtdecoder_classes.idl diff --git a/dlls/wineqtdecoder/main.c b/dlls/wineqtdecoder/main.c index ac9268d70f5..6e0dd8c46b5 100644 --- a/dlls/wineqtdecoder/main.c +++ b/dlls/wineqtdecoder/main.c @@ -2,6 +2,7 @@ * DirectShow filter for QuickTime Toolkit on Mac OS X * * Copyright (C) 2010 Aric Stewart, CodeWeavers + * Copyright (C) 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 @@ -40,158 +41,223 @@ #include "wine/debug.h" #include "wine/strmbase.h"
+#include "wineqtdecoder_classes.h" + #include "initguid.h" -DEFINE_GUID(CLSID_QTVDecoder, 0x683DDACB, 0x4354, 0x490C, 0xA0,0x58, 0xE0,0x5A,0xD0,0xF2,0x05,0x37); -DEFINE_GUID(CLSID_QTSplitter, 0xD0E70E49, 0x5927, 0x4894, 0xA3,0x86, 0x35,0x94,0x60,0xEE,0x87,0xC9); DEFINE_GUID(WINESUBTYPE_QTSplitter, 0xFFFFFFFF, 0x5927, 0x4894, 0xA3,0x86, 0x35,0x94,0x60,0xEE,0x87,0xC9);
WINE_DEFAULT_DEBUG_CHANNEL(qtdecoder);
-extern IUnknown * CALLBACK QTVDecoder_create(IUnknown * pUnkOuter, HRESULT* phr); -extern IUnknown * CALLBACK QTSplitter_create(IUnknown * pUnkOuter, HRESULT* phr); +extern HRESULT video_decoder_create(IUnknown *outer, IUnknown **out); +extern HRESULT qt_splitter_create(IUnknown *outer, IUnknown **out);
static const WCHAR wQTVName[] = {'Q','T',' ','V','i','d','e','o',' ','D','e','c','o','d','e','r',0}; static const WCHAR wQTDName[] = {'Q','T',' ','V','i','d','e','o',' ','D','e','m','u','x',0}; -static WCHAR wNull[] = {'\0'}; - -static const AMOVIESETUP_MEDIATYPE amfMTvideo[] = -{ { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL } }; -static const AMOVIESETUP_MEDIATYPE amfMTaudio[] = -{ { &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL } }; -static const AMOVIESETUP_MEDIATYPE amfMTstream[] = -{ { &MEDIATYPE_Stream, &WINESUBTYPE_QTSplitter}, - { &MEDIATYPE_Stream, &MEDIASUBTYPE_NULL } }; - -static const AMOVIESETUP_PIN amfQTVPin[] = -{ { wNull, - FALSE, FALSE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTvideo - }, + +static HINSTANCE wineqtdecoder_instance; + +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) +{ + if (reason == DLL_PROCESS_ATTACH) { - wNull, - FALSE, TRUE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTvideo - }, + wineqtdecoder_instance = instance; + DisableThreadLibraryCalls(instance); + } + return TRUE; +} + +struct class_factory +{ + IClassFactory IClassFactory_iface; + HRESULT (*create_instance)(IUnknown *outer, IUnknown **out); };
-static const AMOVIESETUP_PIN amfQTDPin[] = -{ { wNull, - FALSE, FALSE, FALSE, FALSE, - &GUID_NULL, - NULL, - 2, - amfMTstream - }, +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)) { - wNull, - FALSE, TRUE, TRUE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTvideo - }, + *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))) { - wNull, - FALSE, TRUE, TRUE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTaudio - }, -}; + hr = IUnknown_QueryInterface(unk, iid, out); + IUnknown_Release(unk); + } + return hr; +}
-static const AMOVIESETUP_FILTER amfQTV = -{ &CLSID_QTVDecoder, - wQTVName, - MERIT_NORMAL-1, - 2, - amfQTVPin -}; +static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock) +{ + TRACE("iface %p, lock %d.\n", iface, lock); + return S_OK; +}
-static const AMOVIESETUP_FILTER amfQTD = -{ &CLSID_QTSplitter, - wQTDName, - MERIT_NORMAL-1, - 3, - amfQTDPin +static const IClassFactoryVtbl class_factory_vtbl = +{ + class_factory_QueryInterface, + class_factory_AddRef, + class_factory_Release, + class_factory_CreateInstance, + class_factory_LockServer, };
-FactoryTemplate const g_Templates[] = { +static struct class_factory qt_splitter_cf = {{&class_factory_vtbl}, qt_splitter_create}; +static struct class_factory video_decoder_cf = {{&class_factory_vtbl}, video_decoder_create}; + +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) +{ + struct class_factory *factory; + HRESULT hr; + + TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out); + + if (IsEqualGUID(clsid, &CLSID_QTSplitter)) + factory = &qt_splitter_cf; + else if (IsEqualGUID(clsid, &CLSID_QTVDecoder)) + factory = &video_decoder_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 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 REGFILTERPINS2 reg_qt_splitter_pins[3] = +{ { - wQTVName, - &CLSID_QTVDecoder, - QTVDecoder_create, - NULL, - &amfQTV, + .nMediaTypes = 1, + .lpMediaType = ®_stream_mt, }, { - wQTDName, - &CLSID_QTSplitter, - QTSplitter_create, - NULL, - &amfQTD, - } + .dwFlags = REG_PINFLAG_B_OUTPUT | REG_PINFLAG_B_ZERO, + .nMediaTypes = 1, + .lpMediaType = ®_audio_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT | REG_PINFLAG_B_ZERO, + .nMediaTypes = 1, + .lpMediaType = ®_video_mt, + }, };
-int g_cTemplates = ARRAY_SIZE(g_Templates); -static HINSTANCE hInst = NULL; +static const REGFILTER2 reg_qt_splitter = +{ + .dwVersion = 2, + .dwMerit = MERIT_NORMAL - 1, + .u.s2.cPins2 = 3, + .u.s2.rgPins2 = reg_qt_splitter_pins, +};
-/*********************************************************************** - * Dll EntryPoint (wineqtdecoder.@) - */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +static const REGFILTERPINS2 reg_qt_splitter_pins[2] = { - hInst = hInstDLL; - return STRMBASE_DllMain(hInstDLL,fdwReason,lpv); -} + { + .nMediaTypes = 1, + .lpMediaType = ®_video_mt, + }, + { + .dwFlags = REG_PINFLAG_B_OUTPUT, + .nMediaTypes = 1, + .lpMediaType = ®_video_mt, + }, +};
-/*********************************************************************** - * DllGetClassObject - */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +static const REGFILTER2 reg_video_decoder = { - return STRMBASE_DllGetClassObject( rclsid, riid, ppv ); -} + .dwVersion = 2, + .dwMerit = MERIT_NORMAL - 1, + .u.s2.cPins2 = 2, + .u.s2.rgPins2 = reg_video_decoder_pins, +};
-/*********************************************************************** - * DllRegisterServer (wineqtdecoder.@) - */ HRESULT WINAPI DllRegisterServer(void) { + IFilterMapper2 *mapper; HRESULT hr; - TRACE("()\n"); - hr = AMovieDllRegisterServer2(TRUE); - if (SUCCEEDED(hr)) - hr = __wine_register_resources(hInst); - return hr; + + TRACE(".\n"); + + if (FAILED(hr = __wine_register_resources(wineqtdecoder_instance))) + return hr; + + if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper2, (void **)&mapper))) + return hr; + + IFilterMapper2_RegisterFilter(mapper, &CLSID_QTSplitter, wQTDName, NULL, NULL, NULL, ®_qt_splitter); + IFilterMapper2_RegisterFilter(mapper, &CLSID_QTVDecoder, wQTVName, NULL, NULL, NULL, ®_video_decoder); + + IFilterMapper2_Release(mapper); + return S_OK; }
-/*********************************************************************** - * DllUnregisterServer (wineqtdecoder.@) - */ HRESULT WINAPI DllUnregisterServer(void) { + IFilterMapper2 *mapper; HRESULT hr; - TRACE("\n"); - hr = AMovieDllRegisterServer2(FALSE); - if (SUCCEEDED(hr)) - hr = __wine_unregister_resources(hInst); - return hr; + + TRACE(".\n"); + + if (FAILED(hr = __wine_unregister_resources(wineqtdecoder_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_QTSplitter); + IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_QTVDecoder); + + IFilterMapper2_Release(mapper); + return S_OK; }
-/*********************************************************************** - * DllCanUnloadNow (wineqtdecoder.@) - */ HRESULT WINAPI DllCanUnloadNow(void) { - TRACE("\n"); - return STRMBASE_DllCanUnloadNow(); + TRACE(".\n"); + return S_FALSE; } diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c index 1421e0bf53c..69736208097 100644 --- a/dlls/wineqtdecoder/qtsplitter.c +++ b/dlls/wineqtdecoder/qtsplitter.c @@ -124,6 +124,7 @@ #include "wine/strmbase.h"
#include "qtprivate.h" +#include "wineqtdecoder_classes.h"
WINE_DEFAULT_DEBUG_CHANNEL(qtsplitter); extern CLSID CLSID_QTSplitter; @@ -402,7 +403,7 @@ static const struct strmbase_sink_ops sink_ops = .sink_disconnect = qt_splitter_sink_disconnect, };
-IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr) +HRESULT qt_splitter_create(IUnknown *outer, IUnknown **out) { QTSplitter *This; static const WCHAR wcsInputPinName[] = {'I','n','p','u','t',' ','P','i','n',0}; @@ -411,12 +412,8 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr)
RegisterWineDataHandler();
- This = CoTaskMemAlloc(sizeof(*This)); - if (!This) - { - *phr = E_OUTOFMEMORY; - return NULL; - } + if (!(This = CoTaskMemAlloc(sizeof(*This)))) + return E_OUTOFMEMORY; ZeroMemory(This,sizeof(*This));
strmbase_filter_init(&This->filter, outer, &CLSID_QTSplitter, &filter_ops); @@ -430,8 +427,9 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr) This->aSession = NULL; This->runEvent = CreateEventW(NULL, 0, 0, NULL);
- *phr = S_OK; - return &This->filter.IUnknown_inner; + TRACE("Created QT splitter %p.\n", This); + *out = &This->filter.IUnknown_inner; + return S_OK; }
static OSErr QT_Create_Extract_Session(QTSplitter *filter) diff --git a/dlls/wineqtdecoder/qtvdecoder.c b/dlls/wineqtdecoder/qtvdecoder.c index 4be654e5a10..5417124782c 100644 --- a/dlls/wineqtdecoder/qtvdecoder.c +++ b/dlls/wineqtdecoder/qtvdecoder.c @@ -126,6 +126,7 @@ #include "wine/strmbase.h"
#include "qtprivate.h" +#include "wineqtdecoder_classes.h"
extern CLSID CLSID_QTVDecoder;
@@ -505,22 +506,17 @@ static const TransformFilterFuncTable QTVDecoder_FuncsTable = { .pfnBreakConnect = QTVDecoder_BreakConnect, };
-IUnknown * CALLBACK QTVDecoder_create(IUnknown *outer, HRESULT* phr) +HRESULT video_decoder_create(IUnknown *outer, IUnknown **out) { + QTVDecoderImpl *object; HRESULT hr; - QTVDecoderImpl * This; - - *phr = S_OK;
hr = strmbase_transform_create(sizeof(QTVDecoderImpl), outer, &CLSID_QTVDecoder, - &QTVDecoder_FuncsTable, (IBaseFilter **)&This); - + &QTVDecoder_FuncsTable, (IBaseFilter **)&object); if (FAILED(hr)) - { - *phr = hr; - return NULL; - } + return hr;
- *phr = hr; - return &This->tf.filter.IUnknown_inner; + TRACE("Created video decoder %p.\n", object); + *out = &object->tf.filter.IUnknown_inner; + return S_OK; } diff --git a/dlls/wineqtdecoder/wineqtdecoder_classes.idl b/dlls/wineqtdecoder/wineqtdecoder_classes.idl new file mode 100644 index 00000000000..49badcc6d72 --- /dev/null +++ b/dlls/wineqtdecoder/wineqtdecoder_classes.idl @@ -0,0 +1,37 @@ +/* + * COM classes for wineqtdecoder + * + * 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 + * 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 + */ + +#pragma makedep header +#pragma makedep ident +#pragma makedep register + +[ + helpstring("Wine QuickTime splitter"), + threading(both), + uuid(d0e70e49-5927-4894-a386-359460ee87c9) +] +coclass QTSplitter {} + +[ + helpstring("Wine QuickTime video decoder"), + threading(both), + uuid(683ddacb-4354-490c-a058-e05ad0f20537) +] +coclass QTVDecoder {}
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/Makefile.in | 1 - dlls/strmbase/dllfunc.c | 375 -------------------------------------- include/wine/strmbase.h | 32 ---- 3 files changed, 408 deletions(-) delete mode 100644 dlls/strmbase/dllfunc.c
diff --git a/dlls/strmbase/Makefile.in b/dlls/strmbase/Makefile.in index 8fc9e242b1c..e3fc30957e3 100644 --- a/dlls/strmbase/Makefile.in +++ b/dlls/strmbase/Makefile.in @@ -2,7 +2,6 @@ MODULE = libstrmbase.a
C_SRCS = \ dispatch.c \ - dllfunc.c \ filter.c \ mediatype.c \ outputqueue.c \ diff --git a/dlls/strmbase/dllfunc.c b/dlls/strmbase/dllfunc.c deleted file mode 100644 index ca5557ec249..00000000000 --- a/dlls/strmbase/dllfunc.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Strmbase DLL functions - * - * Copyright (C) 2005 Rolf Kalbermatter - * Copyright (C) 2010 Aric Stewart, CodeWeavers -* - * 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 - */ - -#include "strmbase_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(strmbase); - -extern const int g_cTemplates; -extern const FactoryTemplate g_Templates[]; - -static HINSTANCE g_hInst = NULL; -static LONG server_locks = 0; - -/* - * defines and constants - */ - -static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0 }; -static const WCHAR ips32_keyname[] = {'I','n','P','r','o','c','S','e','r','v','e','r','3','2',0}; -static const WCHAR tmodel_keyname[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0}; -static const WCHAR tmodel_both[] = {'B','o','t','h',0}; - -/* - * SetupRegisterClass() - */ -static HRESULT SetupRegisterClass(HKEY clsid, LPCWSTR szCLSID, - LPCWSTR szDescription, - LPCWSTR szFileName, - LPCWSTR szServerType, - LPCWSTR szThreadingModel) -{ - HKEY hkey, hsubkey = NULL; - LONG ret = RegCreateKeyW(clsid, szCLSID, &hkey); - if (ERROR_SUCCESS != ret) - return HRESULT_FROM_WIN32(ret); - - /* set description string */ - ret = RegSetValueW(hkey, NULL, REG_SZ, szDescription, - sizeof(WCHAR) * (lstrlenW(szDescription) + 1)); - if (ERROR_SUCCESS != ret) - goto err_out; - - /* create CLSID\{"CLSID"}\"ServerType" key, using key to CLSID\{"CLSID"} - passed back by last call to RegCreateKeyW(). */ - ret = RegCreateKeyW(hkey, szServerType, &hsubkey); - if (ERROR_SUCCESS != ret) - goto err_out; - - /* set server path */ - ret = RegSetValueW(hsubkey, NULL, REG_SZ, szFileName, - sizeof(WCHAR) * (lstrlenW(szFileName) + 1)); - if (ERROR_SUCCESS != ret) - goto err_out; - - /* set threading model */ - ret = RegSetValueExW(hsubkey, tmodel_keyname, 0L, REG_SZ, - (const BYTE*)szThreadingModel, - sizeof(WCHAR) * (lstrlenW(szThreadingModel) + 1)); -err_out: - if (hsubkey) - RegCloseKey(hsubkey); - RegCloseKey(hkey); - return HRESULT_FROM_WIN32(ret); -} - -/* - * RegisterAllClasses() - */ -static HRESULT SetupRegisterAllClasses(const FactoryTemplate * pList, int num, - LPCWSTR szFileName, BOOL bRegister) -{ - HRESULT hr = NOERROR; - HKEY hkey; - OLECHAR szCLSID[CHARS_IN_GUID]; - LONG i, ret = RegCreateKeyW(HKEY_CLASSES_ROOT, clsid_keyname, &hkey); - if (ERROR_SUCCESS != ret) - return HRESULT_FROM_WIN32(ret); - - for (i = 0; i < num; i++, pList++) - { - /* (un)register CLSID and InprocServer32 */ - hr = StringFromGUID2(pList->m_ClsID, szCLSID, CHARS_IN_GUID); - if (SUCCEEDED(hr)) - { - if (bRegister ) - hr = SetupRegisterClass(hkey, szCLSID, - pList->m_Name, szFileName, - ips32_keyname, tmodel_both); - else - hr = RegDeleteTreeW(hkey, szCLSID); - } - } - RegCloseKey(hkey); - return hr; -} - -HRESULT WINAPI AMovieSetupRegisterFilter2(const AMOVIESETUP_FILTER *pFilter, IFilterMapper2 *pIFM2, BOOL bRegister) -{ - if (!pFilter) - return S_OK; - - if (bRegister) - { - { - REGFILTER2 rf2; - rf2.dwVersion = 1; - rf2.dwMerit = pFilter->merit; - rf2.u.s1.cPins = pFilter->pins; - rf2.u.s1.rgPins = pFilter->pPin; - - return IFilterMapper2_RegisterFilter(pIFM2, pFilter->clsid, pFilter->name, NULL, &CLSID_LegacyAmFilterCategory, NULL, &rf2); - } - } - else - return IFilterMapper2_UnregisterFilter(pIFM2, &CLSID_LegacyAmFilterCategory, NULL, pFilter->clsid); -} - -HRESULT WINAPI AMovieDllRegisterServer2(BOOL bRegister) -{ - HRESULT hr; - int i; - IFilterMapper2 *pIFM2 = NULL; - WCHAR szFileName[MAX_PATH]; - - if (!GetModuleFileNameW(g_hInst, szFileName, MAX_PATH)) - { - ERR("Failed to get module file name for registration\n"); - return E_FAIL; - } - - if (bRegister) - hr = SetupRegisterAllClasses(g_Templates, g_cTemplates, szFileName, TRUE ); - - TRACE("Getting IFilterMapper2\r\n"); - hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, - &IID_IFilterMapper2, (void **)&pIFM2); - - for (i = 0; SUCCEEDED(hr) && i < g_cTemplates; i++) - hr = AMovieSetupRegisterFilter2(g_Templates[i].m_pAMovieSetup_Filter, pIFM2, bRegister); - - /* release interface */ - if (pIFM2) - IFilterMapper2_Release(pIFM2); - - /* if unregistering, unregister all OLE servers */ - if (SUCCEEDED(hr) && !bRegister) - hr = SetupRegisterAllClasses(g_Templates, g_cTemplates, szFileName, FALSE); - - return hr; -} - -/**************************************************************************** - * SetupInitializeServers - * - * This function is table driven using the static members of the - * CFactoryTemplate class defined in the Dll. - * - * It calls the initialize function for any class in CFactoryTemplate with - * one defined. - * - ****************************************************************************/ -static void SetupInitializeServers(const FactoryTemplate * pList, int num, - BOOL bLoading) -{ - int i; - - for (i = 0; i < num; i++, pList++) - { - if (pList->m_lpfnInit) - pList->m_lpfnInit(bLoading, pList->m_ClsID); - } -} - -BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - g_hInst = hInstDLL; - DisableThreadLibraryCalls(hInstDLL); - SetupInitializeServers(g_Templates, g_cTemplates, TRUE); - break; - case DLL_PROCESS_DETACH: - SetupInitializeServers(g_Templates, g_cTemplates, FALSE); - break; - } - return TRUE; -} - -/****************************************************************************** - * DLL ClassFactory - */ -typedef struct { - IClassFactory IClassFactory_iface; - LONG ref; - LPFNNewCOMObject pfnCreateInstance; -} IClassFactoryImpl; - -static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) -{ - return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); -} - -static HRESULT WINAPI DSCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) -{ - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IClassFactory)) - { - IClassFactory_AddRef(iface); - *ppobj = iface; - return S_OK; - } - - *ppobj = NULL; - WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj); - return E_NOINTERFACE; -} - -static ULONG WINAPI DSCF_AddRef(IClassFactory *iface) -{ - IClassFactoryImpl *This = impl_from_IClassFactory(iface); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI DSCF_Release(IClassFactory *iface) -{ - IClassFactoryImpl *This = impl_from_IClassFactory(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); - - return ref; -} - -static HRESULT WINAPI DSCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, - REFIID riid, void **ppobj) -{ - IClassFactoryImpl *This = impl_from_IClassFactory(iface); - HRESULT hres = ERROR_SUCCESS; - LPUNKNOWN punk; - - TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj); - - if (!ppobj) - return E_POINTER; - - /* Enforce the normal OLE rules regarding interfaces and delegation */ - if (pOuter && !IsEqualGUID(riid, &IID_IUnknown)) - return E_NOINTERFACE; - - *ppobj = NULL; - punk = This->pfnCreateInstance(pOuter, &hres); - if (!punk) - { - /* No object created, update error if it isn't done already and return */ - if (SUCCEEDED(hres)) - hres = E_OUTOFMEMORY; - return hres; - } - - if (SUCCEEDED(hres)) - { - hres = IUnknown_QueryInterface(punk, riid, ppobj); - } - /* Releasing the object. If everything was successful, QueryInterface - should have incremented the refcount once more, otherwise this will - purge the object. */ - IUnknown_Release(punk); - return hres; -} - -static HRESULT WINAPI DSCF_LockServer(IClassFactory *iface, BOOL dolock) -{ - IClassFactoryImpl *This = impl_from_IClassFactory(iface); - TRACE("(%p)->(%d)\n",This, dolock); - - if (dolock) - InterlockedIncrement(&server_locks); - else - InterlockedDecrement(&server_locks); - return S_OK; -} - -static const IClassFactoryVtbl DSCF_Vtbl = -{ - DSCF_QueryInterface, - DSCF_AddRef, - DSCF_Release, - DSCF_CreateInstance, - DSCF_LockServer -}; - -/*********************************************************************** - * DllGetClassObject - */ -HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) -{ - const FactoryTemplate *pList = g_Templates; - IClassFactoryImpl *factory; - int i; - - TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - - if (!ppv) - return E_POINTER; - - *ppv = NULL; - - if (!IsEqualGUID(&IID_IClassFactory, riid) && - !IsEqualGUID(&IID_IUnknown, riid)) - return E_NOINTERFACE; - - for (i = 0; i < g_cTemplates; i++, pList++) - { - if (IsEqualGUID(pList->m_ClsID, rclsid)) - break; - } - - if (i == g_cTemplates) - { - char dllname[MAX_PATH]; - if (!GetModuleFileNameA(g_hInst, dllname, sizeof(dllname))) - strcpy(dllname, "???"); - ERR("%s: no class found in %s.\n", debugstr_guid(rclsid), dllname); - return CLASS_E_CLASSNOTAVAILABLE; - } - else if (!pList->m_lpfnNew) - { - FIXME("%s: class not implemented yet.\n", debugstr_guid(rclsid)); - return CLASS_E_CLASSNOTAVAILABLE; - } - - factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl)); - if (!factory) - return E_OUTOFMEMORY; - - factory->IClassFactory_iface.lpVtbl = &DSCF_Vtbl; - factory->ref = 1; - - factory->pfnCreateInstance = pList->m_lpfnNew; - - *ppv = &factory->IClassFactory_iface; - return S_OK; -} - -/*********************************************************************** - * DllCanUnloadNow - */ -HRESULT WINAPI STRMBASE_DllCanUnloadNow(void) -{ - TRACE("\n"); - - if (server_locks == 0) - return S_OK; - return S_FALSE; -} diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 0e0f73afa3c..6fc4cc08b3e 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -256,33 +256,6 @@ HRESULT WINAPI SourceSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pP HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru); HRESULT WINAPI PosPassThru_Construct(IUnknown* pUnkOuter, LPVOID *ppPassThru);
-/* Filter Registration */ - -typedef REGPINTYPES AMOVIESETUP_MEDIATYPE; -typedef REGFILTERPINS AMOVIESETUP_PIN; - -typedef struct AMOVIESETUP_FILTER { - const CLSID *clsid; - const WCHAR *name; - DWORD merit; - UINT pins; - const AMOVIESETUP_PIN *pPin; -} AMOVIESETUP_FILTER, *LPAMOVIESETUP_FILTER; - -typedef IUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr); -typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid); - -typedef struct tagFactoryTemplate { - const WCHAR *m_Name; - const CLSID *m_ClsID; - LPFNNewCOMObject m_lpfnNew; - LPFNInitRoutine m_lpfnInit; - const AMOVIESETUP_FILTER *m_pAMovieSetup_Filter; -} FactoryTemplate; - -HRESULT WINAPI AMovieDllRegisterServer2(BOOL bRegister); -HRESULT WINAPI AMovieSetupRegisterFilter2(const AMOVIESETUP_FILTER *pFilter, IFilterMapper2 *pIFM2, BOOL bRegister); - /* Output Queue */ typedef struct tagOutputQueue { CRITICAL_SECTION csQueue; @@ -528,8 +501,3 @@ HRESULT WINAPI BaseRendererImpl_Receive(struct strmbase_renderer *filter, IMedia HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown *outer, const CLSID *clsid, const WCHAR *sink_name, const struct strmbase_renderer_ops *ops); void strmbase_renderer_cleanup(struct strmbase_renderer *filter); - -/* Dll Functions */ -BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv); -HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv); -HRESULT WINAPI STRMBASE_DllCanUnloadNow(void);