gst/videorate/gstvideorate.*: React (more) to NEWSEGMENT
authorMark Nauwelaerts <manauw@skynet.be>
Wed, 28 May 2008 14:49:24 +0000 (14:49 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 28 May 2008 14:49:24 +0000 (14:49 +0000)
Original commit message from CVS:
Patch by: Mark Nauwelaerts <manauw at skynet be>
* gst/videorate/gstvideorate.c: (gst_video_rate_reset),
(gst_video_rate_flush_prev), (gst_video_rate_event),
(gst_video_rate_chain):
* gst/videorate/gstvideorate.h:
React (more) to NEWSEGMENT
Small adjustment in timestamp calculation to prevent mismatches
Fixes #435633.

ChangeLog
common
gst/videorate/gstvideorate.c
gst/videorate/gstvideorate.h

index 782a6bf..0166b1d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-05-28  Wim Taymans  <wim.taymans@collabora.co.uk>
+
+       Patch by: Mark Nauwelaerts <manauw at skynet be>
+
+       * gst/videorate/gstvideorate.c: (gst_video_rate_reset),
+       (gst_video_rate_flush_prev), (gst_video_rate_event),
+       (gst_video_rate_chain):
+       * gst/videorate/gstvideorate.h:
+       React (more) to NEWSEGMENT
+       Small adjustment in timestamp calculation to prevent mismatches
+       Fixes #435633.
+
 2008-05-28  Tim-Philipp Müller  <tim.muller at collabora co uk>
 
        * tests/examples/seek/seek.c: (make_parselaunch_pipeline):
diff --git a/common b/common
index 032f2d9..130fa8f 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 032f2d973bd5c9a9b457cb5fc72d13dafe85c01e
+Subproject commit 130fa8f739ff09aedb520c33239f53d06cfe9bd5
index 47c8518..ce7582e 100644 (file)
@@ -364,6 +364,7 @@ gst_video_rate_reset (GstVideoRate * videorate)
 
   videorate->in = 0;
   videorate->out = 0;
+  videorate->segment_out = 0;
   videorate->drop = 0;
   videorate->dup = 0;
   videorate->next_ts = GST_CLOCK_TIME_NONE;
@@ -423,10 +424,11 @@ gst_video_rate_flush_prev (GstVideoRate * videorate)
   push_ts = videorate->next_ts;
 
   videorate->out++;
+  videorate->segment_out++;
   if (videorate->to_rate_numerator) {
     /* interpolate next expected timestamp in the segment */
     videorate->next_ts = videorate->segment.accum + videorate->segment.start +
-        gst_util_uint64_scale (videorate->out,
+        gst_util_uint64_scale (videorate->segment_out,
         videorate->to_rate_denominator * GST_SECOND,
         videorate->to_rate_numerator);
     GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts;
@@ -464,6 +466,7 @@ gst_video_rate_swap_prev (GstVideoRate * videorate, GstBuffer * buffer,
   videorate->prev_ts = time;
 }
 
+#define MAGIC_LIMIT  25
 static gboolean
 gst_video_rate_event (GstPad * pad, GstEvent * event)
 {
@@ -488,6 +491,38 @@ gst_video_rate_event (GstPad * pad, GstEvent * event)
 
       GST_DEBUG_OBJECT (videorate, "handle NEWSEGMENT");
 
+      /* close up the previous segment, if appropriate */
+      if (!update && videorate->prevbuf) {
+        gint count = 0;
+        GstFlowReturn res;
+
+        res = GST_FLOW_OK;
+        /* fill up to the end of current segment,
+         * or only send out the stored buffer if there is no specific stop.
+         * regardless, prevent going loopy in strange cases */
+        while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
+            ((GST_CLOCK_TIME_IS_VALID (videorate->segment.stop) &&
+                    videorate->next_ts - videorate->segment.accum
+                    < videorate->segment.stop)
+                || count < 1)) {
+          gst_video_rate_flush_prev (videorate);
+          count++;
+        }
+        if (count > 1) {
+          videorate->dup += count - 1;
+          if (!videorate->silent)
+            g_object_notify (G_OBJECT (videorate), "duplicate");
+        } else if (count == 0) {
+          videorate->drop++;
+          if (!videorate->silent)
+            g_object_notify (G_OBJECT (videorate), "drop");
+        }
+        /* clean up for the new one; _chain will resume from the new start */
+        videorate->segment_out = 0;
+        gst_video_rate_swap_prev (videorate, NULL, 0);
+        videorate->next_ts = GST_CLOCK_TIME_NONE;
+      }
+
       /* We just want to update the accumulated stream_time  */
       gst_segment_set_newsegment_full (&videorate->segment, update, rate, arate,
           format, start, stop, time);
@@ -617,7 +652,7 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer)
     if (!GST_CLOCK_TIME_IS_VALID (videorate->next_ts)) {
       /* new buffer, we expect to output a buffer that matches the first
        * timestamp in the segment */
-      videorate->next_ts = videorate->segment.start;
+      videorate->next_ts = videorate->segment.start + videorate->segment.accum;
     }
   } else {
     GstClockTime prevtime;
index 36cae5c..ea6063b 100644 (file)
@@ -55,6 +55,7 @@ struct _GstVideoRate
   guint64 next_ts;              /* Timestamp of next buffer to output */
   GstBuffer *prevbuf;
   guint64 prev_ts;              /* Previous buffer timestamp */
+  guint64 segment_out;          /* in-segment counting */
 
   /* segment handling */
   GstSegment segment;