mpegtsbase: Add a GList of streams to the program
authorEdward Hervey <bilboed@bilboed.com>
Tue, 19 Jul 2011 07:34:37 +0000 (09:34 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Tue, 19 Jul 2011 07:49:40 +0000 (09:49 +0200)
Allows faster iteration of all program streams.

We still keep the Array to allow fast retrieval of stream by PID.

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

index 55ed3bf..e4118b6 100644 (file)
@@ -432,14 +432,16 @@ mpegts_base_deactivate_program (MpegTSBase * base, MpegTSBaseProgram * program)
 static void
 mpegts_base_free_program (MpegTSBaseProgram * program)
 {
-  guint i;
+  GList *tmp;
 
   if (program->pmt_info)
     gst_structure_free (program->pmt_info);
 
-  for (i = 0; i < 0x2000; i++)
-    if (program->streams[i])
-      mpegts_base_free_stream (program->streams[i]);
+  for (tmp = program->stream_list; tmp; tmp = tmp->next)
+    mpegts_base_free_stream ((MpegTSBaseStream *) tmp->data);
+  if (program->stream_list)
+    g_list_free (program->stream_list);
+
   g_free (program->streams);
 
   if (program->tags)
@@ -482,6 +484,7 @@ mpegts_base_program_add_stream (MpegTSBase * base,
   stream->stream_info = stream_info;
 
   program->streams[pid] = stream;
+  program->stream_list = g_list_append (program->stream_list, stream);
 
   if (klass->stream_added)
     klass->stream_added (base, stream, program);
@@ -500,12 +503,17 @@ mpegts_base_program_remove_stream (MpegTSBase * base,
     MpegTSBaseProgram * program, guint16 pid)
 {
   MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base);
+  MpegTSBaseStream *stream = program->streams[pid];
+
+  GST_DEBUG ("pid:0x%04x", pid);
+
 
   /* If subclass needs it, inform it of the stream we are about to remove */
   if (klass->stream_removed)
-    klass->stream_removed (base, program->streams[pid]);
+    klass->stream_removed (base, stream);
 
-  mpegts_base_free_stream (program->streams[pid]);
+  program->stream_list = g_list_remove_all (program->stream_list, stream);
+  mpegts_base_free_stream (stream);
   program->streams[pid] = NULL;
 }
 
index 4ba0a4b..44cb501 100644 (file)
@@ -64,6 +64,7 @@ struct _MpegTSBaseProgram
   guint16 pcr_pid;
   GstStructure *pmt_info;
   MpegTSBaseStream **streams;
+  GList *stream_list;
   gint patcount;
 
   /* Pending Tags for the program */
index 05f6a9e..94b4671 100644 (file)
@@ -891,18 +891,16 @@ static gboolean
 push_event (MpegTSBase * base, GstEvent * event)
 {
   GstTSDemux *demux = (GstTSDemux *) base;
-  guint i;
+  GList *tmp;
 
   if (G_UNLIKELY (demux->program == NULL))
     return FALSE;
 
-  for (i = 0; i < 0x2000; i++) {
-    if (demux->program->streams[i]) {
-      if (((TSDemuxStream *) demux->program->streams[i])->pad) {
-        gst_event_ref (event);
-        gst_pad_push_event (((TSDemuxStream *) demux->program->streams[i])->pad,
-            event);
-      }
+  for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
+    TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
+    if (stream->pad) {
+      gst_event_ref (event);
+      gst_pad_push_event (stream->pad, event);
     }
   }
 
@@ -913,7 +911,7 @@ static GstFlowReturn
 tsdemux_combine_flows (GstTSDemux * demux, TSDemuxStream * stream,
     GstFlowReturn ret)
 {
-  guint i;
+  GList *tmp;
 
   /* Store the value */
   stream->flow_return = ret;
@@ -923,16 +921,14 @@ tsdemux_combine_flows (GstTSDemux * demux, TSDemuxStream * stream,
     goto done;
 
   /* Only return NOT_LINKED if all other pads returned NOT_LINKED */
-  for (i = 0; i < 0x2000; i++) {
-    if (demux->program->streams[i]) {
-      stream = (TSDemuxStream *) demux->program->streams[i];
-      if (stream->pad) {
-        ret = stream->flow_return;
-        /* some other return value (must be SUCCESS but we can return
-         * other values as well) */
-        if (ret != GST_FLOW_NOT_LINKED)
-          goto done;
-      }
+  for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
+    stream = (TSDemuxStream *) tmp->data;
+    if (stream->pad) {
+      ret = stream->flow_return;
+      /* some other return value (must be SUCCESS but we can return
+       * other values as well) */
+      if (ret != GST_FLOW_NOT_LINKED)
+        goto done;
     }
     /* if we get here, all other pads were unlinked and we return
      * NOT_LINKED then */
@@ -1262,13 +1258,8 @@ gst_ts_demux_stream_flush (TSDemuxStream * stream)
 static void
 gst_ts_demux_flush_streams (GstTSDemux * demux)
 {
-  gint i;
-
-  for (i = 0; i < 0x2000; i++) {
-    if (demux->program->streams[i]) {
-      gst_ts_demux_stream_flush ((TSDemuxStream *) demux->program->streams[i]);
-    }
-  }
+  g_list_foreach (demux->program->stream_list,
+      (GFunc) gst_ts_demux_stream_flush, NULL);
 }
 
 static void
@@ -1278,7 +1269,7 @@ gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
 
   if (demux->program_number == -1 ||
       demux->program_number == program->program_number) {
-    guint i;
+    GList *tmp;
 
     GST_LOG ("program %d started", program->program_number);
     demux->program_number = program->program_number;
@@ -1290,10 +1281,8 @@ gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
      * For example, we don't want to expose HDV AUX private streams, we will just
      * be using them directly for seeking and metadata. */
     if (base->mode != BASE_MODE_SCANNING)
-      for (i = 0; i < 0x2000; i++)
-        if (program->streams[i])
-          activate_pad_for_stream (demux,
-              (TSDemuxStream *) program->streams[i]);
+      for (tmp = program->stream_list; tmp; tmp = tmp->next)
+        activate_pad_for_stream (demux, (TSDemuxStream *) tmp->data);
 
     /* Inform scanner we have got our program */
     demux->current_program_number = program->program_number;
@@ -1303,7 +1292,7 @@ gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
 static void
 gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program)
 {
-  guint i;
+  GList *tmp;
   GstTSDemux *demux = GST_TS_DEMUX (base);
   TSDemuxStream *localstream = NULL;
 
@@ -1312,19 +1301,18 @@ gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program)
   if (demux->program == NULL || program != demux->program)
     return;
 
-  for (i = 0; i < 0x2000; i++) {
-    if (demux->program->streams[i]) {
-      localstream = (TSDemuxStream *) program->streams[i];
-      if (localstream->pad) {
-        GST_DEBUG ("HAVE PAD %s:%s", GST_DEBUG_PAD_NAME (localstream->pad));
-        if (gst_pad_is_active (localstream->pad))
-          gst_element_remove_pad (GST_ELEMENT_CAST (demux), localstream->pad);
-        else
-          gst_object_unref (localstream->pad);
-        localstream->pad = NULL;
-      }
+  for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
+    localstream = (TSDemuxStream *) tmp->data;
+    if (localstream->pad) {
+      GST_DEBUG ("HAVE PAD %s:%s", GST_DEBUG_PAD_NAME (localstream->pad));
+      if (gst_pad_is_active (localstream->pad))
+        gst_element_remove_pad (GST_ELEMENT_CAST (demux), localstream->pad);
+      else
+        gst_object_unref (localstream->pad);
+      localstream->pad = NULL;
     }
   }
+
   demux->program = NULL;
   demux->program_number = -1;
 }
@@ -2067,7 +2055,7 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
   MpegTSBase *base = (MpegTSBase *) demux;
   GstClockTime firstpts = GST_CLOCK_TIME_NONE;
   GstEvent *newsegmentevent;
-  guint i;
+  GList *tmp;
   gint64 start, stop, position;
 
   GST_DEBUG ("Creating new newsegment");
@@ -2083,12 +2071,10 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
    */
 
   /* Find the earliest current PTS we're going to push */
-  for (i = 0; i < 0x2000; i++) {
-    if (demux->program->streams[i]) {
-      if ((!GST_CLOCK_TIME_IS_VALID (firstpts))
-          || (((TSDemuxStream *) demux->program->streams[i])->pts < firstpts))
-        firstpts = ((TSDemuxStream *) demux->program->streams[i])->pts;
-    }
+  for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
+    TSDemuxStream *pstream = (TSDemuxStream *) tmp->data;
+    if (!GST_CLOCK_TIME_IS_VALID (firstpts) || pstream->pts < firstpts)
+      firstpts = pstream->pts;
   }
 
   if (base->mode == BASE_MODE_PUSHING) {