Aric Stewart : strmbase: Implement renderer quality control into the base renderer.

Alexandre Julliard julliard at winehq.org
Tue Apr 3 12:17:38 CDT 2012


Module: wine
Branch: master
Commit: 54eafc73e51666c3edf9fa78a0534ea7b1fa23c9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=54eafc73e51666c3edf9fa78a0534ea7b1fa23c9

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon Apr  2 07:52:08 2012 -0500

strmbase: Implement renderer quality control into the base renderer.

---

 dlls/quartz/dsoundrender.c |   28 ++++++++++------------------
 dlls/quartz/nullrenderer.c |    2 +-
 dlls/strmbase/renderer.c   |   42 +++++++++++++++++++++++++++++++++++++++++-
 include/wine/strmbase.h    |    4 ++++
 4 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index 5b4408d..4714b2b 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 ab4dba2..5d2680f 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 3f665f7..a4261ee 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 7e25c04..6be9b0d 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);




More information about the wine-cvs mailing list