From e49c550bdc76a0418f60a9adddb324a61743b8d0 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 22 Apr 2020 16:32:14 +0300 Subject: [PATCH] mf: Release presentation clock on sample grabber shutdown. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mf/samplegrabber.c | 48 +++++++++++++++++++++++------------------ dlls/mf/tests/mf.c | 5 +++-- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c index bd5859d4f44..1919ce62208 100644 --- a/dlls/mf/samplegrabber.c +++ b/dlls/mf/samplegrabber.c @@ -956,6 +956,31 @@ static HRESULT WINAPI sample_grabber_sink_GetStreamSinkById(IMFMediaSink *iface, return hr; } +static void sample_grabber_set_presentation_clock(struct sample_grabber *grabber, IMFPresentationClock *clock) +{ + if (grabber->clock) + { + IMFPresentationClock_RemoveClockStateSink(grabber->clock, &grabber->IMFClockStateSink_iface); + IMFPresentationClock_Release(grabber->clock); + if (grabber->timer) + { + IMFTimer_Release(grabber->timer); + grabber->timer = NULL; + } + } + grabber->clock = clock; + if (grabber->clock) + { + IMFPresentationClock_AddRef(grabber->clock); + IMFPresentationClock_AddClockStateSink(grabber->clock, &grabber->IMFClockStateSink_iface); + if (FAILED(IMFPresentationClock_QueryInterface(grabber->clock, &IID_IMFTimer, (void **)&grabber->timer))) + { + WARN("Failed to get IMFTimer interface.\n"); + grabber->timer = NULL; + } + } +} + static HRESULT WINAPI sample_grabber_sink_SetPresentationClock(IMFMediaSink *iface, IMFPresentationClock *clock) { struct sample_grabber *grabber = impl_from_IMFMediaSink(iface); @@ -968,27 +993,7 @@ static HRESULT WINAPI sample_grabber_sink_SetPresentationClock(IMFMediaSink *ifa if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnSetPresentationClock(sample_grabber_get_callback(grabber), clock))) { - if (grabber->clock) - { - IMFPresentationClock_RemoveClockStateSink(grabber->clock, &grabber->IMFClockStateSink_iface); - IMFPresentationClock_Release(grabber->clock); - if (grabber->timer) - { - IMFTimer_Release(grabber->timer); - grabber->timer = NULL; - } - } - grabber->clock = clock; - if (grabber->clock) - { - IMFPresentationClock_AddRef(grabber->clock); - IMFPresentationClock_AddClockStateSink(grabber->clock, &grabber->IMFClockStateSink_iface); - if (FAILED(IMFPresentationClock_QueryInterface(grabber->clock, &IID_IMFTimer, (void **)&grabber->timer))) - { - WARN("Failed to get IMFTimer interface.\n"); - grabber->timer = NULL; - } - } + sample_grabber_set_presentation_clock(grabber, clock); } LeaveCriticalSection(&grabber->cs); @@ -1035,6 +1040,7 @@ static HRESULT WINAPI sample_grabber_sink_Shutdown(IMFMediaSink *iface) grabber->is_shut_down = TRUE; if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnShutdown(sample_grabber_get_callback(grabber)))) { + sample_grabber_set_presentation_clock(grabber, NULL); IMFMediaEventQueue_Shutdown(grabber->stream_event_queue); IMFMediaEventQueue_Shutdown(grabber->event_queue); } diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 9e6b45e2f6f..ae9f58a4bcc 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2102,8 +2102,6 @@ static void test_sample_grabber(void) ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr); IMFPresentationTimeSource_Release(time_source); - IMFPresentationClock_Release(clock); - hr = IMFMediaSink_GetCharacteristics(sink, &flags); ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr); @@ -2221,8 +2219,10 @@ static void test_sample_grabber(void) hr = IMFStreamSink_GetEvent(stream, MF_EVENT_FLAG_NO_WAIT, &event); ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr); + EXPECT_REF(clock, 3); hr = IMFMediaSink_Shutdown(sink); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); + EXPECT_REF(clock, 1); hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); @@ -2355,6 +2355,7 @@ static void test_sample_grabber(void) IMFActivate_Release(activate); IMFMediaType_Release(media_type); + IMFPresentationClock_Release(clock); hr = MFShutdown(); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);