segment: add option to disable clipping
authorWim Taymans <wtaymans@redhat.com>
Thu, 19 Mar 2015 16:36:36 +0000 (17:36 +0100)
committerWim Taymans <wtaymans@redhat.com>
Thu, 19 Mar 2015 16:36:36 +0000 (17:36 +0100)
Add a clip argument to gst_segment_to_running_time_full() to disable
the checks against the segment boundaries. This makes it possible to
generate an extrapolated running-time for timestamps outside of the
segment.

See https://bugzilla.gnome.org/show_bug.cgi?id=740575

gst/gstsegment.c
gst/gstsegment.h
tests/check/gst/gstsegment.c

index e132c65..78046e7 100644 (file)
@@ -457,24 +457,28 @@ gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
  * @segment: a #GstSegment structure.
  * @format: the format of the segment.
  * @position: the position in the segment
+ * @clip: clip against segment boundaries
  * @running_time: result running-time
  *
  * Translate @position to the total running time using the currently configured
- * segment. Position is a value between @segment start and stop time. Compared to
- * gst_segment_to_running_time() this function can return negative running-time
- * and specify if the position was before or after the segment incase it is outside
- * of the segment.
+ * segment. Compared to gst_segment_to_running_time() this function can return
+ * negative running-time and also check if a @position is before or after the
+ * segment.
  *
  * This function is typically used by elements that need to synchronize buffers
  * against the clock or eachother.
  *
- * When #GST_SEGMENT_RESULT_OK is returned, @position is between start and stop of
- * @segment and thus resulted in a positive running-time returned in @running_time.
- *
+ * If clip is %TRUE, @position is a value between @segment start and stop.
  * When @position is outside of the segment start and stop values,
  * #GST_SEGMENT_RESULT_BEFORE or #GST_SEGMENT_RESULT_AFTER is returned depending
  * if @position is respectively before or after the segment.
  *
+ * If clip is %FALSE, @position can be any value and the result of this function
+ * for values outside of the segment is extrapolated.
+ *
+ * When #GST_SEGMENT_RESULT_OK is returned, @position resulted in a positive
+ * running-time returned in @running_time.
+ *
  * When this function returns #GST_SEGMENT_RESULT_NEGATIVE, the returned
  * @running_time should be negated to get the real negative running time.
  *
@@ -484,7 +488,7 @@ gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
  */
 GstSegmentResult
 gst_segment_to_running_time_full (const GstSegment * segment, GstFormat format,
-    guint64 position, guint64 * running_time)
+    guint64 position, gboolean clip, guint64 * running_time)
 {
   GstSegmentResult res;
   guint64 result;
@@ -502,7 +506,7 @@ gst_segment_to_running_time_full (const GstSegment * segment, GstFormat format,
 
   start = segment->start;
   /* before the segment boundary */
-  if (G_UNLIKELY (position < start)) {
+  if (clip && G_UNLIKELY (position < start)) {
     GST_DEBUG ("position(%" G_GUINT64_FORMAT ") < start(%" G_GUINT64_FORMAT
         ")", position, start);
     if (G_LIKELY (segment->rate > 0.0))
@@ -514,7 +518,7 @@ gst_segment_to_running_time_full (const GstSegment * segment, GstFormat format,
 
   stop = segment->stop;
   /* after the segment boundary */
-  if (G_UNLIKELY (stop != -1 && position > stop)) {
+  if (clip && G_UNLIKELY (stop != -1 && position > stop)) {
     GST_DEBUG ("position(%" G_GUINT64_FORMAT ") > stop(%" G_GUINT64_FORMAT
         ")", position, stop);
     if (G_LIKELY (segment->rate > 0.0))
@@ -527,13 +531,15 @@ gst_segment_to_running_time_full (const GstSegment * segment, GstFormat format,
   offset = segment->offset;
 
   if (G_LIKELY (segment->rate > 0.0)) {
+    start += offset;
+
     /* bring to uncorrected position in segment */
-    if (position < start + offset) {
+    if (position < start) {
       /* negative value */
-      result = (start + offset) - position;
+      result = start - position;
       res = GST_SEGMENT_RESULT_NEGATIVE;
     } else {
-      result = position - (start + offset);
+      result = position - start;
       res = GST_SEGMENT_RESULT_OK;
     }
   } else {
@@ -541,13 +547,15 @@ gst_segment_to_running_time_full (const GstSegment * segment, GstFormat format,
     g_return_val_if_fail (stop != -1, GST_SEGMENT_RESULT_INVALID);
     g_return_val_if_fail (stop >= segment->offset, GST_SEGMENT_RESULT_INVALID);
 
+    stop -= offset;
+
     /* bring to uncorrected position in segment */
-    if (position > stop - offset) {
+    if (position > stop) {
       /* negative value */
-      result = position - (stop - offset);
+      result = position - stop;
       res = GST_SEGMENT_RESULT_NEGATIVE;
     } else {
-      result = (stop - offset) - position;
+      result = stop - position;
       res = GST_SEGMENT_RESULT_OK;
     }
   }
@@ -610,7 +618,9 @@ gst_segment_to_running_time (const GstSegment * segment, GstFormat format,
   guint64 result;
   GstSegmentResult res;
 
-  res = gst_segment_to_running_time_full (segment, format, position, &result);
+  res =
+      gst_segment_to_running_time_full (segment, format, position, TRUE,
+      &result);
   if (res == GST_SEGMENT_RESULT_OK)
     return result;
 
index 29212b9..8e9de6f 100644 (file)
@@ -240,7 +240,7 @@ guint64      gst_segment_to_stream_time      (const GstSegment *segment, GstForm
 guint64      gst_segment_to_running_time     (const GstSegment *segment, GstFormat format, guint64 position);
 GstSegmentResult
              gst_segment_to_running_time_full (const GstSegment *segment, GstFormat format, guint64 position,
-                                               guint64 * running_time);
+                                               gboolean clip, guint64 * running_time);
 guint64      gst_segment_to_position         (const GstSegment *segment, GstFormat format, guint64 running_time);
 
 gboolean     gst_segment_set_running_time    (GstSegment *segment, GstFormat format, guint64 running_time);
index 8f642d5..1fc3ac9 100644 (file)
@@ -762,24 +762,24 @@ GST_START_TEST (segment_full)
   check_times (&segment, 220, -1, -1);
 
   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
-          50, &rt) == GST_SEGMENT_RESULT_OK);
+          50, TRUE, &rt) == GST_SEGMENT_RESULT_OK);
   fail_unless (rt == 0);
   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
-          200, &rt) == GST_SEGMENT_RESULT_OK);
+          200, TRUE, &rt) == GST_SEGMENT_RESULT_OK);
   fail_unless (rt == 150);
   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
-          40, &rt) == GST_SEGMENT_RESULT_BEFORE);
+          40, TRUE, &rt) == GST_SEGMENT_RESULT_BEFORE);
   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
-          49, &rt) == GST_SEGMENT_RESULT_BEFORE);
+          49, TRUE, &rt) == GST_SEGMENT_RESULT_BEFORE);
   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
-          201, &rt) == GST_SEGMENT_RESULT_AFTER);
+          201, TRUE, &rt) == GST_SEGMENT_RESULT_AFTER);
 
   fail_unless (gst_segment_offset_running_time (&segment, GST_FORMAT_TIME,
           -50) == TRUE);
   fail_unless (segment.offset == 50);
 
   fail_unless (gst_segment_to_running_time_full (&segment, GST_FORMAT_TIME,
-          50, &rt) == GST_SEGMENT_RESULT_NEGATIVE);
+          50, TRUE, &rt) == GST_SEGMENT_RESULT_NEGATIVE);
   GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
   fail_unless (rt == 50);
 }