diff options
author | Edward Hervey <edward@collabora.com> | 2013-07-06 10:36:33 +0200 |
---|---|---|
committer | Edward Hervey <edward@collabora.com> | 2013-07-06 10:59:54 +0200 |
commit | a3b6b1a9513bcdadf219e9c4ac48ee0472eb1552 (patch) | |
tree | cab7865630192e62459df9694c889cdaaf479c48 /gst | |
parent | 20e9f0d13933011967a60c4637c5fbe4b70df316 (diff) | |
download | gstreamer-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.h | 13 | ||||
-rw-r--r-- | gst/mpegtsdemux/mpegtsbase.c | 30 | ||||
-rw-r--r-- | gst/mpegtsdemux/mpegtsbase.h | 27 | ||||
-rw-r--r-- | gst/mpegtsdemux/tsdemux.c | 170 |
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. " |