oggmux: properly flush when seeking at the beginning
authorThiago Santos <ts.santos@sisa.samsung.com>
Thu, 13 Feb 2014 19:03:01 +0000 (16:03 -0300)
committerThiago Santos <ts.santos@sisa.samsung.com>
Thu, 13 Feb 2014 19:03:01 +0000 (16:03 -0300)
Reset all internal status when collect pads forwards a flush-stop
from the pads to be able to start the stream again.

ext/ogg/gstoggmux.c

index 53da5a0..36345a8 100644 (file)
@@ -137,6 +137,8 @@ static gboolean gst_ogg_mux_handle_src_event (GstPad * pad, GstObject * parent,
 static GstPad *gst_ogg_mux_request_new_pad (GstElement * element,
     GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_ogg_mux_release_pad (GstElement * element, GstPad * pad);
+static void gst_ogg_pad_data_reset (GstOggMux * ogg_mux,
+    GstOggPadData * pad_data);
 
 static void gst_ogg_mux_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec);
@@ -293,6 +295,22 @@ gst_ogg_mux_sinkconnect (GstPad * pad, GstObject * parent, GstPad * peer)
   return GST_PAD_LINK_OK;
 }
 
+static void
+gst_ogg_mux_flush (GstOggMux * ogg_mux)
+{
+  GSList *walk;
+
+  for (walk = ogg_mux->collect->data; walk; walk = g_slist_next (walk)) {
+    GstOggPadData *pad;
+
+    pad = (GstOggPadData *) walk->data;
+
+    gst_ogg_pad_data_reset (ogg_mux, pad);
+  }
+
+  gst_ogg_mux_clear (ogg_mux);
+}
+
 static gboolean
 gst_ogg_mux_sink_event (GstCollectPads * pads, GstCollectData * pad,
     GstEvent * event, gpointer user_data)
@@ -320,7 +338,8 @@ gst_ogg_mux_sink_event (GstCollectPads * pads, GstCollectData * pad,
       break;
     }
     case GST_EVENT_FLUSH_STOP:{
-      gst_segment_init (&ogg_pad->segment, GST_FORMAT_TIME);
+      /* only a single flush-stop is forwarded from collect pads */
+      gst_ogg_mux_flush (ogg_mux);
       break;
     }
     case GST_EVENT_TAG:{
@@ -362,6 +381,40 @@ gst_ogg_mux_is_serialno_present (GstOggMux * ogg_mux, guint32 serialno)
   return FALSE;
 }
 
+static void
+gst_ogg_pad_data_reset (GstOggMux * ogg_mux, GstOggPadData * oggpad)
+{
+  oggpad->packetno = 0;
+  oggpad->pageno = 0;
+  oggpad->eos = FALSE;
+
+  /* we assume there will be some control data first for this pad */
+  oggpad->state = GST_OGG_PAD_STATE_CONTROL;
+  oggpad->new_page = TRUE;
+  oggpad->first_delta = FALSE;
+  oggpad->prev_delta = FALSE;
+  oggpad->data_pushed = FALSE;
+  oggpad->map.headers = NULL;
+  oggpad->map.queued = NULL;
+  oggpad->next_granule = 0;
+  oggpad->keyframe_granule = -1;
+  ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno);
+
+  if (oggpad->pagebuffers) {
+    GstBuffer *buf;
+
+    while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) {
+      gst_buffer_unref (buf);
+    }
+  } else if (GST_STATE (ogg_mux) > GST_STATE_READY) {
+    /* This will be initialized in init_collectpads when going from ready
+     * paused state */
+    oggpad->pagebuffers = g_queue_new ();
+  }
+
+  gst_segment_init (&oggpad->segment, GST_FORMAT_TIME);
+}
+
 static guint32
 gst_ogg_mux_generate_serialno (GstOggMux * ogg_mux)
 {
@@ -442,28 +495,7 @@ gst_ogg_mux_request_new_pad (GstElement * element,
       ogg_mux->active_pads++;
 
       oggpad->map.serialno = serial;
-      oggpad->packetno = 0;
-      oggpad->pageno = 0;
-      oggpad->eos = FALSE;
-      /* we assume there will be some control data first for this pad */
-      oggpad->state = GST_OGG_PAD_STATE_CONTROL;
-      oggpad->new_page = TRUE;
-      oggpad->first_delta = FALSE;
-      oggpad->prev_delta = FALSE;
-      oggpad->data_pushed = FALSE;
-      oggpad->map.headers = NULL;
-      oggpad->map.queued = NULL;
-      oggpad->next_granule = 0;
-      oggpad->keyframe_granule = -1;
-
-      if (GST_STATE (ogg_mux) > GST_STATE_READY) {
-        /* This will be initialized in init_collectpads when going from ready
-         * paused state */
-        ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno);
-        oggpad->pagebuffers = g_queue_new ();
-      }
-
-      gst_segment_init (&oggpad->segment, GST_FORMAT_TIME);
+      gst_ogg_pad_data_reset (ogg_mux, oggpad);
     }
   }