diff options
author | Alicia Boya GarcĂa <aboya@igalia.com> | 2018-01-10 04:08:57 +0100 |
---|---|---|
committer | Thibault Saunier <tsaunier@igalia.com> | 2018-02-16 10:35:14 -0300 |
commit | 65dcb2adbfe8edeaaa0212df2798695f15497b90 (patch) | |
tree | 81513ab7a4cc784717541c2a4c2f5a76ef1ffba0 | |
parent | 7fad93d03559513c947e38065b1cc160b1621cf6 (diff) |
gstbasesink: Include segment.offset in the computation of position
Position queries with GST_FORMAT_TIME are supposed to return stream
time.
gst_base_sink_get_position() estimates the current stream time on its
own instead of using gst_segment_to_stream_time(), but the algorithm
used was not taking segment.offset into account, resulting in invalid
values when this field was set to a non-zero value.
https://bugzilla.gnome.org/show_bug.cgi?id=792434
-rw-r--r-- | libs/gst/base/gstbasesink.c | 9 | ||||
-rw-r--r-- | tests/check/libs/basesink.c | 41 |
2 files changed, 48 insertions, 2 deletions
diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index b4b11f028..ae0202438 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -4530,7 +4530,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format, GstSegment *segment; GstClockTime now, latency; GstClockTimeDiff base_time; - gint64 time, base, duration; + gint64 time, base, offset, duration; gdouble rate; gint64 last; gboolean last_seen, with_clock, in_paused; @@ -4582,6 +4582,11 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format, else time = 0; + if (GST_CLOCK_TIME_IS_VALID (segment->offset)) + offset = segment->offset; + else + offset = 0; + if (GST_CLOCK_TIME_IS_VALID (segment->stop)) duration = segment->stop - segment->start; else @@ -4703,7 +4708,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format, if (rate < 0.0) time += duration; - *cur = time + gst_guint64_to_gdouble (now - base_time) * rate; + *cur = time + offset + gst_guint64_to_gdouble (now - base_time) * rate; /* never report more than last seen position */ if (last != -1) { diff --git a/tests/check/libs/basesink.c b/tests/check/libs/basesink.c index ee971521c..5415d70ba 100644 --- a/tests/check/libs/basesink.c +++ b/tests/check/libs/basesink.c @@ -242,6 +242,46 @@ GST_START_TEST (basesink_test_eos_after_playing) GST_END_TEST; + +GST_START_TEST (basesink_position_query_handles_segment_offset) +{ + GstElement *pipeline, *sink; + GstPad *pad; + GstEvent *ev; + GstSegment segment; + gint64 position; + + sink = gst_element_factory_make ("fakesink", "sink"); + g_object_set (sink, "async", FALSE, "sync", TRUE, NULL); + pad = gst_element_get_static_pad (sink, "sink"); + + pipeline = gst_pipeline_new (NULL); + + gst_bin_add (GST_BIN (pipeline), sink); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED), + GST_STATE_CHANGE_SUCCESS); + + ev = gst_event_new_stream_start ("test"); + fail_unless (gst_pad_send_event (pad, ev)); + + gst_segment_init (&segment, GST_FORMAT_TIME); + segment.offset = 15000; + ev = gst_event_new_segment (&segment); + fail_unless (gst_pad_send_event (pad, ev)); + + fail_unless (gst_element_query_position (pipeline, GST_FORMAT_TIME, + &position)); + fail_unless_equals_int (position, 15000); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + gst_object_unref (pad); + gst_object_unref (pipeline); +} + +GST_END_TEST; + static Suite * gst_basesrc_suite (void) { @@ -253,6 +293,7 @@ gst_basesrc_suite (void) tcase_add_test (tc, basesink_last_sample_disabled); tcase_add_test (tc, basesink_test_gap); tcase_add_test (tc, basesink_test_eos_after_playing); + tcase_add_test (tc, basesink_position_query_handles_segment_offset); return s; } |