mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 12:20:07 +00:00
strmbase: Implement renderer quality control into the base renderer.
This commit is contained in:
parent
448986f1c4
commit
54eafc73e5
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user