mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-07 07:55:41 +00:00
segment: Correct stream_time calc for negative applied rate
Updated gst_segment_position_from_stream_time and gst_segment_to_stream_time to reflect correct calculations for the case when the applied rate is negative. Pasting from design docs: =============================== Stream time is calculated using the buffer times and the preceding SEGMENT event as follows: stream_time = (B.timestamp - S.start) * ABS (S.applied_rate) + S.time For negative rates, B.timestamp will go backwards from S.stop to S.start, making the stream time go backwards. =============================== Therefore, the calculation for applied_rate < 0 should be: stream_time = (S.stop - B.timestamp) * ABS (S.applied_rate) + S.time and the reverse: B.timestamp = S.stop - (stream_time - S.time) / ABS (S.applied_rate) https://bugzilla.gnome.org/show_bug.cgi?id=756810
This commit is contained in:
parent
fb39b3853f
commit
5cccf9846f
2 changed files with 95 additions and 11 deletions
|
@ -426,27 +426,29 @@ gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
|
|||
if (G_UNLIKELY (time == -1))
|
||||
return -1;
|
||||
|
||||
/* bring to uncorrected position in segment */
|
||||
stream_time = position - start;
|
||||
|
||||
abs_applied_rate = ABS (segment->applied_rate);
|
||||
|
||||
/* correct for applied rate if needed */
|
||||
if (G_UNLIKELY (abs_applied_rate != 1.0))
|
||||
stream_time *= abs_applied_rate;
|
||||
|
||||
/* add or subtract from segment time based on applied rate */
|
||||
if (G_LIKELY (segment->applied_rate > 0.0)) {
|
||||
if (G_UNLIKELY (position < start))
|
||||
return -1;
|
||||
/* bring to uncorrected position in segment */
|
||||
stream_time = position - start;
|
||||
/* correct for applied rate if needed */
|
||||
if (G_UNLIKELY (abs_applied_rate != 1.0))
|
||||
stream_time *= abs_applied_rate;
|
||||
/* correct for segment time */
|
||||
stream_time += 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 (G_LIKELY (time > stream_time))
|
||||
stream_time = time - stream_time;
|
||||
else
|
||||
stream_time = 0;
|
||||
if (G_UNLIKELY (position > stop))
|
||||
return -1;
|
||||
stream_time = stop - position;
|
||||
if (G_UNLIKELY (abs_applied_rate != 1.0))
|
||||
stream_time *= abs_applied_rate;
|
||||
stream_time += time;
|
||||
}
|
||||
|
||||
return stream_time;
|
||||
|
|
|
@ -792,6 +792,86 @@ GST_START_TEST (segment_full)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (segment_negative_rate)
|
||||
{
|
||||
GstSegment segment;
|
||||
|
||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||
|
||||
segment.start = 50;
|
||||
segment.position = 150;
|
||||
segment.stop = 200;
|
||||
segment.time = 0;
|
||||
segment.applied_rate = -1;
|
||||
segment.rate = -1;
|
||||
|
||||
/* somewhere in the middle */
|
||||
check_times (&segment, 100, 100, 100);
|
||||
/* after stop */
|
||||
check_times (&segment, 220, -1, -1);
|
||||
/* before start */
|
||||
check_times (&segment, 10, -1, -1);
|
||||
/* at segment start */
|
||||
check_times (&segment, 50, 150, 150);
|
||||
/* another place in the middle */
|
||||
check_times (&segment, 150, 50, 50);
|
||||
/* at segment stop */
|
||||
check_times (&segment, 200, 0, 0);
|
||||
|
||||
segment.time = 100;
|
||||
segment.base = 100;
|
||||
/* somewhere in the middle */
|
||||
check_times (&segment, 100, 200, 200);
|
||||
/* at segment start */
|
||||
check_times (&segment, 50, 250, 250);
|
||||
/* another place in the middle */
|
||||
check_times (&segment, 150, 150, 150);
|
||||
/* at segment stop */
|
||||
check_times (&segment, 200, 100, 100);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (segment_negative_applied_rate)
|
||||
{
|
||||
GstSegment segment;
|
||||
|
||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||
|
||||
segment.start = 50;
|
||||
segment.position = 150;
|
||||
segment.stop = 200;
|
||||
segment.time = 0;
|
||||
segment.applied_rate = -1;
|
||||
segment.rate = 1;
|
||||
|
||||
/* somewhere in the middle */
|
||||
check_times (&segment, 100, 100, 50);
|
||||
/* after stop */
|
||||
check_times (&segment, 220, -1, -1);
|
||||
/* before start */
|
||||
check_times (&segment, 10, -1, -1);
|
||||
/* at segment start */
|
||||
check_times (&segment, 50, 150, 0);
|
||||
/* another place in the middle */
|
||||
check_times (&segment, 150, 50, 100);
|
||||
/* at segment stop */
|
||||
check_times (&segment, 200, 0, 150);
|
||||
|
||||
segment.time = 100;
|
||||
segment.base = 100;
|
||||
/* somewhere in the middle */
|
||||
check_times (&segment, 100, 200, 150);
|
||||
/* at segment start */
|
||||
check_times (&segment, 50, 250, 100);
|
||||
/* another place in the middle */
|
||||
check_times (&segment, 150, 150, 200);
|
||||
/* at segment stop */
|
||||
check_times (&segment, 200, 100, 250);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
gst_segment_suite (void)
|
||||
{
|
||||
|
@ -809,6 +889,8 @@ gst_segment_suite (void)
|
|||
tcase_add_test (tc_chain, segment_seek_noupdate);
|
||||
tcase_add_test (tc_chain, segment_offset);
|
||||
tcase_add_test (tc_chain, segment_full);
|
||||
tcase_add_test (tc_chain, segment_negative_rate);
|
||||
tcase_add_test (tc_chain, segment_negative_applied_rate);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue