strmbase: Support aggregation in the base filter.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-06-04 10:01:17 -05:00 committed by Alexandre Julliard
parent d6a44a9187
commit 31a5cb5f05
30 changed files with 158 additions and 166 deletions

View File

@ -117,7 +117,7 @@ static ULONG WINAPI inner_AddRef(IUnknown *iface)
static ULONG WINAPI inner_Release(IUnknown *iface) static ULONG WINAPI inner_Release(IUnknown *iface)
{ {
evr_filter *This = impl_from_inner_IUnknown(iface); evr_filter *This = impl_from_inner_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->filter.refCount); ULONG ref = InterlockedDecrement(&This->filter.refcount);
TRACE("(%p, %p)->(): new ref %d\n", iface, This, ref); TRACE("(%p, %p)->(): new ref %d\n", iface, This, ref);
@ -220,7 +220,7 @@ HRESULT evr_filter_create(IUnknown *outer_unk, void **ppv)
if (!object) if (!object)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
BaseFilter_Init(&object->filter, &basefilter_vtbl, &CLSID_EnhancedVideoRenderer, strmbase_filter_init(&object->filter, &basefilter_vtbl, NULL, &CLSID_EnhancedVideoRenderer,
(DWORD_PTR)(__FILE__ ": EVR.csFilter"), &basefilter_functable); (DWORD_PTR)(__FILE__ ": EVR.csFilter"), &basefilter_functable);
object->IUnknown_inner.lpVtbl = &evr_inner_vtbl; object->IUnknown_inner.lpVtbl = &evr_inner_vtbl;

View File

@ -99,7 +99,7 @@ static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
static ULONG WINAPI Unknown_Release(IUnknown *iface) static ULONG WINAPI Unknown_Release(IUnknown *iface)
{ {
AudioRecord *This = impl_from_IUnknown(iface); AudioRecord *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->filter.refCount); ULONG ref = InterlockedDecrement(&This->filter.refcount);
TRACE("(%p/%p)->() ref=%d\n", iface, This, ref); TRACE("(%p/%p)->() ref=%d\n", iface, This, ref);
if (!ref) { if (!ref) {
strmbase_filter_cleanup(&This->filter); strmbase_filter_cleanup(&This->filter);
@ -271,7 +271,7 @@ IUnknown* WINAPI QCAP_createAudioCaptureFilter(IUnknown *outer, HRESULT *phr)
else else
This->outerUnknown = &This->IUnknown_iface; This->outerUnknown = &This->IUnknown_iface;
BaseFilter_Init(&This->filter, &AudioRecordVtbl, &CLSID_AudioRecord, strmbase_filter_init(&This->filter, &AudioRecordVtbl, NULL, &CLSID_AudioRecord,
(DWORD_PTR)(__FILE__ ": AudioRecord.csFilter"), &AudioRecordFuncs); (DWORD_PTR)(__FILE__ ": AudioRecord.csFilter"), &AudioRecordFuncs);
*phr = S_OK; *phr = S_OK;

View File

@ -640,15 +640,13 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
AVICompressor *compressor; AVICompressor *compressor;
HRESULT hres; HRESULT hres;
TRACE("\n");
compressor = heap_alloc_zero(sizeof(*compressor)); compressor = heap_alloc_zero(sizeof(*compressor));
if(!compressor) { if(!compressor) {
*phr = E_NOINTERFACE; *phr = E_NOINTERFACE;
return NULL; return NULL;
} }
BaseFilter_Init(&compressor->filter, &AVICompressorVtbl, &CLSID_AVICo, strmbase_filter_init(&compressor->filter, &AVICompressorVtbl, outer, &CLSID_AVICo,
(DWORD_PTR)(__FILE__ ": AVICompressor.csFilter"), &filter_func_table); (DWORD_PTR)(__FILE__ ": AVICompressor.csFilter"), &filter_func_table);
compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl; compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
@ -672,5 +670,5 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
} }
*phr = S_OK; *phr = S_OK;
return (IUnknown*)&compressor->filter.IBaseFilter_iface; return &compressor->filter.IUnknown_inner;
} }

View File

@ -2270,7 +2270,7 @@ static HRESULT create_input_pin(AviMux *avimux)
return S_OK; return S_OK;
} }
IUnknown* WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr) IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
{ {
static const WCHAR output_name[] = {'A','V','I',' ','O','u','t',0}; static const WCHAR output_name[] = {'A','V','I',' ','O','u','t',0};
@ -2278,20 +2278,13 @@ IUnknown* WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr)
PIN_INFO info; PIN_INFO info;
HRESULT hr; HRESULT hr;
TRACE("(%p)\n", pUnkOuter);
if(pUnkOuter) {
*phr = CLASS_E_NOAGGREGATION;
return NULL;
}
avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux)); avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux));
if(!avimux) { if(!avimux) {
*phr = E_OUTOFMEMORY; *phr = E_OUTOFMEMORY;
return NULL; return NULL;
} }
BaseFilter_Init(&avimux->filter, &AviMuxVtbl, &CLSID_AviDest, strmbase_filter_init(&avimux->filter, &AviMuxVtbl, outer, &CLSID_AviDest,
(DWORD_PTR)(__FILE__ ": AviMux.csFilter"), &filter_func_table); (DWORD_PTR)(__FILE__ ": AviMux.csFilter"), &filter_func_table);
avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl; avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl;
avimux->IConfigInterleaving_iface.lpVtbl = &ConfigInterleavingVtbl; avimux->IConfigInterleaving_iface.lpVtbl = &ConfigInterleavingVtbl;
@ -2328,5 +2321,5 @@ IUnknown* WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr)
ObjectRefCount(TRUE); ObjectRefCount(TRUE);
*phr = S_OK; *phr = S_OK;
return (IUnknown*)&avimux->filter.IBaseFilter_iface; return &avimux->filter.IUnknown_inner;
} }

