summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlicia Boya GarcĂ­a <aboya@igalia.com>2018-01-10 04:08:57 +0100
committerThibault Saunier <tsaunier@igalia.com>2018-02-16 10:35:14 -0300
commit65dcb2adbfe8edeaaa0212df2798695f15497b90 (patch)
tree81513ab7a4cc784717541c2a4c2f5a76ef1ffba0
parent7fad93d03559513c947e38065b1cc160b1621cf6 (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.c9
-rw-r--r--tests/check/libs/basesink.c41
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;
}