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)
{
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);
@ -220,7 +220,7 @@ HRESULT evr_filter_create(IUnknown *outer_unk, void **ppv)
if (!object)
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);
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)
{
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);
if (!ref) {
strmbase_filter_cleanup(&This->filter);
@ -271,7 +271,7 @@ IUnknown* WINAPI QCAP_createAudioCaptureFilter(IUnknown *outer, HRESULT *phr)
else
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);
*phr = S_OK;

View File

@ -640,15 +640,13 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
AVICompressor *compressor;
HRESULT hres;
TRACE("\n");
compressor = heap_alloc_zero(sizeof(*compressor));
if(!compressor) {
*phr = E_NOINTERFACE;
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);
compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
@ -672,5 +670,5 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
}
*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;
}
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};
@ -2278,20 +2278,13 @@ IUnknown* WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr)
PIN_INFO info;
HRESULT hr;
TRACE("(%p)\n", pUnkOuter);
if(pUnkOuter) {
*phr = CLASS_E_NOAGGREGATION;
return NULL;
}
avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux));
if(!avimux) {
*phr = E_OUTOFMEMORY;
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);
avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl;
avimux->IConfigInterleaving_iface.lpVtbl = &ConfigInterleavingVtbl;
@ -2328,5 +2321,5 @@ IUnknown* WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr)
ObjectRefCount(TRUE);
*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)
{
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);
@ -600,7 +600,7 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
else
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);
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);
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);
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);
ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
IBaseFilter_Release(filter);
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);
}

View File

@ -135,8 +135,7 @@ static void test_aggregation(void)
hr = CoCreateInstance(&CLSID_AviDest, &test_outer, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
if (FAILED(hr)) return;
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
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)
{
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);
@ -219,7 +219,8 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr)
if (!pVfwCapture)
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->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)
{
NullRendererImpl *This = impl_from_IUnknown(iface);
ULONG refCount = InterlockedDecrement(&This->renderer.filter.refCount);
ULONG refCount = InterlockedDecrement(&This->renderer.filter.refcount);
if (!refCount)
{
@ -190,7 +190,7 @@ HRESULT NullRenderer_create(IUnknown *pUnkOuter, void **ppv)
else
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,
(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)
{
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);
@ -1267,7 +1267,7 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv)
}
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);
obj->IUnknown_inner.lpVtbl = &samplegrabber_vtbl;
obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable;

View File

@ -1424,18 +1424,13 @@ static const BaseFilterFuncTable avi_splitter_func_table =
.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};
HRESULT hr;
AVISplitterImpl * This;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
*out = NULL;
/* Note: This memory is managed by the transform filter once created */
This = CoTaskMemAlloc(sizeof(AVISplitterImpl));
@ -1443,7 +1438,7 @@ HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
This->streams = 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,
AVISplitter_InputPin_PreConnect, AVISplitter_Flush,
AVISplitter_Disconnect, AVISplitter_first_request,
@ -1452,7 +1447,7 @@ HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv)
if (FAILED(hr))
return hr;
*ppv = &This->Parser.filter.IBaseFilter_iface;
*out = &This->Parser.filter.IUnknown_inner;
return hr;
}

View File

@ -652,19 +652,14 @@ static const BaseRendererFuncTable BaseFuncTable = {
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};
HRESULT hr;
DSoundRenderImpl * pDSoundRender;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
*out = NULL;
pDSoundRender = CoTaskMemAlloc(sizeof(DSoundRenderImpl));
if (!pDSoundRender)
@ -672,8 +667,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl));
hr = strmbase_renderer_init(&pDSoundRender->renderer, &DSoundRender_Vtbl,
(IUnknown *)&pDSoundRender->renderer. filter.IBaseFilter_iface,
&CLSID_DSoundRender, sink_name,
outer, &CLSID_DSoundRender, sink_name,
(DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"), &BaseFuncTable);
BasicAudio_Init(&pDSoundRender->basicAudio,&IBasicAudio_Vtbl);
@ -712,7 +706,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
return HRESULT_FROM_WIN32(GetLastError());
}
*ppv = pDSoundRender;
*out = &pDSoundRender->renderer.filter.IUnknown_inner;
}
else
{

View File

@ -446,19 +446,17 @@ static const BaseFilterFuncTable BaseFuncTable =
.filter_query_interface = async_reader_query_interface,
};
HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv)
HRESULT AsyncReader_create(IUnknown *outer, void **out)
{
AsyncReader *pAsyncRead;
if( pUnkOuter )
return CLASS_E_NOAGGREGATION;
pAsyncRead = CoTaskMemAlloc(sizeof(AsyncReader));
if (!pAsyncRead)
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->pOutputPin = NULL;
@ -466,7 +464,7 @@ HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv)
pAsyncRead->pszFileName = NULL;
pAsyncRead->pmt = NULL;
*ppv = pAsyncRead;
*out = &pAsyncRead->filter.IUnknown_inner;
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,
};
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};
MPEGSplitterImpl *This;
HRESULT hr = E_FAIL;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
*out = NULL;
This = CoTaskMemAlloc(sizeof(MPEGSplitterImpl));
if (!This)
return E_OUTOFMEMORY;
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,
MPEGSplitter_pre_connect, MPEGSplitter_cleanup, MPEGSplitter_disconnect,
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->seek = TRUE;
/* Note: This memory is managed by the parser filter once created */
*ppv = &This->Parser.filter.IBaseFilter_iface;
*out = &This->Parser.filter.IUnknown_inner;
return hr;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -691,7 +691,7 @@ static ULONG WINAPI VideoRendererInner_AddRef(IUnknown *iface)
static ULONG WINAPI VideoRendererInner_Release(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);
@ -1002,7 +1002,7 @@ HRESULT VideoRenderer_create(IUnknown *pUnkOuter, void **ppv)
pVideoRenderer->outer_unk = &pVideoRenderer->IUnknown_inner;
hr = strmbase_renderer_init(&pVideoRenderer->renderer, &VideoRenderer_Vtbl,
pUnkOuter, &CLSID_VideoRenderer, sink_name,
NULL, &CLSID_VideoRenderer, sink_name,
(DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter"), &BaseFuncTable);
if (FAILED(hr))

View File

@ -831,7 +831,7 @@ static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
static ULONG WINAPI VMR9Inner_Release(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);
@ -2418,11 +2418,11 @@ static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid)
pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
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,
(DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable);
else
hr = strmbase_renderer_init(&pVMR->renderer, &VMR_Vtbl, outer_unk,
hr = strmbase_renderer_init(&pVMR->renderer, &VMR_Vtbl, NULL,
&CLSID_VideoMixingRenderer9, sink_name,
(DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);

View File

@ -425,23 +425,18 @@ static const BaseFilterFuncTable wave_parser_func_table =
.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};
HRESULT hr;
WAVEParserImpl * This;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
*out = NULL;
/* Note: This memory is managed by the transform filter once created */
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,
WAVEParser_InputPin_PreConnect, WAVEParser_Cleanup, WAVEParser_disconnect,
WAVEParser_first_request, NULL, NULL, WAVEParserImpl_seek, NULL);
@ -449,7 +444,7 @@ HRESULT WAVEParser_create(IUnknown * pUnkOuter, LPVOID * ppv)
if (FAILED(hr))
return hr;
*ppv = &This->Parser.filter.IBaseFilter_iface;
*out = &This->Parser.filter.IUnknown_inner;
return hr;
}

View File

@ -22,14 +22,14 @@
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;
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;
}
if (IsEqualIID(iid, &IID_IUnknown)
|| IsEqualIID(iid, &IID_IPersist)
if (IsEqualIID(iid, &IID_IUnknown))
*out = iface;
else if (IsEqualIID(iid, &IID_IPersist)
|| IsEqualIID(iid, &IID_IMediaFilter)
|| IsEqualIID(iid, &IID_IBaseFilter))
{
*out = iface;
IBaseFilter_AddRef(iface);
return S_OK;
*out = &filter->IBaseFilter_iface;
}
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));
return E_NOINTERFACE;
IUnknown_AddRef((IUnknown *)*out);
return S_OK;
}
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface)
static ULONG WINAPI filter_inner_AddRef(IUnknown *iface)
{
BaseFilter *This = impl_from_IBaseFilter(iface);
ULONG refCount = InterlockedIncrement(&This->refCount);
BaseFilter *filter = impl_from_IUnknown(iface);
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)
{
BaseFilter *This = impl_from_IBaseFilter(iface);
ULONG refCount = InterlockedDecrement(&This->refCount);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
if (!refCount)
This->pFuncsTable->filter_destroy(This);
return refCount;
BaseFilter *filter = impl_from_IBaseFilter(iface);
return IUnknown_Release(filter->outer_unk);
}
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
@ -222,21 +256,21 @@ VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter *filter)
InterlockedIncrement(&filter->pin_version);
}
void BaseFilter_Init(BaseFilter *This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid,
DWORD_PTR DebugInfo, const BaseFilterFuncTable *pBaseFuncsTable)
void strmbase_filter_init(BaseFilter *filter, const IBaseFilterVtbl *vtbl, IUnknown *outer,
const CLSID *clsid, DWORD_PTR debug_info, const BaseFilterFuncTable *func_table)
{
This->IBaseFilter_iface.lpVtbl = Vtbl;
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;
memset(filter, 0, sizeof(*filter));
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)

View File

@ -249,14 +249,14 @@ static const BaseInputPinFuncTable input_BaseInputFuncTable = {
};
HRESULT WINAPI strmbase_renderer_init(BaseRenderer *This, const IBaseFilterVtbl *Vtbl,
IUnknown *pUnkOuter, const CLSID *pClsid, const WCHAR *sink_name, DWORD_PTR DebugInfo,
HRESULT WINAPI strmbase_renderer_init(BaseRenderer *This, const IBaseFilterVtbl *vtbl,
IUnknown *outer, const CLSID *clsid, const WCHAR *sink_name, DWORD_PTR debug_info,
const BaseRendererFuncTable *pBaseFuncsTable)
{
PIN_INFO piInput;
HRESULT hr;
BaseFilter_Init(&This->filter, Vtbl, pClsid, DebugInfo, &RendererBaseFilterFuncTable);
strmbase_filter_init(&This->filter, vtbl, outer, clsid, debug_info, &RendererBaseFilterFuncTable);
This->pFuncsTable = pBaseFuncsTable;
@ -270,7 +270,7 @@ HRESULT WINAPI strmbase_renderer_init(BaseRenderer *This, const IBaseFilterVtbl
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);
if (FAILED(hr))
return hr;

View File

@ -288,7 +288,7 @@ static HRESULT strmbase_transform_init(const CLSID *clsid,
PIN_INFO piInput;
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);
InitializeCriticalSection(&filter->csReceive);

View File

@ -1257,14 +1257,11 @@ static const BaseFilterFuncTable BaseFuncTable = {
.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;
GSTImpl *This;
TRACE("%p %p\n", pUnkOuter, phr);
if (!init_gstreamer())
{
*phr = E_FAIL;
@ -1281,8 +1278,8 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr)
}
memset(This, 0, sizeof(*This));
obj = (IUnknown*)&This->filter.IBaseFilter_iface;
BaseFilter_Init(&This->filter, &GST_Vtbl, &CLSID_Gstreamer_Splitter, (DWORD_PTR)(__FILE__ ": GSTImpl.csFilter"), &BaseFuncTable);
strmbase_filter_init(&This->filter, &GST_Vtbl, outer, &CLSID_Gstreamer_Splitter,
(DWORD_PTR)(__FILE__ ": GSTImpl.csFilter"), &BaseFuncTable);
This->cStreams = 0;
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));
*phr = S_OK;
TRACE("returning %p\n", obj);
return obj;
TRACE("Created GStreamer demuxer %p.\n", This);
return &This->filter.IUnknown_inner;
}
static HRESULT WINAPI GST_Stop(IBaseFilter *iface)

View File

@ -296,9 +296,8 @@ static const BaseFilterFuncTable BaseFuncTable = {
.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;
QTSplitter *This;
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();
This = CoTaskMemAlloc(sizeof(*This));
obj = (IUnknown*)This;
if (!This)
{
*phr = E_OUTOFMEMORY;
@ -316,7 +314,8 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *punkout, HRESULT *phr)
}
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);
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);
*phr = S_OK;
return obj;
return &This->filter.IUnknown_inner;
}
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
{
IBaseFilter IBaseFilter_iface;
LONG refCount;
CRITICAL_SECTION csFilter;
IBaseFilter IBaseFilter_iface;
IUnknown IUnknown_inner;
IUnknown *outer_unk;
LONG refcount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
CLSID clsid;
LONG pin_version;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
CLSID clsid;
LONG pin_version;
const struct BaseFilterFuncTable* pFuncsTable;
const struct BaseFilterFuncTable* pFuncsTable;
} BaseFilter;
typedef struct BaseFilterFuncTable
@ -190,7 +192,7 @@ HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVend
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);
void strmbase_filter_cleanup(BaseFilter *filter);