View File

@ -104,7 +104,7 @@ static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
static ULONG WINAPI Unknown_Release(IUnknown *iface) static ULONG WINAPI Unknown_Release(IUnknown *iface)
{ {
SmartTeeFilter *This = impl_from_IUnknown(iface); SmartTeeFilter *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->filter.refCount); ULONG ref = InterlockedDecrement(&This->filter.refcount);
TRACE("(%p)->() ref=%d\n", This, ref); TRACE("(%p)->() ref=%d\n", This, ref);
@ -600,7 +600,7 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
else else
This->outerUnknown = &This->IUnknown_iface; This->outerUnknown = &This->IUnknown_iface;
BaseFilter_Init(&This->filter, &SmartTeeFilterVtbl, &CLSID_SmartTee, strmbase_filter_init(&This->filter, &SmartTeeFilterVtbl, NULL, &CLSID_SmartTee,
(DWORD_PTR)(__FILE__ ": SmartTeeFilter.csFilter"), &SmartTeeFilterFuncs); (DWORD_PTR)(__FILE__ ": SmartTeeFilter.csFilter"), &SmartTeeFilterFuncs);
inputPinInfo.pFilter = &This->filter.IBaseFilter_iface; inputPinInfo.pFilter = &This->filter.IBaseFilter_iface;

View File

@ -172,23 +172,23 @@ static void test_aggregation(void)
hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2); hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2); hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2); ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2); hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
IBaseFilter_Release(filter); IBaseFilter_Release(filter);
ref = IUnknown_Release(unk); ref = IUnknown_Release(unk);
todo_wine ok(!ref, "Got unexpected refcount %d.\n", ref); ok(!ref, "Got unexpected refcount %d.\n", ref);
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
} }

View File

@ -135,8 +135,7 @@ static void test_aggregation(void)
hr = CoCreateInstance(&CLSID_AviDest, &test_outer, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_AviDest, &test_outer, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk); &IID_IUnknown, (void **)&unk);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
if (FAILED(hr)) return;
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
ref = get_refcount(unk); ref = get_refcount(unk);

View File

@ -154,7 +154,7 @@ static ULONG WINAPI unknown_inner_AddRef(IUnknown *iface)
static ULONG WINAPI unknown_inner_Release(IUnknown *iface) static ULONG WINAPI unknown_inner_Release(IUnknown *iface)
{ {
VfwCapture *This = impl_from_IUnknown(iface); VfwCapture *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->filter.refCount); ULONG ref = InterlockedDecrement(&This->filter.refcount);
TRACE("(%p) ref=%d\n", This, ref); TRACE("(%p) ref=%d\n", This, ref);
@ -219,7 +219,8 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr)
if (!pVfwCapture) if (!pVfwCapture)
return NULL; return NULL;
BaseFilter_Init(&pVfwCapture->filter, &VfwCapture_Vtbl, &CLSID_VfwCapture, (DWORD_PTR)(__FILE__ ": VfwCapture.csFilter"), &BaseFuncTable); strmbase_filter_init(&pVfwCapture->filter, &VfwCapture_Vtbl, NULL, &CLSID_VfwCapture,
(DWORD_PTR)(__FILE__ ": VfwCapture.csFilter"), &BaseFuncTable);
pVfwCapture->IUnknown_inner.lpVtbl = &unknown_inner_vtbl; pVfwCapture->IUnknown_inner.lpVtbl = &unknown_inner_vtbl;
pVfwCapture->IAMStreamConfig_iface.lpVtbl = &IAMStreamConfig_VTable; pVfwCapture->IAMStreamConfig_iface.lpVtbl = &IAMStreamConfig_VTable;

View File

