mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
segment: add method for converting to position
Add gst_segment_to_position() that converts a running_time to a position in the segment. A faulty variant of this function is currently used in inputselector but we'll need it for frame stepping too. API: GstSegment::gst_segment_to_position()
This commit is contained in:
parent
a907f8d145
commit
92984a116b
5 changed files with 150 additions and 9 deletions
|
@ -1983,6 +1983,7 @@ gst_segment_set_newsegment_full
|
|||
gst_segment_set_seek
|
||||
gst_segment_to_running_time
|
||||
gst_segment_to_stream_time
|
||||
gst_segment_to_position
|
||||
<SUBSECTION Standard>
|
||||
GST_TYPE_SEGMENT
|
||||
gst_segment_get_type
|
||||
|
|
|
@ -465,7 +465,7 @@ gst_segment_set_newsegment_full (GstSegment * segment, gboolean update,
|
|||
g_return_if_fail (segment->format == format);
|
||||
|
||||
if (update) {
|
||||
if (segment->rate > 0.0) {
|
||||
if (G_LIKELY (segment->rate > 0.0)) {
|
||||
/* an update to the current segment is done, elapsed time is
|
||||
* difference between the old start and new start. */
|
||||
if (start > segment->start)
|
||||
|
@ -511,7 +511,7 @@ gst_segment_set_newsegment_full (GstSegment * segment, gboolean update,
|
|||
last_stop = stop;
|
||||
}
|
||||
/* use previous rate to calculate duration */
|
||||
if (segment->abs_rate != 1.0)
|
||||
if (G_LIKELY (segment->abs_rate != 1.0))
|
||||
duration /= segment->abs_rate;
|
||||
|
||||
/* accumulate duration */
|
||||
|
@ -565,7 +565,7 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
|
|||
|
||||
/* if we have the position for the same format as the segment, we can compare
|
||||
* the start and stop values, otherwise we assume 0 and -1 */
|
||||
if (segment->format == format) {
|
||||
if (G_LIKELY (segment->format == format)) {
|
||||
start = segment->start;
|
||||
stop = segment->stop;
|
||||
time = segment->time;
|
||||
|
@ -593,18 +593,18 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
|
|||
abs_applied_rate = ABS (segment->applied_rate);
|
||||
|
||||
/* correct for applied rate if needed */
|
||||
if (abs_applied_rate != 1.0)
|
||||
if (G_UNLIKELY (abs_applied_rate != 1.0))
|
||||
result *= abs_applied_rate;
|
||||
|
||||
/* add or subtract from segment time based on applied rate */
|
||||
if (segment->applied_rate > 0.0) {
|
||||
if (G_LIKELY (segment->applied_rate > 0.0)) {
|
||||
/* correct for segment time */
|
||||
result += time;
|
||||
} else {
|
||||
/* correct for segment time, clamp at 0. Streams with a negative
|
||||
* applied_rate have timestamps between start and stop, as usual, but have
|
||||
* the time member starting high and going backwards. */
|
||||
if (time > result)
|
||||
if (G_LIKELY (time > result))
|
||||
result = time - result;
|
||||
else
|
||||
result = 0;
|
||||
|
@ -650,7 +650,7 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
|
|||
|
||||
/* if we have the position for the same format as the segment, we can compare
|
||||
* the start and stop values, otherwise we assume 0 and -1 */
|
||||
if (segment->format == format) {
|
||||
if (G_LIKELY (segment->format == format)) {
|
||||
start = segment->start;
|
||||
stop = segment->stop;
|
||||
accum = segment->accum;
|
||||
|
@ -664,7 +664,7 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
|
|||
if (G_UNLIKELY (position < start))
|
||||
return -1;
|
||||
|
||||
if (segment->rate > 0.0) {
|
||||
if (G_LIKELY (segment->rate > 0.0)) {
|
||||
/* outside of the segment boundary stop */
|
||||
if (G_UNLIKELY (stop != -1 && position > stop))
|
||||
return -1;
|
||||
|
@ -683,7 +683,7 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
|
|||
|
||||
/* scale based on the rate, avoid division by and conversion to
|
||||
* float when not needed */
|
||||
if (segment->abs_rate != 1.0)
|
||||
if (G_UNLIKELY (segment->abs_rate != 1.0))
|
||||
result /= segment->abs_rate;
|
||||
|
||||
/* correct for accumulated segments */
|
||||
|
@ -761,3 +761,73 @@ gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_segment_to_position:
|
||||
* @segment: a #GstSegment structure.
|
||||
* @format: the format of the segment.
|
||||
* @running_time: the running_time in the segment
|
||||
*
|
||||
* Convert @running_time into a position in the segment so that
|
||||
* gst_segment_to_running_time() with that position returns @running_time.
|
||||
*
|
||||
* Returns: the position in the segment for @running_time.
|
||||
*
|
||||
* Since: 0.10.24
|
||||
*/
|
||||
gint64
|
||||
gst_segment_to_position (GstSegment * segment, GstFormat format,
|
||||
gint64 running_time)
|
||||
{
|
||||
gint64 result;
|
||||
gint64 start, stop, accum;
|
||||
|
||||
g_return_val_if_fail (segment != NULL, -1);
|
||||
|
||||
if (G_UNLIKELY (running_time == -1))
|
||||
return -1;
|
||||
|
||||
if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
|
||||
segment->format = format;
|
||||
|
||||
/* if we have the position for the same format as the segment, we can compare
|
||||
* the start and stop values, otherwise we assume 0 and -1 */
|
||||
if (G_LIKELY (segment->format == format)) {
|
||||
start = segment->start;
|
||||
stop = segment->stop;
|
||||
accum = segment->accum;
|
||||
} else {
|
||||
start = 0;
|
||||
stop = -1;
|
||||
accum = 0;
|
||||
}
|
||||
|
||||
/* this running_time was for a previous segment */
|
||||
if (running_time < accum)
|
||||
return -1;
|
||||
|
||||
/* start by subtracting the accumulated time */
|
||||
result = running_time - accum;
|
||||
|
||||
/* move into the segment at the right rate */
|
||||
if (G_UNLIKELY (segment->abs_rate != 1.0))
|
||||
result *= segment->abs_rate;
|
||||
|
||||
if (G_LIKELY (segment->rate > 0.0)) {
|
||||
/* bring to corrected position in segment */
|
||||
result += start;
|
||||
|
||||
/* outside of the segment boundary stop */
|
||||
if (G_UNLIKELY (stop != -1 && result > stop))
|
||||
return -1;
|
||||
} else {
|
||||
/* cannot continue if no stop position set or outside of
|
||||
* the segment. */
|
||||
if (G_UNLIKELY (stop == -1 || result + start > stop))
|
||||
return -1;
|
||||
|
||||
/* bring to corrected position in segment */
|
||||
result = stop - result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ void gst_segment_set_newsegment_full (GstSegment *segment, gboolean upda
|
|||
|
||||
gint64 gst_segment_to_stream_time (GstSegment *segment, GstFormat format, gint64 position);
|
||||
gint64 gst_segment_to_running_time (GstSegment *segment, GstFormat format, gint64 position);
|
||||
gint64 gst_segment_to_position (GstSegment *segment, GstFormat format, gint64 running_time);
|
||||
|
||||
gboolean gst_segment_clip (GstSegment *segment, GstFormat format, gint64 start,
|
||||
gint64 stop, gint64 *clip_start, gint64 *clip_stop);
|
||||
|
|
|
@ -1341,17 +1341,25 @@ GST_START_TEST (segment_newsegment_runningtime)
|
|||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 0);
|
||||
fail_unless (result == 0);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 0);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
|
||||
fail_unless (result == 100);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 100);
|
||||
|
||||
/* at edge is exactly the segment duration */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
|
||||
fail_unless (result == 200);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 200);
|
||||
|
||||
/* outside of the segment */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 300);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 300);
|
||||
fail_unless (result == -1);
|
||||
|
||||
/***********************************************************
|
||||
* time shifted by 500, check if accumulation worked.
|
||||
|
@ -1371,13 +1379,19 @@ GST_START_TEST (segment_newsegment_runningtime)
|
|||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 0);
|
||||
fail_unless (result == 200);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 0);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
|
||||
fail_unless (result == 250);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 100);
|
||||
|
||||
/* outside of the segment */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 310);
|
||||
fail_unless (result == -1);
|
||||
|
||||
/********************************************
|
||||
* time offset by 500
|
||||
|
@ -1397,19 +1411,29 @@ GST_START_TEST (segment_newsegment_runningtime)
|
|||
/* before segment is invalid */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 200);
|
||||
fail_unless (result == -1);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
|
||||
fail_unless (result == 300);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 500);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
|
||||
fail_unless (result == 400);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 600);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
|
||||
fail_unless (result == 500);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 700);
|
||||
|
||||
/* outside of the segment */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 600);
|
||||
fail_unless (result == -1);
|
||||
|
||||
/**********************************************************
|
||||
* time offset by 500, shifted by 200
|
||||
|
@ -1429,19 +1453,29 @@ GST_START_TEST (segment_newsegment_runningtime)
|
|||
/* before segment is invalid */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 400);
|
||||
fail_unless (result == -1);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
|
||||
fail_unless (result == 700);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 500);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
|
||||
fail_unless (result == 600);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 600);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
|
||||
fail_unless (result == 500);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 700);
|
||||
|
||||
/* outside of the segment */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 800);
|
||||
fail_unless (result == -1);
|
||||
|
||||
/**********************************************************
|
||||
* time offset by 500, shifted by 200
|
||||
|
@ -1461,20 +1495,30 @@ GST_START_TEST (segment_newsegment_runningtime)
|
|||
/* before segment is invalid */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 400);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 600);
|
||||
fail_unless (result == -1);
|
||||
|
||||
/* total scaled segment time is 100, accum is 700, so we get 800 */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 500);
|
||||
fail_unless (result == 800);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 500);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 600);
|
||||
fail_unless (result == 750);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 600);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 700);
|
||||
fail_unless (result == 700);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 700);
|
||||
|
||||
/* outside of the segment */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 800);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 900);
|
||||
fail_unless (result == -1);
|
||||
|
||||
/* see if negative rate closed segment correctly */
|
||||
gst_segment_set_newsegment_full (&segment, FALSE, -2.0, -1.0,
|
||||
|
@ -1482,6 +1526,8 @@ GST_START_TEST (segment_newsegment_runningtime)
|
|||
|
||||
/* previous segment lasted 100, and was at 700 so we should get 800 */
|
||||
fail_unless (segment.accum == 800);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 800);
|
||||
fail_unless (result == 700);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
@ -1517,9 +1563,13 @@ GST_START_TEST (segment_newsegment_accum)
|
|||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
|
||||
fail_unless (result == 0);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 200);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
|
||||
fail_unless (result == 50);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 150);
|
||||
|
||||
/* update segment, this accumulates 50 from the previous segment. */
|
||||
gst_segment_set_newsegment_full (&segment, TRUE, -2.0, 1.0,
|
||||
|
@ -1538,10 +1588,14 @@ GST_START_TEST (segment_newsegment_accum)
|
|||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
|
||||
fail_unless (result == 50);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 150);
|
||||
|
||||
/* 50 accumulated + 50 / 2 */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
|
||||
fail_unless (result == 75);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 100);
|
||||
|
||||
/* update segment, this does not accumulate anything. */
|
||||
gst_segment_set_newsegment_full (&segment, TRUE, 1.0, 1.0,
|
||||
|
@ -1560,9 +1614,13 @@ GST_START_TEST (segment_newsegment_accum)
|
|||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
|
||||
fail_unless (result == 50);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 100);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
|
||||
fail_unless (result == 100);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 150);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
@ -1595,12 +1653,18 @@ GST_START_TEST (segment_newsegment_accum2)
|
|||
/* invalid time gives invalid result */
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
|
||||
fail_unless (result == -1);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == -1);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
|
||||
fail_unless (result == 0);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 200);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
|
||||
fail_unless (result == 50);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 150);
|
||||
|
||||
/* close segment, this accumulates nothing. */
|
||||
gst_segment_set_newsegment_full (&segment, TRUE, -1.0, 1.0,
|
||||
|
@ -1638,9 +1702,13 @@ GST_START_TEST (segment_newsegment_accum2)
|
|||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
|
||||
fail_unless (result == 50);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 150);
|
||||
|
||||
result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 200);
|
||||
fail_unless (result == 100);
|
||||
result = gst_segment_to_position (&segment, GST_FORMAT_TIME, result);
|
||||
fail_unless (result == 200);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
|
|
@ -836,6 +836,7 @@ EXPORTS
|
|||
gst_segment_set_newsegment
|
||||
gst_segment_set_newsegment_full
|
||||
gst_segment_set_seek
|
||||
gst_segment_to_position
|
||||
gst_segment_to_running_time
|
||||
gst_segment_to_stream_time
|
||||
gst_segtrap_is_enabled
|
||||
|
|
Loading…
Reference in a new issue