mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-08 08:25:33 +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))
|
if (G_UNLIKELY (time == -1))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* bring to uncorrected position in segment */
|
|
||||||
stream_time = position - start;
|
|
||||||
|
|
||||||
abs_applied_rate = ABS (segment->applied_rate);
|
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 */
|
/* add or subtract from segment time based on applied rate */
|
||||||
if (G_LIKELY (segment->applied_rate > 0.0)) {
|
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 */
|
/* correct for segment time */
|
||||||
stream_time += time;
|
stream_time += time;
|
||||||
} else {
|
} else {
|
||||||
/* correct for segment time, clamp at 0. Streams with a negative
|
/* correct for segment time, clamp at 0. Streams with a negative
|
||||||
* applied_rate have timestamps between start and stop, as usual, but have
|
* applied_rate have timestamps between start and stop, as usual, but have
|
||||||
* the time member starting high and going backwards. */
|
* the time member starting high and going backwards. */
|
||||||
if (G_LIKELY (time > stream_time))
|
if (G_UNLIKELY (position > stop))
|
||||||
stream_time = time - stream_time;
|
return -1;
|
||||||
else
|
stream_time = stop - position;
|
||||||
stream_time = 0;
|
if (G_UNLIKELY (abs_applied_rate != 1.0))
|
||||||
|
stream_time *= abs_applied_rate;
|
||||||
|
stream_time += time;
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream_time;
|
return stream_time;
|
||||||
|
|
|
@ -792,6 +792,86 @@ GST_START_TEST (segment_full)
|
||||||
|
|
||||||
GST_END_TEST;
|
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 *
|
static Suite *
|
||||||
gst_segment_suite (void)
|
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_seek_noupdate);
|
||||||
tcase_add_test (tc_chain, segment_offset);
|
tcase_add_test (tc_chain, segment_offset);
|
||||||
tcase_add_test (tc_chain, segment_full);
|
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;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue