From 1917fe0e0734df60911739872efcdcbf2c665a68 Mon Sep 17 00:00:00 2001 From: Anton Baskanov Date: Tue, 20 Apr 2021 00:22:55 +0700 Subject: [PATCH] amstream: Call IMediaStreamFilter::Flush in IPin::BeginFlush. Signed-off-by: Anton Baskanov Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/amstream/audiostream.c | 8 ++++++++ dlls/amstream/ddrawstream.c | 8 ++++++++ dlls/amstream/tests/amstream.c | 12 ++++++------ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/dlls/amstream/audiostream.c b/dlls/amstream/audiostream.c index a07e62a4672..77ed4072ccf 100644 --- a/dlls/amstream/audiostream.c +++ b/dlls/amstream/audiostream.c @@ -1168,17 +1168,25 @@ static HRESULT WINAPI audio_sink_EndOfStream(IPin *iface) static HRESULT WINAPI audio_sink_BeginFlush(IPin *iface) { struct audio_stream *stream = impl_from_IPin(iface); + BOOL cancel_eos; TRACE("stream %p.\n", stream); EnterCriticalSection(&stream->cs); + cancel_eos = stream->eos; + stream->flushing = TRUE; stream->eos = FALSE; flush_receive_queue(stream); LeaveCriticalSection(&stream->cs); + /* Calling IMediaStreamFilter::Flush() inside the critical section would + * invert the locking order, so we must leave it first to avoid the + * application thread deadlocking on the filter's critical section. */ + IMediaStreamFilter_Flush(stream->filter, cancel_eos); + return S_OK; } diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index e04e3a1c56f..b1ef12cb524 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -1188,17 +1188,25 @@ static HRESULT WINAPI ddraw_sink_EndOfStream(IPin *iface) static HRESULT WINAPI ddraw_sink_BeginFlush(IPin *iface) { struct ddraw_stream *stream = impl_from_IPin(iface); + BOOL cancel_eos; TRACE("stream %p.\n", stream); EnterCriticalSection(&stream->cs); + cancel_eos = stream->eos; + stream->flushing = TRUE; stream->eos = FALSE; WakeConditionVariable(&stream->update_queued_cv); LeaveCriticalSection(&stream->cs); + /* Calling IMediaStreamFilter::Flush() inside the critical section would + * invert the locking order, so we must leave it first to avoid the + * application thread deadlocking on the filter's critical section. */ + IMediaStreamFilter_Flush(stream->filter, cancel_eos); + return S_OK; } diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index eaa1073532d..182fb06a082 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -4214,7 +4214,7 @@ static void test_audiostream_begin_flush_end_flush(void) hr = IPin_EndOfStream(pin2); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); hr = IPin_EndOfStream(pin); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -4248,8 +4248,8 @@ static void test_audiostream_begin_flush_end_flush(void) hr = IPin_EndOfStream(pin2); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); - todo_wine ok(graph.event_code == EC_COMPLETE, "Got event code %d.\n", graph.event_code); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.event_code == EC_COMPLETE, "Got event code %d.\n", graph.event_code); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -5808,7 +5808,7 @@ static void test_ddrawstream_begin_flush_end_flush(void) hr = IPin_EndOfStream(pin2); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); hr = IPin_EndOfStream(pin); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -5842,8 +5842,8 @@ static void test_ddrawstream_begin_flush_end_flush(void) hr = IPin_EndOfStream(pin2); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); - todo_wine ok(graph.event_code == EC_COMPLETE, "Got event code %d.\n", graph.event_code); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.event_code == EC_COMPLETE, "Got event code %d.\n", graph.event_code); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr);