mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 20:51:13 +00:00
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
This commit is contained in:
parent
7fad93d035
commit
65dcb2adbf
2 changed files with 48 additions and 2 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue