matroskademux: Defer seeks received before GST_MATROSKA_READ_STATE_DATA
authorAlicia Boya García <aboya@igalia.com>
Wed, 14 Nov 2018 07:57:55 +0000 (08:57 +0100)
committerSebastian Dröge <slomo@coaxion.net>
Thu, 15 Nov 2018 08:01:29 +0000 (08:01 +0000)
This patch enables matroskademux to receive seeks before it reaches
GST_MATROSKA_READ_STATE_DATA.

Closes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/issues/514

This also enables receiving seeks in the element READY state.

When such a seek is received, it is stored to be later handled when
GST_MATROSKA_READ_STATE_DATA is reached.

gst/matroska/matroska-demux.c
gst/matroska/matroska-demux.h

index 2362c97..b06c2df 100644 (file)
@@ -357,6 +357,11 @@ gst_matroska_demux_reset (GstElement * element)
 
   demux->cached_length = G_MAXUINT64;
 
+  if (demux->deferred_seek_event)
+    gst_event_unref (demux->deferred_seek_event);
+  demux->deferred_seek_event = NULL;
+  demux->deferred_seek_pad = NULL;
+
   gst_flow_combiner_clear (demux->flowcombiner);
 }
 
@@ -1898,9 +1903,13 @@ gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
   if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
     /* no seeking until we are (safely) ready */
     if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
-      GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
-      gst_event_unref (event);
-      return FALSE;
+      GST_DEBUG_OBJECT (demux,
+          "not ready for seeking yet, deferring seek: %" GST_PTR_FORMAT, event);
+      if (demux->deferred_seek_event)
+        gst_event_unref (demux->deferred_seek_event);
+      demux->deferred_seek_event = event;
+      demux->deferred_seek_pad = NULL;
+      return TRUE;
     }
     res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
   } else {
@@ -3009,9 +3018,14 @@ gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
     case GST_EVENT_SEEK:
       /* no seeking until we are (safely) ready */
       if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
-        GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
-        gst_event_unref (event);
-        return FALSE;
+        GST_DEBUG_OBJECT (demux,
+            "not ready for seeking yet, deferring seek event: %" GST_PTR_FORMAT,
+            event);
+        if (demux->deferred_seek_event)
+          gst_event_unref (demux->deferred_seek_event);
+        demux->deferred_seek_event = event;
+        demux->deferred_seek_pad = pad;
+        return TRUE;
       }
 
       {
@@ -5324,6 +5338,20 @@ gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
               demux->common.offset = demux->first_cluster_offset;
             }
 
+            if (demux->deferred_seek_event) {
+              GstEvent *seek_event;
+              GstPad *seek_pad;
+              seek_event = demux->deferred_seek_event;
+              seek_pad = demux->deferred_seek_pad;
+              demux->deferred_seek_event = NULL;
+              demux->deferred_seek_pad = NULL;
+              GST_DEBUG_OBJECT (demux,
+                  "Handling deferred seek event: %" GST_PTR_FORMAT, seek_event);
+              gst_matroska_demux_handle_seek_event (demux, seek_pad,
+                  seek_event);
+              gst_event_unref (seek_event);
+            }
+
             /* send initial segment - we wait till we know the first
                incoming timestamp, so we can properly set the start of
                the segment. */
index 67a2610..68569b5 100644 (file)
@@ -100,6 +100,8 @@ typedef struct _GstMatroskaDemux {
   gboolean                 building_index;
   guint64                  index_offset;
   GstEvent                *seek_event;
+  GstEvent                *deferred_seek_event;
+  GstPad                  *deferred_seek_pad;
   gboolean                 need_segment;
   guint32                  segment_seqnum;