strmbase: Implement BaseFilter in strmbase.

This commit is contained in:
Aric Stewart 2010-10-07 14:47:33 -05:00 committed by Alexandre Julliard
parent db27d9afa9
commit 1d42659c40
17 changed files with 516 additions and 1047 deletions

View file

@ -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");
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -50,18 +50,14 @@ static const IAMDirectSoundVtbl IAMDirectSound_Vtbl;
typedef struct DSoundRenderImpl
{
const IBaseFilterVtbl * lpVtbl;
BaseFilter filter;
const IBasicAudioVtbl *IBasicAudio_vtbl;
const IReferenceClockVtbl *IReferenceClock_vtbl;
const IAMDirectSoundVtbl *IAMDirectSound_vtbl;
IUnknown *seekthru_unk;
LONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart, rtLastStop;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
REFERENCE_TIME rtLastStop;
BaseInputPin * pInputPin;
@ -87,13 +83,13 @@ static inline HRESULT DSoundRender_GetPos(DSoundRenderImpl *This, DWORD *pPlayPo
{
HRESULT hr;
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
DWORD state;
DWORD write_pos;
hr = IDirectSoundBuffer_GetStatus(This->dsbuffer, &state);
if (SUCCEEDED(hr) && !(state & DSBSTATUS_PLAYING) && This->state == State_Running)
if (SUCCEEDED(hr) && !(state & DSBSTATUS_PLAYING) && This->filter.state == State_Running)
{
TRACE("Not playing, kickstarting the engine\n");
@ -136,7 +132,7 @@ static inline HRESULT DSoundRender_GetPos(DSoundRenderImpl *This, DWORD *pPlayPo
}
}
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -169,15 +165,15 @@ static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *d
{
DWORD ret;
This->in_loop = 1;
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
ret = WaitForSingleObject(This->blocked, 50);
if (ret != WAIT_TIMEOUT)
ERR("%x\n", ret);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
This->in_loop = 0;
if (This->pInputPin->flushing)
return VFW_E_WRONG_STATE;
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
return VFW_E_WRONG_STATE;
continue;
}
@ -206,7 +202,7 @@ static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *d
This->write_pos -= This->buf_size;
This->write_loops++;
}
} while (size && This->state == State_Running);
} while (size && This->filter.state == State_Running);
return hr;
}
@ -227,17 +223,17 @@ static HRESULT WINAPI DSoundRender_Receive(IPin *iface, IMediaSample * pSample)
* pause completion here, but for sound playing a single frame doesn't make sense
*/
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
if (This->pInputPin->end_of_stream || This->pInputPin->flushing)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_FALSE;
}
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return VFW_E_WRONG_STATE;
}
@ -259,7 +255,7 @@ static HRESULT WINAPI DSoundRender_Receive(IPin *iface, IMediaSample * pSample)
newfmt->nSamplesPerSec);
if (FAILED(hr))
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return VFW_E_TYPE_NOT_ACCEPTED;
}
FreeMediaType(orig);
@ -269,7 +265,7 @@ static HRESULT WINAPI DSoundRender_Receive(IPin *iface, IMediaSample * pSample)
}
else
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return VFW_E_TYPE_NOT_ACCEPTED;
}
}
@ -278,7 +274,7 @@ static HRESULT WINAPI DSoundRender_Receive(IPin *iface, IMediaSample * pSample)
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%x)\n", hr);
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -297,27 +293,27 @@ static HRESULT WINAPI DSoundRender_Receive(IPin *iface, IMediaSample * pSample)
if (IMediaSample_IsPreroll(pSample) == S_OK)
{
TRACE("Preroll!\n");
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
if (This->state == State_Paused)
if (This->filter.state == State_Paused)
{
SetEvent(This->state_change);
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
WaitForSingleObject(This->blocked, INFINITE);
EnterCriticalSection(&This->csFilter);
if (This->state == State_Stopped)
EnterCriticalSection(&This->filter.csFilter);
if (This->filter.state == State_Stopped)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return VFW_E_WRONG_STATE;
}
if (This->state == State_Paused)
if (This->filter.state == State_Paused)
{
/* Assuming we return because of flushing */
TRACE("Flushing\n");
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
SetEvent(This->state_change);
@ -341,7 +337,7 @@ static HRESULT WINAPI DSoundRender_Receive(IPin *iface, IMediaSample * pSample)
hr = DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream);
SetEvent(This->state_change);
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -385,20 +381,17 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
return E_OUTOFMEMORY;
ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl));
pDSoundRender->lpVtbl = &DSoundRender_Vtbl;
BaseFilter_Init(&pDSoundRender->filter, &DSoundRender_Vtbl, &CLSID_DSoundRender, (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"));
pDSoundRender->IBasicAudio_vtbl = &IBasicAudio_Vtbl;
pDSoundRender->IReferenceClock_vtbl = &IReferenceClock_Vtbl;
pDSoundRender->IAMDirectSound_vtbl = &IAMDirectSound_Vtbl;
pDSoundRender->refCount = 1;
InitializeCriticalSection(&pDSoundRender->csFilter);
pDSoundRender->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter");
pDSoundRender->state = State_Stopped;
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pDSoundRender;
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = BaseInputPin_Construct(&DSoundRender_InputPin_Vtbl, &piInput, DSoundRender_CheckMediaType, DSoundRender_Receive, &pDSoundRender->csFilter, NULL, (IPin **)&pDSoundRender->pInputPin);
hr = BaseInputPin_Construct(&DSoundRender_InputPin_Vtbl, &piInput, DSoundRender_CheckMediaType, DSoundRender_Receive, &pDSoundRender->filter.csFilter, NULL, (IPin **)&pDSoundRender->pInputPin);
if (SUCCEEDED(hr))
{
@ -430,8 +423,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
if (pDSoundRender->pInputPin)
IPin_Release((IPin*)pDSoundRender->pInputPin);
pDSoundRender->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pDSoundRender->csFilter);
BaseFilterImpl_Release((IBaseFilter*)pDSoundRender);
CoTaskMemFree(pDSoundRender);
}
@ -474,20 +466,10 @@ static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter * iface, REFIID ri
return E_NOINTERFACE;
}
static ULONG WINAPI DSoundRender_AddRef(IBaseFilter * iface)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->refCount);
TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
return refCount;
}
static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->refCount);
ULONG refCount = BaseFilterImpl_Release(iface);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
@ -495,9 +477,6 @@ static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface)
{
IPin *pConnectedTo;
if (This->pClock)
IReferenceClock_Release(This->pClock);
if (This->dsbuffer)
IDirectSoundBuffer_Release(This->dsbuffer);
This->dsbuffer = NULL;
@ -514,12 +493,9 @@ static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface)
IPin_Release((IPin *)This->pInputPin);
This->lpVtbl = NULL;
This->IBasicAudio_vtbl = NULL;
if (This->seekthru_unk)
IUnknown_Release(This->seekthru_unk);
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
CloseHandle(This->state_change);
CloseHandle(This->blocked);
@ -533,18 +509,6 @@ static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface)
return refCount;
}
/** IPersist methods **/
static HRESULT WINAPI DSoundRender_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
*pClsid = CLSID_DSoundRender;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI DSoundRender_Stop(IBaseFilter * iface)
@ -554,7 +518,7 @@ static HRESULT WINAPI DSoundRender_Stop(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
DWORD state = 0;
if (This->dsbuffer)
@ -567,14 +531,14 @@ static HRESULT WINAPI DSoundRender_Stop(IBaseFilter * iface)
}
}
if (SUCCEEDED(hr))
This->state = State_Stopped;
This->filter.state = State_Stopped;
/* Complete our transition */
SetEvent(This->state_change);
SetEvent(This->blocked);
MediaSeekingPassThru_ResetMediaTime(This->seekthru_unk);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -586,11 +550,11 @@ static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
if (This->state != State_Paused)
EnterCriticalSection(&This->filter.csFilter);
if (This->filter.state != State_Paused)
{
DWORD state = 0;
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
This->pInputPin->end_of_stream = 0;
}
@ -605,12 +569,12 @@ static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface)
}
}
if (SUCCEEDED(hr))
This->state = State_Paused;
This->filter.state = State_Paused;
ResetEvent(This->blocked);
ResetEvent(This->state_change);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -622,24 +586,24 @@ static HRESULT WINAPI DSoundRender_Run(IBaseFilter * iface, REFERENCE_TIME tStar
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
This->rtStreamStart = tStart;
if (This->state == State_Paused)
This->filter.rtStreamStart = tStart;
if (This->filter.state == State_Paused)
{
/* Unblock our thread, state changing from paused to running doesn't need a reset for state change */
SetEvent(This->blocked);
}
else if (This->state == State_Stopped)
else if (This->filter.state == State_Stopped)
{
ResetEvent(This->state_change);
This->pInputPin->end_of_stream = 0;
}
ResetEvent(This->blocked);
This->state = State_Running;
This->filter.state = State_Running;
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -656,51 +620,11 @@ static HRESULT WINAPI DSoundRender_GetState(IBaseFilter * iface, DWORD dwMilliSe
else
hr = S_OK;
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
BaseFilterImpl_GetState(iface, dwMilliSecsTimeout, pState);
return hr;
}
static HRESULT WINAPI DSoundRender_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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;
}
static HRESULT WINAPI DSoundRender_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
/** IBaseFilter implementation **/
static IPin* WINAPI DSoundRender_GetPin(IBaseFilter *iface, int pos)
@ -748,64 +672,23 @@ static HRESULT WINAPI DSoundRender_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin
return E_NOTIMPL;
}
static HRESULT WINAPI DSoundRender_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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 DSoundRender_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->(%p, %s)\n", This, iface, 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 S_OK;
}
static HRESULT WINAPI DSoundRender_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl DSoundRender_Vtbl =
{
DSoundRender_QueryInterface,
DSoundRender_AddRef,
BaseFilterImpl_AddRef,
DSoundRender_Release,
DSoundRender_GetClassID,
BaseFilterImpl_GetClassID,
DSoundRender_Stop,
DSoundRender_Pause,
DSoundRender_Run,
DSoundRender_GetState,
DSoundRender_SetSyncSource,
DSoundRender_GetSyncSource,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
DSoundRender_EnumPins,
DSoundRender_FindPin,
DSoundRender_QueryFilterInfo,
DSoundRender_JoinFilterGraph,
DSoundRender_QueryVendorInfo
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
@ -931,7 +814,7 @@ static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
return hr;
}
hr = IFilterGraph_QueryInterface(me->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
hr = IFilterGraph_QueryInterface(me->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
if (SUCCEEDED(hr))
{
BYTE * silence;
@ -984,7 +867,7 @@ static HRESULT WINAPI DSoundRender_InputPin_EndFlush(IPin * iface)
WaitForSingleObject(pFilter->state_change, -1);
EnterCriticalSection(This->pin.pCritSec);
}
if (pFilter->state != State_Stopped)
if (pFilter->filter.state != State_Stopped)
ResetEvent(pFilter->blocked);
if (pFilter->dsbuffer)
@ -1048,7 +931,7 @@ static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) {
TRACE("(%p/%p)->()\n", This, iface);
return DSoundRender_AddRef((IBaseFilter*)This);
return BaseFilterImpl_AddRef((IBaseFilter*)This);
}
static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) {
@ -1206,7 +1089,7 @@ static ULONG WINAPI ReferenceClock_AddRef(IReferenceClock *iface)
TRACE("(%p/%p)->()\n", This, iface);
return DSoundRender_AddRef((IBaseFilter*)This);
return BaseFilterImpl_AddRef((IBaseFilter*)This);
}
static ULONG WINAPI ReferenceClock_Release(IReferenceClock *iface)
@ -1301,7 +1184,7 @@ static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface)
TRACE("(%p/%p)->()\n", This, iface);
return DSoundRender_AddRef((IBaseFilter*)This);
return BaseFilterImpl_AddRef((IBaseFilter*)This);
}
static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface)

View file

@ -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))

View file

@ -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);

View file

@ -51,17 +51,10 @@ static const IPinVtbl NullRenderer_InputPin_Vtbl;
typedef struct NullRendererImpl
{
const IBaseFilterVtbl * lpVtbl;
BaseFilter filter;
const IUnknownVtbl * IInner_vtbl;
IUnknown *seekthru_unk;
LONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
BaseInputPin *pInputPin;
IUnknown * pUnkOuter;
BOOL bUnkOuterValid;
@ -79,10 +72,10 @@ static HRESULT WINAPI NullRenderer_Receive(IPin *iface, IMediaSample * pSample)
if (SUCCEEDED(IMediaSample_GetTime(pSample, &start, &stop)))
MediaSeekingPassThru_RegisterMediaTime(This->seekthru_unk, start);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
if (This->pInputPin->flushing || This->pInputPin->end_of_stream)
hr = S_FALSE;
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -109,20 +102,14 @@ HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
pNullRenderer->bAggregatable = FALSE;
pNullRenderer->IInner_vtbl = &IInner_VTable;
pNullRenderer->lpVtbl = &NullRenderer_Vtbl;
pNullRenderer->refCount = 1;
InitializeCriticalSection(&pNullRenderer->csFilter);
pNullRenderer->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter");
pNullRenderer->state = State_Stopped;
pNullRenderer->pClock = NULL;
ZeroMemory(&pNullRenderer->filterInfo, sizeof(FILTER_INFO));
BaseFilter_Init(&pNullRenderer->filter, &NullRenderer_Vtbl, &CLSID_NullRenderer, (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"));
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pNullRenderer;
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = BaseInputPin_Construct(&NullRenderer_InputPin_Vtbl, &piInput, NullRenderer_CheckMediaType, NullRenderer_Receive, &pNullRenderer->csFilter, NULL, (IPin **)&pNullRenderer->pInputPin);
hr = BaseInputPin_Construct(&NullRenderer_InputPin_Vtbl, &piInput, NullRenderer_CheckMediaType, NullRenderer_Receive, &pNullRenderer->filter.csFilter, NULL, (IPin **)&pNullRenderer->pInputPin);
if (SUCCEEDED(hr))
{
@ -139,8 +126,7 @@ HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
}
else
{
pNullRenderer->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pNullRenderer->csFilter);
BaseFilterImpl_Release((IBaseFilter*)pNullRenderer);
CoTaskMemFree(pNullRenderer);
}
@ -183,7 +169,7 @@ static HRESULT WINAPI NullRendererInner_QueryInterface(IUnknown * iface, REFIID
static ULONG WINAPI NullRendererInner_AddRef(IUnknown * iface)
{
ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface);
ULONG refCount = InterlockedIncrement(&This->refCount);
ULONG refCount = InterlockedIncrement(&This->filter.refCount);
TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
@ -193,7 +179,7 @@ static ULONG WINAPI NullRendererInner_AddRef(IUnknown * iface)
static ULONG WINAPI NullRendererInner_Release(IUnknown * iface)
{
ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface);
ULONG refCount = InterlockedDecrement(&This->refCount);
ULONG refCount = InterlockedDecrement(&This->filter.refCount);
TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
@ -201,9 +187,6 @@ static ULONG WINAPI NullRendererInner_Release(IUnknown * iface)
{
IPin *pConnectedTo;
if (This->pClock)
IReferenceClock_Release(This->pClock);
if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo)))
{
IPin_Disconnect(pConnectedTo);
@ -212,12 +195,12 @@ static ULONG WINAPI NullRendererInner_Release(IUnknown * iface)
IPin_Disconnect((IPin *)This->pInputPin);
IPin_Release((IPin *)This->pInputPin);
This->lpVtbl = NULL;
This->filter.lpVtbl = NULL;
if (This->seekthru_unk)
IUnknown_Release(This->seekthru_unk);
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
This->filter.csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->filter.csFilter);
TRACE("Destroying Null Renderer\n");
CoTaskMemFree(This);
@ -282,19 +265,6 @@ static ULONG WINAPI NullRenderer_Release(IBaseFilter * iface)
return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
}
/** IPersist methods **/
static HRESULT WINAPI NullRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
*pClsid = CLSID_NullRenderer;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI NullRenderer_Stop(IBaseFilter * iface)
@ -303,12 +273,12 @@ static HRESULT WINAPI NullRenderer_Stop(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
This->state = State_Stopped;
This->filter.state = State_Stopped;
MediaSeekingPassThru_ResetMediaTime(This->seekthru_unk);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -319,13 +289,13 @@ static HRESULT WINAPI NullRenderer_Pause(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
This->pInputPin->end_of_stream = 0;
This->state = State_Paused;
This->filter.state = State_Paused;
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -336,64 +306,13 @@ static HRESULT WINAPI NullRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStar
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
This->rtStreamStart = tStart;
This->state = State_Running;
This->filter.rtStreamStart = tStart;
This->filter.state = State_Running;
This->pInputPin->end_of_stream = 0;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI NullRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState);
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI NullRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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;
}
static HRESULT WINAPI NullRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -450,64 +369,23 @@ static HRESULT WINAPI NullRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin
return VFW_E_NOT_FOUND;
}
static HRESULT WINAPI NullRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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 NullRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%p, %s)\n", This, iface, 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 S_OK;
}
static HRESULT WINAPI NullRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl NullRenderer_Vtbl =
{
NullRenderer_QueryInterface,
NullRenderer_AddRef,
NullRenderer_Release,
NullRenderer_GetClassID,
BaseFilterImpl_GetClassID,
NullRenderer_Stop,
NullRenderer_Pause,
NullRenderer_Run,
NullRenderer_GetState,
NullRenderer_SetSyncSource,
NullRenderer_GetSyncSource,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
NullRenderer_EnumPins,
NullRenderer_FindPin,
NullRenderer_QueryFilterInfo,
NullRenderer_JoinFilterGraph,
NullRenderer_QueryVendorInfo
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface)
@ -522,10 +400,10 @@ static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface)
BaseInputPinImpl_EndOfStream(iface);
pNull = (NullRendererImpl*)This->pin.pinInfo.pFilter;
graph = pNull->filterInfo.pGraph;
graph = pNull->filter.filterInfo.pGraph;
if (graph)
{
hr = IFilterGraph_QueryInterface(((NullRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
hr = IFilterGraph_QueryInterface(((NullRendererImpl*)This->pin.pinInfo.pFilter)->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
if (SUCCEEDED(hr))
{
hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0);

View file

@ -57,15 +57,9 @@ HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, c
PIN_INFO piInput;
/* pTransformFilter is already allocated */
pParser->clsid = *pClsid;
pParser->lpVtbl = Parser_Vtbl;
pParser->refCount = 1;
InitializeCriticalSection(&pParser->csFilter);
pParser->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ParserImpl.csFilter");
pParser->state = State_Stopped;
pParser->pClock = NULL;
BaseFilter_Init(&pParser->filter, Parser_Vtbl, pClsid, (DWORD_PTR)(__FILE__ ": ParserImpl.csFilter"));
pParser->fnDisconnect = fnDisconnect;
ZeroMemory(&pParser->filterInfo, sizeof(FILTER_INFO));
pParser->lastpinchange = GetTickCount();
pParser->cStreams = 0;
@ -85,10 +79,10 @@ HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, c
if (!rate)
rate = Parser_ChangeRate;
MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->csFilter);
MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->filter.csFilter);
pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, fnRequest, fnDone, &pParser->csFilter, (IPin **)&pParser->pInputPin);
hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, fnRequest, fnDone, &pParser->filter.csFilter, (IPin **)&pParser->pInputPin);
if (SUCCEEDED(hr))
{
@ -98,8 +92,7 @@ HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, c
else
{
CoTaskMemFree(pParser->ppPins);
pParser->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pParser->csFilter);
BaseFilterImpl_Release((IBaseFilter*)pParser);
CoTaskMemFree(pParser);
}
@ -133,12 +126,7 @@ HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID *
ULONG WINAPI Parser_AddRef(IBaseFilter * iface)
{
ParserImpl *This = (ParserImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->refCount);
TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
return refCount;
return BaseFilterImpl_AddRef(iface);
}
void Parser_Destroy(ParserImpl *This)
@ -146,12 +134,9 @@ void Parser_Destroy(ParserImpl *This)
IPin *connected = NULL;
ULONG pinref;
assert(!This->refCount);
assert(!This->filter.refCount);
PullPin_WaitForStateChange(This->pInputPin, INFINITE);
if (This->pClock)
IReferenceClock_Release(This->pClock);
/* Don't need to clean up output pins, freeing input pin will do that */
IPin_ConnectedTo((IPin *)This->pInputPin, &connected);
if (connected)
@ -172,10 +157,6 @@ void Parser_Destroy(ParserImpl *This)
}
CoTaskMemFree(This->ppPins);
This->lpVtbl = NULL;
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
TRACE("Destroying parser\n");
CoTaskMemFree(This);
@ -184,7 +165,7 @@ void Parser_Destroy(ParserImpl *This)
ULONG WINAPI Parser_Release(IBaseFilter * iface)
{
ParserImpl *This = (ParserImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->refCount);
ULONG refCount = BaseFilterImpl_Release(iface);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
@ -202,7 +183,7 @@ HRESULT WINAPI Parser_GetClassID(IBaseFilter * iface, CLSID * pClsid)
TRACE("(%p)\n", pClsid);
*pClsid = This->clsid;
*pClsid = This->filter.clsid;
return S_OK;
}
@ -220,24 +201,24 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface)
EnterCriticalSection(&pin->thread_lock);
IAsyncReader_BeginFlush(This->pInputPin->pReader);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
IAsyncReader_EndFlush(This->pInputPin->pReader);
LeaveCriticalSection(&pin->thread_lock);
return S_OK;
}
This->state = State_Stopped;
This->filter.state = State_Stopped;
for (i = 1; i < (This->cStreams + 1); i++)
{
BaseOutputPinImpl_Inactive((BaseOutputPin *)This->ppPins[i]);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
PullPin_PauseProcessing(This->pInputPin);
PullPin_WaitForStateChange(This->pInputPin, INFINITE);
@ -256,26 +237,26 @@ HRESULT WINAPI Parser_Pause(IBaseFilter * iface)
TRACE("()\n");
EnterCriticalSection(&pin->thread_lock);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
if (This->state == State_Paused)
if (This->filter.state == State_Paused)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
LeaveCriticalSection(&pin->thread_lock);
return S_OK;
}
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
hr = IBaseFilter_Run(iface, -1);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
}
if (SUCCEEDED(hr))
This->state = State_Paused;
This->filter.state = State_Paused;
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
LeaveCriticalSection(&pin->thread_lock);
return hr;
@ -292,19 +273,19 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
TRACE("(%s)\n", wine_dbgstr_longlong(tStart));
EnterCriticalSection(&pin->thread_lock);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
HRESULT hr_any = VFW_E_NOT_CONNECTED;
if (This->state == State_Running || This->state == State_Paused)
if (This->filter.state == State_Running || This->filter.state == State_Paused)
{
This->state = State_Running;
LeaveCriticalSection(&This->csFilter);
This->filter.state = State_Running;
LeaveCriticalSection(&This->filter.csFilter);
LeaveCriticalSection(&pin->thread_lock);
return S_OK;
}
This->rtStreamStart = tStart;
This->filter.rtStreamStart = tStart;
for (i = 1; i < (This->cStreams + 1); i++)
{
@ -316,15 +297,15 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
hr = hr_any;
if (SUCCEEDED(hr))
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
hr = PullPin_StartProcessing(This->pInputPin);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
}
if (SUCCEEDED(hr))
This->state = State_Running;
This->filter.state = State_Running;
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
LeaveCriticalSection(&pin->thread_lock);
return hr;
@ -339,11 +320,11 @@ HRESULT WINAPI Parser_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FI
TRACE("(%d, %p)\n", dwMilliSecsTimeout, pState);
EnterCriticalSection(&pin->thread_lock);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
*pState = This->state;
*pState = This->filter.state;
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
if (This->pInputPin && (PullPin_WaitForStateChange(This->pInputPin, dwMilliSecsTimeout) == S_FALSE))
hr = VFW_S_STATE_INTERMEDIATE;
@ -360,15 +341,7 @@ HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock
TRACE("(%p)\n", pClock);
EnterCriticalSection(&pin->thread_lock);
EnterCriticalSection(&This->csFilter);
{
if (This->pClock)
IReferenceClock_Release(This->pClock);
This->pClock = pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
BaseFilterImpl_SetSyncSource(iface,pClock);
LeaveCriticalSection(&pin->thread_lock);
return S_OK;
@ -376,19 +349,7 @@ HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock
HRESULT WINAPI Parser_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
ParserImpl *This = (ParserImpl *)iface;
TRACE("(%p)\n", ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
return BaseFilterImpl_GetSyncSource(iface, ppClock);
}
/** IBaseFilter implementation **/
@ -442,43 +403,17 @@ HRESULT WINAPI Parser_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
HRESULT WINAPI Parser_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
ParserImpl *This = (ParserImpl *)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;
return BaseFilterImpl_QueryFilterInfo(iface, pInfo);
}
HRESULT WINAPI Parser_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
HRESULT hr = S_OK;
ParserImpl *This = (ParserImpl *)iface;
TRACE("(%p, %s)\n", 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;
return BaseFilterImpl_JoinFilterGraph(iface, pGraph, pName);
}
HRESULT WINAPI Parser_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
TRACE("(%p)\n", pVendorInfo);
return E_NOTIMPL;
return BaseFilterImpl_QueryVendorInfo(iface, pVendorInfo);
}
HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt)
@ -491,7 +426,7 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR
This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *));
memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * sizeof(IPin *));
hr = BaseOutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, props, NULL, &This->csFilter, This->ppPins + (This->cStreams + 1));
hr = BaseOutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, props, NULL, &This->filter.csFilter, This->ppPins + (This->cStreams + 1));
if (SUCCEEDED(hr))
{

View file

@ -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;

View file

@ -80,18 +80,10 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
PIN_INFO piInput;
PIN_INFO piOutput;
BaseFilter_Init(&pTransformFilter->filter, &TransformFilter_Vtbl, pClsid, (DWORD_PTR)(__FILE__ ": TransformFilterImpl.csFilter"));
/* pTransformFilter is already allocated */
pTransformFilter->clsid = *pClsid;
pTransformFilter->pFuncsTable = pFuncsTable;
pTransformFilter->lpVtbl = &TransformFilter_Vtbl;
pTransformFilter->refCount = 1;
InitializeCriticalSection(&pTransformFilter->csFilter);
pTransformFilter->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TransformFilterImpl.csFilter");
pTransformFilter->state = State_Stopped;
pTransformFilter->pClock = NULL;
ZeroMemory(&pTransformFilter->filterInfo, sizeof(FILTER_INFO));
ZeroMemory(&pTransformFilter->pmt, sizeof(pTransformFilter->pmt));
pTransformFilter->npins = 2;
@ -105,7 +97,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
piOutput.pFilter = (IBaseFilter *)pTransformFilter;
lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
hr = BaseInputPin_Construct(&TransformFilter_InputPin_Vtbl, &piInput, TransformFilter_Input_CheckMediaType, pFuncsTable->pfnProcessSampleData, &pTransformFilter->csFilter, NULL, &pTransformFilter->ppPins[0]);
hr = BaseInputPin_Construct(&TransformFilter_InputPin_Vtbl, &piInput, TransformFilter_Input_CheckMediaType, pFuncsTable->pfnProcessSampleData, &pTransformFilter->filter.csFilter, NULL, &pTransformFilter->ppPins[0]);
if (SUCCEEDED(hr))
{
@ -115,7 +107,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
props.cbBuffer = 0; /* Will be updated at connection time */
props.cBuffers = 1;
hr = BaseOutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(BaseOutputPin), &piOutput, &props, NULL, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]);
hr = BaseOutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(BaseOutputPin), &piOutput, &props, NULL, &pTransformFilter->filter.csFilter, &pTransformFilter->ppPins[1]);
if (FAILED(hr))
ERR("Cannot create output pin (%x)\n", hr);
@ -131,8 +123,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
if (FAILED(hr))
{
CoTaskMemFree(pTransformFilter->ppPins);
pTransformFilter->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pTransformFilter->csFilter);
BaseFilterImpl_Release((IBaseFilter*)pTransformFilter);
CoTaskMemFree(pTransformFilter);
}
@ -169,20 +160,10 @@ static HRESULT WINAPI TransformFilter_QueryInterface(IBaseFilter * iface, REFIID
return E_NOINTERFACE;
}
static ULONG WINAPI TransformFilter_AddRef(IBaseFilter * iface)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->refCount);
TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
return refCount;
}
static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->refCount);
ULONG refCount = BaseFilterImpl_Release(iface);
TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
@ -190,9 +171,6 @@ static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface)
{
ULONG i;
if (This->pClock)
IReferenceClock_Release(This->pClock);
for (i = 0; i < This->npins; i++)
{
IPin *pConnectedTo;
@ -208,10 +186,6 @@ static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface)
}
CoTaskMemFree(This->ppPins);
This->lpVtbl = NULL;
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
TRACE("Destroying transform filter\n");
FreeMediaType(&This->pmt);
@ -223,19 +197,6 @@ static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface)
return refCount;
}
/** IPersist methods **/
static HRESULT WINAPI TransformFilter_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
*pClsid = This->clsid;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI TransformFilter_Stop(IBaseFilter * iface)
@ -245,13 +206,13 @@ static HRESULT WINAPI TransformFilter_Stop(IBaseFilter * iface)
TRACE("(%p/%p)\n", This, iface);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
This->state = State_Stopped;
This->filter.state = State_Stopped;
if (This->pFuncsTable->pfnProcessEnd)
hr = This->pFuncsTable->pfnProcessEnd(This);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -263,17 +224,17 @@ static HRESULT WINAPI TransformFilter_Pause(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
hr = IBaseFilter_Run(iface, -1);
else
hr = S_OK;
if (SUCCEEDED(hr))
This->state = State_Paused;
This->filter.state = State_Paused;
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -285,9 +246,9 @@ static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tS
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
((BaseInputPin *)This->ppPins[0])->end_of_stream = 0;
if (This->pFuncsTable->pfnProcessBegin)
@ -298,66 +259,15 @@ static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tS
if (SUCCEEDED(hr))
{
This->rtStreamStart = tStart;
This->state = State_Running;
This->filter.rtStreamStart = tStart;
This->filter.state = State_Running;
}
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
static HRESULT WINAPI TransformFilter_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState);
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI TransformFilter_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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;
}
static HRESULT WINAPI TransformFilter_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
/** IBaseFilter implementation **/
static IPin* WINAPI TransformFilter_GetPin(IBaseFilter *iface, int pos)
@ -402,65 +312,23 @@ static HRESULT WINAPI TransformFilter_FindPin(IBaseFilter * iface, LPCWSTR Id, I
return E_NOTIMPL;
}
static HRESULT WINAPI TransformFilter_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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 TransformFilter_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
HRESULT hr = S_OK;
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%p, %s)\n", This, iface, 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;
}
static HRESULT WINAPI TransformFilter_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl TransformFilter_Vtbl =
{
TransformFilter_QueryInterface,
TransformFilter_AddRef,
BaseFilterImpl_AddRef,
TransformFilter_Release,
TransformFilter_GetClassID,
BaseFilterImpl_GetClassID,
TransformFilter_Stop,
TransformFilter_Pause,
TransformFilter_Run,
TransformFilter_GetState,
TransformFilter_SetSyncSource,
TransformFilter_GetSyncSource,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
TransformFilter_EnumPins,
TransformFilter_FindPin,
TransformFilter_QueryFilterInfo,
TransformFilter_JoinFilterGraph,
TransformFilter_QueryVendorInfo
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface)
@ -532,12 +400,12 @@ static HRESULT WINAPI TransformFilter_InputPin_BeginFlush(IPin * iface)
TRACE("(%p)->()\n", iface);
pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter;
EnterCriticalSection(&pTransform->csFilter);
EnterCriticalSection(&pTransform->filter.csFilter);
if (pTransform->pFuncsTable->pfnBeginFlush)
hr = pTransform->pFuncsTable->pfnBeginFlush(This);
if (SUCCEEDED(hr))
hr = BaseInputPinImpl_BeginFlush(iface);
LeaveCriticalSection(&pTransform->csFilter);
LeaveCriticalSection(&pTransform->filter.csFilter);
return hr;
}
@ -550,12 +418,12 @@ static HRESULT WINAPI TransformFilter_InputPin_EndFlush(IPin * iface)
TRACE("(%p)->()\n", iface);
pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter;
EnterCriticalSection(&pTransform->csFilter);
EnterCriticalSection(&pTransform->filter.csFilter);
if (pTransform->pFuncsTable->pfnEndFlush)
hr = pTransform->pFuncsTable->pfnEndFlush(This);
if (SUCCEEDED(hr))
hr = BaseInputPinImpl_EndFlush(iface);
LeaveCriticalSection(&pTransform->csFilter);
LeaveCriticalSection(&pTransform->filter.csFilter);
return hr;
}
@ -568,12 +436,12 @@ static HRESULT WINAPI TransformFilter_InputPin_NewSegment(IPin * iface, REFERENC
TRACE("(%p)->()\n", iface);
pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter;
EnterCriticalSection(&pTransform->csFilter);
EnterCriticalSection(&pTransform->filter.csFilter);
if (pTransform->pFuncsTable->pfnNewSegment)
hr = pTransform->pFuncsTable->pfnNewSegment(This, tStart, tStop, dRate);
if (SUCCEEDED(hr))
hr = BaseInputPinImpl_NewSegment(iface, tStart, tStop, dRate);
LeaveCriticalSection(&pTransform->csFilter);
LeaveCriticalSection(&pTransform->filter.csFilter);
return hr;
}

View file

@ -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;

View file

@ -55,19 +55,12 @@ static const IPinVtbl VideoRenderer_InputPin_Vtbl;
typedef struct VideoRendererImpl
{
const IBaseFilterVtbl * lpVtbl;
BaseFilter filter;
const IBasicVideoVtbl * IBasicVideo_vtbl;
const IVideoWindowVtbl * IVideoWindow_vtbl;
const IUnknownVtbl * IInner_vtbl;
IUnknown *seekthru_unk;
LONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
BaseInputPin *pInputPin;
BOOL init;
@ -365,17 +358,17 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
TRACE("(%p)->(%p)\n", iface, pSample);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
if (This->pInputPin->flushing || This->pInputPin->end_of_stream)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_FALSE;
}
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return VFW_E_WRONG_STATE;
}
@ -385,7 +378,7 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
else
MediaSeekingPassThru_RegisterMediaTime(This->seekthru_unk, tStart);
if (This->rtLastStop != tStart && This->state == State_Running)
if (This->rtLastStop != tStart && This->filter.state == State_Running)
{
LONG64 delta;
delta = tStart - This->rtLastStop;
@ -402,7 +395,7 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
if (IMediaSample_IsPreroll(pSample) == S_OK)
{
This->rtLastStop = tStop;
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -410,7 +403,7 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%x)\n", hr);
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
@ -432,27 +425,27 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
#endif
SetEvent(This->hEvent);
if (This->state == State_Paused)
if (This->filter.state == State_Paused)
{
This->sample_held = pSample;
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
WaitForSingleObject(This->blocked, INFINITE);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
This->sample_held = NULL;
if (This->state == State_Paused)
if (This->filter.state == State_Paused)
{
/* Flushing */
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return VFW_E_WRONG_STATE;
}
}
if (This->pClock && This->state == State_Running)
if (This->filter.pClock && This->filter.state == State_Running)
{
REFERENCE_TIME time, trefstart, trefstop;
LONG delta;
@ -461,12 +454,12 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
* I'm not going to! When I tried, it seemed to generate lag and
* it caused instability.
*/
IReferenceClock_GetTime(This->pClock, &time);
IReferenceClock_GetTime(This->filter.pClock, &time);
trefstart = This->rtStreamStart;
trefstop = (REFERENCE_TIME)((double)(tStop - tStart) / This->pInputPin->dRate) + This->rtStreamStart;
trefstart = This->filter.rtStreamStart;
trefstop = (REFERENCE_TIME)((double)(tStop - tStart) / This->pInputPin->dRate) + This->filter.rtStreamStart;
delta = (LONG)((trefstart-time)/10000);
This->rtStreamStart = trefstop;
This->filter.rtStreamStart = trefstop;
This->rtLastStop = tStop;
if (delta > 0)
@ -480,7 +473,7 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
(DWORD)(time / 10000000), (DWORD)((time / 10000)%1000),
(DWORD)(trefstop / 10000000), (DWORD)((trefstop / 10000)%1000) );
This->rtLastStop = tStop;
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
}
@ -488,7 +481,7 @@ static HRESULT WINAPI VideoRenderer_Receive(IPin* iface, IMediaSample * pSample)
VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -559,19 +552,14 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
pVideoRenderer->bAggregatable = FALSE;
pVideoRenderer->IInner_vtbl = &IInner_VTable;
pVideoRenderer->lpVtbl = &VideoRenderer_Vtbl;
BaseFilter_Init(&pVideoRenderer->filter, &VideoRenderer_Vtbl, &CLSID_VideoRenderer, (DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter"));
pVideoRenderer->IBasicVideo_vtbl = &IBasicVideo_VTable;
pVideoRenderer->IVideoWindow_vtbl = &IVideoWindow_VTable;
pVideoRenderer->refCount = 1;
InitializeCriticalSection(&pVideoRenderer->csFilter);
pVideoRenderer->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter");
pVideoRenderer->state = State_Stopped;
pVideoRenderer->pClock = NULL;
pVideoRenderer->init = 0;
pVideoRenderer->AutoShow = 1;
pVideoRenderer->rtLastStop = -1;
ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO));
ZeroMemory(&pVideoRenderer->SourceRect, sizeof(RECT));
ZeroMemory(&pVideoRenderer->DestRect, sizeof(RECT));
ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT));
@ -583,7 +571,7 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
piInput.pFilter = (IBaseFilter *)pVideoRenderer;
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = BaseInputPin_Construct(&VideoRenderer_InputPin_Vtbl, &piInput, VideoRenderer_CheckMediaType, VideoRenderer_Receive, &pVideoRenderer->csFilter, NULL, (IPin **)&pVideoRenderer->pInputPin);
hr = BaseInputPin_Construct(&VideoRenderer_InputPin_Vtbl, &piInput, VideoRenderer_CheckMediaType, VideoRenderer_Receive, &pVideoRenderer->filter.csFilter, NULL, (IPin **)&pVideoRenderer->pInputPin);
if (SUCCEEDED(hr))
{
@ -613,8 +601,7 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
return hr;
fail:
pVideoRenderer->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pVideoRenderer->csFilter);
BaseFilterImpl_Release((IBaseFilter*)pVideoRenderer);
CoTaskMemFree(pVideoRenderer);
return hr;
}
@ -665,7 +652,7 @@ static HRESULT WINAPI VideoRendererInner_QueryInterface(IUnknown * iface, REFIID
static ULONG WINAPI VideoRendererInner_AddRef(IUnknown * iface)
{
ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface);
ULONG refCount = InterlockedIncrement(&This->refCount);
ULONG refCount = InterlockedIncrement(&This->filter.refCount);
TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
@ -675,7 +662,7 @@ static ULONG WINAPI VideoRendererInner_AddRef(IUnknown * iface)
static ULONG WINAPI VideoRendererInner_Release(IUnknown * iface)
{
ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface);
ULONG refCount = InterlockedDecrement(&This->refCount);
ULONG refCount = InterlockedDecrement(&This->filter.refCount);
TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
@ -689,9 +676,6 @@ static ULONG WINAPI VideoRendererInner_Release(IUnknown * iface)
CloseHandle(This->hThread);
CloseHandle(This->hEvent);
if (This->pClock)
IReferenceClock_Release(This->pClock);
if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo)))
{
IPin_Disconnect(pConnectedTo);
@ -701,10 +685,10 @@ static ULONG WINAPI VideoRendererInner_Release(IUnknown * iface)
IPin_Release((IPin *)This->pInputPin);
This->lpVtbl = NULL;
This->filter.lpVtbl = NULL;
IUnknown_Release(This->seekthru_unk);
This->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csFilter);
This->filter.csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->filter.csFilter);
TRACE("Destroying Video Renderer\n");
CoTaskMemFree(This);
@ -770,19 +754,6 @@ static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface)
return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
}
/** IPersist methods **/
static HRESULT WINAPI VideoRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
VideoRendererImpl *This = (VideoRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
*pClsid = CLSID_VideoRenderer;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface)
@ -791,14 +762,14 @@ static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
{
This->state = State_Stopped;
This->filter.state = State_Stopped;
SetEvent(This->hEvent);
SetEvent(This->blocked);
MediaSeekingPassThru_ResetMediaTime(This->seekthru_unk);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -809,19 +780,19 @@ static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
if (This->state != State_Paused)
EnterCriticalSection(&This->filter.csFilter);
if (This->filter.state != State_Paused)
{
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
This->pInputPin->end_of_stream = 0;
ResetEvent(This->hEvent);
}
This->state = State_Paused;
This->filter.state = State_Paused;
ResetEvent(This->blocked);
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -832,20 +803,20 @@ static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tSta
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
if (This->state != State_Running)
EnterCriticalSection(&This->filter.csFilter);
if (This->filter.state != State_Running)
{
if (This->state == State_Stopped)
if (This->filter.state == State_Stopped)
{
This->pInputPin->end_of_stream = 0;
ResetEvent(This->hEvent);
}
SetEvent(This->blocked);
This->rtStreamStart = tStart;
This->state = State_Running;
This->filter.rtStreamStart = tStart;
This->filter.state = State_Running;
}
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
@ -862,51 +833,11 @@ static HRESULT WINAPI VideoRenderer_GetState(IBaseFilter * iface, DWORD dwMilliS
else
hr = S_OK;
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
BaseFilterImpl_GetState(iface, dwMilliSecsTimeout, pState);
return hr;
}
static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
VideoRendererImpl *This = (VideoRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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;
}
static HRESULT WINAPI VideoRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
VideoRendererImpl *This = (VideoRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
/** IBaseFilter implementation **/
static IPin* WINAPI VideoRenderer_GetPin(IBaseFilter *iface, int pos)
@ -951,64 +882,23 @@ static HRESULT WINAPI VideoRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPi
return E_NOTIMPL;
}
static HRESULT WINAPI VideoRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
VideoRendererImpl *This = (VideoRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, 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 VideoRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
VideoRendererImpl *This = (VideoRendererImpl *)iface;
TRACE("(%p/%p)->(%p, %s)\n", This, iface, 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 S_OK;
}
static HRESULT WINAPI VideoRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
VideoRendererImpl *This = (VideoRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl VideoRenderer_Vtbl =
{
VideoRenderer_QueryInterface,
VideoRenderer_AddRef,
VideoRenderer_Release,
VideoRenderer_GetClassID,
BaseFilterImpl_GetClassID,
VideoRenderer_Stop,
VideoRenderer_Pause,
VideoRenderer_Run,
VideoRenderer_GetState,
VideoRenderer_SetSyncSource,
VideoRenderer_GetSyncSource,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
VideoRenderer_EnumPins,
VideoRenderer_FindPin,
VideoRenderer_QueryFilterInfo,
VideoRenderer_JoinFilterGraph,
VideoRenderer_QueryVendorInfo
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface)
@ -1021,7 +911,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface)
TRACE("(%p/%p)->()\n", This, iface);
pFilter = (VideoRendererImpl*)This->pin.pinInfo.pFilter;
hr = IFilterGraph_QueryInterface(pFilter->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
hr = IFilterGraph_QueryInterface(pFilter->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
if (SUCCEEDED(hr))
{
hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0);
@ -1041,7 +931,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_BeginFlush(IPin * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(This->pin.pCritSec);
if (pVideoRenderer->state == State_Paused)
if (pVideoRenderer->filter.state == State_Paused)
SetEvent(pVideoRenderer->blocked);
hr = BaseInputPinImpl_BeginFlush(iface);
@ -1059,7 +949,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(This->pin.pCritSec);
if (pVideoRenderer->state == State_Paused)
if (pVideoRenderer->filter.state == State_Paused)
ResetEvent(pVideoRenderer->blocked);
hr = BaseInputPinImpl_EndFlush(iface);
@ -1543,12 +1433,12 @@ static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage);
EnterCriticalSection(&This->csFilter);
EnterCriticalSection(&This->filter.csFilter);
if (!This->sample_held)
{
LeaveCriticalSection(&This->csFilter);
return (This->state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
LeaveCriticalSection(&This->filter.csFilter);
return (This->filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
}
if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
@ -1562,7 +1452,7 @@ static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
else
{
FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return VFW_E_RUNTIME_ERROR;
}
@ -1572,14 +1462,14 @@ static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
if (!pDIBImage)
{
*pBufferSize = needed_size;
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}
if (needed_size < *pBufferSize)
{
ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return E_FAIL;
}
*pBufferSize = needed_size;
@ -1588,7 +1478,7 @@ static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
IMediaSample_GetPointer(This->sample_held, (BYTE **)&ptr);
memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->sample_held));
LeaveCriticalSection(&This->csFilter);
LeaveCriticalSection(&This->filter.csFilter);
return S_OK;
}

View file

@ -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);

View file

@ -2,6 +2,7 @@ MODULE = strmbase
C_SRCS = \
enumpins.c \
filter.c \
mediatype.c \
pin.c

198
dlls/strmbase/filter.c Normal file
View file

@ -0,0 +1,198 @@
/*
* 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;
}

View file

@ -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);