mf: Detach sink stream on sample grabber shutdown.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2407a0f53b
commit
5d6241fbcb
|
@ -48,7 +48,7 @@ struct sample_grabber
|
||||||
IMFSampleGrabberSinkCallback *callback;
|
IMFSampleGrabberSinkCallback *callback;
|
||||||
IMFMediaType *media_type;
|
IMFMediaType *media_type;
|
||||||
BOOL is_shut_down;
|
BOOL is_shut_down;
|
||||||
IMFStreamSink *stream;
|
struct sample_grabber_stream *stream;
|
||||||
IMFMediaEventQueue *event_queue;
|
IMFMediaEventQueue *event_queue;
|
||||||
IMFPresentationClock *clock;
|
IMFPresentationClock *clock;
|
||||||
CRITICAL_SECTION cs;
|
CRITICAL_SECTION cs;
|
||||||
|
@ -139,7 +139,8 @@ static ULONG WINAPI sample_grabber_stream_Release(IMFStreamSink *iface)
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
{
|
{
|
||||||
IMFMediaSink_Release(&stream->sink->IMFMediaSink_iface);
|
if (stream->sink)
|
||||||
|
IMFMediaSink_Release(&stream->sink->IMFMediaSink_iface);
|
||||||
if (stream->event_queue)
|
if (stream->event_queue)
|
||||||
{
|
{
|
||||||
IMFMediaEventQueue_Shutdown(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);
|
TRACE("%p, %p.\n", iface, sink);
|
||||||
|
|
||||||
|
if (!stream->sink)
|
||||||
|
return MF_E_STREAMSINK_REMOVED;
|
||||||
|
|
||||||
*sink = &stream->sink->IMFMediaSink_iface;
|
*sink = &stream->sink->IMFMediaSink_iface;
|
||||||
IMFMediaSink_AddRef(*sink);
|
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)
|
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);
|
TRACE("%p, %p.\n", iface, identifier);
|
||||||
|
|
||||||
|
if (!stream->sink)
|
||||||
|
return MF_E_STREAMSINK_REMOVED;
|
||||||
|
|
||||||
*identifier = 0;
|
*identifier = 0;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -217,6 +226,12 @@ static HRESULT WINAPI sample_grabber_stream_GetMediaTypeHandler(IMFStreamSink *i
|
||||||
|
|
||||||
TRACE("%p, %p.\n", iface, handler);
|
TRACE("%p, %p.\n", iface, handler);
|
||||||
|
|
||||||
|
if (!handler)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
if (!stream->sink)
|
||||||
|
return MF_E_STREAMSINK_REMOVED;
|
||||||
|
|
||||||
*handler = &stream->IMFMediaTypeHandler_iface;
|
*handler = &stream->IMFMediaTypeHandler_iface;
|
||||||
IMFMediaTypeHandler_AddRef(*handler);
|
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);
|
TRACE("%p, %p, %p.\n", iface, in_type, out_type);
|
||||||
|
|
||||||
|
if (!stream->sink)
|
||||||
|
return MF_E_STREAMSINK_REMOVED;
|
||||||
|
|
||||||
if (!in_type)
|
if (!in_type)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
|
@ -332,6 +350,9 @@ static HRESULT WINAPI sample_grabber_stream_type_handler_SetCurrentMediaType(IMF
|
||||||
if (!media_type)
|
if (!media_type)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
|
if (!stream->sink)
|
||||||
|
return MF_E_STREAMSINK_REMOVED;
|
||||||
|
|
||||||
IMFMediaType_Release(stream->sink->media_type);
|
IMFMediaType_Release(stream->sink->media_type);
|
||||||
stream->sink->media_type = media_type;
|
stream->sink->media_type = media_type;
|
||||||
IMFMediaType_AddRef(stream->sink->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,
|
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);
|
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;
|
if (!media_type)
|
||||||
IMFMediaType_AddRef(*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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -358,6 +385,12 @@ static HRESULT WINAPI sample_grabber_stream_type_handler_GetMajorType(IMFMediaTy
|
||||||
|
|
||||||
TRACE("%p, %p.\n", iface, type);
|
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);
|
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;
|
hr = MF_E_INVALIDINDEX;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*stream = grabber->stream;
|
*stream = &grabber->stream->IMFStreamSink_iface;
|
||||||
IMFStreamSink_AddRef(*stream);
|
IMFStreamSink_AddRef(*stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,7 +564,7 @@ static HRESULT WINAPI sample_grabber_sink_GetStreamSinkById(IMFMediaSink *iface,
|
||||||
hr = MF_E_INVALIDSTREAMNUMBER;
|
hr = MF_E_INVALIDSTREAMNUMBER;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*stream = grabber->stream;
|
*stream = &grabber->stream->IMFStreamSink_iface;
|
||||||
IMFStreamSink_AddRef(*stream);
|
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)
|
static HRESULT WINAPI sample_grabber_sink_Shutdown(IMFMediaSink *iface)
|
||||||
{
|
{
|
||||||
struct sample_grabber *grabber = impl_from_IMFMediaSink(iface);
|
struct sample_grabber *grabber = impl_from_IMFMediaSink(iface);
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("%p.\n", iface);
|
TRACE("%p.\n", iface);
|
||||||
|
|
||||||
|
@ -605,11 +639,16 @@ static HRESULT WINAPI sample_grabber_sink_Shutdown(IMFMediaSink *iface)
|
||||||
|
|
||||||
EnterCriticalSection(&grabber->cs);
|
EnterCriticalSection(&grabber->cs);
|
||||||
grabber->is_shut_down = TRUE;
|
grabber->is_shut_down = TRUE;
|
||||||
IMFStreamSink_Release(grabber->stream);
|
if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnShutdown(grabber->callback)))
|
||||||
grabber->stream = NULL;
|
{
|
||||||
|
IMFMediaSink_Release(&grabber->stream->sink->IMFMediaSink_iface);
|
||||||
|
grabber->stream->sink = NULL;
|
||||||
|
IMFStreamSink_Release(&grabber->stream->IMFStreamSink_iface);
|
||||||
|
grabber->stream = NULL;
|
||||||
|
}
|
||||||
EnterCriticalSection(&grabber->cs);
|
EnterCriticalSection(&grabber->cs);
|
||||||
|
|
||||||
return E_NOTIMPL;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IMFMediaSinkVtbl sample_grabber_sink_vtbl =
|
static const IMFMediaSinkVtbl sample_grabber_sink_vtbl =
|
||||||
|
@ -761,7 +800,7 @@ static const IMFClockStateSinkVtbl sample_grabber_clock_sink_vtbl =
|
||||||
sample_grabber_clock_sink_OnClockSetRate,
|
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;
|
struct sample_grabber_stream *object;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -779,7 +818,7 @@ static HRESULT sample_grabber_create_stream(struct sample_grabber *sink, IMFStre
|
||||||
if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
|
if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
*stream = &object->IMFStreamSink_iface;
|
*stream = object;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
|
|
@ -946,27 +946,6 @@ static void test_session_events(IMFMediaSession *session)
|
||||||
hr = IMFMediaSession_Shutdown(session);
|
hr = IMFMediaSession_Shutdown(session);
|
||||||
todo_wine
|
todo_wine
|
||||||
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
|
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)
|
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)
|
static HRESULT WINAPI grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl =
|
static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl =
|
||||||
|
@ -1767,33 +1746,6 @@ static void test_sample_grabber(void)
|
||||||
todo_wine
|
todo_wine
|
||||||
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
|
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);
|
hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
|
||||||
ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
|
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);
|
hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
|
||||||
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
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_type2);
|
||||||
IMFMediaType_Release(media_type);
|
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);
|
IMFMediaSink_Release(sink);
|
||||||
IMFStreamSink_Release(stream);
|
IMFStreamSink_Release(stream);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue