From: Wim Taymans Date: Wed, 3 Jun 2009 17:06:30 +0000 (+0200) Subject: segment: add method for converting to position X-Git-Tag: RELEASE-0.10.24~158 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=92984a116b5925a36ea5d64d5f2502dc0578c40e;p=platform%2Fupstream%2Fgstreamer.git 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() --- diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index bd2abd0..790b0b9 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -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 GST_TYPE_SEGMENT gst_segment_get_type diff --git a/gst/gstsegment.c b/gst/gstsegment.c index e1014d9..88601bf 100644 --- a/gst/gstsegment.c +++ b/gst/gstsegment.c @@ -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; +} diff --git a/gst/gstsegment.h b/gst/gstsegment.h index 18c728b..6f66c06 100644 --- a/gst/gstsegment.h +++ b/gst/gstsegment.h @@ -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); diff --git a/tests/check/gst/gstsegment.c b/tests/check/gst/gstsegment.c index eba1271..8e489d4 100644 --- a/tests/check/gst/gstsegment.c +++ b/tests/check/gst/gstsegment.c @@ -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; diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index f7cc829..55a41e2 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -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