tsdemux: fixes seeking in pull mode
authorJosep Torra <n770galaxy@gmail.com>
Fri, 24 May 2013 08:59:59 +0000 (10:59 +0200)
committerEdward Hervey <edward@collabora.com>
Wed, 12 Jun 2013 06:01:06 +0000 (08:01 +0200)
Preserve the current segment and observations in pull mode seeks with
flushing.

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

gst/mpegtsdemux/mpegtsbase.c
gst/mpegtsdemux/mpegtsbase.h
gst/mpegtsdemux/mpegtspacketizer.c
gst/mpegtsdemux/mpegtspacketizer.h
gst/mpegtsdemux/tsdemux.c

index 02fa53bae4b391339623a68e4521c737d6c276b1..8914e4fef2454e97df473a069ed56c3cf938057a 100644 (file)
@@ -1291,7 +1291,7 @@ gst_mpegts_base_handle_eos (MpegTSBase * base)
 }
 
 static inline void
-mpegts_base_flush (MpegTSBase * base)
+mpegts_base_flush (MpegTSBase * base, gboolean hard)
 {
   MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base);
 
@@ -1299,7 +1299,7 @@ mpegts_base_flush (MpegTSBase * base)
   if (G_UNLIKELY (klass->flush == NULL))
     GST_WARNING_OBJECT (base, "Class doesn't have a 'flush' implementation !");
   else
-    klass->flush (base);
+    klass->flush (base, hard);
 }
 
 static gboolean
@@ -1337,8 +1337,8 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
       break;
     case GST_EVENT_FLUSH_STOP:
       res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
-      mpegts_packetizer_flush (base->packetizer);
-      mpegts_base_flush (base);
+      mpegts_packetizer_flush (base->packetizer, TRUE);
+      mpegts_base_flush (base, TRUE);
       gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED);
       base->seen_pat = FALSE;
       break;
@@ -1684,9 +1684,10 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad,
     /* send a FLUSH_STOP for the sinkpad, since we need data for seeking */
     GST_DEBUG_OBJECT (base, "sending flush stop");
     gst_pad_push_event (base->sinkpad, gst_event_new_flush_stop (TRUE));
-    /* And actually flush our pending data */
-    mpegts_base_flush (base);
-    mpegts_packetizer_flush (base->packetizer);
+    /* And actually flush our pending data but allow to preserve some info
+     * to perform the seek */
+    mpegts_base_flush (base, FALSE);
+    mpegts_packetizer_flush (base->packetizer, FALSE);
   }
 
   if (flags & (GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_SKIP)) {
index e87233036275a14801069c74576500a993666475..83c0c94a86e276e91c7242438773c931c7024e45 100644 (file)
@@ -165,8 +165,10 @@ struct _MpegTSBaseClass {
   /* seek is called to wait for seeking */
   GstFlowReturn (*seek) (MpegTSBase * base, GstEvent * event);
 
-  /* flush all streams */
-  void (*flush) (MpegTSBase * base);
+  /* flush all streams
+   * The hard inicator is used to flush completelly on FLUSH_STOP events
+   * or partially in pull mode seeks of tsdemux */
+  void (*flush) (MpegTSBase * base, gboolean hard);
 
   /* Notifies subclasses input buffer has been handled */
   GstFlowReturn (*input_done) (MpegTSBase *base, GstBuffer *buffer);
index d28bda5db441435816e3430ba34ff899a12c9248..a19c3909c3bf9f243b245843d704a332bbaf139f 100644 (file)
@@ -2480,7 +2480,7 @@ mpegts_packetizer_clear (MpegTSPacketizer2 * packetizer)
 }
 
 void
-mpegts_packetizer_flush (MpegTSPacketizer2 * packetizer)
+mpegts_packetizer_flush (MpegTSPacketizer2 * packetizer, gboolean hard)
 {
   GST_DEBUG ("Flushing");
 
@@ -2501,7 +2501,10 @@ mpegts_packetizer_flush (MpegTSPacketizer2 * packetizer)
   packetizer->priv->offset = 0;
   packetizer->priv->mapped_size = 0;
   packetizer->priv->last_in_time = GST_CLOCK_TIME_NONE;
-  flush_observations (packetizer);
+  if (hard) {
+    /* For pull mode seeks in tsdemux the observation must be preserved */
+    flush_observations (packetizer);
+  }
 }
 
 void
index e51b2cae051d2c2ae1caf989b7767f8c51d83bb3..78a4008912b358d10dffe5f798248eb45e2c62f9 100644 (file)
@@ -167,7 +167,7 @@ G_GNUC_INTERNAL GType mpegts_packetizer_get_type(void);
 
 G_GNUC_INTERNAL MpegTSPacketizer2 *mpegts_packetizer_new (void);
 G_GNUC_INTERNAL void mpegts_packetizer_clear (MpegTSPacketizer2 *packetizer);
-G_GNUC_INTERNAL void mpegts_packetizer_flush (MpegTSPacketizer2 *packetizer);
+G_GNUC_INTERNAL void mpegts_packetizer_flush (MpegTSPacketizer2 *packetizer, gboolean hard);
 G_GNUC_INTERNAL void mpegts_packetizer_push (MpegTSPacketizer2 *packetizer, GstBuffer *buffer);
 G_GNUC_INTERNAL gboolean mpegts_packetizer_has_packets (MpegTSPacketizer2 *packetizer);
 G_GNUC_INTERNAL MpegTSPacketizerPacketReturn mpegts_packetizer_next_packet (MpegTSPacketizer2 *packetizer,
index 20b08e30465451deee5610730ef4571013af8aff..475f9ceccf0b8428ec7a43a6c5dd9f5101a3f6f4 100644 (file)
@@ -228,7 +228,7 @@ static void gst_ts_demux_reset (MpegTSBase * base);
 static GstFlowReturn
 gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet,
     MpegTSPacketizerSection * section);
-static void gst_ts_demux_flush (MpegTSBase * base);
+static void gst_ts_demux_flush (MpegTSBase * base, gboolean hard);
 static void
 gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * stream,
     MpegTSBaseProgram * program);
@@ -1579,7 +1579,7 @@ gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream,
 }
 
 static void
-gst_ts_demux_flush (MpegTSBase * base)
+gst_ts_demux_flush (MpegTSBase * base, gboolean hard)
 {
   GstTSDemux *demux = GST_TS_DEMUX_CAST (base);
 
@@ -1590,7 +1590,10 @@ gst_ts_demux_flush (MpegTSBase * base)
     demux->segment_event = NULL;
   }
   demux->calculate_update_segment = FALSE;
-  gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
+  if (hard) {
+    /* For pull mode seeks the current segment needs to be preserved */
+    gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
+  }
 }
 
 static GstFlowReturn