diff --git a/gst-libs/gst/mpegts/gst-dvb-descriptor.c b/gst-libs/gst/mpegts/gst-dvb-descriptor.c index 09a42da6d7..2fd46133f0 100644 --- a/gst-libs/gst/mpegts/gst-dvb-descriptor.c +++ b/gst-libs/gst/mpegts/gst-dvb-descriptor.c @@ -2460,3 +2460,116 @@ gst_mpegts_descriptor_parse_dvb_t2_delivery_system (const GstMpegtsDescriptor *desc = res; return TRUE; } + +/** + * gst_mpegts_descriptor_parse_audio_selection_list: + * @descriptor: a %GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION #GstMpegtsDescriptor + * @list: (out) (transfer full) (element-type GstMpegtsAudioPreselectionDescriptor): + * the list of audio preselection + * + * + * Parses out a list of audio preselection from the @descriptor. + * + * Returns: %TRUE if the parsing happened correctly, else %FALSE. + */ +gboolean +gst_mpegts_descriptor_parse_audio_preselection_list (const GstMpegtsDescriptor + * descriptor, GPtrArray ** list) +{ + guint8 *data; + guint8 i, num_preselections, num_aux_components, future_extension_length; + GstMpegtsAudioPreselectionDescriptor *item; + + g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE); + __common_desc_ext_check_base (descriptor, + GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION, FALSE); + + *list = g_ptr_array_new_with_free_func ((GDestroyNotify) + gst_mpegts_descriptor_parse_audio_preselection_free); + + data = (guint8 *) descriptor->data + 3; + num_preselections = (guint8) ((*data & 0xF8) >> 3); + data += 1; + + for (i = 0; i < num_preselections; i++) { + item = g_slice_new0 (GstMpegtsAudioPreselectionDescriptor); + g_ptr_array_add (*list, item); + + item->preselection_id = (*data & 0xF8) >> 3; + item->audio_rendering_indication = *data & 0x7; + data += 1; + + item->audio_description = (*data & 0x80) >> 7; + item->spoken_subtitles = (*data & 0x40) >> 6; + item->dialogue_enhancement = (*data & 0x20) >> 5; + item->interactivity_enabled = (*data & 0x10) >> 4; + item->language_code_present = (*data & 0x08) >> 3; + item->text_label_present = (*data & 0x04) >> 2; + item->multi_stream_info_present = (*data & 0x02) >> 1; + item->future_extension = (*data) & 0x01; + data += 1; + + if (item->language_code_present == 1) { + item->language_code = convert_lang_code (data); + data += 3; + } + + if (item->text_label_present == 1) { + item->message_id = *data; + data += 1; + } + + if (item->multi_stream_info_present == 1) { + num_aux_components = (*data & 0xE0) >> 5; + data += 1; + for (i = 0; i < num_aux_components; i++) { + data += 1; + } + } + + if (item->future_extension == 1) { + future_extension_length = *data & 0x1F; + data += 1; + for (i = 0; i < future_extension_length; i++) { + data += 1; + } + } + } + + return TRUE; +} + +void gst_mpegts_descriptor_parse_audio_preselection_free + (GstMpegtsAudioPreselectionDescriptor * source) +{ + if (source->language_code_present == 1) { + g_free (source->language_code); + } + g_slice_free (GstMpegtsAudioPreselectionDescriptor, source); +} + +void gst_mpegts_descriptor_parse_audio_preselection_dump + (GstMpegtsAudioPreselectionDescriptor * source) +{ + GST_DEBUG ("[Audio Preselection Descriptor]"); + GST_DEBUG (" preselection_id: 0x%02x", source->preselection_id); + GST_DEBUG ("audio_rendering_indication: 0x%02x", + source->audio_rendering_indication); + GST_DEBUG (" audio_description: %d", source->audio_description); + GST_DEBUG (" spoken_subtitles: %d", source->spoken_subtitles); + GST_DEBUG (" dialogue_enhancement: %d", source->dialogue_enhancement); + GST_DEBUG (" interactivity_enabled: %d", source->interactivity_enabled); + GST_DEBUG (" language_code_present: %d", source->language_code_present); + GST_DEBUG (" text_label_present: %d", source->text_label_present); + GST_DEBUG (" multi_stream_info_present: %d", + source->multi_stream_info_present); + GST_DEBUG (" future_extension: %d", source->future_extension); + + if (source->language_code_present == 1) { + GST_DEBUG (" language_code: %s", source->language_code); + } + if (source->text_label_present == 1) { + GST_DEBUG (" message_id: 0x%02x", source->message_id); + } + GST_DEBUG ("-------------------------------"); +} diff --git a/gst-libs/gst/mpegts/gst-dvb-descriptor.h b/gst-libs/gst/mpegts/gst-dvb-descriptor.h index c68046b330..f6b34c2e84 100644 --- a/gst-libs/gst/mpegts/gst-dvb-descriptor.h +++ b/gst-libs/gst/mpegts/gst-dvb-descriptor.h @@ -152,6 +152,14 @@ typedef enum { GST_MTS_DESC_EXT_DVB_T2MI = 0x11, GST_MTS_DESC_EXT_DVB_URI_LINKAGE = 0x13, GST_MTS_DESC_EXT_DVB_AC4 = 0x15, + /** + * GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION: + * + * Provide all avaliable audio programme for user selection + * + * Since: 1.20 + */ + GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION = 0x19 } GstMpegtsDVBExtendedDescriptorType; /* GST_MTS_DESC_DVB_CAROUSEL_IDENTIFIER (0x13) */ @@ -1055,6 +1063,75 @@ GST_MPEGTS_API gboolean gst_mpegts_descriptor_parse_dvb_t2_delivery_system (const GstMpegtsDescriptor *descriptor, GstMpegtsT2DeliverySystemDescriptor ** res); +/** + * GstMpegtsAudioPreselectionDescriptor: + * @preselection_id: 5-bit + * @audio_rendering_indication: 3-bit field + * @audio_description: visually impaired + * @spoken_subtitles: + * @dialogue_enhancement: + * @interactivity_enabled: + * @language_code_present: + * @text_label_present: + * @multi_stream_info_present: indicates if this PID conveys a complete audio programme + * @future_extension: + * @language_code: NULL terminated ISO 639 language code. + * @message_id: + * @items: (element-type GstMpegtsExtendedEventItem): the #GstMpegtsExtendedEventItem + * @text: + * + * Table 110: Audio Preselection Descriptor (ETSI EN 300 468 v1.16.1) + * + * Since: 1.20 + */ +typedef struct _GstMpegtsAudioPreselectionDescriptor GstMpegtsAudioPreselectionDescriptor; +struct _GstMpegtsAudioPreselectionDescriptor +{ + guint8 preselection_id; + guint8 audio_rendering_indication; + gboolean audio_description; + gboolean spoken_subtitles; + gboolean dialogue_enhancement; + gboolean interactivity_enabled; + gboolean language_code_present; + gboolean text_label_present; + gboolean multi_stream_info_present; + gboolean future_extension; + gchar *language_code; + guint8 message_id; +}; + +/** + * gst_mpegts_descriptor_parse_audio_preselection_list: + * + * Since: 1.20 + */ +GST_MPEGTS_API +gboolean +gst_mpegts_descriptor_parse_audio_preselection_list (const GstMpegtsDescriptor + * descriptor, GPtrArray ** list); + +/** + * gst_mpegts_descriptor_parse_audio_preselection_free: + * + * Since: 1.20 + */ +GST_MPEGTS_API +void +gst_mpegts_descriptor_parse_audio_preselection_free (GstMpegtsAudioPreselectionDescriptor + * source); + +/** + * gst_mpegts_descriptor_parse_audio_preselection_dump: + * + * Since: 1.20 + */ +GST_MPEGTS_API +void +gst_mpegts_descriptor_parse_audio_preselection_dump (GstMpegtsAudioPreselectionDescriptor + * source); + + G_END_DECLS #endif /* GST_MPEGTS_DESCRIPTOR_H */ diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 44f964a168..52665762f7 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -1147,6 +1147,32 @@ gst_ts_demux_create_tags (TSDemuxStream * stream) g_free (lang_code); } } + + if (bstream->stream_type == GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS) { + desc = mpegts_get_descriptor_from_stream_with_extension (bstream, + GST_MTS_DESC_DVB_EXTENSION, GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION); + + if (desc) { + GPtrArray *list; + GstMpegtsAudioPreselectionDescriptor *item; + + if (gst_mpegts_descriptor_parse_audio_preselection_list (desc, &list)) { + GST_DEBUG ("Found AUDIO PRESELECTION descriptor (%d entries)", + list->len); + + for (i = 0; i < list->len; i++) { + item = g_ptr_array_index (list, i); + gst_mpegts_descriptor_parse_audio_preselection_dump (item); + + if (item->language_code_present) { + add_iso639_language_to_tags (stream, item->language_code); + break; + } + } + g_ptr_array_unref (list); + } + } + } } static GstPad *