qcap: Reimplement COM registration and vending locally.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cf376c96e8
commit
7bcb8e74ce
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
|
||||
strmbase_filter_init(&object->filter, outer, &CLSID_AudioRecord, &filter_ops);
|
||||
|
||||
strmbase_filter_init(&This->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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
strmbase_filter_init(&compressor->filter, outer, &CLSID_AVICo, &filter_ops);
|
||||
strmbase_filter_init(&object->filter, outer, &CLSID_AVICo, &filter_ops);
|
||||
object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
|
||||
|
||||
compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
|
||||
strmbase_sink_init(&object->sink, &object->filter, sink_name, &sink_ops, NULL);
|
||||
strmbase_source_init(&object->source, &object->filter, source_name, &source_ops);
|
||||
|
||||
strmbase_sink_init(&compressor->sink, &compressor->filter, sink_name, &sink_ops, NULL);
|
||||
strmbase_source_init(&compressor->source, &compressor->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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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 {}
|
|
@ -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[] = {
|
||||
{
|
||||
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
|
||||
}
|
||||
struct class_factory
|
||||
{
|
||||
IClassFactory IClassFactory_iface;
|
||||
HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
|
||||
};
|
||||
|
||||
const int g_cTemplates = ARRAY_SIZE(g_Templates);
|
||||
|
||||
/***********************************************************************
|
||||
* Dll EntryPoint (QCAP.@)
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
|
||||
{
|
||||
return STRMBASE_DllMain(hInstDLL,fdwReason,lpv);
|
||||
return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllGetClassObject
|
||||
*/
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
|
||||
{
|
||||
return STRMBASE_DllGetClassObject( rclsid, riid, ppv );
|
||||
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
||||
|
||||
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
|
||||
{
|
||||
*out = iface;
|
||||
IClassFactory_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*out = NULL;
|
||||
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI class_factory_Release(IClassFactory *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out)
|
||||
{
|
||||
struct class_factory *factory = impl_from_IClassFactory(iface);
|
||||
IUnknown *unk;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
|
||||
|
||||
if (outer && !IsEqualGUID(iid, &IID_IUnknown))
|
||||
return E_NOINTERFACE;
|
||||
|
||||
*out = NULL;
|
||||
if (SUCCEEDED(hr = factory->create_instance(outer, &unk)))
|
||||
{
|
||||
hr = IUnknown_QueryInterface(unk, iid, out);
|
||||
IUnknown_Release(unk);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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};
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
qcap_instance = instance;
|
||||
DisableThreadLibraryCalls(instance);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
|
||||
{
|
||||
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_AviDest);
|
||||
IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_SmartTee);
|
||||
|
||||
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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -563,16 +563,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);
|
||||
|
||||
|
@ -587,6 +584,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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue