Currently, the winegstreamer media source checks for EOS when RequestSample() is called, but doesn't handle the cases when EOS is detected between the RequestSample() call and the moment when the request is popped from the command queue and serviced. This can result in the media source waiting forever for a sample and get stuck.
This commit fixes the bug by adding a check for EOS in wg_parser_stream_get_event().
This commit fixes Medieval Dynasty hanging on developer logos on the Steam Deck.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- dlls/winegstreamer/media_source.c | 13 ++++++++++--- dlls/winegstreamer/wg_parser.c | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 85ec31d2498..5393835b696 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -548,9 +548,16 @@ static void wait_on_sample(struct media_stream *stream, IUnknown *token) return;
case WG_PARSER_EVENT_EOS: - stream->eos = TRUE; - IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEEndOfStream, &GUID_NULL, S_OK, &empty_var); - dispatch_end_of_presentation(stream->parent_source); + if (stream->eos) + { + IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEError, &GUID_NULL, MF_E_END_OF_STREAM, &empty_var); + } + else + { + stream->eos = TRUE; + IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEEndOfStream, &GUID_NULL, S_OK, &empty_var); + dispatch_end_of_presentation(stream->parent_source); + } return;
case WG_PARSER_EVENT_SEGMENT: diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 013566b25e9..beb4d92bf5b 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -106,7 +106,7 @@ struct wg_parser_stream GstBuffer *buffer; GstMapInfo map_info;
- bool flushing, eos, enabled, has_caps; + bool flushing, eos, processed_eos, enabled, has_caps;
uint64_t duration; }; @@ -681,7 +681,7 @@ static NTSTATUS wg_parser_stream_get_event(void *args)
pthread_mutex_lock(&parser->mutex);
- while (!parser->flushing && stream->event.type == WG_PARSER_EVENT_NONE) + while (!parser->flushing && !stream->processed_eos && stream->event.type == WG_PARSER_EVENT_NONE) pthread_cond_wait(&stream->event_cond, &parser->mutex);
if (parser->flushing) @@ -691,7 +691,16 @@ static NTSTATUS wg_parser_stream_get_event(void *args) return VFW_E_WRONG_STATE; }
- *params->event = stream->event; + if (stream->processed_eos) + params->event->type = WG_PARSER_EVENT_EOS; + else + *params->event = stream->event; + + if (stream->event.type == WG_PARSER_EVENT_EOS && !stream->processed_eos) + { + stream->processed_eos = true; + pthread_cond_signal(&stream->event_cond); + }
if (stream->event.type != WG_PARSER_EVENT_BUFFER) {