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 {}