strmbase: Implement BaseFilter in strmbase.
This commit is contained in:
parent
db27d9afa9
commit
1d42659c40
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue