mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-29 18:48:44 +00:00
segment: add offset field
Add an offset field that is used to track at what position the segment was updated. This is used to set the running time to 0 when we do a flushing seek that doesn't update the position. See https://bugzilla.gnome.org/show_bug.cgi?id=680306
This commit is contained in:
parent
f05b0e222f
commit
c8840b8270
3 changed files with 98 additions and 7 deletions
|
@ -174,6 +174,7 @@ gst_segment_init (GstSegment * segment, GstFormat format)
|
|||
segment->applied_rate = 1.0;
|
||||
segment->format = format;
|
||||
segment->base = 0;
|
||||
segment->offset = 0;
|
||||
segment->start = 0;
|
||||
segment->stop = -1;
|
||||
segment->time = 0;
|
||||
|
@ -308,6 +309,7 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
|
|||
/* flush resets the running_time */
|
||||
base = 0;
|
||||
} else {
|
||||
/* remember the elapsed time */
|
||||
base = gst_segment_to_running_time (segment, format, position);
|
||||
}
|
||||
|
||||
|
@ -324,14 +326,12 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
|
|||
position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* set update arg to reflect update of position */
|
||||
if (update)
|
||||
*update = position != segment->position;
|
||||
|
||||
/* update new values */
|
||||
segment->rate = rate;
|
||||
segment->applied_rate = 1.0;
|
||||
segment->base = base;
|
||||
/* be explicit about our GstSeekFlag -> GstSegmentFlag conversion */
|
||||
segment->flags = GST_SEGMENT_FLAG_NONE;
|
||||
if ((flags & GST_SEEK_FLAG_FLUSH) != 0)
|
||||
|
@ -340,6 +340,22 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
|
|||
segment->flags |= GST_SEGMENT_FLAG_SKIP;
|
||||
if ((flags & GST_SEEK_FLAG_SEGMENT) != 0)
|
||||
segment->flags |= GST_SEGMENT_FLAG_SEGMENT;
|
||||
|
||||
segment->rate = rate;
|
||||
segment->applied_rate = 1.0;
|
||||
|
||||
segment->base = base;
|
||||
if (rate > 0.0)
|
||||
segment->offset = position - start;
|
||||
else {
|
||||
if (stop != -1)
|
||||
segment->offset = stop - position;
|
||||
else if (segment->duration != -1)
|
||||
segment->offset = segment->duration - position;
|
||||
else
|
||||
segment->offset = 0;
|
||||
}
|
||||
|
||||
segment->start = start;
|
||||
segment->stop = stop;
|
||||
segment->time = start;
|
||||
|
@ -461,6 +477,9 @@ gst_segment_to_running_time (const GstSegment * segment, GstFormat format,
|
|||
|
||||
start = segment->start;
|
||||
|
||||
if (segment->rate > 0.0)
|
||||
start += segment->offset;
|
||||
|
||||
/* before the segment boundary */
|
||||
if (G_UNLIKELY (position < start))
|
||||
return -1;
|
||||
|
@ -477,7 +496,11 @@ gst_segment_to_running_time (const GstSegment * segment, GstFormat format,
|
|||
} else {
|
||||
/* cannot continue if no stop position set or outside of
|
||||
* the segment. */
|
||||
if (G_UNLIKELY (stop == -1 || position > stop))
|
||||
if (G_UNLIKELY (stop == -1))
|
||||
return -1;
|
||||
|
||||
stop -= segment->offset;
|
||||
if (G_UNLIKELY (position > stop))
|
||||
return -1;
|
||||
|
||||
/* bring to uncorrected position in segment */
|
||||
|
|
|
@ -144,7 +144,8 @@ typedef enum {
|
|||
* @rate: the rate of the segment
|
||||
* @applied_rate: the already applied rate to the segment
|
||||
* @format: the format of the segment values
|
||||
* @base: the base time of the segment
|
||||
* @base: the base of the segment
|
||||
* @offset: the offset to apply to @start or @stop
|
||||
* @start: the start of the segment
|
||||
* @stop: the stop of the segment
|
||||
* @time: the stream time of the segment
|
||||
|
@ -163,6 +164,7 @@ struct _GstSegment {
|
|||
|
||||
GstFormat format;
|
||||
guint64 base;
|
||||
guint64 offset;
|
||||
guint64 start;
|
||||
guint64 stop;
|
||||
guint64 time;
|
||||
|
|
|
@ -31,8 +31,8 @@ check_times (GstSegment * segment, guint64 position, guint64 stream_time,
|
|||
st = gst_segment_to_stream_time (segment, segment->format, position);
|
||||
rt = gst_segment_to_running_time (segment, segment->format, position);
|
||||
|
||||
fail_unless (st == stream_time);
|
||||
fail_unless (rt == running_time);
|
||||
fail_unless_equals_int64 (st, stream_time);
|
||||
fail_unless_equals_int64 (rt, running_time);
|
||||
}
|
||||
|
||||
/* mess with the segment structure in the bytes format */
|
||||
|
@ -138,8 +138,10 @@ GST_START_TEST (segment_seek_nosize)
|
|||
fail_unless (segment.start == 200);
|
||||
fail_unless (segment.position == 200);
|
||||
fail_unless (segment.stop == 300);
|
||||
fail_unless (segment.base == 50);
|
||||
fail_unless (update == TRUE);
|
||||
check_times (&segment, 200, 200, 50);
|
||||
check_times (&segment, 250, 250, 100);
|
||||
|
||||
update = FALSE;
|
||||
/* add 100 to start (to 300), set stop to 200, this is not allowed.
|
||||
|
@ -152,8 +154,10 @@ GST_START_TEST (segment_seek_nosize)
|
|||
fail_unless (segment.start == 200);
|
||||
fail_unless (segment.position == 200);
|
||||
fail_unless (segment.stop == 300);
|
||||
fail_unless (segment.base == 50);
|
||||
/* update didn't change */
|
||||
fail_unless (update == FALSE);
|
||||
check_times (&segment, 200, 200, 50);
|
||||
check_times (&segment, 250, 250, 100);
|
||||
|
||||
update = TRUE;
|
||||
|
@ -166,6 +170,7 @@ GST_START_TEST (segment_seek_nosize)
|
|||
fail_unless (segment.start == 200);
|
||||
fail_unless (segment.position == 200);
|
||||
fail_unless (segment.stop == 300);
|
||||
fail_unless (segment.base == 50);
|
||||
fail_unless (update == FALSE);
|
||||
check_times (&segment, 250, 250, 100);
|
||||
|
||||
|
@ -477,9 +482,11 @@ GST_START_TEST (segment_seek_rate)
|
|||
GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
|
||||
fail_unless (segment.format == GST_FORMAT_BYTES);
|
||||
fail_unless (segment.start == 0);
|
||||
fail_unless (segment.position == 0);
|
||||
fail_unless (segment.stop == -1);
|
||||
fail_unless (segment.rate == 2.0);
|
||||
fail_unless (update == FALSE);
|
||||
check_times (&segment, 50, 50, 25);
|
||||
|
||||
/* set a real stop position, this must happen in bytes */
|
||||
gst_segment_do_seek (&segment, 3.0,
|
||||
|
@ -493,6 +500,7 @@ GST_START_TEST (segment_seek_rate)
|
|||
/* no seek should happen, we just updated the stop position in forward
|
||||
* playback mode.*/
|
||||
fail_unless (update == FALSE);
|
||||
check_times (&segment, 60, 60, 20);
|
||||
|
||||
/* set some duration, stop -1 END seeks will now work with the
|
||||
* duration, if the formats match */
|
||||
|
@ -549,6 +557,63 @@ GST_START_TEST (segment_copy)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
/* mess with the segment structure in the bytes format */
|
||||
GST_START_TEST (segment_seek_noupdate)
|
||||
{
|
||||
GstSegment segment;
|
||||
gboolean update;
|
||||
|
||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||
|
||||
segment.start = 0;
|
||||
segment.position = 50;
|
||||
segment.stop = 200;
|
||||
segment.time = 0;
|
||||
|
||||
/* doesn't change anything */
|
||||
gst_segment_do_seek (&segment, 1.0,
|
||||
GST_FORMAT_TIME,
|
||||
GST_SEEK_FLAG_NONE,
|
||||
GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
|
||||
fail_unless (update == FALSE);
|
||||
fail_unless (segment.format == GST_FORMAT_TIME);
|
||||
fail_unless (segment.start == 0);
|
||||
fail_unless (segment.stop == 200);
|
||||
fail_unless (segment.time == 0);
|
||||
fail_unless (segment.position == 50);
|
||||
fail_unless (segment.base == 50);
|
||||
fail_unless (segment.offset == 50);
|
||||
|
||||
gst_segment_do_seek (&segment, 2.0,
|
||||
GST_FORMAT_TIME,
|
||||
GST_SEEK_FLAG_NONE,
|
||||
GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
|
||||
fail_unless (update == FALSE);
|
||||
fail_unless (segment.format == GST_FORMAT_TIME);
|
||||
fail_unless (segment.start == 0);
|
||||
fail_unless (segment.stop == 200);
|
||||
fail_unless (segment.time == 0);
|
||||
fail_unless (segment.position == 50);
|
||||
fail_unless (segment.base == 50);
|
||||
fail_unless_equals_int (segment.offset, 50);
|
||||
|
||||
gst_segment_do_seek (&segment, 1.0,
|
||||
GST_FORMAT_TIME,
|
||||
GST_SEEK_FLAG_FLUSH,
|
||||
GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0, &update);
|
||||
fail_unless (update == FALSE);
|
||||
fail_unless (segment.format == GST_FORMAT_TIME);
|
||||
fail_unless (segment.start == 0);
|
||||
fail_unless (segment.stop == 200);
|
||||
fail_unless (segment.time == 0);
|
||||
fail_unless (segment.position == 50);
|
||||
fail_unless (segment.base == 0);
|
||||
fail_unless (segment.offset == 50);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
static Suite *
|
||||
gst_segment_suite (void)
|
||||
{
|
||||
|
@ -563,6 +628,7 @@ gst_segment_suite (void)
|
|||
tcase_add_test (tc_chain, segment_seek_reverse);
|
||||
tcase_add_test (tc_chain, segment_seek_rate);
|
||||
tcase_add_test (tc_chain, segment_copy);
|
||||
tcase_add_test (tc_chain, segment_seek_noupdate);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue