Signed-off-by: Nikolay Sivov nsivov@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);