[PATCH] winegstreamer: Do not block forever if EOS races with command queue.

Giovanni Mascellani gmascellani at codeweavers.com
Tue Feb 8 11:11:49 CST 2022


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 at 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)
     {
-- 
2.34.1




More information about the wine-devel mailing list