Nikolay Sivov : mf/evr: Handle mixer sample requests during sink state transitions.
Alexandre Julliard
julliard at winehq.org
Mon Apr 26 15:51:31 CDT 2021
Module: wine
Branch: master
Commit: 2a6f0a4093a5465f87615bdbf313e9d82c627d53
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2a6f0a4093a5465f87615bdbf313e9d82c627d53
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Apr 26 11:23:33 2021 +0300
mf/evr: Handle mixer sample requests during sink state transitions.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mf/evr.c | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c
index 8b4a9c03b5f..baa6665853e 100644
--- a/dlls/mf/evr.c
+++ b/dlls/mf/evr.c
@@ -47,6 +47,7 @@ enum video_stream_flags
{
EVR_STREAM_PREROLLING = 0x1,
EVR_STREAM_PREROLLED = 0x2,
+ EVR_STREAM_SAMPLE_NEEDED = 0x4,
};
struct video_renderer;
@@ -1825,13 +1826,19 @@ static ULONG WINAPI video_renderer_clock_sink_Release(IMFClockStateSink *iface)
static HRESULT WINAPI video_renderer_clock_sink_OnClockStart(IMFClockStateSink *iface, MFTIME systime, LONGLONG offset)
{
struct video_renderer *renderer = impl_from_IMFClockStateSink(iface);
+ unsigned int state, request_sample;
size_t i;
TRACE("%p, %s, %s.\n", iface, debugstr_time(systime), debugstr_time(offset));
EnterCriticalSection(&renderer->cs);
- if (renderer->state == EVR_STATE_STOPPED)
+ state = renderer->state;
+
+ /* Update sink state before sending sample requests, to avoid potentially receiving new sample in stopped state */
+ renderer->state = EVR_STATE_RUNNING;
+
+ if (state == EVR_STATE_STOPPED)
{
IMFTransform_ProcessMessage(renderer->mixer, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
IMFVideoPresenter_ProcessMessage(renderer->presenter, MFVP_MESSAGE_BEGINSTREAMING, 0);
@@ -1840,19 +1847,19 @@ static HRESULT WINAPI video_renderer_clock_sink_OnClockStart(IMFClockStateSink *
{
struct video_stream *stream = renderer->streams[i];
- IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamSinkStarted, &GUID_NULL, S_OK, NULL);
-
EnterCriticalSection(&stream->cs);
- if (!(stream->flags & EVR_STREAM_PREROLLED))
- IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamSinkRequestSample,
- &GUID_NULL, S_OK, NULL);
+ request_sample = !(stream->flags & EVR_STREAM_PREROLLED) || (stream->flags & EVR_STREAM_SAMPLE_NEEDED);
stream->flags |= EVR_STREAM_PREROLLED;
+ stream->flags &= ~EVR_STREAM_SAMPLE_NEEDED;
LeaveCriticalSection(&stream->cs);
+
+ IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamSinkStarted, &GUID_NULL, S_OK, NULL);
+ if (request_sample)
+ IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamSinkRequestSample,
+ &GUID_NULL, S_OK, NULL);
}
}
- renderer->state = EVR_STATE_RUNNING;
-
IMFVideoPresenter_OnClockStart(renderer->presenter, systime, offset);
LeaveCriticalSection(&renderer->cs);
@@ -1886,7 +1893,7 @@ static HRESULT WINAPI video_renderer_clock_sink_OnClockStop(IMFClockStateSink *i
IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamSinkStopped, &GUID_NULL, S_OK, NULL);
EnterCriticalSection(&stream->cs);
- stream->flags &= ~EVR_STREAM_PREROLLED;
+ stream->flags &= ~(EVR_STREAM_PREROLLED | EVR_STREAM_SAMPLE_NEEDED);
LeaveCriticalSection(&stream->cs);
}
renderer->state = EVR_STATE_STOPPED;
@@ -2184,11 +2191,17 @@ static HRESULT WINAPI video_renderer_event_sink_Notify(IMediaEventSink *iface, L
idx = param1;
if (idx >= renderer->stream_count)
hr = MF_E_INVALIDSTREAMNUMBER;
- else
+ else if (renderer->state == EVR_STATE_RUNNING)
{
hr = IMFMediaEventQueue_QueueEventParamVar(renderer->streams[idx]->event_queue,
MEStreamSinkRequestSample, &GUID_NULL, S_OK, NULL);
}
+ else
+ {
+ /* Mixer asks for more input right after preroll too, before renderer finished running state transition.
+ Mark such streams here, and issue requests later in OnClockStart(). */
+ renderer->streams[idx]->flags |= EVR_STREAM_SAMPLE_NEEDED;
+ }
}
else if (event == EC_DISPLAY_CHANGED)
{
More information about the wine-cvs
mailing list