summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorEdward Hervey <edward@collabora.com>2013-07-06 10:36:33 +0200
committerEdward Hervey <edward@collabora.com>2013-07-06 10:59:54 +0200
commita3b6b1a9513bcdadf219e9c4ac48ee0472eb1552 (patch)
treecab7865630192e62459df9694c889cdaaf479c48 /gst
parent20e9f0d13933011967a60c4637c5fbe4b70df316 (diff)
downloadgstreamer-plugins-bad-a3b6b1a9513bcdadf219e9c4ac48ee0472eb1552.tar.gz
mpegtsdemux: Handle registration descriptor for programs and streams
* Allows us to simplify some code and prepare for future cleanups. * Remove useless casts * Add some FIXME regarding VC1
Diffstat (limited to 'gst')
-rw-r--r--gst/mpegtsdemux/gstmpegdefs.h13
-rw-r--r--gst/mpegtsdemux/mpegtsbase.c30
-rw-r--r--gst/mpegtsdemux/mpegtsbase.h27
-rw-r--r--gst/mpegtsdemux/tsdemux.c170
4 files changed, 134 insertions, 106 deletions
diff --git a/gst/mpegtsdemux/gstmpegdefs.h b/gst/mpegtsdemux/gstmpegdefs.h
index de14cb921..4f636d900 100644
--- a/gst/mpegtsdemux/gstmpegdefs.h
+++ b/gst/mpegtsdemux/gstmpegdefs.h
@@ -26,6 +26,19 @@
#ifndef __GST_MPEG_DEFS_H__
#define __GST_MPEG_DEFS_H__
+#include <glib/gprintf.h>
+
+#define SAFE_FOURCC_FORMAT "02x%02x%02x%02x (%c%c%c%c)"
+#define SAFE_CHAR(a) (g_ascii_isalnum((gchar) (a)) ? ((gchar)(a)) : '.')
+#define SAFE_FOURCC_ARGS(a) \
+ ((guint8) ((a)>>24)), \
+ ((guint8) ((a) >> 16 & 0xff)), \
+ ((guint8) a >> 8 & 0xff), \
+ ((guint8) a & 0xff), \
+ SAFE_CHAR((a)>>24), \
+ SAFE_CHAR((a) >> 16 & 0xff), \
+ SAFE_CHAR((a) >> 8 & 0xff), \
+ SAFE_CHAR(a & 0xff)
/* Stream type assignments */
/* FIXME: Put these in mpegts lib separate stream type enums */
diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c
index f1e98d535..bdf6cff8b 100644
--- a/gst/mpegtsdemux/mpegtsbase.c
+++ b/gst/mpegtsdemux/mpegtsbase.c
@@ -390,6 +390,23 @@ mpegts_base_remove_program (MpegTSBase * base, gint program_number)
g_hash_table_remove (base->programs, GINT_TO_POINTER (program_number));
}
+static guint32
+get_registration_from_descriptors (GArray * descriptors)
+{
+ const GstMpegTsDescriptor *desc;
+
+ if ((desc =
+ gst_mpegts_find_descriptor (descriptors,
+ GST_MTS_DESC_REGISTRATION))) {
+ if (G_UNLIKELY (desc->descriptor_length < 4)) {
+ GST_WARNING ("Registration descriptor with length < 4. (Corrupted ?)");
+ } else
+ return GST_READ_UINT32_BE (desc->descriptor_data + 2);
+ }
+
+ return 0;
+}
+
static MpegTSBaseStream *
mpegts_base_program_add_stream (MpegTSBase * base,
MpegTSBaseProgram * program, guint16 pid, guint8 stream_type,
@@ -410,6 +427,13 @@ mpegts_base_program_add_stream (MpegTSBase * base,
bstream->pid = pid;
bstream->stream_type = stream_type;
bstream->stream = stream;
+ if (stream) {
+ bstream->registration_id =
+ get_registration_from_descriptors (stream->descriptors);
+ GST_DEBUG ("PID 0x%04x, registration_id %" SAFE_FOURCC_FORMAT,
+ bstream->pid, SAFE_FOURCC_ARGS (bstream->registration_id));
+ }
+
program->streams[pid] = bstream;
program->stream_list = g_list_append (program->stream_list, bstream);
@@ -562,6 +586,12 @@ mpegts_base_activate_program (MpegTSBase * base, MpegTSBaseProgram * program,
program->pmt_pid = pmt_pid;
program->pcr_pid = pmt->pcr_pid;
+ /* extract top-level registration_id if present */
+ program->registration_id =
+ get_registration_from_descriptors (pmt->descriptors);
+ GST_DEBUG ("program 0x%04x, registration_id %" SAFE_FOURCC_FORMAT,
+ program->program_number, SAFE_FOURCC_ARGS (program->registration_id));
+
for (i = 0; i < pmt->streams->len; ++i) {
GstMpegTsPMTStream *stream = g_ptr_array_index (pmt->streams, i);
diff --git a/gst/mpegtsdemux/mpegtsbase.h b/gst/mpegtsdemux/mpegtsbase.h
index 164041fbd..8af7cc577 100644
--- a/gst/mpegtsdemux/mpegtsbase.h
+++ b/gst/mpegtsdemux/mpegtsbase.h
@@ -57,21 +57,30 @@ typedef struct _MpegTSBaseProgram MpegTSBaseProgram;
struct _MpegTSBaseStream
{
- guint16 pid;
- guint8 stream_type;
+ guint16 pid;
+ guint8 stream_type;
+
+ /* Content of the registration descriptor (if present) */
+ guint32 registration_id;
+
GstMpegTsPMTStream *stream;
};
struct _MpegTSBaseProgram
{
- gint program_number;
- guint16 pmt_pid;
- guint16 pcr_pid;
- GstMpegTsSection *section;
+ gint program_number;
+ guint16 pmt_pid;
+ guint16 pcr_pid;
+
+ /* Content of the registration descriptor (if present) */
+ guint32 registration_id;
+
+ GstMpegTsSection *section;
const GstMpegTsPMT *pmt;
- MpegTSBaseStream **streams;
- GList *stream_list;
- gint patcount;
+
+ MpegTSBaseStream **streams;
+ GList *stream_list;
+ gint patcount;
/* Pending Tags for the program */
GstTagList *tags;
diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c
index 3822659a4..cafc1576a 100644
--- a/gst/mpegtsdemux/tsdemux.c
+++ b/gst/mpegtsdemux/tsdemux.c
@@ -696,59 +696,50 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
GST_LOG ("Attempting to create pad for stream 0x%04x with stream_type %d",
bstream->pid, bstream->stream_type);
- /* FIXME : Extract the registration descriptor in mpegtsbase for each
- * program and stream. This will help provide cleaner detection of all the
- * mpeg-ts variants (Bluray, HDV, ...) and "private" types (dirac, vc1,
- * ac3, eac3, ... */
-
/* First handle BluRay-specific stream types since there is some overlap
* between BluRay and non-BluRay streay type identifiers */
- desc =
- mpegts_get_descriptor_from_program (program, GST_MTS_DESC_REGISTRATION);
- if (desc) {
- if (DESC_REGISTRATION_format_identifier (desc) == DRF_ID_HDMV) {
- switch (bstream->stream_type) {
- case ST_BD_AUDIO_AC3:
- {
- const guint8 *ac3_desc;
-
- /* ATSC ac3 audio descriptor */
- ac3_desc =
- mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
- GST_MTS_DESC_AC3_AUDIO_STREAM);
- if (ac3_desc && DESC_AC_AUDIO_STREAM_bsid (ac3_desc) != 16) {
- GST_LOG ("ac3 audio");
- template = gst_static_pad_template_get (&audio_template);
- name = g_strdup_printf ("audio_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("audio/x-ac3");
- } else {
- template = gst_static_pad_template_get (&audio_template);
- name = g_strdup_printf ("audio_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("audio/x-eac3");
- }
- break;
- }
- case ST_BD_AUDIO_EAC3:
+ if (program->registration_id == DRF_ID_HDMV) {
+ switch (bstream->stream_type) {
+ case ST_BD_AUDIO_AC3:
+ {
+ const guint8 *ac3_desc;
+
+ /* ATSC ac3 audio descriptor */
+ ac3_desc =
+ mpegts_get_descriptor_from_stream (bstream,
+ GST_MTS_DESC_AC3_AUDIO_STREAM);
+ if (ac3_desc && DESC_AC_AUDIO_STREAM_bsid (ac3_desc) != 16) {
+ GST_LOG ("ac3 audio");
template = gst_static_pad_template_get (&audio_template);
name = g_strdup_printf ("audio_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("audio/x-eac3");
- break;
- case ST_BD_AUDIO_AC3_TRUE_HD:
- template = gst_static_pad_template_get (&audio_template);
- name = g_strdup_printf ("audio_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("audio/x-true-hd");
- break;
- case ST_BD_AUDIO_LPCM:
+ caps = gst_caps_new_empty_simple ("audio/x-ac3");
+ } else {
template = gst_static_pad_template_get (&audio_template);
name = g_strdup_printf ("audio_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("audio/x-private-ts-lpcm");
- break;
- case ST_BD_PGS_SUBPICTURE:
- template = gst_static_pad_template_get (&subpicture_template);
- name = g_strdup_printf ("subpicture_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
- break;
+ caps = gst_caps_new_empty_simple ("audio/x-eac3");
+ }
+ break;
}
+ case ST_BD_AUDIO_EAC3:
+ template = gst_static_pad_template_get (&audio_template);
+ name = g_strdup_printf ("audio_%04x", bstream->pid);
+ caps = gst_caps_new_empty_simple ("audio/x-eac3");
+ break;
+ case ST_BD_AUDIO_AC3_TRUE_HD:
+ template = gst_static_pad_template_get (&audio_template);
+ name = g_strdup_printf ("audio_%04x", bstream->pid);
+ caps = gst_caps_new_empty_simple ("audio/x-true-hd");
+ break;
+ case ST_BD_AUDIO_LPCM:
+ template = gst_static_pad_template_get (&audio_template);
+ name = g_strdup_printf ("audio_%04x", bstream->pid);
+ caps = gst_caps_new_empty_simple ("audio/x-private-ts-lpcm");
+ break;
+ case ST_BD_PGS_SUBPICTURE:
+ template = gst_static_pad_template_get (&subpicture_template);
+ name = g_strdup_printf ("subpicture_%04x", bstream->pid);
+ caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
+ break;
}
}
if (template && name && caps)
@@ -788,8 +779,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
/* FIXME: Move all of this into a common method (there might be other
* types also, depending on registratino descriptors also
*/
- desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
- GST_MTS_DESC_DVB_AC3);
+ desc = mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_AC3);
if (desc) {
GST_LOG ("ac3 audio");
template = gst_static_pad_template_get (&audio_template);
@@ -798,7 +788,8 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
break;
}
- desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
+ desc =
+ mpegts_get_descriptor_from_stream (bstream,
GST_MTS_DESC_DVB_ENHANCED_AC3);
if (desc) {
GST_LOG ("ac3 audio");
@@ -807,7 +798,8 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
caps = gst_caps_new_empty_simple ("audio/x-eac3");
break;
}
- desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
+ desc =
+ mpegts_get_descriptor_from_stream (bstream,
GST_MTS_DESC_DVB_TELETEXT);
if (desc) {
GST_LOG ("teletext");
@@ -817,7 +809,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
break;
}
desc =
- mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
+ mpegts_get_descriptor_from_stream (bstream,
GST_MTS_DESC_DVB_SUBTITLING);
if (desc) {
GST_LOG ("subtitling");
@@ -827,25 +819,21 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
break;
}
- desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
- GST_MTS_DESC_REGISTRATION);
- if (desc) {
- switch (DESC_REGISTRATION_format_identifier (desc)) {
- case DRF_ID_DTS1:
- case DRF_ID_DTS2:
- case DRF_ID_DTS3:
- /* SMPTE registered DTS */
- GST_LOG ("subtitling");
- template = gst_static_pad_template_get (&private_template);
- name = g_strdup_printf ("private_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("audio/x-dts");
- break;
- case DRF_ID_S302M:
- template = gst_static_pad_template_get (&audio_template);
- name = g_strdup_printf ("audio_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("audio/x-smpte-302m");
- break;
- }
+ switch (bstream->registration_id) {
+ case DRF_ID_DTS1:
+ case DRF_ID_DTS2:
+ case DRF_ID_DTS3:
+ /* SMPTE registered DTS */
+ GST_LOG ("subtitling");
+ template = gst_static_pad_template_get (&private_template);
+ name = g_strdup_printf ("private_%04x", bstream->pid);
+ caps = gst_caps_new_empty_simple ("audio/x-dts");
+ break;
+ case DRF_ID_S302M:
+ template = gst_static_pad_template_get (&audio_template);
+ name = g_strdup_printf ("audio_%04x", bstream->pid);
+ caps = gst_caps_new_empty_simple ("audio/x-smpte-302m");
+ break;
}
if (template)
break;
@@ -914,34 +902,23 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
"alignment", G_TYPE_STRING, "nal", NULL);
break;
case ST_VIDEO_DIRAC:
- desc =
- mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
- GST_MTS_DESC_REGISTRATION);
- if (desc) {
- if (DESC_LENGTH (desc) >= 4) {
- if (DESC_REGISTRATION_format_identifier (desc) == 0x64726163) {
- GST_LOG ("dirac");
- /* dirac in hex */
- template = gst_static_pad_template_get (&video_template);
- name = g_strdup_printf ("video_%04x", bstream->pid);
- caps = gst_caps_new_empty_simple ("video/x-dirac");
- }
- }
+ if (bstream->registration_id == 0x64726163) {
+ GST_LOG ("dirac");
+ /* dirac in hex */
+ template = gst_static_pad_template_get (&video_template);
+ name = g_strdup_printf ("video_%04x", bstream->pid);
+ caps = gst_caps_new_empty_simple ("video/x-dirac");
}
break;
case ST_PRIVATE_EA: /* Try to detect a VC1 stream */
{
gboolean is_vc1 = FALSE;
- desc =
- mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
- GST_MTS_DESC_REGISTRATION);
- if (desc) {
- if (DESC_LENGTH (desc) >= 4) {
- if (DESC_REGISTRATION_format_identifier (desc) == DRF_ID_VC1) {
- is_vc1 = TRUE;
- }
- }
- }
+
+ /* Note/FIXME: RP-227 specifies that the registration descriptor
+ * for vc1 can also contain other information, such as profile,
+ * level, alignment, buffer_size, .... */
+ if (bstream->registration_id == DRF_ID_VC1)
+ is_vc1 = TRUE;
if (!is_vc1) {
GST_WARNING ("0xea private stream type found but no descriptor "
"for VC1. Assuming plain VC1.");
@@ -956,7 +933,8 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
}
case ST_PS_AUDIO_AC3:
/* DVB_ENHANCED_AC3 */
- desc = mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
+ desc =
+ mpegts_get_descriptor_from_stream (bstream,
GST_MTS_DESC_DVB_ENHANCED_AC3);
if (desc) {
template = gst_static_pad_template_get (&audio_template);
@@ -966,9 +944,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
}
/* DVB_AC3 */
- desc =
- mpegts_get_descriptor_from_stream ((MpegTSBaseStream *) stream,
- GST_MTS_DESC_DVB_AC3);
+ desc = mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_DVB_AC3);
if (!desc)
GST_WARNING ("AC3 stream type found but no corresponding "
"descriptor to differentiate between AC3 and EAC3. "