[gst-cvs] gst-plugins-bad: mpegtsdemux: added autodetect of packet size and removed m2ts mode property

Josep Torra adn770 at kemper.freedesktop.org
Fri Sep 4 03:32:57 PDT 2009


Module: gst-plugins-bad
Branch: master
Commit: 659e90f8f6be64caece8a011c2398111c36a78f3
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=659e90f8f6be64caece8a011c2398111c36a78f3

Author: Josep Torra <n770galaxy at gmail.com>
Date:   Fri Sep  4 12:30:18 2009 +0200

mpegtsdemux: added autodetect of packet size and removed m2ts mode property

---

 gst/mpegdemux/gstmpegtsdemux.c |   70 ++++++++++++++++++---------------------
 gst/mpegdemux/gstmpegtsdemux.h |    4 ++-
 2 files changed, 35 insertions(+), 39 deletions(-)

diff --git a/gst/mpegdemux/gstmpegtsdemux.c b/gst/mpegdemux/gstmpegtsdemux.c
index f6d3b11..a0b1901 100644
--- a/gst/mpegdemux/gstmpegtsdemux.c
+++ b/gst/mpegdemux/gstmpegtsdemux.c
@@ -103,7 +103,6 @@ enum
   PROP_PROGRAM_NUMBER,
   PROP_PAT_INFO,
   PROP_PMT_INFO,
-  PROP_M2TS
 };
 
 #define GSTTIME_TO_BYTES(time) \
@@ -307,11 +306,6 @@ gst_mpegts_demux_class_init (GstMpegTSDemuxClass * klass)
           "about the currently selected program and its streams",
           MPEGTS_TYPE_PMT_INFO, G_PARAM_READABLE));
 
-  g_object_class_install_property (gobject_class, PROP_M2TS,
-      g_param_spec_boolean ("m2ts_mode", "M2TS(192 bytes) Mode",
-          "Defines if the input is normal TS ie .ts(188 bytes)"
-          "or Blue-Ray Format ie .m2ts(192 bytes).", FALSE, G_PARAM_READWRITE));
-
   gstelement_class->change_state = gst_mpegts_demux_change_state;
   gstelement_class->provide_clock = gst_mpegts_demux_provide_clock;
 }
@@ -333,8 +327,6 @@ gst_mpegts_demux_init (GstMpegTSDemux * demux)
   demux->nb_elementary_pids = 0;
   demux->check_crc = DEFAULT_PROP_CHECK_CRC;
   demux->program_number = DEFAULT_PROP_PROGRAM_NUMBER;
-  demux->packetsize = MPEGTS_NORMAL_TS_PACKETSIZE;
-  demux->m2ts_mode = FALSE;
   demux->sync_lut = NULL;
   demux->sync_lut_len = 0;
   demux->bitrate = -1;
@@ -487,34 +479,18 @@ static gboolean
 gst_mpegts_demux_sink_setcaps (GstPad * pad, GstCaps * caps)
 {
   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
-  gboolean ret = FALSE;
   GstStructure *structure = NULL;
-  gint expected_packetsize =
-      (demux->m2ts_mode ? MPEGTS_M2TS_TS_PACKETSIZE :
-      MPEGTS_NORMAL_TS_PACKETSIZE);
-  gint packetsize = expected_packetsize;
 
   structure = gst_caps_get_structure (caps, 0);
 
   GST_DEBUG_OBJECT (demux, "setcaps called with %" GST_PTR_FORMAT, caps);
 
-  if (!gst_structure_get_int (structure, "packetsize", &packetsize)) {
+  if (!gst_structure_get_int (structure, "packetsize", &demux->packetsize)) {
     GST_DEBUG_OBJECT (demux, "packetsize parameter not found in sink caps");
   }
 
-  if (packetsize < expected_packetsize) {
-    GST_WARNING_OBJECT (demux, "packetsize = %" G_GINT32_FORMAT "is less then"
-        "expected packetsize of %d bytes", packetsize, expected_packetsize);
-    goto beach;
-  }
-
-  /* here we my have a correct value for packet size */
-  demux->packetsize = packetsize;
-  ret = TRUE;
-
-beach:
   gst_object_unref (demux);
-  return ret;
+  return TRUE;
 }
 
 static FORCE_INLINE guint32
@@ -2901,6 +2877,26 @@ is_mpegts_sync (const guint8 * in_data, const guint8 * end_data,
   return ret;
 }
 
+static inline void
+gst_mpegts_demux_detect_packet_size (GstMpegTSDemux * demux, guint len)
+{
+  guint i, packetsize;
+
+  for (i = 1; i < len; i++) {
+    packetsize = demux->sync_lut[i] - demux->sync_lut[i - 1];
+    if (packetsize == MPEGTS_NORMAL_TS_PACKETSIZE ||
+        packetsize == MPEGTS_M2TS_TS_PACKETSIZE ||
+        packetsize == MPEGTS_DVB_ASI_TS_PACKETSIZE ||
+        packetsize == MPEGTS_ATSC_TS_PACKETSIZE)
+      goto done;
+    else
+      packetsize = 0;
+  }
+
+done:
+  demux->packetsize = (packetsize ? packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
+  GST_DEBUG_OBJECT (demux, "packet_size set to %d bytes", demux->packetsize);
+}
 
 static FORCE_INLINE guint
 gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
@@ -2909,10 +2905,12 @@ gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
   guint sync_count = 0;
   const guint8 *end_scan = in_data + size - demux->packetsize;
   guint8 *ptr_data = (guint8 *) in_data;
+  guint packetsize =
+      (demux->packetsize ? demux->packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
 
   /* Check if the LUT table is big enough */
-  if (G_UNLIKELY (demux->sync_lut_len < (size / MPEGTS_NORMAL_TS_PACKETSIZE))) {
-    demux->sync_lut_len = size / MPEGTS_NORMAL_TS_PACKETSIZE;
+  if (G_UNLIKELY (demux->sync_lut_len < (size / packetsize))) {
+    demux->sync_lut_len = size / packetsize;
     if (demux->sync_lut)
       g_free (demux->sync_lut);
     demux->sync_lut = g_new0 (guint8 *, demux->sync_lut_len);
@@ -2922,22 +2920,24 @@ gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
 
   while (ptr_data <= end_scan && sync_count < demux->sync_lut_len) {
     /* if sync code is found try to store it in the LUT */
-    guint chance = is_mpegts_sync (ptr_data, end_scan, demux->packetsize);
+    guint chance = is_mpegts_sync (ptr_data, end_scan, packetsize);
     if (G_LIKELY (chance > 50)) {
       /* skip paketsize bytes and try find next */
-      guint8 *next_sync = ptr_data + demux->packetsize;
+      guint8 *next_sync = ptr_data + packetsize;
       if (next_sync < end_scan) {
         demux->sync_lut[sync_count] = ptr_data;
         sync_count++;
-        ptr_data += demux->packetsize;
+        ptr_data += packetsize;
       } else
         goto done;
-
     } else {
       ptr_data++;
     }
   }
 done:
+  if (G_UNLIKELY (!demux->packetsize))
+    gst_mpegts_demux_detect_packet_size (demux, sync_count);
+
   *flush = ptr_data - in_data;
 
   return sync_count;
@@ -3147,9 +3147,6 @@ gst_mpegts_demux_set_property (GObject * object, guint prop_id,
     case PROP_PROGRAM_NUMBER:
       demux->program_number = g_value_get_int (value);
       break;
-    case PROP_M2TS:
-      demux->m2ts_mode = g_value_get_boolean (value);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3200,9 +3197,6 @@ gst_mpegts_demux_get_property (GObject * object, guint prop_id,
       }
       break;
     }
-    case PROP_M2TS:
-      g_value_set_boolean (value, demux->m2ts_mode);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
diff --git a/gst/mpegdemux/gstmpegtsdemux.h b/gst/mpegdemux/gstmpegtsdemux.h
index fde6892..693ece1 100644
--- a/gst/mpegdemux/gstmpegtsdemux.h
+++ b/gst/mpegdemux/gstmpegtsdemux.h
@@ -59,6 +59,8 @@ G_BEGIN_DECLS
 #define MPEGTS_MAX_PID 0x1fff
 #define MPEGTS_NORMAL_TS_PACKETSIZE  188
 #define MPEGTS_M2TS_TS_PACKETSIZE    192
+#define MPEGTS_DVB_ASI_TS_PACKETSIZE 204
+#define MPEGTS_ATSC_TS_PACKETSIZE    208
 
 #define IS_MPEGTS_SYNC(data) (((data)[0] == 0x47) && \
                                     (((data)[1] & 0x80) == 0x00) && \
@@ -200,7 +202,7 @@ struct _GstMpegTSDemux {
   /* indicates that we need to close our pad group, because we've added
    * at least one pad */
   gboolean          need_no_more_pads;
-  guint16           packetsize;
+  gint              packetsize;
   gboolean          m2ts_mode;
   /* clocking */
   GstClock          * clock;





More information about the Gstreamer-commits mailing list