[PATCH 3/5] winegstreamer: Return S_FALSE from wg_parser_stream_get_event() if the stream is EOS.

Zebediah Figura zfigura at codeweavers.com
Wed Feb 23 15:46:48 CST 2022


Instead of using WG_PARSER_EVENT_EOS.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
This obviates 4853f65c844de8277b8b0420df1a2cdb1c5b17c8.

 dlls/winegstreamer/gst_private.h   |   2 +-
 dlls/winegstreamer/main.c          |   4 +-
 dlls/winegstreamer/media_source.c  |  30 ++----
 dlls/winegstreamer/quartz_parser.c |  26 ++---
 dlls/winegstreamer/unixlib.h       |   1 -
 dlls/winegstreamer/wg_parser.c     |  56 +++++-----
 dlls/winegstreamer/wm_reader.c     | 164 +++++++++++++----------------
 7 files changed, 120 insertions(+), 163 deletions(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 288d127b23b..2f37d97378d 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -80,7 +80,7 @@ void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, stru
 void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format);
 void wg_parser_stream_disable(struct wg_parser_stream *stream);
 
-void wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event);
+bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event);
 bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
         void *data, uint32_t offset, uint32_t size);
 void wg_parser_stream_release_buffer(struct wg_parser_stream *stream);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 13db07c6edb..e9e347b0c65 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -172,7 +172,7 @@ void wg_parser_stream_disable(struct wg_parser_stream *stream)
     __wine_unix_call(unix_handle, unix_wg_parser_stream_disable, stream);
 }
 
-void wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event)
+bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event)
 {
     struct wg_parser_stream_get_event_params params =
     {
@@ -180,7 +180,7 @@ void wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parse
         .event = event,
     };
 
-    __wine_unix_call(unix_handle, unix_wg_parser_stream_get_event, &params);
+    return !__wine_unix_call(unix_handle, unix_wg_parser_stream_get_event, &params);
 }
 
 bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index 694497da259..92cb27dc5dc 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -532,33 +532,15 @@ static void wait_on_sample(struct media_stream *stream, IUnknown *token)
 
     TRACE("%p, %p\n", stream, token);
 
-    if (stream->eos)
+    if (wg_parser_stream_get_event(stream->wg_stream, &event))
     {
-        IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEError, &GUID_NULL, MF_E_END_OF_STREAM, &empty_var);
-        return;
+        send_buffer(stream, &event, token);
     }
-
-    for (;;)
+    else
     {
-        wg_parser_stream_get_event(stream->wg_stream, &event);
-
-        TRACE("Got event of type %#x.\n", event.type);
-
-        switch (event.type)
-        {
-            case WG_PARSER_EVENT_BUFFER:
-                send_buffer(stream, &event, 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);
-                return;
-
-            case WG_PARSER_EVENT_NONE:
-                assert(0);
-        }
+        stream->eos = TRUE;
+        IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEEndOfStream, &GUID_NULL, S_OK, &empty_var);
+        dispatch_end_of_presentation(stream->parent_source);
     }
 }
 
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index 628758b838b..9b0fa4acb93 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -833,25 +833,19 @@ static DWORD CALLBACK stream_thread(void *arg)
             continue;
         }
 
-        wg_parser_stream_get_event(pin->wg_stream, &event);
-
-        TRACE("Got event of type %#x.\n", event.type);
-
-        switch (event.type)
+        if (wg_parser_stream_get_event(pin->wg_stream, &event))
         {
-            case WG_PARSER_EVENT_BUFFER:
-                send_buffer(pin, &event);
-                break;
-
-            case WG_PARSER_EVENT_EOS:
-                IPin_EndOfStream(pin->pin.pin.peer);
-                pin->eos = true;
-                break;
-
-            case WG_PARSER_EVENT_NONE:
-                assert(0);
+            send_buffer(pin, &event);
+        }
+        else
+        {
+            TRACE("Got EOS.\n");
+            IPin_EndOfStream(pin->pin.pin.peer);
+            pin->eos = true;
         }
 
