Commit 1d42659c authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

strmbase: Implement BaseFilter in strmbase.

parent db27d9af
......@@ -59,17 +59,13 @@ static HRESULT VfwPin_Construct( IBaseFilter *, LPCRITICAL_SECTION, IPin ** );
typedef struct VfwCapture
{
const IBaseFilterVtbl * lpVtbl;
BaseFilter filter;
const IAMStreamConfigVtbl * IAMStreamConfig_vtbl;
const IAMVideoProcAmpVtbl * IAMVideoProcAmp_vtbl;
const IPersistPropertyBagVtbl * IPersistPropertyBag_vtbl;
BOOL init;
Capture *driver_info;
LONG refCount;
FILTER_INFO filterInfo;
FILTER_STATE state;
CRITICAL_SECTION csFilter;
IPin * pOutputPin;
} VfwCapture;
......@@ -101,19 +97,15 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr)
if (!pVfwCapture)
return NULL;
pVfwCapture->lpVtbl = &VfwCapture_Vtbl;
BaseFilter_Init(&pVfwCapture->filter, &VfwCapture_Vtbl, &CLSID_VfwCapture, (DWORD_PTR)(__FILE__ ": VfwCapture.csFilter"));
pVfwCapture->IAMStreamConfig_vtbl = &IAMStreamConfig_VTable;
pVfwCapture->IAMVideoProcAmp_vtbl = &IAMVideoProcAmp_VTable;
pVfwCapture->IPersistPropertyBag_vtbl = &IPersistPropertyBag_VTable;
pVfwCapture->refCount = 1;
pVfwCapture->filterInfo.achName[0] = '\0';
pVfwCapture->filterInfo.pGraph = NULL;
pVfwCapture->state = State_Stopped;
pVfwCapture->init = FALSE;
InitializeCriticalSection(&pVfwCapture->csFilter);
pVfwCapture->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": VfwCapture.csFilter");
hr = VfwPin_Construct((IBaseFilter *)&pVfwCapture->lpVtbl,
&pVfwCapture->csFilter, &pVfwCapture->pOutputPin);
hr = VfwPin_Construct((IBaseFilter *)&pVfwCapture->filter.lpVtbl,
&pVfwCapture->filter.csFilter, &pVfwCapture->pOutputPin);
if (FAILED(hr))
{
CoTaskMemFree(pVfwCapture);
......@@ -173,20 +165,10 @@ static HRESULT WINAPI VfwCapture_QueryInterface(IBaseFilter * iface, REFIID riid
return E_NOINTERFACE;
}
static ULONG WINAPI VfwCapture_AddRef(IBaseFilter * iface)
{
VfwCapture *This = (VfwCapture *)iface;
ULONG refCount = InterlockedIncrement(&This->refCount);
TRACE("%p->() New refcount: %d\n", This, refCount);
return refCount;
}
static ULONG WINAPI VfwCapture_Release(IBaseFilter * iface)
{
VfwCapture *This = (VfwCapture *)iface;
ULONG refCount = InterlockedDecrement(&This->refCount);
ULONG refCount = BaseFilterImpl_Release(iface);
TRACE("%p->() New refcount: %d\n", This, refCount);
......@@ -197,8 +179,8 @@ static ULONG WINAPI VfwCapture_Release(IBaseFilter * iface)
TRACE("destroying everything\n");
if (This->init)
{
if (This->state != State_Stopped)
qcap_driver_stop(This->driver_info, &This->state);
if (This->filter.state != State_Stopped)
qcap_driver_stop(This->driver_info, &This->filter.state);
qcap_driver_destroy(This->driver_info);
}
pin = (BasePin*) This->pOutputPin;
......@@ -208,24 +190,12 @@ static ULONG WINAPI VfwCapture_Release(IBaseFilter * iface)
IPin_Disconnect(This->pOutputPin);
}
IPin_Release(This->pOutputPin);
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
This->lpVtbl = NULL;
CoTaskMemFree(This);
ObjectRefCount(FALSE);
}
return refCount;
}
/** IPersist methods **/
static HRESULT WINAPI VfwCapture_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
TRACE("(%p)\n", pClsid);
*pClsid = CLSID_VfwCapture;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI VfwCapture_Stop(IBaseFilter * iface)
......@@ -233,7 +203,7 @@ static HRESULT WINAPI VfwCapture_Stop(IBaseFilter * iface)
VfwCapture *This = (VfwCapture *)iface;
TRACE("()\n");
return qcap_driver_stop(This->driver_info, &This->state);
return qcap_driver_stop(This->driver_info, &This->filter.state);
}
static HRESULT WINAPI VfwCapture_Pause(IBaseFilter * iface)
......@@ -241,42 +211,14 @@ static HRESULT WINAPI VfwCapture_Pause(IBaseFilter * iface)
VfwCapture *This = (VfwCapture *)iface;
TRACE("()\n");
return qcap_driver_pause(This->driver_info, &This->state);
return qcap_driver_pause(This->driver_info, &This->filter.state);
}
static HRESULT WINAPI VfwCapture_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
{
VfwCapture *This = (VfwCapture *)iface;
TRACE("(%x%08x)\n", (ULONG)(tStart >> 32), (ULONG)tStart);
return qcap_driver_run(This->driver_info, &This->state);
}
static HRESULT WINAPI
VfwCapture_GetState( IBaseFilter * iface, DWORD dwMilliSecsTimeout,
FILTER_STATE *pState )
{
VfwCapture *This = (VfwCapture *)iface;
TRACE("(%u, %p)\n", dwMilliSecsTimeout, pState);
*pState = This->state;
return S_OK;
}
static HRESULT WINAPI
VfwCapture_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
TRACE("(%p)\n", pClock);
return S_OK;
}
static HRESULT WINAPI
VfwCapture_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
TRACE("(%p)\n", ppClock);
return S_OK;
return qcap_driver_run(This->driver_info, &This->filter.state);
}
/** IBaseFilter methods **/
......@@ -316,60 +258,23 @@ static HRESULT WINAPI VfwCapture_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin *
return E_NOTIMPL;
}
static HRESULT WINAPI VfwCapture_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
VfwCapture *This = (VfwCapture *)iface;
TRACE("(%p)\n", pInfo);
lstrcpyW(pInfo->achName, This->filterInfo.achName);
pInfo->pGraph = This->filterInfo.pGraph;
if (pInfo->pGraph)
IFilterGraph_AddRef(pInfo->pGraph);
return S_OK;
}
static HRESULT WINAPI
VfwCapture_JoinFilterGraph( IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName )
{
VfwCapture *This = (VfwCapture *)iface;
TRACE("(%p, %s)\n", pGraph, debugstr_w(pName));
if (pName)
lstrcpyW(This->filterInfo.achName, pName);
else
*This->filterInfo.achName = 0;
This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
return S_OK;
}
static HRESULT WINAPI
VfwCapture_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
FIXME("(%p) - stub\n", pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl VfwCapture_Vtbl =
{
VfwCapture_QueryInterface,
VfwCapture_AddRef,
BaseFilterImpl_AddRef,
VfwCapture_Release,
VfwCapture_GetClassID,
BaseFilterImpl_GetClassID,
VfwCapture_Stop,
VfwCapture_Pause,
VfwCapture_Run,
VfwCapture_GetState,
VfwCapture_SetSyncSource,
VfwCapture_GetSyncSource,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
VfwCapture_EnumPins,
VfwCapture_FindPin,
VfwCapture_QueryFilterInfo,
VfwCapture_JoinFilterGraph,
VfwCapture_QueryVendorInfo
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
/* AMStreamConfig interface, we only need to implement {G,S}etFormat */
......@@ -417,7 +322,7 @@ AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt)
TRACE("(%p): %p->%p\n", iface, pmt, pmt ? pmt->pbFormat : NULL);
if (This->state != State_Stopped)
if (This->filter.state != State_Stopped)
{
TRACE("Returning not stopped error\n");
return VFW_E_NOT_STOPPED;
......@@ -441,9 +346,9 @@ AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt)
}
hr = qcap_driver_set_format(This->driver_info, pmt);
if (SUCCEEDED(hr) && This->filterInfo.pGraph && pin->pConnectedTo )
if (SUCCEEDED(hr) && This->filter.filterInfo.pGraph && pin->pConnectedTo )
{
hr = IFilterGraph_Reconnect(This->filterInfo.pGraph, This->pOutputPin);
hr = IFilterGraph_Reconnect(This->filter.filterInfo.pGraph, This->pOutputPin);
if (SUCCEEDED(hr))
TRACE("Reconnection completed, with new media format..\n");
}
......
......@@ -67,16 +67,16 @@ static HRESULT WINAPI ACMWrapper_ProcessSampleData(IPin *iface, IMediaSample *pS
HRESULT hr;
LONGLONG tStart = -1, tStop = -1, tMed;
EnterCriticalSection(&This->tf.csFilter);
if (This->tf.state == State_Stopped)
EnterCriticalSection(&This->tf.filter.csFilter);
if (This->tf.filter.state == State_Stopped)
{
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return VFW_E_WRONG_STATE;
}
if (pin->end_of_stream || pin->flushing)
{
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return S_FALSE;
}
......@@ -84,7 +84,7 @@ static HRESULT WINAPI ACMWrapper_ProcessSampleData(IPin *iface, IMediaSample *pS
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%x)\n", hr);
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return hr;
}
......@@ -112,7 +112,7 @@ static HRESULT WINAPI ACMWrapper_ProcessSampleData(IPin *iface, IMediaSample *pS
if (FAILED(hr))
{
ERR("Unable to retrieve media type\n");
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return hr;
}
......@@ -125,7 +125,7 @@ static HRESULT WINAPI ACMWrapper_ProcessSampleData(IPin *iface, IMediaSample *pS
if (FAILED(hr))
{
ERR("Unable to get delivery buffer (%x)\n", hr);
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return hr;
}
IMediaSample_SetPreroll(pOutSample, preroll);
......@@ -205,9 +205,9 @@ static HRESULT WINAPI ACMWrapper_ProcessSampleData(IPin *iface, IMediaSample *pS
}
TRACE("Sample stop time: %u.%03u\n", (DWORD)(tStart/10000000), (DWORD)((tStart/10000)%1000));
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample);
EnterCriticalSection(&This->tf.csFilter);
EnterCriticalSection(&This->tf.filter.csFilter);
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
if (FAILED(hr))
......@@ -231,7 +231,7 @@ error:
This->lasttime_real = tStop;
This->lasttime_sent = tMed;
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return hr;
}
......
......@@ -80,16 +80,16 @@ static HRESULT WINAPI AVIDec_ProcessSampleData(IPin *iface, IMediaSample *pSampl
LPBYTE pbSrcStream;
LONGLONG tStart, tStop;
EnterCriticalSection(&This->tf.csFilter);
if (This->tf.state == State_Stopped)
EnterCriticalSection(&This->tf.filter.csFilter);
if (This->tf.filter.state == State_Stopped)
{
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return VFW_E_WRONG_STATE;
}
if (pin->end_of_stream || pin->flushing)
{
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return S_FALSE;
}
......@@ -149,7 +149,7 @@ static HRESULT WINAPI AVIDec_ProcessSampleData(IPin *iface, IMediaSample *pSampl
else
IMediaSample_SetTime(pOutSample, NULL, NULL);
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample);
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED)
ERR("Error sending sample (%x)\n", hr);
......@@ -160,7 +160,7 @@ error:
if (pOutSample)
IMediaSample_Release(pOutSample);
LeaveCriticalSection(&This->tf.csFilter);
LeaveCriticalSection(&This->tf.filter.csFilter);
return hr;
}
......
......@@ -1239,7 +1239,7 @@ static ULONG WINAPI AVISplitter_Release(IBaseFilter *iface)
AVISplitterImpl *This = (AVISplitterImpl *)iface;
ULONG ref;
ref = InterlockedDecrement(&This->Parser.refCount);
ref = InterlockedDecrement(&This->Parser.filter.refCount);
TRACE("(%p)->() Release from %d\n", This, ref + 1);
......@@ -1275,7 +1275,7 @@ static HRESULT AVISplitter_seek(IBaseFilter *iface)
IPin_BeginFlush((IPin *)pPin);
/* Make sure this is done while stopped, BeginFlush takes care of this */
EnterCriticalSection(&This->Parser.csFilter);
EnterCriticalSection(&This->Parser.filter.csFilter);
for (x = 0; x < This->Parser.cStreams; ++x)
{
Parser_OutputPin *pin = (Parser_OutputPin *)This->Parser.ppPins[1+x];
......@@ -1377,7 +1377,7 @@ static HRESULT AVISplitter_seek(IBaseFilter *iface)
stream->preroll = preroll;
stream->seek = 1;
}
LeaveCriticalSection(&This->Parser.csFilter);
LeaveCriticalSection(&This->Parser.filter.csFilter);
TRACE("Done flushing\n");
IPin_EndFlush((IPin *)pPin);
......
......@@ -39,13 +39,9 @@ static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 };
typedef struct AsyncReader
{
const IBaseFilterVtbl * lpVtbl;
BaseFilter filter;
const IFileSourceFilterVtbl * lpVtblFSF;
LONG refCount;
FILTER_INFO filterInfo;
FILTER_STATE state;
CRITICAL_SECTION csFilter;
DWORD lastpinchange;
IPin * pOutputPin;
......@@ -346,17 +342,11 @@ HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv)
if (!pAsyncRead)
return E_OUTOFMEMORY;
pAsyncRead->lpVtbl = &AsyncReader_Vtbl;
BaseFilter_Init(&pAsyncRead->filter, &AsyncReader_Vtbl, &CLSID_AsyncReader, (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter"));
pAsyncRead->lpVtblFSF = &FileSource_Vtbl;
pAsyncRead->refCount = 1;
pAsyncRead->filterInfo.achName[0] = '\0';
pAsyncRead->filterInfo.pGraph = NULL;
pAsyncRead->pOutputPin = NULL;
pAsyncRead->lastpinchange = GetTickCount();
pAsyncRead->state = State_Stopped;
InitializeCriticalSection(&pAsyncRead->csFilter);
pAsyncRead->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter");
pAsyncRead->pszFileName = NULL;
pAsyncRead->pmt = NULL;
......@@ -402,20 +392,10 @@ static HRESULT WINAPI AsyncReader_QueryInterface(IBaseFilter * iface, REFIID rii
return E_NOINTERFACE;
}
static ULONG WINAPI AsyncReader_AddRef(IBaseFilter * iface)
{
AsyncReader *This = (AsyncReader *)iface;
ULONG refCount = InterlockedIncrement(&This->refCount);
TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
return refCount;
}
static ULONG WINAPI AsyncReader_Release(IBaseFilter * iface)
{
AsyncReader *This = (AsyncReader *)iface;
ULONG refCount = InterlockedDecrement(&This->refCount);
ULONG refCount = BaseFilterImpl_Release(iface);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
......@@ -432,9 +412,6 @@ static ULONG WINAPI AsyncReader_Release(IBaseFilter * iface)
IPin_Disconnect(This->pOutputPin);
IPin_Release(This->pOutputPin);
}
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
This->lpVtbl = NULL;
CoTaskMemFree(This->pszFileName);
if (This->pmt)
FreeMediaType(This->pmt);
......@@ -445,17 +422,6 @@ static ULONG WINAPI AsyncReader_Release(IBaseFilter * iface)
return refCount;
}
/** IPersist methods **/
static HRESULT WINAPI AsyncReader_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
TRACE("(%p)\n", pClsid);
*pClsid = CLSID_AsyncReader;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI AsyncReader_Stop(IBaseFilter * iface)
......@@ -464,7 +430,7 @@ static HRESULT WINAPI AsyncReader_Stop(IBaseFilter * iface)
TRACE("()\n");
This->state = State_Stopped;
This->filter.state = State_Stopped;
return S_OK;
}
......@@ -475,7 +441,7 @@ static HRESULT WINAPI AsyncReader_Pause(IBaseFilter * iface)
TRACE("()\n");
This->state = State_Paused;
This->filter.state = State_Paused;
return S_OK;
}
......@@ -486,36 +452,7 @@ static HRESULT WINAPI AsyncReader_Run(IBaseFilter * iface, REFERENCE_TIME tStart
TRACE("(%x%08x)\n", (ULONG)(tStart >> 32), (ULONG)tStart);
This->state = State_Running;
return S_OK;
}
static HRESULT WINAPI AsyncReader_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
AsyncReader *This = (AsyncReader *)iface;
TRACE("(%u, %p)\n", dwMilliSecsTimeout, pState);
*pState = This->state;
return S_OK;
}
static HRESULT WINAPI AsyncReader_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
/* AsyncReader *This = (AsyncReader *)iface;*/
TRACE("(%p)\n", pClock);
return S_OK;
}
static HRESULT WINAPI AsyncReader_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
/* AsyncReader *This = (AsyncReader *)iface;*/
TRACE("(%p)\n", ppClock);
This->filter.state = State_Running;
return S_OK;
}
......@@ -567,81 +504,44 @@ static HRESULT WINAPI AsyncReader_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin
return E_NOTIMPL;
}
static HRESULT WINAPI AsyncReader_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
AsyncReader *This = (AsyncReader *)iface;
TRACE("(%p)\n", pInfo);
strcpyW(pInfo->achName, This->filterInfo.achName);
pInfo->pGraph = This->filterInfo.pGraph;
if (pInfo->pGraph)
IFilterGraph_AddRef(pInfo->pGraph);
return S_OK;
}
static HRESULT WINAPI AsyncReader_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
AsyncReader *This = (AsyncReader *)iface;
TRACE("(%p, %s)\n", pGraph, debugstr_w(pName));
if (pName)
strcpyW(This->filterInfo.achName, pName);
else
*This->filterInfo.achName = 0;
This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
return S_OK;
}
static HRESULT WINAPI AsyncReader_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
FIXME("(%p)\n", pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl AsyncReader_Vtbl =
{
AsyncReader_QueryInterface,
AsyncReader_AddRef,
BaseFilterImpl_AddRef,
AsyncReader_Release,
AsyncReader_GetClassID,
BaseFilterImpl_GetClassID,
AsyncReader_Stop,
AsyncReader_Pause,
AsyncReader_Run,
AsyncReader_GetState,
AsyncReader_SetSyncSource,
AsyncReader_GetSyncSource,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
AsyncReader_EnumPins,
AsyncReader_FindPin,
AsyncReader_QueryFilterInfo,
AsyncReader_JoinFilterGraph,
AsyncReader_QueryVendorInfo
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
static HRESULT WINAPI FileSource_QueryInterface(IFileSourceFilter * iface, REFIID riid, LPVOID * ppv)
{
AsyncReader *This = impl_from_IFileSourceFilter(iface);
return IBaseFilter_QueryInterface((IFileSourceFilter*)&This->lpVtbl, riid, ppv);
return IBaseFilter_QueryInterface((IFileSourceFilter*)&This->filter.lpVtbl, riid, ppv);
}
static ULONG WINAPI FileSource_AddRef(IFileSourceFilter * iface)
{
AsyncReader *This = impl_from_IFileSourceFilter(iface);
return IBaseFilter_AddRef((IFileSourceFilter*)&This->lpVtbl);
return IBaseFilter_AddRef((IFileSourceFilter*)&This->filter.lpVtbl);
}
static ULONG WINAPI FileSource_Release(IFileSourceFilter * iface)
{
AsyncReader *This = impl_from_IFileSourceFilter(iface);
return IBaseFilter_Release((IFileSourceFilter*)&This->lpVtbl);
return IBaseFilter_Release((IFileSourceFilter*)&This->filter.lpVtbl);
}
static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFileName, const AM_MEDIA_TYPE * pmt)
......@@ -663,7 +563,7 @@ static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFi
}
/* create pin */
hr = FileAsyncReader_Construct(hFile, (IBaseFilter *)&This->lpVtbl, &This->csFilter, &This->pOutputPin);
hr = FileAsyncReader_Construct(hFile, (IBaseFilter *)&This->filter.lpVtbl, &This->filter.csFilter, &This->pOutputPin);
This->lastpinchange = GetTickCount();
if (SUCCEEDED(hr))
......
......@@ -675,7 +675,7 @@ static HRESULT MPEGSplitter_seek(IBaseFilter *iface)
IPin_BeginFlush((IPin *)pin);
/* Make sure this is done while stopped, BeginFlush takes care of this */
EnterCriticalSection(&This->Parser.csFilter);
EnterCriticalSection(&This->Parser.filter.csFilter);
memcpy(This->header, header, 4);
IPin_ConnectedTo(This->Parser.ppPins[1], &victim);
if (victim)
......@@ -688,7 +688,7 @@ static HRESULT MPEGSplitter_seek(IBaseFilter *iface)
pin->rtStop = MEDIATIME_FROM_BYTES((REFERENCE_TIME)This->EndOfFile);
This->seek = TRUE;
This->position = newpos;
LeaveCriticalSection(&This->Parser.csFilter);
LeaveCriticalSection(&This->Parser.filter.csFilter);
TRACE("Done flushing\n");
IPin_EndFlush((IPin *)pin);
......
......@@ -28,17 +28,10 @@ typedef HRESULT (*PFN_DISCONNECT) (LPVOID iface);
struct ParserImpl
{
const IBaseFilterVtbl *lpVtbl;
BaseFilter filter;
LONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
PFN_CLEANUP fnCleanup;
PFN_DISCONNECT fnDisconnect;
FILTER_INFO filterInfo;
CLSID clsid;
PullPin * pInputPin;
IPin ** ppPins;
......
......@@ -37,17 +37,9 @@ typedef struct TransformFuncsTable {
struct TransformFilterImpl
{
const IBaseFilterVtbl * lpVtbl;
BaseFilter filter;
IUnknown *seekthru_unk;
LONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
CLSID clsid;
IPin **ppPins;
ULONG npins;
AM_MEDIA_TYPE pmt;
......
......@@ -214,7 +214,7 @@ static HRESULT WAVEParserImpl_seek(IBaseFilter *iface)
IPin_BeginFlush((IPin *)pPin);
/* Make sure this is done while stopped, BeginFlush takes care of this */
EnterCriticalSection(&This->Parser.csFilter);
EnterCriticalSection(&This->Parser.filter.csFilter);
IPin_ConnectedTo(This->Parser.ppPins[1], &victim);
if (victim)
{
......@@ -224,7 +224,7 @@ static HRESULT WAVEParserImpl_seek(IBaseFilter *iface)
pPin->rtStart = pPin->rtCurrent = bytepos;
((Parser_OutputPin *)This->Parser.ppPins[1])->dwSamplesProcessed = 0;
LeaveCriticalSection(&This->Parser.csFilter);
LeaveCriticalSection(&This->Parser.filter.csFilter);
TRACE("Done flushing\n");
IPin_EndFlush((IPin *)pPin);
......
......@@ -2,6 +2,7 @@ MODULE = strmbase
C_SRCS = \
enumpins.c \
filter.c \
mediatype.c \
pin.c
......
/*
* Generic Implementation of IBaseFilter Interface
*
* Copyright 2010 Aric Stewart, CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "dshow.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/strmbase.h"
#include "uuids.h"
#include <assert.h>
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
BaseFilter *This = (BaseFilter *)iface;
TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown))
*ppv = This;
else if (IsEqualIID(riid, &IID_IPersist))
*ppv = This;
else if (IsEqualIID(riid, &IID_IMediaFilter))
*ppv = This;
else if (IsEqualIID(riid, &IID_IBaseFilter))
*ppv = This;
if (*ppv)
{
IUnknown_AddRef((IUnknown *)(*ppv));
return S_OK;
}
return E_NOINTERFACE;
}
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface)
{
BaseFilter *This = (BaseFilter*)iface;
ULONG refCount = InterlockedIncrement(&This->refCount);
TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
return refCount;
}
ULONG WINAPI BaseFilterImpl_Release(IBaseFilter * iface)
{
BaseFilter *This = (BaseFilter *)iface;
ULONG refCount = InterlockedDecrement(&This->refCount);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
if (!refCount)
{
if (This->pClock)
IReferenceClock_Release(This->pClock);
This->lpVtbl = NULL;
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
}
return refCount;
}
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
BaseFilter *This = (BaseFilter*)iface;
TRACE("(%p)->(%p)\n", This, pClsid);
*pClsid = This->clsid;
return S_OK;
}
HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState )
{
BaseFilter *This = (BaseFilter*)iface;
TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState);
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
BaseFilter *This = (BaseFilter*)iface;
TRACE("(%p)->(%p)\n", This, pClock);
EnterCriticalSection(&This->csFilter);
{
if (This->pClock)
IReferenceClock_Release(This->pClock);
This->pClock = pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
BaseFilter *This = (BaseFilter*)iface;
TRACE("(%p)->(%p)\n", This, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
BaseFilter *This = (BaseFilter*)iface;
TRACE("(%p)->(%p)\n", This, pInfo);
strcpyW(pInfo->achName, This->filterInfo.achName);
pInfo->pGraph = This->filterInfo.pGraph;
if (pInfo->pGraph)
IFilterGraph_AddRef(pInfo->pGraph);
return S_OK;
}
HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName )
{
HRESULT hr = S_OK;
BaseFilter *This = (BaseFilter*)iface;
TRACE("(%p)->(%p, %s)\n", This, pGraph, debugstr_w(pName));
EnterCriticalSection(&This->csFilter);
{
if (pName)
strcpyW(This->filterInfo.achName, pName);
else
*This->filterInfo.achName = '\0';
This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
}
LeaveCriticalSection(&This->csFilter);
return hr;
}
HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
TRACE("(%p)->(%p)\n", iface, pVendorInfo);
return E_NOTIMPL;
}
HRESULT WINAPI BaseFilter_Init(BaseFilter * This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo)
{
This->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;
return S_OK;
}
......@@ -124,3 +124,29 @@ HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin * iface);
HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
HRESULT BaseInputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, BasePin_CheckMediaType pQueryAccept, BaseInputPin_Receive pSampleProc, LPCRITICAL_SECTION pCritSec, IMemAllocator *, IPin ** ppPin);
typedef struct BaseFilter
{
const struct IBaseFilterVtbl *lpVtbl;
LONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
CLSID clsid;
} BaseFilter;
HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv);
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface);
ULONG WINAPI BaseFilterImpl_Release(IBaseFilter * iface);
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid);
HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState );
HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock);
HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock);
HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo);
HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName );
HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo);
HRESULT WINAPI BaseFilter_Init(BaseFilter * This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment