[PATCH 2/2] mf: Detach sink stream on sample grabber shutdown.

Nikolay Sivov nsivov at codeweavers.com
Tue May 28 07:08:29 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/samplegrabber.c |  65 ++++++++++++++++++-----
 dlls/mf/tests/mf.c      | 112 ++++++++++++++++++++++------------------
 2 files changed, 114 insertions(+), 63 deletions(-)

diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c
index 755d80f218..d501e0865d 100644
--- a/dlls/mf/samplegrabber.c
+++ b/dlls/mf/samplegrabber.c
@@ -48,7 +48,7 @@ struct sample_grabber
     IMFSampleGrabberSinkCallback *callback;
     IMFMediaType *media_type;
     BOOL is_shut_down;
-    IMFStreamSink *stream;
+    struct sample_grabber_stream *stream;
     IMFMediaEventQueue *event_queue;
     IMFPresentationClock *clock;
     CRITICAL_SECTION cs;
@@ -139,7 +139,8 @@ static ULONG WINAPI sample_grabber_stream_Release(IMFStreamSink *iface)
 
     if (!refcount)
     {
-        IMFMediaSink_Release(&stream->sink->IMFMediaSink_iface);
+        if (stream->sink)
+            IMFMediaSink_Release(&stream->sink->IMFMediaSink_iface);
         if (stream->event_queue)
         {
             IMFMediaEventQueue_Shutdown(stream->event_queue);
@@ -196,6 +197,9 @@ static HRESULT WINAPI sample_grabber_stream_GetMediaSink(IMFStreamSink *iface, I
 
     TRACE("%p, %p.\n", iface, sink);
 
+    if (!stream->sink)
+        return MF_E_STREAMSINK_REMOVED;
+
     *sink = &stream->sink->IMFMediaSink_iface;
     IMFMediaSink_AddRef(*sink);
 
@@ -204,8 +208,13 @@ static HRESULT WINAPI sample_grabber_stream_GetMediaSink(IMFStreamSink *iface, I
 
 static HRESULT WINAPI sample_grabber_stream_GetIdentifier(IMFStreamSink *iface, DWORD *identifier)
 {
+    struct sample_grabber_stream *stream = impl_from_IMFStreamSink(iface);
+
     TRACE("%p, %p.\n", iface, identifier);
 
+    if (!stream->sink)
+        return MF_E_STREAMSINK_REMOVED;
+
     *identifier = 0;
 
     return S_OK;
@@ -217,6 +226,12 @@ static HRESULT WINAPI sample_grabber_stream_GetMediaTypeHandler(IMFStreamSink *i
 
     TRACE("%p, %p.\n", iface, handler);
 
+    if (!handler)
+        return E_POINTER;
+
+    if (!stream->sink)
+        return MF_E_STREAMSINK_REMOVED;
+
     *handler = &stream->IMFMediaTypeHandler_iface;
     IMFMediaTypeHandler_AddRef(*handler);
 
@@ -290,6 +305,9 @@ static HRESULT WINAPI sample_grabber_stream_type_handler_IsMediaTypeSupported(IM
 
     TRACE("%p, %p, %p.\n", iface, in_type, out_type);
 
+    if (!stream->sink)
+        return MF_E_STREAMSINK_REMOVED;
+
     if (!in_type)
         return E_POINTER;
 
@@ -332,6 +350,9 @@ static HRESULT WINAPI sample_grabber_stream_type_handler_SetCurrentMediaType(IMF
     if (!media_type)
         return E_POINTER;
 
+    if (!stream->sink)
+        return MF_E_STREAMSINK_REMOVED;
+
     IMFMediaType_Release(stream->sink->media_type);
     stream->sink->media_type = media_type;
     IMFMediaType_AddRef(stream->sink->media_type);
@@ -340,14 +361,20 @@ static HRESULT WINAPI sample_grabber_stream_type_handler_SetCurrentMediaType(IMF
 }
 
 static HRESULT WINAPI sample_grabber_stream_type_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface,
-        IMFMediaType **type)
+        IMFMediaType **media_type)
 {
     struct sample_grabber_stream *stream = impl_from_IMFMediaTypeHandler(iface);
 
-    TRACE("%p, %p.\n", iface, type);
+    TRACE("%p, %p.\n", iface, media_type);
 
-    *type = stream->sink->media_type;
-    IMFMediaType_AddRef(*type);
+    if (!media_type)
+        return E_POINTER;
+
+    if (!stream->sink)
+        return MF_E_STREAMSINK_REMOVED;
+
+    *media_type = stream->sink->media_type;
+    IMFMediaType_AddRef(*media_type);
 
     return S_OK;
 }
@@ -358,6 +385,12 @@ static HRESULT WINAPI sample_grabber_stream_type_handler_GetMajorType(IMFMediaTy
 
     TRACE("%p, %p.\n", iface, type);
 
+    if (!type)
+        return E_POINTER;
+
+    if (!stream->sink)
+        return MF_E_STREAMSINK_REMOVED;
+
     return IMFMediaType_GetMajorType(stream->sink->media_type, type);
 }
 
@@ -506,7 +539,7 @@ static HRESULT WINAPI sample_grabber_sink_GetStreamSinkByIndex(IMFMediaSink *ifa
         hr = MF_E_INVALIDINDEX;
     else
     {
-       *stream = grabber->stream;
+       *stream = &grabber->stream->IMFStreamSink_iface;
        IMFStreamSink_AddRef(*stream);
     }
 
@@ -531,7 +564,7 @@ static HRESULT WINAPI sample_grabber_sink_GetStreamSinkById(IMFMediaSink *iface,
         hr = MF_E_INVALIDSTREAMNUMBER;
     else
     {
-        *stream = grabber->stream;
+        *stream = &grabber->stream->IMFStreamSink_iface;
         IMFStreamSink_AddRef(*stream);
     }
 
@@ -597,6 +630,7 @@ static HRESULT WINAPI sample_grabber_sink_GetPresentationClock(IMFMediaSink *ifa
 static HRESULT WINAPI sample_grabber_sink_Shutdown(IMFMediaSink *iface)
 {
     struct sample_grabber *grabber = impl_from_IMFMediaSink(iface);
+    HRESULT hr;
 
     TRACE("%p.\n", iface);
 
@@ -605,11 +639,16 @@ static HRESULT WINAPI sample_grabber_sink_Shutdown(IMFMediaSink *iface)
 
     EnterCriticalSection(&grabber->cs);
     grabber->is_shut_down = TRUE;
-    IMFStreamSink_Release(grabber->stream);
-    grabber->stream = NULL;
+    if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnShutdown(grabber->callback)))
+    {
+        IMFMediaSink_Release(&grabber->stream->sink->IMFMediaSink_iface);
+        grabber->stream->sink = NULL;
+        IMFStreamSink_Release(&grabber->stream->IMFStreamSink_iface);
+        grabber->stream = NULL;
+    }
     EnterCriticalSection(&grabber->cs);
 
-    return E_NOTIMPL;
+    return hr;
 }
 
 static const IMFMediaSinkVtbl sample_grabber_sink_vtbl =
@@ -761,7 +800,7 @@ static const IMFClockStateSinkVtbl sample_grabber_clock_sink_vtbl =
     sample_grabber_clock_sink_OnClockSetRate,
 };
 
-static HRESULT sample_grabber_create_stream(struct sample_grabber *sink, IMFStreamSink **stream)
+static HRESULT sample_grabber_create_stream(struct sample_grabber *sink, struct sample_grabber_stream **stream)
 {
     struct sample_grabber_stream *object;
     HRESULT hr;
@@ -779,7 +818,7 @@ static HRESULT sample_grabber_create_stream(struct sample_grabber *sink, IMFStre
     if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
         goto failed;
 
-    *stream = &object->IMFStreamSink_iface;
+    *stream = object;
 
     return S_OK;
 
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 2285eb8a0c..18aafe2bd0 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -946,27 +946,6 @@ static void test_session_events(IMFMediaSession *session)
     hr = IMFMediaSession_Shutdown(session);
 todo_wine
     ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
-
-    hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSession_QueueEvent(session, MEError, &GUID_NULL, E_FAIL, NULL);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, NULL);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL);
-    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSession_EndGetEvent(session, result, &event);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-    IMFAsyncResult_Release(result);
-
-    /* Already shut down. */
-    hr = IMFMediaSession_Shutdown(session);
-todo_wine
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
 }
 
 static void test_media_session(void)
@@ -1616,7 +1595,7 @@ static HRESULT WINAPI grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallb
 
 static HRESULT WINAPI grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
 {
-    return E_NOTIMPL;
+    return S_OK;
 }
 
 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl =
@@ -1767,33 +1746,6 @@ static void test_sample_grabber(void)
 todo_wine
     ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
 
-    hr = IMFMediaSink_Shutdown(sink);
-    ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSink_Shutdown(sink);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSink_GetCharacteristics(sink, &flags);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream2);
-    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
-
-    hr = IMFStreamSink_GetMediaSink(stream, &sink2);
-    ok(hr == S_OK, "Failed to get media sink, hr %x.\n", hr);
-    ok(sink2 == sink, "Unexpected sink.\n");
-    IMFMediaSink_Release(sink2);
-
-    hr = IMFStreamSink_GetIdentifier(stream, &id);
-    ok(hr == S_OK, "Failed to get stream id, hr %#x.\n", hr);
-    ok(id == 0, "Unexpected id %#x.\n", id);
-
     hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
     ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
 
@@ -1880,11 +1832,71 @@ todo_wine
     hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
     ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
 
-    IMFMediaTypeHandler_Release(handler);
+    hr = IMFMediaSink_Shutdown(sink);
+    ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
+
+    hr = IMFMediaSink_Shutdown(sink);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetCharacteristics(sink, &flags);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream2);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFStreamSink_GetMediaSink(stream, &sink2);
+    ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
+
+    id = 1;
+    hr = IMFStreamSink_GetIdentifier(stream, &id);
+    ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
+    ok(id == 1, "Unexpected id %u.\n", id);
+
+    media_type3 = (void *)0xdeadbeef;
+    hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
+    ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
+    ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
+
+    hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
+    ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
+    ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
 
     IMFMediaType_Release(media_type2);
     IMFMediaType_Release(media_type);
 
+    hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
+    ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
+    ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetMajorType(handler, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
+    ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
+
+    IMFMediaTypeHandler_Release(handler);
+
+    handler = (void *)0xdeadbeef;
+    hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
+    ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
+    ok(handler == (void *)0xdeadbeef, "Unexpected pointer.\n");
+
+    hr = IMFStreamSink_GetMediaTypeHandler(stream, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
     IMFMediaSink_Release(sink);
     IMFStreamSink_Release(stream);
 
-- 
2.20.1




More information about the wine-devel mailing list