+        TRACE("Got event of type %#x.\n", event.type);
+
         LeaveCriticalSection(&pin->flushing_cs);
     }
 
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index 1ef80991fb4..9d75e94cb6a 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -107,7 +107,6 @@ enum wg_parser_event_type
 {
     WG_PARSER_EVENT_NONE = 0,
     WG_PARSER_EVENT_BUFFER,
-    WG_PARSER_EVENT_EOS,
 };
 
 struct wg_parser_event
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 61120a72da8..3cdeeeb5374 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -259,19 +259,20 @@ static NTSTATUS wg_parser_stream_get_event(void *args)
 
     pthread_mutex_lock(&parser->mutex);
 
-    while (stream->event.type == WG_PARSER_EVENT_NONE)
+    while (!stream->eos && stream->event.type == WG_PARSER_EVENT_NONE)
         pthread_cond_wait(&stream->event_cond, &parser->mutex);
 
-    *params->event = stream->event;
-
-    if (stream->event.type != WG_PARSER_EVENT_BUFFER)
+    /* Note that we can both have a buffer and stream->eos, in which case we
+     * must return the buffer. */
+    if (stream->event.type != WG_PARSER_EVENT_NONE)
     {
-        stream->event.type = WG_PARSER_EVENT_NONE;
-        pthread_cond_signal(&stream->event_empty_cond);
+        *params->event = stream->event;
+        pthread_mutex_unlock(&parser->mutex);
+        return S_OK;
     }
-    pthread_mutex_unlock(&parser->mutex);
 
-    return S_OK;
+    pthread_mutex_unlock(&parser->mutex);
+    return S_FALSE;
 }
 
 static NTSTATUS wg_parser_stream_copy_buffer(void *args)
@@ -434,16 +435,15 @@ static GstFlowReturn queue_stream_event(struct wg_parser_stream *stream,
         GST_DEBUG("Filter is flushing; discarding event.");
         return GST_FLOW_FLUSHING;
     }
-    if (buffer)
+
+    assert(GST_IS_BUFFER(buffer));
+    if (!gst_buffer_map(buffer, &stream->map_info, GST_MAP_READ))
     {
-        assert(GST_IS_BUFFER(buffer));
-        if (!gst_buffer_map(buffer, &stream->map_info, GST_MAP_READ))
-        {
-            pthread_mutex_unlock(&parser->mutex);
-            GST_ERROR("Failed to map buffer.\n");
-            return GST_FLOW_ERROR;
-        }
+        pthread_mutex_unlock(&parser->mutex);
+        GST_ERROR("Failed to map buffer.\n");
+        return GST_FLOW_ERROR;
     }
+
     stream->event = *event;
     stream->buffer = buffer;
     pthread_mutex_unlock(&parser->mutex);
@@ -479,20 +479,13 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
             break;
 
         case GST_EVENT_EOS:
+            pthread_mutex_lock(&parser->mutex);
+            stream->eos = true;
+            pthread_mutex_unlock(&parser->mutex);
             if (stream->enabled)
-            {
-                struct wg_parser_event stream_event;
-
-                stream_event.type = WG_PARSER_EVENT_EOS;
-                queue_stream_event(stream, &stream_event, NULL);
-            }
+                pthread_cond_signal(&stream->event_cond);
             else
-            {
-                pthread_mutex_lock(&parser->mutex);
-                stream->eos = true;
-                pthread_mutex_unlock(&parser->mutex);
                 pthread_cond_signal(&parser->init_cond);
-            }
             break;
 
         case GST_EVENT_FLUSH_START:
@@ -524,12 +517,13 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
             if (reset_time)
                 gst_segment_init(&stream->segment, GST_FORMAT_UNDEFINED);
 
+            pthread_mutex_lock(&parser->mutex);
+
+            stream->eos = false;
             if (stream->enabled)
