summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@collabora.com>2013-07-06 14:50:52 +0200
committerEdward Hervey <edward@collabora.com>2013-07-06 14:50:52 +0200
commit1c96c79b88cce303bf02fe9b2723d09c6caa938c (patch)
treea90b6ed23d7058e04359f20dd4cb8ad77ff1035c
parent057d24811daae96c2353add41453d118cd9eb586 (diff)
downloadgstreamer-plugins-bad-1c96c79b88cce303bf02fe9b2723d09c6caa938c.tar.gz
mpegtsdemux: Handle private section streams
Until now we simply ignored those streams (since we couldn't do anything with it anyway). Now that we have the mpegts library and we offload the section handling to the application side we can properly identify and extract them. By default it is disabled for tsparse and enabled for tsdemux, but there is a property to change that. This should open the way to properly handle all private section streams, including: * DSM-CC * MHEG * Carousel data * Metadata streams (though I haven't seen any of those in the wild) * ... And all other specs/protocols making use of those Partially fixes #560631
-rw-r--r--gst/mpegtsdemux/mpegtsbase.c110
-rw-r--r--gst/mpegtsdemux/mpegtsbase.h3
-rw-r--r--gst/mpegtsdemux/tsdemux.c18
3 files changed, 103 insertions, 28 deletions
diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c
index bdf6cff8b..ded860616 100644
--- a/gst/mpegtsdemux/mpegtsbase.c
+++ b/gst/mpegtsdemux/mpegtsbase.c
@@ -64,12 +64,18 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
enum
{
- ARG_0,
+ PROP_0,
+ PROP_PARSE_PRIVATE_SECTIONS,
/* FILL ME */
};
static void mpegts_base_dispose (GObject * object);
static void mpegts_base_finalize (GObject * object);
+static void mpegts_base_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void mpegts_base_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
static void mpegts_base_free_program (MpegTSBaseProgram * program);
static gboolean mpegts_base_sink_activate (GstPad * pad, GstObject * parent);
static gboolean mpegts_base_sink_activate_mode (GstPad * pad,
@@ -115,9 +121,48 @@ mpegts_base_class_init (MpegTSBaseClass * klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = mpegts_base_dispose;
gobject_class->finalize = mpegts_base_finalize;
+ gobject_class->set_property = mpegts_base_set_property;
+ gobject_class->get_property = mpegts_base_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_PARSE_PRIVATE_SECTIONS,
+ g_param_spec_boolean ("parse-private-sections", "Parse private sections",
+ "Parse private sections", FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+}
+
+static void
+mpegts_base_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ MpegTSBase *base = GST_MPEGTS_BASE (object);
+
+ switch (prop_id) {
+ case PROP_PARSE_PRIVATE_SECTIONS:
+ base->parse_private_sections = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
+mpegts_base_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ MpegTSBase *base = GST_MPEGTS_BASE (object);
+
+ switch (prop_id) {
+ case PROP_PARSE_PRIVATE_SECTIONS:
+ g_value_set_boolean (value, base->parse_private_sections);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+
+static void
mpegts_base_reset (MpegTSBase * base)
{
MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base);
@@ -185,6 +230,7 @@ mpegts_base_init (MpegTSBase * base)
base->programs = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) mpegts_base_free_program);
+ base->parse_private_sections = FALSE;
base->is_pes = g_new0 (guint8, 1024);
base->known_psi = g_new0 (guint8, 1024);
base->program_size = sizeof (MpegTSBaseProgram);
@@ -544,10 +590,28 @@ mpegts_base_deactivate_program (MpegTSBase * base, MpegTSBaseProgram * program)
mpegts_base_program_remove_stream (base, program, stream->pid);
- /* Only unset the is_pes bit if the PID isn't used in any other active
+ /* Only unset the is_pes/known_psi bit if the PID isn't used in any other active
* program */
- if (!mpegts_pid_in_active_programs (base, stream->pid))
- MPEGTS_BIT_UNSET (base->is_pes, stream->pid);
+ if (!mpegts_pid_in_active_programs (base, stream->pid)) {
+ switch (stream->stream_type) {
+ case GST_MPEG_TS_STREAM_TYPE_PRIVATE_SECTIONS:
+ case GST_MPEG_TS_STREAM_TYPE_MHEG:
+ case GST_MPEG_TS_STREAM_TYPE_DSM_CC:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_A:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_B:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_C:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_D:
+ case GST_MPEG_TS_STREAM_TYPE_SL_FLEXMUX_SECTIONS:
+ case GST_MPEG_TS_STREAM_TYPE_METADATA_SECTIONS:
+ /* Set known PSI streams */
+ if (base->parse_private_sections)
+ MPEGTS_BIT_UNSET (base->known_psi, stream->pid);
+ break;
+ default:
+ MPEGTS_BIT_UNSET (base->is_pes, stream->pid);
+ break;
+ }
+ }
}
/* remove pcr stream */
@@ -595,17 +659,35 @@ mpegts_base_activate_program (MpegTSBase * base, MpegTSBaseProgram * program,
for (i = 0; i < pmt->streams->len; ++i) {
GstMpegTsPMTStream *stream = g_ptr_array_index (pmt->streams, i);
- if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->is_pes, stream->pid)))
- GST_FIXME ("Refcounting issue. Setting twice a PID (0x%04x) as known PES",
- stream->pid);
- if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->known_psi, stream->pid))) {
- GST_FIXME
- ("Refcounting issue. Setting a known PSI PID (0x%04x) as known PES",
- stream->pid);
- MPEGTS_BIT_UNSET (base->known_psi, stream->pid);
- }
+ switch (stream->stream_type) {
+ case GST_MPEG_TS_STREAM_TYPE_PRIVATE_SECTIONS:
+ case GST_MPEG_TS_STREAM_TYPE_MHEG:
+ case GST_MPEG_TS_STREAM_TYPE_DSM_CC:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_A:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_B:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_C:
+ case GST_MPEG_TS_STREAM_TYPE_DSMCC_D:
+ case GST_MPEG_TS_STREAM_TYPE_SL_FLEXMUX_SECTIONS:
+ case GST_MPEG_TS_STREAM_TYPE_METADATA_SECTIONS:
+ /* Set known PSI streams */
+ if (base->parse_private_sections)
+ MPEGTS_BIT_SET (base->known_psi, stream->pid);
+ break;
+ default:
+ if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->is_pes, stream->pid)))
+ GST_FIXME
+ ("Refcounting issue. Setting twice a PID (0x%04x) as known PES",
+ stream->pid);
+ if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->known_psi, stream->pid))) {
+ GST_FIXME
+ ("Refcounting issue. Setting a known PSI PID (0x%04x) as known PES",
+ stream->pid);
+ MPEGTS_BIT_UNSET (base->known_psi, stream->pid);
+ }
- MPEGTS_BIT_SET (base->is_pes, stream->pid);
+ MPEGTS_BIT_SET (base->is_pes, stream->pid);
+ break;
+ }
mpegts_base_program_add_stream (base, program,
stream->pid, stream->stream_type, stream);
diff --git a/gst/mpegtsdemux/mpegtsbase.h b/gst/mpegtsdemux/mpegtsbase.h
index 8af7cc577..e55cc5718 100644
--- a/gst/mpegtsdemux/mpegtsbase.h
+++ b/gst/mpegtsdemux/mpegtsbase.h
@@ -148,6 +148,9 @@ struct _MpegTSBase {
/* Upstream segment */
GstSegment segment;
+
+ /* Whether to parse private section or not */
+ gboolean parse_private_sections;
};
struct _MpegTSBaseClass {
diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c
index cafc1576a..9a4e05fc2 100644
--- a/gst/mpegtsdemux/tsdemux.c
+++ b/gst/mpegtsdemux/tsdemux.c
@@ -335,9 +335,11 @@ gst_ts_demux_reset (MpegTSBase * base)
static void
gst_ts_demux_init (GstTSDemux * demux)
{
- GST_MPEGTS_BASE (demux)->stream_size = sizeof (TSDemuxStream);
+ MpegTSBase *base = (MpegTSBase *) demux;
- gst_ts_demux_reset ((MpegTSBase *) demux);
+ base->stream_size = sizeof (TSDemuxStream);
+ base->parse_private_sections = TRUE;
+ gst_ts_demux_reset (base);
}
@@ -861,18 +863,6 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
/* name = g_strdup_printf ("private_%04x", bstream->pid); */
/* caps = gst_caps_new_simple ("hdv/aux-a", NULL); */
break;
- case GST_MPEG_TS_STREAM_TYPE_PRIVATE_SECTIONS:
- case GST_MPEG_TS_STREAM_TYPE_MHEG:
- case GST_MPEG_TS_STREAM_TYPE_DSM_CC:
- case GST_MPEG_TS_STREAM_TYPE_DSMCC_A:
- case GST_MPEG_TS_STREAM_TYPE_DSMCC_B:
- case GST_MPEG_TS_STREAM_TYPE_DSMCC_C:
- case GST_MPEG_TS_STREAM_TYPE_DSMCC_D:
- /* FIXME: Unsetting them from the PES table makes sense since they
- * are sections .. but then why don't we set them as know PSI ?
- * Also: shouldn't this be handled in mpegtsbase ? */
- MPEGTS_BIT_UNSET (base->is_pes, bstream->pid);
- break;
case GST_MPEG_TS_STREAM_TYPE_AUDIO_AAC_ADTS:
template = gst_static_pad_template_get (&audio_template);
name = g_strdup_printf ("audio_%04x", bstream->pid);