Zebediah Figura : strmbase: Split RenderEvent into separate events for advising and flushing.

Alexandre Julliard julliard at winehq.org
Tue Jul 2 15:32:01 CDT 2019


Module: wine
Branch: master
Commit: 881f9380676887668d9be8018d7b5e0df8d15f42
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=881f9380676887668d9be8018d7b5e0df8d15f42

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Mon Jul  1 22:49:48 2019 -0500

strmbase: Split RenderEvent into separate events for advising and flushing.

While it's certainly possible to use one event for both purposes, it's a
little less clear, and it makes it a little more difficult to do other waits
that need to be interrupted by flushing. For example, the video renderer
should block in Receive() after rendering the sample until the filter is run.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/quartz/dsoundrender.c  |  2 +-
 dlls/quartz/videorenderer.c |  2 +-
 dlls/strmbase/renderer.c    | 20 ++++++++++++--------
 include/wine/strmbase.h     | 27 ++++++++++++++++-----------
 4 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index 0a69a5c..f74b673 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -736,7 +736,7 @@ static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface)
             This->renderer.filter.state = State_Paused;
 
         ResetEvent(This->blocked);
-        ResetEvent(This->renderer.RenderEvent);
+        ResetEvent(This->renderer.flush_event);
     }
     LeaveCriticalSection(&This->renderer.csRenderLock);
 
diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c
index ba512a2..2a18015 100644
--- a/dlls/quartz/videorenderer.c
+++ b/dlls/quartz/videorenderer.c
@@ -679,7 +679,7 @@ static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
             VideoRenderer_AutoShowWindow(This);
         }
 
-        ResetEvent(This->renderer.RenderEvent);
+        ResetEvent(This->renderer.flush_event);
         This->renderer.filter.state = State_Paused;
     }
     LeaveCriticalSection(&This->renderer.csRenderLock);
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index 1ba975d..06adbe7 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -267,7 +267,8 @@ HRESULT WINAPI strmbase_renderer_init(BaseRenderer *filter, const IBaseFilterVtb
     InitializeCriticalSection(&filter->csRenderLock);
     filter->csRenderLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": BaseRenderer.csRenderLock");
     filter->state_event = CreateEventW(NULL, TRUE, TRUE, NULL);
-    filter->RenderEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+    filter->advise_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+    filter->flush_event = CreateEventW(NULL, TRUE, TRUE, NULL);
     filter->pMediaSample = NULL;
 
     QualityControlImpl_Create(&filter->sink.pin.IPin_iface, &filter->filter.IBaseFilter_iface, &filter->qcimpl);
@@ -291,7 +292,8 @@ void strmbase_renderer_cleanup(BaseRenderer *filter)
 
     BaseRendererImpl_ClearPendingSample(filter);
     CloseHandle(filter->state_event);
-    CloseHandle(filter->RenderEvent);
+    CloseHandle(filter->advise_event);
+    CloseHandle(filter->flush_event);
     QualityControlImpl_Destroy(filter->qcimpl);
     strmbase_filter_cleanup(&filter->filter);
 }
@@ -366,12 +368,14 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp
 
             if (now - This->filter.rtStreamStart - start <= -10000)
             {
+                HANDLE handles[2] = {This->advise_event, This->flush_event};
+
                 IReferenceClock_AdviseTime(This->filter.pClock, This->filter.rtStreamStart,
-                        start, (HEVENT)This->RenderEvent, &cookie);
+                        start, (HEVENT)This->advise_event, &cookie);
 
                 LeaveCriticalSection(&This->csRenderLock);
 
-                WaitForSingleObject(This->RenderEvent, INFINITE);
+                WaitForMultipleObjects(2, handles, FALSE, INFINITE);
                 IReferenceClock_Unadvise(This->filter.pClock, cookie);
 
                 EnterCriticalSection(&This->csRenderLock);
@@ -418,7 +422,7 @@ HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface)
             This->pFuncsTable->pfnOnStopStreaming(This);
         This->filter.state = State_Stopped;
         SetEvent(This->state_event);
-        SetEvent(This->RenderEvent);
+        SetEvent(This->flush_event);
     }
     LeaveCriticalSection(&This->csRenderLock);
 
@@ -489,7 +493,7 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface)
 
             if (This->filter.state == State_Stopped)
                 BaseRendererImpl_ClearPendingSample(This);
-            ResetEvent(This->RenderEvent);
+            ResetEvent(This->flush_event);
             This->filter.state = State_Paused;
         }
     }
@@ -555,7 +559,7 @@ HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface)
 {
     TRACE("(%p)\n", iface);
     BaseRendererImpl_ClearPendingSample(iface);
-    SetEvent(iface->RenderEvent);
+    SetEvent(iface->flush_event);
     return S_OK;
 }
 
@@ -564,7 +568,7 @@ HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface)
     TRACE("(%p)\n", iface);
     QualityControlRender_Start(iface->qcimpl, iface->filter.rtStreamStart);
     RendererPosPassThru_ResetMediaTime(iface->pPosition);
-    ResetEvent(iface->RenderEvent);
+    ResetEvent(iface->flush_event);
     return S_OK;
 }
 
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 4ea45cf..22d65f8 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -535,21 +535,26 @@ HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo);
 /* BaseRenderer Filter */
 typedef struct BaseRendererTag
 {
-	BaseFilter filter;
+    BaseFilter filter;
 
-	BaseInputPin sink;
-	IUnknown *pPosition;
-	CRITICAL_SECTION csRenderLock;
+    BaseInputPin sink;
+    IUnknown *pPosition;
+    CRITICAL_SECTION csRenderLock;
     /* Signaled when the filter has completed a state change. The filter waits
      * for this event in IBaseFilter::GetState(). */
-	HANDLE state_event;
-	HANDLE RenderEvent;
-	IMediaSample *pMediaSample;
-
-	IQualityControl *pQSink;
-	struct QualityControlImpl *qcimpl;
+    HANDLE state_event;
+    /* Signaled when the sample presentation time occurs. The streaming thread
+     * waits for this event in Receive() if applicable. */
+    HANDLE advise_event;
+    /* Signaled when a flush or state change occurs, i.e. anything that needs
+     * to immediately unblock the streaming thread. */
+    HANDLE flush_event;
+    IMediaSample *pMediaSample;
+
+    IQualityControl *pQSink;
+    struct QualityControlImpl *qcimpl;
 
-	const struct BaseRendererFuncTable * pFuncsTable;
+    const struct BaseRendererFuncTable *pFuncsTable;
 } BaseRenderer;
 
 typedef HRESULT (WINAPI *BaseRenderer_CheckMediaType)(BaseRenderer *This, const AM_MEDIA_TYPE *pmt);




More information about the wine-cvs mailing list