strmbase: Implement renderer quality control into the base renderer.

This commit is contained in:
Aric Stewart 2012-04-02 07:52:08 -05:00 committed by Alexandre Julliard
parent 448986f1c4
commit 54eafc73e5
4 changed files with 56 additions and 20 deletions

View File

@ -49,13 +49,6 @@ static const IReferenceClockVtbl IReferenceClock_Vtbl;
static const IMediaSeekingVtbl IMediaSeeking_Vtbl; static const IMediaSeekingVtbl IMediaSeeking_Vtbl;
static const IAMDirectSoundVtbl IAMDirectSound_Vtbl; static const IAMDirectSoundVtbl IAMDirectSound_Vtbl;
static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl; static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl;
static const IQualityControlVtbl DSoundRender_QualityControl_Vtbl = {
QualityControlImpl_QueryInterface,
QualityControlImpl_AddRef,
QualityControlImpl_Release,
QualityControlImpl_Notify,
QualityControlImpl_SetSink
};
typedef struct DSoundRenderImpl typedef struct DSoundRenderImpl
{ {
@ -66,8 +59,6 @@ typedef struct DSoundRenderImpl
const IAMDirectSoundVtbl *IAMDirectSound_vtbl; const IAMDirectSoundVtbl *IAMDirectSound_vtbl;
const IAMFilterMiscFlagsVtbl *IAMFilterMiscFlags_vtbl; const IAMFilterMiscFlagsVtbl *IAMFilterMiscFlags_vtbl;
QualityControlImpl qcimpl;
IDirectSound8 *dsound; IDirectSound8 *dsound;
LPDIRECTSOUNDBUFFER dsbuffer; LPDIRECTSOUNDBUFFER dsbuffer;
DWORD buf_size; DWORD buf_size;
@ -322,6 +313,13 @@ static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, REFERENCE_TIM
return S_OK; return S_OK;
} }
static HRESULT WINAPI DSoundRender_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pMediaSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
{
/* We time ourselves do not use the base renderers timing */
return S_OK;
}
HRESULT WINAPI DSoundRender_PrepareReceive(BaseRenderer *iface, IMediaSample *pSample) HRESULT WINAPI DSoundRender_PrepareReceive(BaseRenderer *iface, IMediaSample *pSample)
{ {
DSoundRenderImpl *This = impl_from_BaseRenderer(iface); DSoundRenderImpl *This = impl_from_BaseRenderer(iface);
@ -409,7 +407,7 @@ static HRESULT WINAPI DSoundRender_DoRenderSample(BaseRenderer *iface, IMediaSam
q.Proportion = 1.; q.Proportion = 1.;
q.Late = jitter; q.Late = jitter;
q.TimeStamp = tStart; q.TimeStamp = tStart;
IQualityControl_Notify((IQualityControl *)&This->qcimpl, (IBaseFilter*)This, q); IQualityControl_Notify((IQualityControl *)&This->renderer.qcimpl, (IBaseFilter*)This, q);
} }
return hr; return hr;
} }
@ -455,7 +453,6 @@ static VOID WINAPI DSoundRender_OnStartStreaming(BaseRenderer * iface)
if (This->renderer.pInputPin->pin.pConnectedTo) if (This->renderer.pInputPin->pin.pConnectedTo)
{ {
QualityControlRender_Start(&This->qcimpl, This->renderer.filter.rtStreamStart);
if (This->renderer.filter.state == State_Paused) if (This->renderer.filter.state == State_Paused)
{ {
/* Unblock our thread, state changing from paused to running doesn't need a reset for state change */ /* Unblock our thread, state changing from paused to running doesn't need a reset for state change */
@ -604,7 +601,6 @@ static HRESULT WINAPI DSoundRender_EndFlush(BaseRenderer* iface)
IDirectSoundBuffer_Unlock(This->dsbuffer, buffer, size, NULL, 0); IDirectSoundBuffer_Unlock(This->dsbuffer, buffer, size, NULL, 0);
This->writepos = This->buf_size; This->writepos = This->buf_size;
} }
QualityControlRender_Start(&This->qcimpl, This->renderer.filter.rtStreamStart);
return S_OK; return S_OK;
} }
@ -621,7 +617,7 @@ static const BaseRendererFuncTable BaseFuncTable = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, DSoundRender_ShouldDrawSampleNow,
DSoundRender_PrepareReceive, DSoundRender_PrepareReceive,
/**/ /**/
DSoundRender_CompleteConnect, DSoundRender_CompleteConnect,
@ -687,8 +683,6 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
QualityControlImpl_init(&pDSoundRender->qcimpl, (IPin*)pDSoundRender->renderer.pInputPin, (IBaseFilter*)pDSoundRender);
pDSoundRender->qcimpl.lpVtbl = &DSoundRender_QualityControl_Vtbl;
*ppv = pDSoundRender; *ppv = pDSoundRender;
} }
else else
@ -715,8 +709,6 @@ static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter * iface, REFIID ri
*ppv = &This->IAMDirectSound_vtbl; *ppv = &This->IAMDirectSound_vtbl;
else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
*ppv = &This->IAMFilterMiscFlags_vtbl; *ppv = &This->IAMFilterMiscFlags_vtbl;
else if (IsEqualIID(riid, &IID_IQualityControl))
*ppv = &This->qcimpl;
else else
{ {
HRESULT hr; HRESULT hr;
@ -782,7 +774,7 @@ static const IBaseFilterVtbl DSoundRender_Vtbl =
BaseRendererImpl_Pause, BaseRendererImpl_Pause,
BaseRendererImpl_Run, BaseRendererImpl_Run,
BaseRendererImpl_GetState, BaseRendererImpl_GetState,
BaseFilterImpl_SetSyncSource, BaseRendererImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource, BaseFilterImpl_GetSyncSource,
BaseFilterImpl_EnumPins, BaseFilterImpl_EnumPins,
BaseRendererImpl_FindPin, BaseRendererImpl_FindPin,

View File

@ -239,7 +239,7 @@ static const IBaseFilterVtbl NullRenderer_Vtbl =
BaseRendererImpl_Pause, BaseRendererImpl_Pause,
BaseRendererImpl_Run, BaseRendererImpl_Run,
BaseRendererImpl_GetState, BaseRendererImpl_GetState,
BaseFilterImpl_SetSyncSource, BaseRendererImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource, BaseFilterImpl_GetSyncSource,
BaseFilterImpl_EnumPins, BaseFilterImpl_EnumPins,
BaseRendererImpl_FindPin, BaseRendererImpl_FindPin,

View File

@ -47,6 +47,14 @@ static inline BaseRenderer *impl_from_BaseFilter(BaseFilter *iface)
return CONTAINING_RECORD(iface, BaseRenderer, filter); return CONTAINING_RECORD(iface, BaseRenderer, filter);
} }
static const IQualityControlVtbl Renderer_QualityControl_Vtbl = {
QualityControlImpl_QueryInterface,
QualityControlImpl_AddRef,
QualityControlImpl_Release,
QualityControlImpl_Notify,
QualityControlImpl_SetSink
};
static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
{ {
BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); BaseInputPin *This = impl_BaseInputPin_from_IPin(iface);
@ -258,6 +266,9 @@ HRESULT WINAPI BaseRenderer_Init(BaseRenderer * This, const IBaseFilterVtbl *Vtb
This->ThreadSignal = CreateEventW(NULL, TRUE, TRUE, NULL); This->ThreadSignal = CreateEventW(NULL, TRUE, TRUE, NULL);
This->RenderEvent = CreateEventW(NULL, FALSE, FALSE, NULL); This->RenderEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
This->pMediaSample = NULL; This->pMediaSample = NULL;
QualityControlImpl_init(&This->qcimpl, &This->pInputPin->pin.IPin_iface, &This->filter.IBaseFilter_iface);
This->qcimpl.lpVtbl = &Renderer_QualityControl_Vtbl;
} }
return hr; return hr;
@ -269,6 +280,12 @@ HRESULT WINAPI BaseRendererImpl_QueryInterface(IBaseFilter* iface, REFIID riid,
if (IsEqualIID(riid, &IID_IMediaSeeking)) if (IsEqualIID(riid, &IID_IMediaSeeking))
return IUnknown_QueryInterface(This->pPosition, riid, ppv); return IUnknown_QueryInterface(This->pPosition, riid, ppv);
else if (IsEqualIID(riid, &IID_IQualityControl))
{
*ppv = &This->qcimpl.lpVtbl;
IUnknown_AddRef((IUnknown *)(*ppv));
return S_OK;
}
else else
return BaseFilterImpl_QueryInterface(iface, riid, ppv); return BaseFilterImpl_QueryInterface(iface, riid, ppv);
} }
@ -365,7 +382,9 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp
{ {
if (This->pFuncsTable->pfnOnWaitStart) if (This->pFuncsTable->pfnOnWaitStart)
This->pFuncsTable->pfnOnWaitStart(This); This->pFuncsTable->pfnOnWaitStart(This);
/* TODO: Wait */
hr = QualityControlRender_WaitFor(&This->qcimpl, pSample, This->RenderEvent);
if (This->pFuncsTable->pfnOnWaitEnd) if (This->pFuncsTable->pfnOnWaitEnd)
This->pFuncsTable->pfnOnWaitEnd(This); This->pFuncsTable->pfnOnWaitEnd(This);
} }
@ -378,7 +397,13 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{
QualityControlRender_BeginRender(&This->qcimpl);
hr = This->pFuncsTable->pfnDoRenderSample(This, pSample); hr = This->pFuncsTable->pfnDoRenderSample(This, pSample);
QualityControlRender_EndRender(&This->qcimpl);
}
QualityControlRender_DoQOS(&This->qcimpl);
BaseRendererImpl_ClearPendingSample(This); BaseRendererImpl_ClearPendingSample(This);
LeaveCriticalSection(&This->csRenderLock); LeaveCriticalSection(&This->csRenderLock);
@ -457,6 +482,7 @@ HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
QualityControlRender_Start(&This->qcimpl, This->filter.rtStreamStart);
if (This->pFuncsTable->pfnOnStartStreaming) if (This->pFuncsTable->pfnOnStartStreaming)
This->pFuncsTable->pfnOnStartStreaming(This); This->pFuncsTable->pfnOnStartStreaming(This);
if (This->filter.state == State_Stopped) if (This->filter.state == State_Stopped)
@ -501,6 +527,19 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface)
return S_OK; return S_OK;
} }
HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock)
{
BaseRenderer *This = impl_from_IBaseFilter(iface);
HRESULT hr;
EnterCriticalSection(&This->filter.csFilter);
QualityControlRender_SetClock(&This->qcimpl, clock);
hr = BaseFilterImpl_SetSyncSource(iface, clock);
LeaveCriticalSection(&This->filter.csFilter);
return hr;
}
HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{ {
HRESULT hr; HRESULT hr;
@ -553,6 +592,7 @@ HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface)
HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface) HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface)
{ {
TRACE("(%p)\n", iface); TRACE("(%p)\n", iface);
QualityControlRender_Start(&iface->qcimpl, iface->filter.rtStreamStart);
RendererPosPassThru_ResetMediaTime(iface->pPosition); RendererPosPassThru_ResetMediaTime(iface->pPosition);
ResetEvent(iface->ThreadSignal); ResetEvent(iface->ThreadSignal);
ResetEvent(iface->RenderEvent); ResetEvent(iface->RenderEvent);

View File

@ -587,6 +587,9 @@ typedef struct BaseRendererTag
HANDLE RenderEvent; HANDLE RenderEvent;
IMediaSample *pMediaSample; IMediaSample *pMediaSample;
IQualityControl *pQSink;
QualityControlImpl qcimpl;
const struct BaseRendererFuncTable * pFuncsTable; const struct BaseRendererFuncTable * pFuncsTable;
} BaseRenderer; } BaseRenderer;
@ -638,6 +641,7 @@ HRESULT WINAPI BaseRendererImpl_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **
HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface); HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface);
HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart); HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart);
HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface); HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface);
HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock);
HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState); HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState);
HRESULT WINAPI BaseRendererImpl_EndOfStream(BaseRenderer* iface); HRESULT WINAPI BaseRendererImpl_EndOfStream(BaseRenderer* iface);
HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface); HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface);