gst/playback/gstplaybasebin.c: Don't remove our mute-probe if someone else already...
authorJan Schmidt <thaytan@mad.scientist.com>
Fri, 7 Apr 2006 09:51:35 +0000 (09:51 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Fri, 7 Apr 2006 09:51:35 +0000 (09:51 +0000)
Original commit message from CVS:
* gst/playback/gstplaybasebin.c: (mute_stream), (setup_substreams):
Don't remove our mute-probe if someone else already did so.
Don't set a 2nd one if there is already one pending on the pad.
* gst/playback/gstplaybin.c: (gst_play_bin_send_event_to_sink),
(do_playbin_seek):
When a seek fails, ensure that playbin is still set back to playing.
* gst/typefind/gsttypefindfunctions.c: (mpeg_ts_probe_headers),
(mpeg_ts_type_find), (plugin_init):
Add a typefind function for mpeg-ts streams.

ChangeLog
common
gst/playback/gstplaybasebin.c
gst/playback/gstplaybin.c
gst/typefind/gsttypefindfunctions.c

index cb7a19ee647fbb9bc0394705ca525a3f7870ebc1..28546b9b8eabbd721d642185c352f9c7972be36e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-04-07  Jan Schmidt  <thaytan@mad.scientist.com>
+
+       * gst/playback/gstplaybasebin.c: (mute_stream), (setup_substreams):
+         Don't remove our mute-probe if someone else already did so.
+         Don't set a 2nd one if there is already one pending on the pad.
+
+       * gst/playback/gstplaybin.c: (gst_play_bin_send_event_to_sink),
+       (do_playbin_seek):
+         When a seek fails, ensure that playbin is still set back to playing.
+         
+       * gst/typefind/gsttypefindfunctions.c: (mpeg_ts_probe_headers),
+       (mpeg_ts_type_find), (plugin_init):
+         Add a typefind function for mpeg-ts streams.
+
 2006-04-06  Andy Wingo  <wingo@pobox.com>
 
        * gst/videorate/gstvideorate.c (gst_video_rate_reset) 
diff --git a/common b/common
index 623fe1c2cce45bc30d5823c05716349874ae994e..1783855e983a5294434673694e8a57e44980b6f1 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 623fe1c2cce45bc30d5823c05716349874ae994e
+Subproject commit 1783855e983a5294434673694e8a57e44980b6f1
index 9f9c81f3a7357e80888c4c984dd48eee4006aa83..c69a3a47217dbc0ee1bdf2d2be0e227df5ada426 100644 (file)
 GST_DEBUG_CATEGORY_STATIC (gst_play_base_bin_debug);
 #define GST_CAT_DEFAULT gst_play_base_bin_debug
 
+#if 0
+#define DEFAULT_QUEUE_THRESHOLD ((2 * GST_SECOND) / 3)
+#define DEFAULT_QUEUE_SIZE  (GST_SECOND / 2)
+#else
 #define DEFAULT_QUEUE_THRESHOLD (2 * GST_SECOND)
 #define DEFAULT_QUEUE_SIZE  (3 * GST_SECOND)
+#endif
 
 #define GROUP_LOCK(pbb) g_mutex_lock (pbb->group_lock)
 #define GROUP_UNLOCK(pbb) g_mutex_unlock (pbb->group_lock)
@@ -928,7 +933,8 @@ mute_stream (GstPad * pad, GstBuffer * buf, gpointer data)
   g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
   id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe"));
   g_object_set_data (G_OBJECT (info), "mute_probe", NULL);
-  gst_pad_remove_buffer_probe (GST_PAD_CAST (info->object), id);
+  if (id > 0)
+    gst_pad_remove_buffer_probe (GST_PAD_CAST (info->object), id);
 
   /* no data */
   return FALSE;
@@ -1137,9 +1143,12 @@ setup_substreams (GstPlayBaseBin * play_base_bin)
     if (info->type == GST_STREAM_TYPE_UNKNOWN) {
       guint id;
 
-      id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
-          G_CALLBACK (mute_stream), info);
-      g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id));
+      id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe"));
+      if (id == 0) {
+        id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
+            G_CALLBACK (mute_stream), info);
+        g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id));
+      }
     }
   }
 
index b6eb48f15d41264c98833e3ab98bcd5fd28b35bb..f28379e14f8c371d611c2b0c8f9f7a0a153dc80f 100644 (file)
@@ -1286,8 +1286,13 @@ gst_play_bin_send_event_to_sink (GstPlayBin * play_bin, GstEvent * event)
     GstElement *sink = GST_ELEMENT_CAST (sinks->data);
 
     gst_event_ref (event);
-    if ((res = gst_element_send_event (sink, event)))
+    if ((res = gst_element_send_event (sink, event))) {
+      GST_DEBUG_OBJECT (play_bin,
+          "Sent event succesfully to sink %" GST_PTR_FORMAT, sink);
       break;
+    }
+    GST_DEBUG_OBJECT (play_bin,
+        "Event failed when sent to sink %" GST_PTR_FORMAT, sink);
 
     sinks = g_list_next (sinks);
   }
@@ -1320,14 +1325,18 @@ do_playbin_seek (GstElement * element, GstEvent * event)
 
     if (was_playing) {
       gst_element_set_state (element, GST_STATE_PAUSED);
+      gst_element_get_state (element, NULL, NULL, 50 * GST_MSECOND);
     }
   }
 
+  GST_DEBUG_OBJECT (element, "Sending seek event to a sink");
   res = gst_play_bin_send_event_to_sink (GST_PLAY_BIN (element), event);
 
-  if (flush && res) {
+  if (flush) {
     /* need to reset the stream time to 0 after a flushing seek */
-    gst_pipeline_set_new_stream_time (GST_PIPELINE (element), 0);
+    if (res)
+      gst_pipeline_set_new_stream_time (GST_PIPELINE (element), 0);
+
     if (was_playing)
       /* and continue playing */
       gst_element_set_state (element, GST_STATE_PLAYING);
index 5ab91cb251982e5ceac54ab9758660ded5a316a3..eec4c49958569d1eb791f10a4938d2802b9b763b 100644 (file)
@@ -1073,6 +1073,90 @@ mpeg1_sys_type_find (GstTypeFind * tf, gpointer unused)
   }
 }
 
+/** video/mpegts Transport Stream **/
+static GstStaticCaps mpegts_caps = GST_STATIC_CAPS ("video/mpegts, "
+    "systemstream = (boolean) true, packetsize = (int) [ 188, 208 ]");
+#define MPEGTS_CAPS gst_static_caps_get(&mpegts_caps)
+
+#define GST_MPEGTS_TYPEFIND_TRY_HEADERS 4
+#define GST_MPEGTS_MAX_PACKET_SIZE 204
+#define GST_MPEGTS_TYPEFIND_MAX_SYNC (10 * GST_MPEGTS_MAX_PACKET_SIZE)
+#define GST_MPEGTS_TYPEFIND_SYNC_SIZE \
+            (GST_MPEGTS_TYPEFIND_TRY_HEADERS * GST_MPEGTS_MAX_PACKET_SIZE)
+
+#define MPEGTS_HDR_SIZE 4
+#define IS_MPEGTS_HEADER(data) (((data)[0] == 0x47) && \
+                                (((data)[1] & 0x80) == 0x00) && \
+                                (((data)[3] & 0x10) == 0x10))
+
+/* Helper function to search ahead at intervals of packet_size for mpegts
+ * headers */
+gint
+mpeg_ts_probe_headers (GstTypeFind * tf, guint64 offset, gint packet_size)
+{
+  /* We always enter this function having found at least one header already */
+  gint found = 1;
+  guint8 *data = NULL;
+
+  while (found < GST_MPEGTS_TYPEFIND_TRY_HEADERS) {
+    offset += packet_size;
+
+    data = gst_type_find_peek (tf, offset, MPEGTS_HDR_SIZE);
+    if (data == NULL || !IS_MPEGTS_HEADER (data))
+      return found;
+
+    found++;
+  }
+
+  return found;
+}
+
+/* Try and detect at least 4 packets in at most 10 packets worth of
+ * data. Need to try several possible packet sizes */
+static void
+mpeg_ts_type_find (GstTypeFind * tf, gpointer unused)
+{
+  /* TS packet sizes to test: normal, DVHS packet size and 
+   * FEC with 16 or 20 byte codes packet size. */
+  const gint pack_sizes[] = { 188, 192, 204, 208 };
+  const gint n_pack_sizes = sizeof (pack_sizes) / sizeof (gint);
+
+  guint8 *data = NULL;
+  guint size = 0;
+  guint64 skipped = 0;
+
+  while (skipped < GST_MPEGTS_TYPEFIND_MAX_SYNC) {
+    if (size < MPEGTS_HDR_SIZE) {
+      data = gst_type_find_peek (tf, skipped, GST_MPEGTS_TYPEFIND_SYNC_SIZE);
+      if (!data)
+        break;
+      size = GST_MPEGTS_TYPEFIND_SYNC_SIZE;
+    }
+
+    /* Have at least MPEGTS_HDR_SIZE bytes at this point */
+    if (IS_MPEGTS_HEADER (data)) {
+      gint p;
+
+      for (p = 0; p < n_pack_sizes; p++) {
+        /* Probe ahead at size pack_sizes[p] */
+        if (mpeg_ts_probe_headers (tf, skipped, pack_sizes[p]) >=
+            GST_MPEGTS_TYPEFIND_TRY_HEADERS) {
+          GstCaps *caps = gst_caps_copy (MPEGTS_CAPS);
+
+          gst_structure_set (gst_caps_get_structure (caps, 0), "packetsize",
+              G_TYPE_INT, pack_sizes[p], NULL);
+          gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 1, caps);
+          gst_caps_unref (caps);
+          return;
+        }
+      }
+    }
+    data++;
+    skipped++;
+    size--;
+  }
+}
+
 /*** video/mpeg MPEG-4 elementary video stream ***/
 
 static GstStaticCaps mpeg4_video_caps = GST_STATIC_CAPS ("video/mpeg, "
@@ -2195,6 +2279,7 @@ plugin_init (GstPlugin * plugin)
   static gchar *musepack_exts[] = { "mpc", NULL };
   static gchar *mpeg_sys_exts[] = { "mpe", "mpeg", "mpg", NULL };
   static gchar *mpeg_video_exts[] = { "mpv", "mpeg", "mpg", NULL };
+  static gchar *mpeg_ts_exts[] = { "ts", NULL };
   static gchar *ogg_exts[] = { "anx", "ogg", "ogm", NULL };
   static gchar *qt_exts[] = { "mov", NULL };
   static gchar *rm_exts[] = { "ra", "ram", "rm", "rmvb", NULL };
@@ -2290,6 +2375,8 @@ plugin_init (GstPlugin * plugin)
       mpeg1_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "video/mpeg2", GST_RANK_SECONDARY,
       mpeg2_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL, NULL);
+  TYPE_FIND_REGISTER (plugin, "video/mpegts", GST_RANK_PRIMARY,
+      mpeg_ts_type_find, mpeg_ts_exts, MPEGTS_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "application/ogg", GST_RANK_PRIMARY,
       ogganx_type_find, ogg_exts, OGGANX_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "video/mpeg", GST_RANK_SECONDARY,