@ -110,7 +110,7 @@ static ULONG WINAPI NullRendererInner_AddRef(IUnknown *iface)
static ULONG WINAPI NullRendererInner_Release(IUnknown *iface) static ULONG WINAPI NullRendererInner_Release(IUnknown *iface)
{ {
NullRendererImpl *This = impl_from_IUnknown(iface); NullRendererImpl *This = impl_from_IUnknown(iface);
ULONG refCount = InterlockedDecrement(&This->renderer.filter.refCount); ULONG refCount = InterlockedDecrement(&This->renderer.filter.refcount);
if (!refCount) if (!refCount)
{ {
@ -190,7 +190,7 @@ HRESULT NullRenderer_create(IUnknown *pUnkOuter, void **ppv)
else else
pNullRenderer->outer_unk = &pNullRenderer->IUnknown_inner; pNullRenderer->outer_unk = &pNullRenderer->IUnknown_inner;
hr = strmbase_renderer_init(&pNullRenderer->renderer, &NullRenderer_Vtbl, pUnkOuter, hr = strmbase_renderer_init(&pNullRenderer->renderer, &NullRenderer_Vtbl, NULL,
&CLSID_NullRenderer, sink_name, &CLSID_NullRenderer, sink_name,
(DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"), &RendererFuncTable); (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"), &RendererFuncTable);

View File

@ -319,7 +319,7 @@ static ULONG WINAPI SampleGrabber_AddRef(IUnknown *iface)
static ULONG WINAPI SampleGrabber_Release(IUnknown *iface) static ULONG WINAPI SampleGrabber_Release(IUnknown *iface)
{ {
SG_Impl *This = impl_from_IUnknown(iface); SG_Impl *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->filter.refCount); ULONG ref = InterlockedDecrement(&This->filter.refcount);
TRACE("(%p) ref=%d\n", This, ref); TRACE("(%p) ref=%d\n", This, ref);
@ -1267,7 +1267,7 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv)
} }
ZeroMemory(obj, sizeof(SG_Impl)); ZeroMemory(obj, sizeof(SG_Impl));
BaseFilter_Init(&obj->filter, &IBaseFilter_VTable, &CLSID_SampleGrabber, strmbase_filter_init(&obj->filter, &IBaseFilter_VTable, NULL, &CLSID_SampleGrabber,
(DWORD_PTR)(__FILE__ ": SG_Impl.csFilter"), &basefunc_vtbl); (DWORD_PTR)(__FILE__ ": SG_Impl.csFilter"), &basefunc_vtbl);
obj->IUnknown_inner.lpVtbl = &samplegrabber_vtbl; obj->IUnknown_inner.lpVtbl = &samplegrabber_vtbl;
obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable; obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable;

View File

@ -1424,18 +1424,13 @@ static const BaseFilterFuncTable avi_splitter_func_table =
.filter_destroy = avi_splitter_destroy, .filter_destroy = avi_splitter_destroy,
}; };
HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv) HRESULT AVISplitter_create(IUnknown *outer, void **out)
{ {
static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0}; static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
HRESULT hr; HRESULT hr;
AVISplitterImpl * This; AVISplitterImpl * This;
TRACE("(%p, %p)\n", pUnkOuter, ppv); *out = NULL;
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
/* Note: This memory is managed by the transform filter once created */ /* Note: This memory is managed by the transform filter once created */
This = CoTaskMemAlloc(sizeof(AVISplitterImpl)); This = CoTaskMemAlloc(sizeof(AVISplitterImpl));
@ -1443,7 +1438,7 @@ HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
This->streams = NULL; This->streams = NULL;
This->oldindex = NULL; This->oldindex = NULL;
hr = Parser_Create(&This->Parser, &AVISplitterImpl_Vtbl, &CLSID_AviSplitter, hr = Parser_Create(&This->Parser, &AVISplitterImpl_Vtbl, outer, &CLSID_AviSplitter,
&avi_splitter_func_table, sink_name, AVISplitter_Sample, AVISplitter_QueryAccept, &avi_splitter_func_table, sink_name, AVISplitter_Sample, AVISplitter_QueryAccept,
AVISplitter_InputPin_PreConnect, AVISplitter_Flush, AVISplitter_InputPin_PreConnect, AVISplitter_Flush,
AVISplitter_Disconnect, AVISplitter_first_request, AVISplitter_Disconnect, AVISplitter_first_request,
@ -1452,7 +1447,7 @@ HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
*ppv = &This->Parser.filter.IBaseFilter_iface; *out = &This->Parser.filter.IUnknown_inner;
return hr; return hr;
} }

View File

@ -652,19 +652,14 @@ static const BaseRendererFuncTable BaseFuncTable = {
dsound_render_query_interface, dsound_render_query_interface,
}; };
HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) HRESULT DSoundRender_create(IUnknown *outer, void **out)
{ {
static const WCHAR sink_name[] = {'A','u','d','i','o',' ','I','n','p','u','t',' ','p','i','n',' ','(','r','e','n','d','e','r','e','d',')',0}; static const WCHAR sink_name[] = {'A','u','d','i','o',' ','I','n','p','u','t',' ','p','i','n',' ','(','r','e','n','d','e','r','e','d',')',0};
HRESULT hr; HRESULT hr;
DSoundRenderImpl * pDSoundRender; DSoundRenderImpl * pDSoundRender;
TRACE("(%p, %p)\n", pUnkOuter, ppv); *out = NULL;
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
pDSoundRender = CoTaskMemAlloc(sizeof(DSoundRenderImpl)); pDSoundRender = CoTaskMemAlloc(sizeof(DSoundRenderImpl));
if (!pDSoundRender) if (!pDSoundRender)
@ -672,8 +667,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl)); ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl));
hr = strmbase_renderer_init(&pDSoundRender->renderer, &DSoundRender_Vtbl, hr = strmbase_renderer_init(&pDSoundRender->renderer, &DSoundRender_Vtbl,
(IUnknown *)&pDSoundRender->renderer. filter.IBaseFilter_iface, outer, &CLSID_DSoundRender, sink_name,
&CLSID_DSoundRender, sink_name,
(DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"), &BaseFuncTable); (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"), &BaseFuncTable);
BasicAudio_Init(&pDSoundRender->basicAudio,&IBasicAudio_Vtbl); BasicAudio_Init(&pDSoundRender->basicAudio,&IBasicAudio_Vtbl);
@ -712,7 +706,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
*ppv = pDSoundRender; *out = &pDSoundRender->renderer.filter.IUnknown_inner;
} }
else else
{ {

View File

@ -446,19 +446,17 @@ static const BaseFilterFuncTable BaseFuncTable =
.filter_query_interface = async_reader_query_interface, .filter_query_interface = async_reader_query_interface,
}; };
HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv) HRESULT AsyncReader_create(IUnknown *outer, void **out)
{ {
AsyncReader *pAsyncRead; AsyncReader *pAsyncRead;
if( pUnkOuter )
return CLASS_E_NOAGGREGATION;
pAsyncRead = CoTaskMemAlloc(sizeof(AsyncReader)); pAsyncRead = CoTaskMemAlloc(sizeof(AsyncReader));
if (!pAsyncRead) if (!pAsyncRead)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
BaseFilter_Init(&pAsyncRead->filter, &AsyncReader_Vtbl, &CLSID_AsyncReader, (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter"), &BaseFuncTable); strmbase_filter_init(&pAsyncRead->filter, &AsyncReader_Vtbl, outer, &CLSID_AsyncReader,
(DWORD_PTR)(__FILE__ ": AsyncReader.csFilter"), &BaseFuncTable);
pAsyncRead->IFileSourceFilter_iface.lpVtbl = &FileSource_Vtbl; pAsyncRead->IFileSourceFilter_iface.lpVtbl = &FileSource_Vtbl;
pAsyncRead->pOutputPin = NULL; pAsyncRead->pOutputPin = NULL;
@ -466,7 +464,7 @@ HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv)
pAsyncRead->pszFileName = NULL; pAsyncRead->pszFileName = NULL;
pAsyncRead->pmt = NULL; pAsyncRead->pmt = NULL;
*ppv = pAsyncRead; *out = &pAsyncRead->filter.IUnknown_inner;
TRACE("-- created at %p\n", pAsyncRead); TRACE("-- created at %p\n", pAsyncRead);

View File

@ -868,25 +868,20 @@ static const BaseFilterFuncTable mpeg_splitter_func_table =
.filter_query_interface = mpeg_splitter_query_interface, .filter_query_interface = mpeg_splitter_query_interface,
}; };
HRESULT MPEGSplitter_create(IUnknown * pUnkOuter, LPVOID * ppv) HRESULT MPEGSplitter_create(IUnknown *outer, void **out)
{ {
static const WCHAR sink_name[] = {'I','n','p','u','t',0}; static const WCHAR sink_name[] = {'I','n','p','u','t',0};
MPEGSplitterImpl *This; MPEGSplitterImpl *This;
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
TRACE("(%p, %p)\n", pUnkOuter, ppv); *out = NULL;
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
This = CoTaskMemAlloc(sizeof(MPEGSplitterImpl)); This = CoTaskMemAlloc(sizeof(MPEGSplitterImpl));
if (!This) if (!This)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
ZeroMemory(This, sizeof(MPEGSplitterImpl)); ZeroMemory(This, sizeof(MPEGSplitterImpl));
hr = Parser_Create(&This->Parser, &MPEGSplitter_Vtbl, &CLSID_MPEG1Splitter, hr = Parser_Create(&This->Parser, &MPEGSplitter_Vtbl, outer, &CLSID_MPEG1Splitter,
&mpeg_splitter_func_table, sink_name, MPEGSplitter_process_sample, MPEGSplitter_query_accept, &mpeg_splitter_func_table, sink_name, MPEGSplitter_process_sample, MPEGSplitter_query_accept,
MPEGSplitter_pre_connect, MPEGSplitter_cleanup, MPEGSplitter_disconnect, MPEGSplitter_pre_connect, MPEGSplitter_cleanup, MPEGSplitter_disconnect,
MPEGSplitter_first_request, NULL, NULL, MPEGSplitter_seek, NULL); MPEGSplitter_first_request, NULL, NULL, MPEGSplitter_seek, NULL);
@ -898,8 +893,7 @@ HRESULT MPEGSplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
This->IAMStreamSelect_iface.lpVtbl = &AMStreamSelectVtbl; This->IAMStreamSelect_iface.lpVtbl = &AMStreamSelectVtbl;
This->seek = TRUE; This->seek = TRUE;
/* Note: This memory is managed by the parser filter once created */ *out = &This->Parser.filter.IUnknown_inner;
*ppv = &This->Parser.filter.IBaseFilter_iface;
return hr; return hr;
} }

View File

@ -73,8 +73,8 @@ IPin *parser_get_pin(BaseFilter *iface, unsigned int index)
return filter->ppPins[index]; return filter->ppPins[index];
} }
HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *Parser_Vtbl, HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown *outer,
const CLSID *pClsid, const BaseFilterFuncTable *func_table, const WCHAR *sink_name, const CLSID *clsid, const BaseFilterFuncTable *func_table, const WCHAR *sink_name,
PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect,
PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest, PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest,
STOPPROCESSPROC fnDone, SourceSeeking_ChangeStop stop, STOPPROCESSPROC fnDone, SourceSeeking_ChangeStop stop,
@ -83,8 +83,8 @@ HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *Parser_Vtbl,
HRESULT hr; HRESULT hr;
PIN_INFO piInput; PIN_INFO piInput;
/* pTransformFilter is already allocated */ strmbase_filter_init(&pParser->filter, vtbl, outer, clsid,
BaseFilter_Init(&pParser->filter, Parser_Vtbl, pClsid, (DWORD_PTR)(__FILE__ ": ParserImpl.csFilter"), func_table); (DWORD_PTR)(__FILE__ ": ParserImpl.csFilter"), func_table);
pParser->fnDisconnect = fnDisconnect; pParser->fnDisconnect = fnDisconnect;
@ -160,7 +160,6 @@ void Parser_Destroy(ParserImpl *This)
ULONG pinref; ULONG pinref;
HRESULT hr; HRESULT hr;
assert(!This->filter.refCount);
PullPin_WaitForStateChange(This->pInputPin, INFINITE); PullPin_WaitForStateChange(This->pInputPin, INFINITE);
/* Don't need to clean up output pins, freeing input pin will do that */ /* Don't need to clean up output pins, freeing input pin will do that */

