[PATCH 1/3] mf/evr: Consistently check for shutdown flag within a lock.

Nikolay Sivov wine at gitlab.winehq.org
Mon Jul 4 14:06:40 CDT 2022


From: Nikolay Sivov <nsivov at codeweavers.com>

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/evr.c | 115 +++++++++++++++++++++++++++++---------------------
 1 file changed, 66 insertions(+), 49 deletions(-)

diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c
index c9506af9143..db7053a1405 100644
--- a/dlls/mf/evr.c
+++ b/dlls/mf/evr.c
@@ -1432,38 +1432,43 @@ static HRESULT WINAPI video_renderer_sink_GetPresentationClock(IMFMediaSink *ifa
 static HRESULT WINAPI video_renderer_sink_Shutdown(IMFMediaSink *iface)
 {
     struct video_renderer *renderer = impl_from_IMFMediaSink(iface);
+    HRESULT hr = S_OK;
     size_t i;
 
     TRACE("%p.\n", iface);
 
-    if (renderer->flags & EVR_SHUT_DOWN)
-        return MF_E_SHUTDOWN;
-
     EnterCriticalSection(&renderer->cs);
-    renderer->flags |= EVR_SHUT_DOWN;
-    /* Detach streams from the sink. */
-    for (i = 0; i < renderer->stream_count; ++i)
+
+    if (renderer->flags & EVR_SHUT_DOWN)
+        hr = MF_E_SHUTDOWN;
+    else
     {
-        struct video_stream *stream = renderer->streams[i];
+        renderer->flags |= EVR_SHUT_DOWN;
+        /* Detach streams from the sink. */
+        for (i = 0; i < renderer->stream_count; ++i)
+        {
+            struct video_stream *stream = renderer->streams[i];
 
-        EnterCriticalSection(&stream->cs);
-        stream->parent = NULL;
-        LeaveCriticalSection(&stream->cs);
+            EnterCriticalSection(&stream->cs);
+            stream->parent = NULL;
+            LeaveCriticalSection(&stream->cs);
 
-        IMFMediaEventQueue_Shutdown(stream->event_queue);
-        IMFStreamSink_Release(&stream->IMFStreamSink_iface);
-        IMFMediaSink_Release(iface);
-        renderer->streams[i] = NULL;
+            IMFMediaEventQueue_Shutdown(stream->event_queue);
+            IMFStreamSink_Release(&stream->IMFStreamSink_iface);
+            IMFMediaSink_Release(iface);
+            renderer->streams[i] = NULL;
+        }
+        free(renderer->streams);
+        renderer->stream_count = 0;
+        renderer->stream_size = 0;
+        IMFMediaEventQueue_Shutdown(renderer->event_queue);
+        video_renderer_set_presentation_clock(renderer, NULL);
+        video_renderer_release_services(renderer);
     }
-    free(renderer->streams);
-    renderer->stream_count = 0;
-    renderer->stream_size = 0;
-    IMFMediaEventQueue_Shutdown(renderer->event_queue);
-    video_renderer_set_presentation_clock(renderer, NULL);
-    video_renderer_release_services(renderer);
+
     LeaveCriticalSection(&renderer->cs);
 
-    return S_OK;
+    return hr;
 }
 
 static const IMFMediaSinkVtbl video_renderer_sink_vtbl =
@@ -1742,52 +1747,64 @@ static HRESULT video_renderer_initialize(struct video_renderer *renderer, IMFTra
     return hr;
 }
 
-static HRESULT WINAPI video_renderer_InitializeRenderer(IMFVideoRenderer *iface, IMFTransform *mixer,
-        IMFVideoPresenter *presenter)
+static HRESULT video_renderer_create_mixer_and_presenter(struct video_renderer *renderer,
+        IMFTransform **mixer, IMFVideoPresenter **presenter)
 {
-    struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface);
     HRESULT hr;
 
-    TRACE("%p, %p, %p.\n", iface, mixer, presenter);
-
-    EnterCriticalSection(&renderer->cs);
-
-    if (renderer->flags & EVR_SHUT_DOWN)
+    if (*mixer)
     {
-        LeaveCriticalSection(&renderer->cs);
-        return MF_E_SHUTDOWN;
+        IMFTransform_AddRef(*mixer);
     }
-
-    video_renderer_uninitialize(renderer);
-
-    if (mixer)
-        IMFTransform_AddRef(mixer);
-    else if (FAILED(hr = video_renderer_create_mixer(NULL, &mixer)))
+    else if (FAILED(hr = video_renderer_create_mixer(NULL, mixer)))
     {
         WARN("Failed to create default mixer object, hr %#lx.\n", hr);
-        LeaveCriticalSection(&renderer->cs);
         return hr;
     }
 
-    if (presenter)
-        IMFVideoPresenter_AddRef(presenter);
-    else if (FAILED(hr = video_renderer_create_presenter(renderer, NULL, &presenter)))
+    if (*presenter)
+    {
+        IMFVideoPresenter_AddRef(*presenter);
+    }
+    else if (FAILED(hr = video_renderer_create_presenter(renderer, NULL, presenter)))
     {
         WARN("Failed to create default presenter, hr %#lx.\n", hr);
-        LeaveCriticalSection(&renderer->cs);
-        IMFTransform_Release(mixer);
+        IMFTransform_Release(*mixer);
         return hr;
     }
 
-    /* FIXME: check clock state */
-    /* FIXME: check that streams are not initialized */
+    return S_OK;
+}
 
-    hr = video_renderer_initialize(renderer, mixer, presenter);
+static HRESULT WINAPI video_renderer_InitializeRenderer(IMFVideoRenderer *iface, IMFTransform *mixer,
+        IMFVideoPresenter *presenter)
+{
+    struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface);
+    HRESULT hr;
 
-    LeaveCriticalSection(&renderer->cs);
+    TRACE("%p, %p, %p.\n", iface, mixer, presenter);
 
-    IMFTransform_Release(mixer);
-    IMFVideoPresenter_Release(presenter);
+    EnterCriticalSection(&renderer->cs);
+
+    if (renderer->flags & EVR_SHUT_DOWN)
+        hr = MF_E_SHUTDOWN;
+    else
+    {
+        video_renderer_uninitialize(renderer);
+
+        if (SUCCEEDED(hr = video_renderer_create_mixer_and_presenter(renderer, &mixer, &presenter)))
+        {
+            /* FIXME: check clock state */
+            /* FIXME: check that streams are not initialized */
+
+            hr = video_renderer_initialize(renderer, mixer, presenter);
+
+            IMFTransform_Release(mixer);
+            IMFVideoPresenter_Release(presenter);
+        }
+    }
+
+    LeaveCriticalSection(&renderer->cs);
 
     return hr;
 }
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/372



More information about the wine-devel mailing list