mpegtsdemux: Remember seek sequence number
authorEdward Hervey <edward@collabora.com>
Mon, 15 Jul 2013 09:15:11 +0000 (11:15 +0200)
committerEdward Hervey <edward@collabora.com>
Mon, 15 Jul 2013 09:20:40 +0000 (11:20 +0200)
* Avoids handling twice the same seek (can happen with playbin and files
  with subtitles)
* Set the sequence number of the segment event to the sequence number of
  the seek event that generated it (-1 for the initial one).

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

index e09b4ab..3344fb0 100644 (file)
@@ -199,6 +199,7 @@ mpegts_base_reset (MpegTSBase * base)
   /* pmt pids will be added and removed dynamically */
 
   gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED);
+  base->last_seek_seqnum = (guint32) - 1;
 
   base->mode = BASE_MODE_STREAMING;
   base->seen_pat = FALSE;
@@ -1335,6 +1336,11 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad,
   if (format != GST_FORMAT_TIME)
     return FALSE;
 
+  if (GST_EVENT_SEQNUM (event) == base->last_seek_seqnum) {
+    GST_DEBUG_OBJECT (base, "Skipping already handled seek");
+    return TRUE;
+  }
+
   if (base->mode == BASE_MODE_PUSHING) {
     /* First try if upstream supports seeking in TIME format */
     if (gst_pad_push_event (base->sinkpad, gst_event_ref (event))) {
@@ -1354,6 +1360,8 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad,
                     GST_SEEK_TYPE_SET, base->seek_offset,
                     GST_SEEK_TYPE_NONE, -1)))
           ret = GST_FLOW_ERROR;
+        else
+          base->last_seek_seqnum = GST_EVENT_SEQNUM (event);
         base->mode = BASE_MODE_PUSHING;
       }
     }
@@ -1396,16 +1404,16 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad,
   }
 
 
-  if (format == GST_FORMAT_TIME) {
-    /* If the subclass can seek, do that */
-    if (klass->seek) {
-      ret = klass->seek (base, event);
-      if (G_UNLIKELY (ret != GST_FLOW_OK)) {
-        GST_WARNING ("seeking failed %s", gst_flow_get_name (ret));
-      }
-    } else {
-      GST_WARNING ("subclass has no seek implementation");
-    }
+  /* If the subclass can seek, do that */
+  if (klass->seek) {
+    ret = klass->seek (base, event);
+    if (G_UNLIKELY (ret != GST_FLOW_OK))
+      GST_WARNING ("seeking failed %s", gst_flow_get_name (ret));
+    else
+      base->last_seek_seqnum = GST_EVENT_SEQNUM (event);
+  } else {
+    /* FIXME : Check this before so we don't do seeks we can't handle ? */
+    GST_WARNING ("subclass has no seek implementation");
   }
 
   if (flush) {
index 81099da..4ed8ba1 100644 (file)
@@ -149,6 +149,9 @@ struct _MpegTSBase {
   /* Upstream segment */
   GstSegment segment;
 
+  /* Last received seek event seqnum (default -1) */
+  guint last_seek_seqnum;
+
   /* Whether to parse private section or not */
   gboolean parse_private_sections;
 
index a5cf2ec..914967c 100644 (file)
@@ -1400,8 +1400,10 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
     }
   }
 
-  if (!demux->segment_event)
+  if (!demux->segment_event) {
     demux->segment_event = gst_event_new_segment (&demux->segment);
+    GST_EVENT_SEQNUM (demux->segment_event) = base->last_seek_seqnum;
+  }
 
 push_new_segment:
   if (demux->update_segment) {