View File

@ -52,7 +52,7 @@ typedef struct Parser_OutputPin
extern HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt); extern HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt);
HRESULT Parser_Create(ParserImpl *parser, const IBaseFilterVtbl *vtbl, HRESULT Parser_Create(ParserImpl *parser, const IBaseFilterVtbl *vtbl, IUnknown *outer,
const CLSID *clsid, const BaseFilterFuncTable *func_table, const WCHAR *sink_name, const CLSID *clsid, const BaseFilterFuncTable *func_table, const WCHAR *sink_name,
PFN_PROCESS_SAMPLE, PFN_QUERY_ACCEPT, PFN_PRE_CONNECT, PFN_CLEANUP, PFN_DISCONNECT, PFN_PROCESS_SAMPLE, PFN_QUERY_ACCEPT, PFN_PRE_CONNECT, PFN_CLEANUP, PFN_DISCONNECT,
REQUESTPROC, STOPPROCESSPROC, SourceSeeking_ChangeStop, REQUESTPROC, STOPPROCESSPROC, SourceSeeking_ChangeStop,

View File

@ -222,8 +222,7 @@ static void test_aggregation(void)
hr = CoCreateInstance(&CLSID_AviSplitter, &test_outer, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_AviSplitter, &test_outer, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk); &IID_IUnknown, (void **)&unk);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
if (FAILED(hr)) return;
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
ref = get_refcount(unk); ref = get_refcount(unk);

View File

@ -217,8 +217,7 @@ static void test_aggregation(void)
hr = CoCreateInstance(&CLSID_DSoundRender, &test_outer, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_DSoundRender, &test_outer, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk); &IID_IUnknown, (void **)&unk);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
if (FAILED(hr)) return;
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
ref = get_refcount(unk); ref = get_refcount(unk);

View File

@ -183,8 +183,7 @@ static void test_aggregation(void)
hr = CoCreateInstance(&CLSID_AsyncReader, &test_outer, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_AsyncReader, &test_outer, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk); &IID_IUnknown, (void **)&unk);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
if (FAILED(hr)) return;
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
ref = get_refcount(unk); ref = get_refcount(unk);

View File

@ -225,8 +225,7 @@ static void test_aggregation(void)
hr = CoCreateInstance(&CLSID_MPEG1Splitter, &test_outer, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_MPEG1Splitter, &test_outer, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk); &IID_IUnknown, (void **)&unk);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
if (FAILED(hr)) return;
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
ref = get_refcount(unk); ref = get_refcount(unk);

View File

@ -219,8 +219,7 @@ static void test_aggregation(void)
hr = CoCreateInstance(&CLSID_WAVEParser, &test_outer, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_WAVEParser, &test_outer, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk); &IID_IUnknown, (void **)&unk);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
if (FAILED(hr)) return;
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
ref = get_refcount(unk); ref = get_refcount(unk);

View File

@ -691,7 +691,7 @@ static ULONG WINAPI VideoRendererInner_AddRef(IUnknown *iface)
static ULONG WINAPI VideoRendererInner_Release(IUnknown *iface) static ULONG WINAPI VideoRendererInner_Release(IUnknown *iface)
{ {
VideoRendererImpl *This = impl_from_IUnknown(iface); VideoRendererImpl *This = impl_from_IUnknown(iface);
ULONG refCount = InterlockedDecrement(&This->renderer.filter.refCount); ULONG refCount = InterlockedDecrement(&This->renderer.filter.refcount);
TRACE("(%p)->(): new ref = %d\n", This, refCount); TRACE("(%p)->(): new ref = %d\n", This, refCount);
@ -1002,7 +1002,7 @@ HRESULT VideoRenderer_create(IUnknown *pUnkOuter, void **ppv)
pVideoRenderer->outer_unk = &pVideoRenderer->IUnknown_inner; pVideoRenderer->outer_unk = &pVideoRenderer->IUnknown_inner;
hr = strmbase_renderer_init(&pVideoRenderer->renderer, &VideoRenderer_Vtbl, hr = strmbase_renderer_init(&pVideoRenderer->renderer, &VideoRenderer_Vtbl,
pUnkOuter, &CLSID_VideoRenderer, sink_name, NULL, &CLSID_VideoRenderer, sink_name,
(DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter"), &BaseFuncTable); (DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter"), &BaseFuncTable);
if (FAILED(hr)) if (FAILED(hr))

View File

@ -831,7 +831,7 @@ static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
static ULONG WINAPI VMR9Inner_Release(IUnknown * iface) static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
{ {
struct quartz_vmr *This = impl_from_inner_IUnknown(iface); struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
ULONG refCount = InterlockedDecrement(&This->renderer.filter.refCount); ULONG refCount = InterlockedDecrement(&This->renderer.filter.refcount);
TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
@ -2418,11 +2418,11 @@ static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid)
pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl; pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer)) if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer))
hr = strmbase_renderer_init(&pVMR->renderer, &VMR_Vtbl, outer_unk, hr = strmbase_renderer_init(&pVMR->renderer, &VMR_Vtbl, NULL,
&CLSID_VideoMixingRenderer, sink_name, &CLSID_VideoMixingRenderer, sink_name,
(DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable); (DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable);
else else
hr = strmbase_renderer_init(&pVMR->renderer, &VMR_Vtbl, outer_unk, hr = strmbase_renderer_init(&pVMR->renderer, &VMR_Vtbl, NULL,
&CLSID_VideoMixingRenderer9, sink_name, &CLSID_VideoMixingRenderer9, sink_name,
(DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable); (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);

View File

@ -425,23 +425,18 @@ static const BaseFilterFuncTable wave_parser_func_table =
.filter_destroy = wave_parser_destroy, .filter_destroy = wave_parser_destroy,
}; };
HRESULT WAVEParser_create(IUnknown * pUnkOuter, LPVOID * ppv) HRESULT WAVEParser_create(IUnknown *outer, void **out)
{ {
static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0}; static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0};
HRESULT hr; HRESULT hr;
WAVEParserImpl * This; WAVEParserImpl * This;
TRACE("(%p, %p)\n", pUnkOuter, ppv); *out = NULL;
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
/* Note: This memory is managed by the transform filter once created */ /* Note: This memory is managed by the transform filter once created */
This = CoTaskMemAlloc(sizeof(WAVEParserImpl)); This = CoTaskMemAlloc(sizeof(WAVEParserImpl));
hr = Parser_Create(&This->Parser, &WAVEParser_Vtbl, &CLSID_WAVEParser, hr = Parser_Create(&This->Parser, &WAVEParser_Vtbl, outer, &CLSID_WAVEParser,
&wave_parser_func_table, sink_name, WAVEParser_Sample, WAVEParser_QueryAccept, &wave_parser_func_table, sink_name, WAVEParser_Sample, WAVEParser_QueryAccept,
WAVEParser_InputPin_PreConnect, WAVEParser_Cleanup, WAVEParser_disconnect, WAVEParser_InputPin_PreConnect, WAVEParser_Cleanup, WAVEParser_disconnect,
WAVEParser_first_request, NULL, NULL, WAVEParserImpl_seek, NULL); WAVEParser_first_request, NULL, NULL, WAVEParserImpl_seek, NULL);
@ -449,7 +444,7 @@ HRESULT WAVEParser_create(IUnknown * pUnkOuter, LPVOID * ppv)
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
*ppv = &This->Parser.filter.IBaseFilter_iface; *out = &This->Parser.filter.IUnknown_inner;
return hr; return hr;
} }

View File

@ -22,14 +22,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(strmbase); WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
static inline BaseFilter *impl_from_IBaseFilter(IBaseFilter *iface) static inline BaseFilter *impl_from_IUnknown(IUnknown *iface)
{ {
return CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface); return CONTAINING_RECORD(iface, BaseFilter, IUnknown_inner);
} }
HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter *iface, REFIID iid, void **out) static HRESULT WINAPI filter_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
{ {
BaseFilter *filter = impl_from_IBaseFilter(iface); BaseFilter *filter = impl_from_IUnknown(iface);
HRESULT hr; HRESULT hr;
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
@ -42,41 +42,75 @@ HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter *iface, REFIID iid, voi
return hr; return hr;
} }
if (IsEqualIID(iid, &IID_IUnknown) if (IsEqualIID(iid, &IID_IUnknown))
|| IsEqualIID(iid, &IID_IPersist) *out = iface;
else if (IsEqualIID(iid, &IID_IPersist)
|| IsEqualIID(iid, &IID_IMediaFilter) || IsEqualIID(iid, &IID_IMediaFilter)
|| IsEqualIID(iid, &IID_IBaseFilter)) || IsEqualIID(iid, &IID_IBaseFilter))
{ {
*out = iface; *out = &filter->IBaseFilter_iface;
IBaseFilter_AddRef(iface); }
return S_OK; else
{
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
return E_NOINTERFACE;
} }
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); IUnknown_AddRef((IUnknown *)*out);
return E_NOINTERFACE; return S_OK;
} }
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface) static ULONG WINAPI filter_inner_AddRef(IUnknown *iface)
{ {
BaseFilter *This = impl_from_IBaseFilter(iface); BaseFilter *filter = impl_from_IUnknown(iface);
ULONG refCount = InterlockedIncrement(&This->refCount); ULONG refcount = InterlockedIncrement(&filter->refcount);
TRACE("(%p)->() AddRef from %d\n", This, refCount - 1); TRACE("%p increasing refcount to %u.\n", filter, refcount);
return refCount; return refcount;
}
static ULONG WINAPI filter_inner_Release(IUnknown *iface)
{
BaseFilter *filter = impl_from_IUnknown(iface);
ULONG refcount = InterlockedDecrement(&filter->refcount);
TRACE("%p decreasing refcount to %u.\n", filter, refcount);
if (!refcount)
filter->pFuncsTable->filter_destroy(filter);
return refcount;
}
static const IUnknownVtbl filter_inner_vtbl =
{
filter_inner_QueryInterface,
filter_inner_AddRef,
filter_inner_Release,
};
static inline BaseFilter *impl_from_IBaseFilter(IBaseFilter *iface)
{
return CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface);
}
HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter *iface, REFIID iid, void **out)
{
BaseFilter *filter = impl_from_IBaseFilter(iface);
return IUnknown_QueryInterface(filter->outer_unk, iid, out);
}
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter *iface)
{
BaseFilter *filter = impl_from_IBaseFilter(iface);
return IUnknown_AddRef(filter->outer_unk);
} }
ULONG WINAPI BaseFilterImpl_Release(IBaseFilter *iface) ULONG WINAPI BaseFilterImpl_Release(IBaseFilter *iface)
{ {
BaseFilter *This = impl_from_IBaseFilter(iface); BaseFilter *filter = impl_from_IBaseFilter(iface);
ULONG refCount = InterlockedDecrement(&This->refCount); return IUnknown_Release(filter->outer_unk);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
if (!refCount)
This->pFuncsTable->filter_destroy(This);
return refCount;
} }
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid) HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
@ -222,21 +256,21 @@ VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter *filter)
InterlockedIncrement(&filter->pin_version); InterlockedIncrement(&filter->pin_version);
} }
void BaseFilter_Init(BaseFilter *This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, void strmbase_filter_init(BaseFilter *filter, const IBaseFilterVtbl *vtbl, IUnknown *outer,
DWORD_PTR DebugInfo, const BaseFilterFuncTable *pBaseFuncsTable) const CLSID *clsid, DWORD_PTR debug_info, const BaseFilterFuncTable *func_table)
{ {
This->IBaseFilter_iface.lpVtbl = Vtbl; memset(filter, 0, sizeof(*filter));
This->refCount = 1;
InitializeCriticalSection(&This->csFilter);
This->state = State_Stopped;
This->rtStreamStart = 0;
This->pClock = NULL;
ZeroMemory(&This->filterInfo, sizeof(FILTER_INFO));
This->clsid = *pClsid;
This->csFilter.DebugInfo->Spare[0] = DebugInfo;
This->pin_version = 1;
This->pFuncsTable = pBaseFuncsTable; filter->IBaseFilter_iface.lpVtbl = vtbl;
filter->IUnknown_inner.lpVtbl = &filter_inner_vtbl;
filter->outer_unk = outer ? outer : &filter->IUnknown_inner;
filter->refcount = 1;
InitializeCriticalSection(&filter->csFilter);
filter->clsid = *clsid;
filter->csFilter.DebugInfo->Spare[0] = debug_info;
filter->pin_version = 1;
filter->pFuncsTable = func_table;
} }
void strmbase_filter_cleanup(BaseFilter *This) void strmbase_filter_cleanup(BaseFilter *This)

