diff options
author | Jan Schmidt <jan@centricular.com> | 2018-08-23 22:34:47 +1000 |
---|---|---|
committer | Jan Schmidt <jan@centricular.com> | 2018-08-28 01:54:02 +1000 |
commit | 260b9791fc7ea524ad949b5cfdd81688d0a3013e (patch) | |
tree | e997beda91d5222e331d790b58905e17701ee9bd /gst/gstsegment.c | |
parent | f87d38c1865264f338eddfa10d8ba8a31ee9322e (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.c | 33 |
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; } } } |