Zebediah Figura : winegstreamer: Convert timestamps to running time in wg_parser_stream_notify_qos().

Alexandre Julliard julliard at winehq.org
Wed Mar 17 16:23:14 CDT 2021


Module: wine
Branch: master
Commit: 5e222064ab27266c0f44ec3986872f611772ff10
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5e222064ab27266c0f44ec3986872f611772ff10

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Tue Mar 16 16:06:32 2021 -0500

winegstreamer: Convert timestamps to running time in wg_parser_stream_notify_qos().

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50733
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winegstreamer/wg_parser.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 51d7e3d9748..aefb097f7f0 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -79,6 +79,7 @@ struct wg_parser_stream
 
     GstPad *their_src, *post_sink, *post_src, *my_sink;
     GstElement *flip;
+    GstSegment segment;
     struct wg_format preferred_format, current_format;
 
     pthread_cond_t event_cond, event_empty_cond;
@@ -691,10 +692,24 @@ static bool CDECL wg_parser_stream_seek(struct wg_parser_stream *stream, double
 static void CDECL wg_parser_stream_notify_qos(struct wg_parser_stream *stream,
         bool underflow, double proportion, int64_t diff, uint64_t timestamp)
 {
+    GstClockTime stream_time;
     GstEvent *event;
 
+    /* We return timestamps in stream time, i.e. relative to the start of the
+     * file (or other medium), but gst_event_new_qos() expects the timestamp in
+     * running time. */
+    stream_time = gst_segment_to_running_time(&stream->segment, GST_FORMAT_TIME, timestamp * 100);
+    if (stream_time == -1)
+    {
+        /* This can happen legitimately if the sample falls outside of the
+         * segment bounds. GStreamer elements shouldn't present the sample in
+         * that case, but DirectShow doesn't care. */
+        TRACE("Ignoring QoS event.\n");
+        return;
+    }
+
     if (!(event = gst_event_new_qos(underflow ? GST_QOS_TYPE_UNDERFLOW : GST_QOS_TYPE_OVERFLOW,
-            proportion, diff * 100, timestamp * 100)))
+            proportion, diff * 100, stream_time)))
         ERR("Failed to create QOS event.\n");
     gst_pad_push_event(stream->my_sink, event);
 }
@@ -792,6 +807,8 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
                     break;
                 }
 
+                gst_segment_copy_into(segment, &stream->segment);
+
                 stream_event.type = WG_PARSER_EVENT_SEGMENT;
                 stream_event.u.segment.position = segment->position / 100;
                 stream_event.u.segment.stop = segment->stop / 100;
@@ -838,6 +855,14 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
             break;
 
         case GST_EVENT_FLUSH_STOP:
+        {
+            gboolean reset_time;
+
+            gst_event_parse_flush_stop(event, &reset_time);
+
+            if (reset_time)
+                gst_segment_init(&stream->segment, GST_FORMAT_UNDEFINED);
+
             if (stream->enabled)
             {
                 pthread_mutex_lock(&parser->mutex);
@@ -845,6 +870,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
                 pthread_mutex_unlock(&parser->mutex);
             }
             break;
+        }
 
         case GST_EVENT_CAPS:
         {
@@ -882,6 +908,10 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu
 
     stream_event.type = WG_PARSER_EVENT_BUFFER;
 
+    /* FIXME: Should we use gst_segment_to_stream_time_full()? Under what
+     * circumstances is the stream time not equal to the buffer PTS? Note that
+     * this will need modification to wg_parser_stream_notify_qos() as well. */
+
     if ((stream_event.u.buffer.has_pts = GST_BUFFER_PTS_IS_VALID(buffer)))
         stream_event.u.buffer.pts = GST_BUFFER_PTS(buffer) / 100;
     if ((stream_event.u.buffer.has_duration = GST_BUFFER_DURATION_IS_VALID(buffer)))
@@ -972,6 +1002,8 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser)
     if (!(stream = calloc(1, sizeof(*stream))))
         return NULL;
 
+    gst_segment_init(&stream->segment, GST_FORMAT_UNDEFINED);
+
     stream->parser = parser;
     pthread_cond_init(&stream->event_cond, NULL);
     pthread_cond_init(&stream->event_empty_cond, NULL);




More information about the wine-cvs mailing list