diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 5b4408d604..4714b2b376 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -49,13 +49,6 @@ static const IReferenceClockVtbl IReferenceClock_Vtbl; static const IMediaSeekingVtbl IMediaSeeking_Vtbl; static const IAMDirectSoundVtbl IAMDirectSound_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 { @@ -66,8 +59,6 @@ typedef struct DSoundRenderImpl const IAMDirectSoundVtbl *IAMDirectSound_vtbl; const IAMFilterMiscFlagsVtbl *IAMFilterMiscFlags_vtbl; - QualityControlImpl qcimpl; - IDirectSound8 *dsound; LPDIRECTSOUNDBUFFER dsbuffer; DWORD buf_size; @@ -322,6 +313,13 @@ static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, REFERENCE_TIM 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) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); @@ -409,7 +407,7 @@ static HRESULT WINAPI DSoundRender_DoRenderSample(BaseRenderer *iface, IMediaSam q.Proportion = 1.; q.Late = jitter; q.TimeStamp = tStart; - IQualityControl_Notify((IQualityControl *)&This->qcimpl, (IBaseFilter*)This, q); + IQualityControl_Notify((IQualityControl *)&This->renderer.qcimpl, (IBaseFilter*)This, q); } return hr; } @@ -455,7 +453,6 @@ static VOID WINAPI DSoundRender_OnStartStreaming(BaseRenderer * iface) if (This->renderer.pInputPin->pin.pConnectedTo) { - QualityControlRender_Start(&This->qcimpl, This->renderer.filter.rtStreamStart); if (This->renderer.filter.state == State_Paused) { /* 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); This->writepos = This->buf_size; } - QualityControlRender_Start(&This->qcimpl, This->renderer.filter.rtStreamStart); return S_OK; } @@ -621,7 +617,7 @@ static const BaseRendererFuncTable BaseFuncTable = { NULL, NULL, NULL, - NULL, + DSoundRender_ShouldDrawSampleNow, DSoundRender_PrepareReceive, /**/ DSoundRender_CompleteConnect, @@ -687,8 +683,6 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) return HRESULT_FROM_WIN32(GetLastError()); } - QualityControlImpl_init(&pDSoundRender->qcimpl, (IPin*)pDSoundRender->renderer.pInputPin, (IBaseFilter*)pDSoundRender); - pDSoundRender->qcimpl.lpVtbl = &DSoundRender_QualityControl_Vtbl; *ppv = pDSoundRender; } else @@ -715,8 +709,6 @@ static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter * iface, REFIID ri *ppv = &This->IAMDirectSound_vtbl; else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) *ppv = &This->IAMFilterMiscFlags_vtbl; - else if (IsEqualIID(riid, &IID_IQualityControl)) - *ppv = &This->qcimpl; else { HRESULT hr; @@ -782,7 +774,7 @@ static const IBaseFilterVtbl DSoundRender_Vtbl = BaseRendererImpl_Pause, BaseRendererImpl_Run, BaseRendererImpl_GetState, - BaseFilterImpl_SetSyncSource, + BaseRendererImpl_SetSyncSource, BaseFilterImpl_GetSyncSource, BaseFilterImpl_EnumPins, BaseRendererImpl_FindPin, diff --git a/dlls/quartz/nullrenderer.c b/dlls/quartz/nullrenderer.c index ab4dba2e6c..5d2680ffa1 100644 --- a/dlls/quartz/nullrenderer.c +++ b/dlls/quartz/nullrenderer.c @@ -239,7 +239,7 @@ static const IBaseFilterVtbl NullRenderer_Vtbl = BaseRendererImpl_Pause, BaseRendererImpl_Run, BaseRendererImpl_GetState, - BaseFilterImpl_SetSyncSource, + BaseRendererImpl_SetSyncSource, BaseFilterImpl_GetSyncSource, BaseFilterImpl_EnumPins, BaseRendererImpl_FindPin, diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 3f665f7a45..a4261ee575 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -47,6 +47,14 @@ static inline BaseRenderer *impl_from_BaseFilter(BaseFilter *iface) 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) { 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->RenderEvent = CreateEventW(NULL, FALSE, FALSE, 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; @@ -269,6 +280,12 @@ HRESULT WINAPI BaseRendererImpl_QueryInterface(IBaseFilter* iface, REFIID riid, if (IsEqualIID(riid, &IID_IMediaSeeking)) 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 return BaseFilterImpl_QueryInterface(iface, riid, ppv); } @@ -365,7 +382,9 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp { if (This->pFuncsTable->pfnOnWaitStart) This->pFuncsTable->pfnOnWaitStart(This); - /* TODO: Wait */ + + hr = QualityControlRender_WaitFor(&This->qcimpl, pSample, This->RenderEvent); + if (This->pFuncsTable->pfnOnWaitEnd) This->pFuncsTable->pfnOnWaitEnd(This); } @@ -378,7 +397,13 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp } if (SUCCEEDED(hr)) + { + QualityControlRender_BeginRender(&This->qcimpl); hr = This->pFuncsTable->pfnDoRenderSample(This, pSample); + QualityControlRender_EndRender(&This->qcimpl); + } + + QualityControlRender_DoQOS(&This->qcimpl); BaseRendererImpl_ClearPendingSample(This); LeaveCriticalSection(&This->csRenderLock); @@ -457,6 +482,7 @@ HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart) } if (SUCCEEDED(hr)) { + QualityControlRender_Start(&This->qcimpl, This->filter.rtStreamStart); if (This->pFuncsTable->pfnOnStartStreaming) This->pFuncsTable->pfnOnStartStreaming(This); if (This->filter.state == State_Stopped) @@ -501,6 +527,19 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) 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 hr; @@ -553,6 +592,7 @@ HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface) HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface) { TRACE("(%p)\n", iface); + QualityControlRender_Start(&iface->qcimpl, iface->filter.rtStreamStart); RendererPosPassThru_ResetMediaTime(iface->pPosition); ResetEvent(iface->ThreadSignal); ResetEvent(iface->RenderEvent); diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 7e25c04475..6be9b0df83 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -587,6 +587,9 @@ typedef struct BaseRendererTag HANDLE RenderEvent; IMediaSample *pMediaSample; + IQualityControl *pQSink; + QualityControlImpl qcimpl; + const struct BaseRendererFuncTable * pFuncsTable; } BaseRenderer; @@ -638,6 +641,7 @@ HRESULT WINAPI BaseRendererImpl_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin ** HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface); HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart); 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_EndOfStream(BaseRenderer* iface); HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface);