Try to make the quality control object more clearly responsible for calculating quality after the fact, and only that.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/qualitycontrol.c | 65 +++++++++++--------------------- dlls/strmbase/renderer.c | 26 ++++++++++--- dlls/strmbase/strmbase_private.h | 3 +- 3 files changed, 44 insertions(+), 50 deletions(-)
diff --git a/dlls/strmbase/qualitycontrol.c b/dlls/strmbase/qualitycontrol.c index d6a91a7133e..139c4dfe862 100644 --- a/dlls/strmbase/qualitycontrol.c +++ b/dlls/strmbase/qualitycontrol.c @@ -171,46 +171,6 @@ static BOOL QualityControlRender_IsLate(QualityControlImpl *This, REFERENCE_TIME return FALSE; }
-HRESULT QualityControlRender_WaitFor(QualityControlImpl *This, IMediaSample *sample, HANDLE ev) -{ - REFERENCE_TIME start = -1, stop = -1, jitter = 0; - - TRACE("%p %p %p\n", This, sample, ev); - - This->current_rstart = This->current_rstop = -1; - This->current_jitter = 0; - if (!This->clock || FAILED(IMediaSample_GetTime(sample, &start, &stop))) - return S_OK; - - if (start >= 0) { - REFERENCE_TIME now; - IReferenceClock_GetTime(This->clock, &now); - now -= This->clockstart; - - jitter = now - start; - if (jitter <= -10000) { - DWORD_PTR cookie; - IReferenceClock_AdviseTime(This->clock, This->clockstart, start, (HEVENT)ev, &cookie); - WaitForSingleObject(ev, INFINITE); - IReferenceClock_Unadvise(This->clock, cookie); - } - } - else - start = stop = -1; - This->current_rstart = start; - This->current_rstop = stop > start ? stop : start; - This->current_jitter = jitter; - This->is_dropped = QualityControlRender_IsLate(This, jitter, start, stop); - TRACE("Dropped: %i %i %i %i\n", This->is_dropped, (int)(start/10000), (int)(stop/10000), (int)(jitter / 10000)); - if (This->is_dropped) { - This->dropped++; - if (!This->qos_handled) - return S_FALSE; - } else - This->rendered++; - return S_OK; -} - void QualityControlRender_DoQOS(QualityControlImpl *priv) { REFERENCE_TIME start, stop, jitter, pt, entered, left, duration; @@ -324,12 +284,31 @@ void QualityControlRender_DoQOS(QualityControlImpl *priv) }
-void QualityControlRender_BeginRender(QualityControlImpl *This) +void QualityControlRender_BeginRender(QualityControlImpl *This, REFERENCE_TIME start, REFERENCE_TIME stop) { - TRACE("%p\n", This); - This->start = -1;
+ This->current_rstart = start; + This->current_rstop = max(stop, start); + + if (start >= 0) + { + REFERENCE_TIME now; + IReferenceClock_GetTime(This->clock, &now); + This->current_jitter = (now - This->clockstart) - start; + } + else + This->current_jitter = 0; + + /* FIXME: This isn't correct; we don't drop samples, nor should. */ + This->is_dropped = QualityControlRender_IsLate(This, This->current_jitter, start, stop); + TRACE("Dropped: %i %i %i %i\n", This->is_dropped, (int)(start/10000), + (int)(stop/10000), (int)(This->current_jitter / 10000)); + if (This->is_dropped) + This->dropped++; + else + This->rendered++; + if (!This->clock) return;
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 0e5dd8c2fcc..33a9d3fecce 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -359,7 +359,7 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp }
/* Wait for render Time */ - if (SUCCEEDED(IMediaSample_GetTime(pSample, &start, &stop))) + if (This->filter.pClock && SUCCEEDED(IMediaSample_GetTime(pSample, &start, &stop))) { hr = S_FALSE; RendererPosPassThru_RegisterMediaTime(This->pPosition, start); @@ -370,12 +370,26 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp ;/* Do not wait: drop through */ else if (hr == S_FALSE) { + REFERENCE_TIME now; + DWORD_PTR cookie; + if (This->pFuncsTable->pfnOnWaitStart) This->pFuncsTable->pfnOnWaitStart(This);
- LeaveCriticalSection(&This->csRenderLock); - hr = QualityControlRender_WaitFor(This->qcimpl, pSample, This->RenderEvent); - EnterCriticalSection(&This->csRenderLock); + IReferenceClock_GetTime(This->filter.pClock, &now); + + if (now - This->filter.rtStreamStart - start <= -10000) + { + IReferenceClock_AdviseTime(This->filter.pClock, This->filter.rtStreamStart, + start, (HEVENT)This->RenderEvent, &cookie); + + LeaveCriticalSection(&This->csRenderLock); + + WaitForSingleObject(This->RenderEvent, INFINITE); + IReferenceClock_Unadvise(This->filter.pClock, cookie); + + EnterCriticalSection(&This->csRenderLock); + }
if (This->pFuncsTable->pfnOnWaitEnd) This->pFuncsTable->pfnOnWaitEnd(This); @@ -387,10 +401,12 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp return S_OK; } } + else + start = stop = -1;
if (SUCCEEDED(hr)) { - QualityControlRender_BeginRender(This->qcimpl); + QualityControlRender_BeginRender(This->qcimpl, start, stop); hr = This->pFuncsTable->pfnDoRenderSample(This, pSample); QualityControlRender_EndRender(This->qcimpl); } diff --git a/dlls/strmbase/strmbase_private.h b/dlls/strmbase/strmbase_private.h index 769c8f20864..439ab9aefaf 100644 --- a/dlls/strmbase/strmbase_private.h +++ b/dlls/strmbase/strmbase_private.h @@ -59,9 +59,8 @@ HRESULT WINAPI QualityControlImpl_SetSink(IQualityControl *iface, IQualityContro
void QualityControlRender_Start(QualityControlImpl *This, REFERENCE_TIME tStart); void QualityControlRender_SetClock(QualityControlImpl *This, IReferenceClock *clock); -HRESULT QualityControlRender_WaitFor(QualityControlImpl *This, IMediaSample *sample, HANDLE ev); void QualityControlRender_DoQOS(QualityControlImpl *priv); -void QualityControlRender_BeginRender(QualityControlImpl *This); +void QualityControlRender_BeginRender(QualityControlImpl *This, REFERENCE_TIME start, REFERENCE_TIME stop); void QualityControlRender_EndRender(QualityControlImpl *This);
HRESULT enum_pins_create(BaseFilter *base, IEnumPins **enum_pins);