basesrc: Send an update NEWSEGMENT event downstream if the duration changes
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 27 May 2011 07:05:46 +0000 (09:05 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 27 May 2011 07:05:46 +0000 (09:05 +0200)
This allows streaming the complete file for files that have grown since
streaming started.

Fixes bug #647940.

libs/gst/base/gstbasesrc.c

index 59319e2..a8098e7 100644 (file)
@@ -2028,6 +2028,7 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
   GstBaseSrcClass *bclass;
   GstFormat format;
   gint64 stop;
+  gboolean updated = FALSE;
 
   bclass = GST_BASE_SRC_GET_CLASS (src);
 
@@ -2083,10 +2084,33 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
   /* keep track of current position and update duration.
    * segment is in bytes, we checked that above. */
   GST_OBJECT_LOCK (src);
+  updated = (src->segment.duration != size);
   gst_segment_set_duration (&src->segment, GST_FORMAT_BYTES, size);
   gst_segment_set_last_stop (&src->segment, GST_FORMAT_BYTES, offset);
   GST_OBJECT_UNLOCK (src);
 
+  /* If we updated the duration and doing forward playback, we
+   * have to update the downstream segments to update the stop
+   * position */
+  if (updated && src->segment.rate >= 0.0) {
+    gint64 stop;
+    GstEvent *event;
+
+    /* for deriving a stop position for the playback segment from the seek
+     * segment, we must take the duration when the stop is not set */
+    if ((stop = src->segment.stop) == -1)
+      stop = src->segment.duration;
+
+    GST_DEBUG_OBJECT (src, "Sending update newsegment from %" G_GINT64_FORMAT
+        " to %" G_GINT64_FORMAT, src->segment.start, stop);
+
+    event =
+        gst_event_new_new_segment_full (TRUE,
+        src->segment.rate, src->segment.applied_rate, src->segment.format,
+        src->segment.start, stop, src->segment.time);
+    gst_pad_push_event (src->srcpad, event);
+  }
+
   return TRUE;
 
   /* ERRORS */