View File

@ -249,14 +249,14 @@ static const BaseInputPinFuncTable input_BaseInputFuncTable = {
}; };
HRESULT WINAPI strmbase_renderer_init(BaseRenderer *This, const IBaseFilterVtbl *Vtbl, HRESULT WINAPI strmbase_renderer_init(BaseRenderer *This, const IBaseFilterVtbl *vtbl,
IUnknown *pUnkOuter, const CLSID *pClsid, const WCHAR *sink_name, DWORD_PTR DebugInfo, IUnknown *outer, const CLSID *clsid, const WCHAR *sink_name, DWORD_PTR debug_info,
const BaseRendererFuncTable *pBaseFuncsTable) const BaseRendererFuncTable *pBaseFuncsTable)
{ {
PIN_INFO piInput; PIN_INFO piInput;
HRESULT hr; HRESULT hr;
BaseFilter_Init(&This->filter, Vtbl, pClsid, DebugInfo, &RendererBaseFilterFuncTable); strmbase_filter_init(&This->filter, vtbl, outer, clsid, debug_info, &RendererBaseFilterFuncTable);
This->pFuncsTable = pBaseFuncsTable; This->pFuncsTable = pBaseFuncsTable;
@ -270,7 +270,7 @@ HRESULT WINAPI strmbase_renderer_init(BaseRenderer *This, const IBaseFilterVtbl
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = CreatePosPassThru(pUnkOuter ? pUnkOuter: (IUnknown *)&This->filter.IBaseFilter_iface, TRUE, hr = CreatePosPassThru(outer ? outer : (IUnknown *)&This->filter.IBaseFilter_iface, TRUE,
&This->pInputPin->pin.IPin_iface, &This->pPosition); &This->pInputPin->pin.IPin_iface, &This->pPosition);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;

View File

@ -288,7 +288,7 @@ static HRESULT strmbase_transform_init(const CLSID *clsid,
PIN_INFO piInput; PIN_INFO piInput;
PIN_INFO piOutput; PIN_INFO piOutput;
BaseFilter_Init(&filter->filter, &transform_vtbl, clsid, strmbase_filter_init(&filter->filter, &transform_vtbl, NULL, clsid,
(DWORD_PTR)(__FILE__ ": TransformFilter.csFilter"), &tfBaseFuncTable); (DWORD_PTR)(__FILE__ ": TransformFilter.csFilter"), &tfBaseFuncTable);
InitializeCriticalSection(&filter->csReceive); InitializeCriticalSection(&filter->csReceive);

View File

@ -1257,14 +1257,11 @@ static const BaseFilterFuncTable BaseFuncTable = {
.filter_destroy = gstdemux_destroy, .filter_destroy = gstdemux_destroy,
}; };
IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr) IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
{ {
IUnknown *obj = NULL;
PIN_INFO *piInput; PIN_INFO *piInput;
GSTImpl *This; GSTImpl *This;
TRACE("%p %p\n", pUnkOuter, phr);
if (!init_gstreamer()) if (!init_gstreamer())
{ {
*phr = E_FAIL; *phr = E_FAIL;
@ -1281,8 +1278,8 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr)
} }
memset(This, 0, sizeof(*This)); memset(This, 0, sizeof(*This));
obj = (IUnknown*)&This->filter.IBaseFilter_iface; strmbase_filter_init(&This->filter, &GST_Vtbl, outer, &CLSID_Gstreamer_Splitter,
BaseFilter_Init(&This->filter, &GST_Vtbl, &CLSID_Gstreamer_Splitter, (DWORD_PTR)(__FILE__ ": GSTImpl.csFilter"), &BaseFuncTable); (DWORD_PTR)(__FILE__ ": GSTImpl.csFilter"), &BaseFuncTable);
This->cStreams = 0; This->cStreams = 0;
This->ppPins = NULL; This->ppPins = NULL;
@ -1302,9 +1299,8 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr)
ZeroMemory(&This->pInputPin.pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); ZeroMemory(&This->pInputPin.pin.mtCurrent, sizeof(AM_MEDIA_TYPE));
*phr = S_OK; *phr = S_OK;
TRACE("returning %p\n", obj); TRACE("Created GStreamer demuxer %p.\n", This);
return &This->filter.IUnknown_inner;
return obj;
} }
static HRESULT WINAPI GST_Stop(IBaseFilter *iface) static HRESULT WINAPI GST_Stop(IBaseFilter *iface)

View File

@ -296,9 +296,8 @@ static const BaseFilterFuncTable BaseFuncTable = {
.filter_destroy = qt_splitter_destroy, .filter_destroy = qt_splitter_destroy,
}; };
IUnknown * CALLBACK QTSplitter_create(IUnknown *punkout, HRESULT *phr) IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr)
{ {
IUnknown *obj = NULL;
PIN_INFO *piInput; PIN_INFO *piInput;
QTSplitter *This; QTSplitter *This;
static const WCHAR wcsInputPinName[] = {'I','n','p','u','t',' ','P','i','n',0}; static const WCHAR wcsInputPinName[] = {'I','n','p','u','t',' ','P','i','n',0};
@ -308,7 +307,6 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *punkout, HRESULT *phr)
RegisterWineDataHandler(); RegisterWineDataHandler();
This = CoTaskMemAlloc(sizeof(*This)); This = CoTaskMemAlloc(sizeof(*This));
obj = (IUnknown*)This;
if (!This) if (!This)
{ {
*phr = E_OUTOFMEMORY; *phr = E_OUTOFMEMORY;
@ -316,7 +314,8 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *punkout, HRESULT *phr)
} }
ZeroMemory(This,sizeof(*This)); ZeroMemory(This,sizeof(*This));
BaseFilter_Init(&This->filter, &QT_Vtbl, &CLSID_QTSplitter, (DWORD_PTR)(__FILE__ ": QTSplitter.csFilter"), &BaseFuncTable); strmbase_filter_init(&This->filter, &QT_Vtbl, outer, &CLSID_QTSplitter,
(DWORD_PTR)(__FILE__ ": QTSplitter.csFilter"), &BaseFuncTable);
InitializeCriticalSection(&This->csReceive); InitializeCriticalSection(&This->csReceive);
This->csReceive.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": QTSplitter.csReceive"); This->csReceive.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": QTSplitter.csReceive");
@ -339,7 +338,7 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *punkout, HRESULT *phr)
SourceSeeking_Init(&This->sourceSeeking, &QT_Seeking_Vtbl, QTSplitter_ChangeStop, QTSplitter_ChangeStart, QTSplitter_ChangeRate, &This->filter.csFilter); SourceSeeking_Init(&This->sourceSeeking, &QT_Seeking_Vtbl, QTSplitter_ChangeStop, QTSplitter_ChangeStart, QTSplitter_ChangeRate, &This->filter.csFilter);
*phr = S_OK; *phr = S_OK;
return obj; return &This->filter.IUnknown_inner;
} }
static HRESULT WINAPI QT_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv) static HRESULT WINAPI QT_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv)

View File

@ -154,18 +154,20 @@ HRESULT WINAPI BaseInputPin_Destroy(BaseInputPin *This);
typedef struct BaseFilter typedef struct BaseFilter
{ {
IBaseFilter IBaseFilter_iface; IBaseFilter IBaseFilter_iface;
LONG refCount; IUnknown IUnknown_inner;
CRITICAL_SECTION csFilter; IUnknown *outer_unk;
LONG refcount;
CRITICAL_SECTION csFilter;
FILTER_STATE state; FILTER_STATE state;
REFERENCE_TIME rtStreamStart; REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock; IReferenceClock * pClock;
FILTER_INFO filterInfo; FILTER_INFO filterInfo;
CLSID clsid; CLSID clsid;
LONG pin_version; LONG pin_version;
const struct BaseFilterFuncTable* pFuncsTable; const struct BaseFilterFuncTable* pFuncsTable;
} BaseFilter; } BaseFilter;
typedef struct BaseFilterFuncTable typedef struct BaseFilterFuncTable
@ -190,7 +192,7 @@ HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVend
VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter* This); VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter* This);
void BaseFilter_Init(BaseFilter *filter, const IBaseFilterVtbl *vtbl, void strmbase_filter_init(BaseFilter *filter, const IBaseFilterVtbl *vtbl, IUnknown *outer,
const CLSID *clsid, DWORD_PTR debug_info, const BaseFilterFuncTable *func_table); const CLSID *clsid, DWORD_PTR debug_info, const BaseFilterFuncTable *func_table);
void strmbase_filter_cleanup(BaseFilter *filter); void strmbase_filter_cleanup(BaseFilter *filter);