summaryrefslogtreecommitdiff
path: root/gst/gstsegment.c
diff options
context:
space:
mode:
authorJan Schmidt <jan@centricular.com>2018-08-23 22:34:47 +1000
committerJan Schmidt <jan@centricular.com>2018-08-28 01:54:02 +1000
commit260b9791fc7ea524ad949b5cfdd81688d0a3013e (patch)
treee997beda91d5222e331d790b58905e17701ee9bd /gst/gstsegment.c
parentf87d38c1865264f338eddfa10d8ba8a31ee9322e (diff)
gstsegment: Handle positions before the segment properly
Fixes for gst_segment_position_from_running_time_full() when converting running_times that precede the segment start (or stop in a negative rate segment) The return value was incorrectly negated in those cases. Add some more unit test checks for those cases, and especially for segments with offsets.
Diffstat (limited to 'gst/gstsegment.c')
-rw-r--r--gst/gstsegment.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/gst/gstsegment.c b/gst/gstsegment.c
index e09d75eb0c..6aa1ce228e 100644
--- a/gst/gstsegment.c
+++ b/gst/gstsegment.c
@@ -992,8 +992,9 @@ gst_segment_position_from_running_time (const GstSegment * segment,
* When 1 is returned, @running_time resulted in a positive position returned
* in @position.
*
- * When this function returns -1, the returned @position should be negated
- * to get the real negative segment position.
+ * When this function returns -1, the returned @position was < 0, and the value
+ * in the position variable should be negated to get the real negative segment
+ * position.
*
* Returns: a 1 or -1 on success, 0 on failure.
*
@@ -1036,12 +1037,15 @@ gst_segment_position_from_running_time_full (const GstSegment * segment,
*position = base - running_time;
if (G_UNLIKELY (abs_rate != 1.0))
*position = ceil (*position * abs_rate);
- if (start + segment->offset > *position) {
- *position -= start + segment->offset;
- res = -1;
- } else {
+ if (start + segment->offset >= *position) {
+ /* The TS is before the segment, but the result is >= 0 */
*position = start + segment->offset - *position;
res = 1;
+ } else {
+ /* The TS is before the segment, and the result is < 0
+ * so negate the return result */
+ *position = *position - (start + segment->offset);
+ res = -1;
}
}
} else {
@@ -1057,15 +1061,24 @@ gst_segment_position_from_running_time_full (const GstSegment * segment,
res = 1;
}
} else {
+ /* This case is tricky. Requested running time precedes the
+ * segment base, so in a reversed segment where rate < 0, that
+ * means it's before the alignment point of (stop - offset).
+ * Before = always bigger than (stop-offset), which is usually +ve,
+ * but could be -ve is offset is big enough. -ve position implies
+ * that the offset has clipped away the entire segment anyway */
*position = base - running_time;
if (G_UNLIKELY (abs_rate != 1.0))
*position = ceil (*position * abs_rate);
- if (G_UNLIKELY (stop < segment->offset - *position)) {
- *position -= segment->offset - stop;
- res = -1;
- } else {
+
+ if (G_LIKELY (stop + *position >= segment->offset)) {
*position = stop + *position - segment->offset;
res = 1;
+ } else {
+ /* Requested position is still negative because offset is big,
+ * so negate the result */
+ *position = segment->offset - *position - stop;
+ res = -1;
}
}
}