-            {
-                pthread_mutex_lock(&parser->mutex);
                 stream->flushing = false;
-                pthread_mutex_unlock(&parser->mutex);
-            }
+
+            pthread_mutex_unlock(&parser->mutex);
             break;
         }
 
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index 6d2b9edbd09..96de6f2a3ba 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -1826,6 +1826,10 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
     IWMReaderCallbackAdvanced *callback_advanced = stream->reader->callback_advanced;
     struct wg_parser_stream *wg_stream = stream->wg_stream;
     struct wg_parser_event event;
+    DWORD size, capacity;
+    INSSBuffer *sample;
+    HRESULT hr;
+    BYTE *data;
 
     if (stream->selection == WMT_OFF)
         return NS_E_INVALID_REQUEST;
@@ -1835,104 +1839,88 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
 
     for (;;)
     {
-        wg_parser_stream_get_event(wg_stream, &event);
+        if (!wg_parser_stream_get_event(wg_stream, &event))
+        {
+            stream->eos = true;
+            TRACE("End of stream.\n");
+            return NS_E_NO_MORE_SAMPLES;
+        }
 
-        TRACE("Got event of type %#x for %s stream %p.\n", event.type,
-                get_major_type_string(stream->format.major_type), stream);
+        TRACE("Got buffer for '%s' stream %p.\n", get_major_type_string(stream->format.major_type), stream);
 
-        switch (event.type)
+        if (callback_advanced && stream->read_compressed && stream->allocate_stream)
         {
-            case WG_PARSER_EVENT_BUFFER:
+            if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForStream(callback_advanced,
+                    stream->index + 1, event.u.buffer.size, &sample, NULL)))
             {
-                DWORD size, capacity;
-                INSSBuffer *sample;
-                HRESULT hr;
-                BYTE *data;
-
-                if (callback_advanced && stream->read_compressed && stream->allocate_stream)
-                {
-                    if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForStream(callback_advanced,
-                            stream->index + 1, event.u.buffer.size, &sample, NULL)))
-                    {
-                        ERR("Failed to allocate stream sample of %u bytes, hr %#lx.\n", event.u.buffer.size, hr);
-                        wg_parser_stream_release_buffer(wg_stream);
-                        return hr;
-                    }
-                }
-                else if (callback_advanced && !stream->read_compressed && stream->allocate_output)
-                {
-                    if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced,
-                            stream->index, event.u.buffer.size, &sample, NULL)))
-                    {
-                        ERR("Failed to allocate output sample of %u bytes, hr %#lx.\n", event.u.buffer.size, hr);
-                        wg_parser_stream_release_buffer(wg_stream);
-                        return hr;
-                    }
-                }
-                else
-                {
-                    struct buffer *object;
-
-                    /* FIXME: Should these be pooled? */
-                    if (!(object = calloc(1, offsetof(struct buffer, data[event.u.buffer.size]))))
-                    {
-                        wg_parser_stream_release_buffer(wg_stream);
-                        return E_OUTOFMEMORY;
-                    }
-
-                    object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
-                    object->refcount = 1;
-                    object->capacity = event.u.buffer.size;
-
-                    TRACE("Created buffer %p.\n", object);
-                    sample = &object->INSSBuffer_iface;
-                }
-
-                if (FAILED(hr = INSSBuffer_GetBufferAndLength(sample, &data, &size)))
-                    ERR("Failed to get data pointer, hr %#lx.\n", hr);
-                if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity)))
-                    ERR("Failed to get capacity, hr %#lx.\n", hr);
-                if (event.u.buffer.size > capacity)
-                    ERR("Returned capacity %lu is less than requested capacity %u.\n",
-                            capacity, event.u.buffer.size);
-
-                if (!wg_parser_stream_copy_buffer(wg_stream, data, 0, event.u.buffer.size))
-                {
-                    /* The GStreamer pin has been flushed. */
-                    INSSBuffer_Release(sample);
-                    break;
-                }
-
-                if (FAILED(hr = INSSBuffer_SetLength(sample, event.u.buffer.size)))
-                    ERR("Failed to set size %u, hr %#lx.\n", event.u.buffer.size, hr);
-
+                ERR("Failed to allocate stream sample of %u bytes, hr %#lx.\n", event.u.buffer.size, hr);
+                wg_parser_stream_release_buffer(wg_stream);
+                return hr;
+            }
+        }
+        else if (callback_advanced && !stream->read_compressed && stream->allocate_output)
+        {
+            if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced,
+                    stream->index, event.u.buffer.size, &sample, NULL)))
+            {
+                ERR("Failed to allocate output sample of %u bytes, hr %#lx.\n", event.u.buffer.size, hr);
                 wg_parser_stream_release_buffer(wg_stream);
+                return hr;
+            }
+        }
+        else
+        {
+            struct buffer *object;
 
-                if (!event.u.buffer.has_pts)
-                    FIXME("Missing PTS.\n");
-                if (!event.u.buffer.has_duration)
-                    FIXME("Missing duration.\n");
-
-                *pts = event.u.buffer.pts;
-                *duration = event.u.buffer.duration;
-                *flags = 0;
-                if (event.u.buffer.discontinuity)
-                    *flags |= WM_SF_DISCONTINUITY;
-                if (!event.u.buffer.delta)
-                    *flags |= WM_SF_CLEANPOINT;
-
-                *ret_sample = sample;
-                return S_OK;
+            /* FIXME: Should these be pooled? */
+            if (!(object = calloc(1, offsetof(struct buffer, data[event.u.buffer.size]))))
+            {
+                wg_parser_stream_release_buffer(wg_stream);
+                return E_OUTOFMEMORY;
             }
 
-            case WG_PARSER_EVENT_EOS:
-                stream->eos = true;
-                TRACE("End of stream.\n");
-                return NS_E_NO_MORE_SAMPLES;
+            object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
+            object->refcount = 1;
+            object->capacity = event.u.buffer.size;
+
+            TRACE("Created buffer %p.\n", object);
+            sample = &object->INSSBuffer_iface;
+        }
 
-            case WG_PARSER_EVENT_NONE:
-                assert(0);
+        if (FAILED(hr = INSSBuffer_GetBufferAndLength(sample, &data, &size)))
+            ERR("Failed to get data pointer, hr %#lx.\n", hr);
+        if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity)))
+            ERR("Failed to get capacity, hr %#lx.\n", hr);
+        if (event.u.buffer.size > capacity)
+            ERR("Returned capacity %lu is less than requested capacity %u.\n", capacity, event.u.buffer.size);
+
+        if (!wg_parser_stream_copy_buffer(wg_stream, data, 0, event.u.buffer.size))
+        {
+            /* The GStreamer pin has been flushed. */
+            INSSBuffer_Release(sample);
+            continue;
         }
+
+        if (FAILED(hr = INSSBuffer_SetLength(sample, event.u.buffer.size)))
+            ERR("Failed to set size %u, hr %#lx.\n", event.u.buffer.size, hr);
+
+        wg_parser_stream_release_buffer(wg_stream);
+
+        if (!event.u.buffer.has_pts)
+            FIXME("Missing PTS.\n");
+        if (!event.u.buffer.has_duration)
+            FIXME("Missing duration.\n");
+
+        *pts = event.u.buffer.pts;
+        *duration = event.u.buffer.duration;
+        *flags = 0;
+        if (event.u.buffer.discontinuity)
+            *flags |= WM_SF_DISCONTINUITY;
+        if (!event.u.buffer.delta)
+            *flags |= WM_SF_CLEANPOINT;
+
+        *ret_sample = sample;
+        return S_OK;
     }
 }
 
-- 
2.35.1




More information about the wine-devel mailing list