[PATCH 2/4] mf/evr: Add per-stream lock.

Nikolay Sivov nsivov at codeweavers.com
Fri Oct 16 08:38:09 CDT 2020


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

diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c
index af9bd9e0e42..ac80193ddd6 100644
--- a/dlls/mf/evr.c
+++ b/dlls/mf/evr.c
@@ -47,6 +47,7 @@ struct video_stream
     struct video_renderer *parent;
     IMFMediaEventQueue *event_queue;
     IMFVideoSampleAllocator *allocator;
+    CRITICAL_SECTION cs;
 };
 
 struct video_renderer
@@ -213,6 +214,7 @@ static ULONG WINAPI video_stream_sink_Release(IMFStreamSink *iface)
             IMFMediaEventQueue_Release(stream->event_queue);
         if (stream->allocator)
             IMFVideoSampleAllocator_Release(stream->allocator);
+        DeleteCriticalSection(&stream->cs);
         heap_free(stream);
     }
 
@@ -260,20 +262,23 @@ static HRESULT WINAPI video_stream_sink_QueueEvent(IMFStreamSink *iface, MediaEv
 static HRESULT WINAPI video_stream_sink_GetMediaSink(IMFStreamSink *iface, IMFMediaSink **sink)
 {
     struct video_stream *stream = impl_from_IMFStreamSink(iface);
+    HRESULT hr = S_OK;
 
     TRACE("%p, %p.\n", iface, sink);
 
+    EnterCriticalSection(&stream->cs);
     if (!stream->parent)
-        return MF_E_STREAMSINK_REMOVED;
-
-    if (!sink)
-        return E_POINTER;
-
-    /* FIXME: not entirely safe if sink is being shut down. */
-    *sink = &stream->parent->IMFMediaSink_iface;
-    IMFMediaSink_AddRef(*sink);
+        hr = MF_E_STREAMSINK_REMOVED;
+    else if (!sink)
+        hr = E_POINTER;
+    else
+    {
+        *sink = &stream->parent->IMFMediaSink_iface;
+        IMFMediaSink_AddRef(*sink);
+    }
+    LeaveCriticalSection(&stream->cs);
 
-    return S_OK;
+    return hr;
 }
 
 static HRESULT WINAPI video_stream_sink_GetIdentifier(IMFStreamSink *iface, DWORD *id)
@@ -533,6 +538,7 @@ static HRESULT video_renderer_stream_create(struct video_renderer *renderer, uns
     stream->IMFMediaTypeHandler_iface.lpVtbl = &video_stream_type_handler_vtbl;
     stream->IMFGetService_iface.lpVtbl = &video_stream_get_service_vtbl;
     stream->refcount = 1;
+    InitializeCriticalSection(&stream->cs);
 
     if (FAILED(hr = MFCreateEventQueue(&stream->event_queue)))
         goto failed;
@@ -894,10 +900,15 @@ static HRESULT WINAPI video_renderer_sink_Shutdown(IMFMediaSink *iface)
     /* Detach streams from the sink. */
     for (i = 0; i < renderer->stream_count; ++i)
     {
-        IMFMediaSink_Release(&renderer->streams[i]->parent->IMFMediaSink_iface);
-        renderer->streams[i]->parent = NULL;
-        IMFMediaEventQueue_Shutdown(renderer->streams[i]->event_queue);
-        IMFStreamSink_Release(&renderer->streams[i]->IMFStreamSink_iface);
+        struct video_stream *stream = renderer->streams[i];
+
+        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;
     }
     heap_free(renderer->streams);
-- 
2.28.0




More information about the wine-devel mailing list