2 * gstmpegtsdescriptor.c -
3 * Copyright (C) 2013 Edward Hervey
6 * Edward Hervey <edward@collabora.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
31 #include "gstmpegts-private.h"
35 * SECTION:gst-dvb-descriptor
36 * @title: DVB variants of MPEG-TS descriptors
37 * @short_description: Descriptors for the various DVB specifications
38 * @include: gst/mpegts/mpegts.h
45 * * Add common validation code for data presence and minimum/maximum expected
47 * * Add parsing methods for the following descriptors that were previously
48 * handled in mpegtsbase:
49 * * GST_MTS_DESC_DVB_DATA_BROADCAST_ID
50 * * GST_MTS_DESC_DVB_CAROUSEL_IDENTIFIER
53 #define BCD_UN(a) ((a) & 0x0f)
54 #define BCD_DEC(a) (((a) >> 4) & 0x0f)
55 #define BCD(a) (BCD_UN(a) + 10 * BCD_DEC(a))
56 #define BCD_16(a) (BCD(a[1]) + 100 * BCD(a[0]))
57 #define BCD_28(a) (BCD_DEC(a[3]) + 10 * BCD(a[2]) + 1000 * BCD(a[1]) + 100000 * BCD(a[0]))
58 #define BCD_32(a) (BCD(a[3]) + 100 * BCD(a[2]) + 10000 * BCD(a[1]) + 1000000 * BCD(a[0]))
60 #define DEFINE_STATIC_COPY_FUNCTION(type, name) \
61 static type * _##name##_copy (type * source) \
63 return g_slice_dup (type, source); \
66 #define DEFINE_STATIC_FREE_FUNCTION(type, name) \
67 static void _##name##_free (type * source) \
69 g_slice_free (type, source); \
72 /* GST_MTS_DESC_DVB_NETWORK_NAME (0x40) */
74 * gst_mpegts_descriptor_parse_dvb_network_name:
75 * @descriptor: a %GST_MTS_DESC_DVB_NETWORK_NAME #GstMpegtsDescriptor
76 * @name: (out) (transfer full): the extracted name
78 * Parses out the dvb network name from the @descriptor:
80 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
83 gst_mpegts_descriptor_parse_dvb_network_name (const GstMpegtsDescriptor *
84 descriptor, gchar ** name)
86 g_return_val_if_fail (descriptor != NULL && name != NULL, FALSE);
87 /* We need at least one byte of data for the string */
88 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_NETWORK_NAME, 1, FALSE);
90 *name = get_encoding_and_convert ((gchar *) descriptor->data + 2,
96 * gst_mpegts_descriptor_from_dvb_network_name:
97 * @name: the network name to set
99 * Creates a #GstMpegtsDescriptor to be a %GST_MTS_DESC_DVB_NETWORK_NAME,
100 * with the network name @name. The data field of the #GstMpegtsDescriptor
101 * will be allocated, and transferred to the caller.
103 * Returns: (transfer full): the #GstMpegtsDescriptor or %NULL on fail
105 GstMpegtsDescriptor *
106 gst_mpegts_descriptor_from_dvb_network_name (const gchar * name)
108 GstMpegtsDescriptor *descriptor;
109 guint8 *converted_name;
112 g_return_val_if_fail (name != NULL, NULL);
114 converted_name = dvb_text_from_utf8 (name, &size);
117 g_free (converted_name);
121 if (!converted_name) {
122 GST_WARNING ("Could not find proper encoding for string `%s`", name);
126 descriptor = _new_descriptor (GST_MTS_DESC_DVB_NETWORK_NAME, size);
127 memcpy (descriptor->data + 2, converted_name, size);
128 g_free (converted_name);
133 /* GST_MTS_DESC_DVB_SERVICE_LIST (0x41) */
135 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBServiceListItem,
136 gst_mpegts_dvb_service_list_item);
138 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBServiceListItem,
139 gst_mpegts_dvb_service_list_item);
141 G_DEFINE_BOXED_TYPE (GstMpegtsDVBServiceListItem,
142 gst_mpegts_dvb_service_list_item,
143 (GBoxedCopyFunc) _gst_mpegts_dvb_service_list_item_copy,
144 (GFreeFunc) _gst_mpegts_dvb_service_list_item_free);
147 * gst_mpegts_descriptor_parse_dvb_service_list:
148 * @descriptor: a %GST_MTS_DESC_DVB_SERVICE_LIST #GstMpegtsDescriptor
149 * @list: (out) (transfer full) (element-type GstMpegtsDVBServiceListItem):
150 * the list of services
152 * Parses out a list of services from the @descriptor:
154 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
157 gst_mpegts_descriptor_parse_dvb_service_list (const GstMpegtsDescriptor *
158 descriptor, GPtrArray ** list)
162 g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE);
163 /* a entry has 3 bytes, 2 for service id, 1 for service type */
164 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SERVICE_LIST, 3, FALSE);
166 data = (guint8 *) descriptor->data + 2;
168 *list = g_ptr_array_new_with_free_func ((GDestroyNotify)
169 _gst_mpegts_dvb_service_list_item_free);
171 for (i = 0; i < descriptor->length - 2; i += 3) {
172 GstMpegtsDVBServiceListItem *item =
173 g_slice_new0 (GstMpegtsDVBServiceListItem);
175 g_ptr_array_add (*list, item);
176 item->service_id = GST_READ_UINT16_BE (data);
186 /* GST_MTS_DESC_DVB_STUFFING (0x42) */
188 * gst_mpegts_descriptor_parse_dvb_stuffing:
189 * @descriptor: a %GST_MTS_DESC_DVB_STUFFING #GstMpegtsDescriptor
190 * @stuffing_bytes: (out) (transfer full): the stuffing bytes
192 * Parses out the stuffing bytes from the @descriptor.
194 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
197 gst_mpegts_descriptor_parse_dvb_stuffing (const GstMpegtsDescriptor *
198 descriptor, guint8 ** stuffing_bytes)
202 g_return_val_if_fail (descriptor != NULL && stuffing_bytes != NULL, FALSE);
203 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_STUFFING, FALSE);
205 data = (guint8 *) descriptor->data + 2;
207 *stuffing_bytes = g_memdup (data, descriptor->length);
212 /* GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM (0x43) */
214 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsSatelliteDeliverySystemDescriptor,
215 gst_mpegts_satellite_delivery_system_descriptor);
217 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsSatelliteDeliverySystemDescriptor,
218 gst_mpegts_satellite_delivery_system_descriptor);
220 G_DEFINE_BOXED_TYPE (GstMpegtsSatelliteDeliverySystemDescriptor,
221 gst_mpegts_satellite_delivery_system_descriptor,
222 (GBoxedCopyFunc) _gst_mpegts_satellite_delivery_system_descriptor_copy,
223 (GFreeFunc) _gst_mpegts_satellite_delivery_system_descriptor_free);
226 * gst_mpegts_descriptor_parse_satellite_delivery_system:
227 * @descriptor: a %GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM #GstMpegtsDescriptor
228 * @res: (out) (transfer none): the #GstMpegtsSatelliteDeliverySystemDescriptor to fill
230 * Extracts the satellite delivery system information from @descriptor.
232 * Returns: %TRUE if parsing succeeded, else %FALSE.
235 gst_mpegts_descriptor_parse_satellite_delivery_system (const GstMpegtsDescriptor
236 * descriptor, GstMpegtsSatelliteDeliverySystemDescriptor * res)
241 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
242 /* This descriptor is always 11 bytes long */
243 __common_desc_checks_exact (descriptor,
244 GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM, 11, FALSE);
246 data = (guint8 *) descriptor->data + 2;
248 /* BCD coded frequency in GHz (decimal point occurs after the 3rd character)
249 * So direct BCD gives us units of (GHz / 100 000) = 10 kHz*/
250 res->frequency = BCD_32 (data) * 10;
252 /* BCD codec position in degrees (float pointer after the 3rd character) */
253 res->orbital_position = (BCD_16 (data)) / 10.0;
257 res->west_east = (tmp & 0x80) == 0x80;
258 res->polarization = (tmp >> 7) & 0x03;
259 res->modulation_system = (tmp & 0x04) == 0x04;
260 if (res->modulation_system)
261 res->roll_off = (tmp >> 3 & 0x03);
263 res->roll_off = GST_MPEGTS_ROLLOFF_AUTO;
264 switch (tmp & 0x03) {
266 res->modulation_type = GST_MPEGTS_MODULATION_QAM_AUTO;
269 res->modulation_type = GST_MPEGTS_MODULATION_QPSK;
272 res->modulation_type = GST_MPEGTS_MODULATION_PSK_8;
275 res->modulation_type = GST_MPEGTS_MODULATION_QAM_16;
278 res->modulation_type = GST_MPEGTS_MODULATION_QAM_AUTO;
282 /* symbol_rate is in Msymbols/ (decimal point occurs after 3rd character) */
283 /* So direct BCD gives us units of (Msymbol / 10 000) = 100 sym/s */
284 res->symbol_rate = BCD_28 (data) * 100;
287 switch (*data >> 4) {
289 res->fec_inner = GST_MPEGTS_FEC_1_2;
292 res->fec_inner = GST_MPEGTS_FEC_2_3;
295 res->fec_inner = GST_MPEGTS_FEC_3_4;
298 res->fec_inner = GST_MPEGTS_FEC_5_6;
301 res->fec_inner = GST_MPEGTS_FEC_7_8;
304 res->fec_inner = GST_MPEGTS_FEC_8_9;
307 res->fec_inner = GST_MPEGTS_FEC_3_5;
310 res->fec_inner = GST_MPEGTS_FEC_4_5;
313 res->fec_inner = GST_MPEGTS_FEC_9_10;
316 res->fec_inner = GST_MPEGTS_FEC_NONE;
319 res->fec_inner = GST_MPEGTS_FEC_AUTO;
326 /* GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM (0x44) */
328 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsCableDeliverySystemDescriptor,
329 gst_mpegts_dvb_cable_delivery_system_descriptor);
331 void gst_mpegts_dvb_cable_delivery_system_descriptor_free
332 (GstMpegtsCableDeliverySystemDescriptor * source)
334 g_slice_free (GstMpegtsCableDeliverySystemDescriptor, source);
337 G_DEFINE_BOXED_TYPE (GstMpegtsCableDeliverySystemDescriptor,
338 gst_mpegts_dvb_cable_delivery_system_descriptor,
339 (GBoxedCopyFunc) _gst_mpegts_dvb_cable_delivery_system_descriptor_copy,
340 (GFreeFunc) gst_mpegts_dvb_cable_delivery_system_descriptor_free);
343 * gst_mpegts_descriptor_parse_cable_delivery_system:
344 * @descriptor: a %GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM #GstMpegtsDescriptor
345 * @res: (out) (transfer none): the #GstMpegtsCableDeliverySystemDescriptor to fill
347 * Extracts the cable delivery system information from @descriptor.
349 * Returns: %TRUE if parsing succeeded, else %FALSE.
352 gst_mpegts_descriptor_parse_cable_delivery_system (const GstMpegtsDescriptor *
353 descriptor, GstMpegtsCableDeliverySystemDescriptor * res)
357 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
358 /* This descriptor is always 11 bytes long */
359 __common_desc_checks_exact (descriptor,
360 GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM, 11, FALSE);
362 data = (guint8 *) descriptor->data + 2;
363 /* BCD in MHz, decimal place after the fourth character */
364 res->frequency = BCD_32 (data) * 100;
366 /* fec_out (4bits) */
367 res->outer_fec = *data++ & 0x0f;
370 res->modulation = GST_MPEGTS_MODULATION_NONE;
373 res->modulation = GST_MPEGTS_MODULATION_QAM_16;
376 res->modulation = GST_MPEGTS_MODULATION_QAM_32;
379 res->modulation = GST_MPEGTS_MODULATION_QAM_64;
382 res->modulation = GST_MPEGTS_MODULATION_QAM_128;
385 res->modulation = GST_MPEGTS_MODULATION_QAM_256;
388 GST_WARNING ("Unsupported cable modulation type: 0x%02x", *data);
389 res->modulation = GST_MPEGTS_MODULATION_NONE;
394 /* symbol_rate is in Msymbols/ (decimal point occurs after 3rd character) */
395 /* So direct BCD gives us units of (Msymbol / 10 000) = 100 sym/s */
396 res->symbol_rate = BCD_28 (data) * 100;
399 switch (*data & 0xf) {
401 res->fec_inner = GST_MPEGTS_FEC_AUTO;
404 res->fec_inner = GST_MPEGTS_FEC_1_2;
407 res->fec_inner = GST_MPEGTS_FEC_2_3;
410 res->fec_inner = GST_MPEGTS_FEC_3_4;
413 res->fec_inner = GST_MPEGTS_FEC_5_6;
416 res->fec_inner = GST_MPEGTS_FEC_7_8;
419 res->fec_inner = GST_MPEGTS_FEC_8_9;
422 res->fec_inner = GST_MPEGTS_FEC_3_5;
425 res->fec_inner = GST_MPEGTS_FEC_4_5;
428 res->fec_inner = GST_MPEGTS_FEC_9_10;
431 res->fec_inner = GST_MPEGTS_FEC_NONE;
434 res->fec_inner = GST_MPEGTS_FEC_AUTO;
441 /* GST_MTS_DESC_DVB_BOUQUET_NAME (0x47) */
443 * gst_mpegts_descriptor_parse_dvb_bouquet_name:
444 * @bouquet_name: (out) (transfer full) (allow-none): the bouquet name
446 * Extracts the bouquet name from @descriptor.
448 * Returns: %TRUE if parsing succeeded, else %FALSE.
451 gst_mpegts_descriptor_parse_dvb_bouquet_name (const GstMpegtsDescriptor *
452 descriptor, gchar ** bouquet_name)
456 g_return_val_if_fail (descriptor != NULL && bouquet_name != NULL, FALSE);
457 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_BOUQUET_NAME, 1, FALSE);
459 data = (guint8 *) descriptor->data + 2;
462 get_encoding_and_convert ((const gchar *) data, descriptor->length);
467 /* GST_MTS_DESC_DVB_SERVICE (0x48) */
469 * gst_mpegts_descriptor_parse_dvb_service:
470 * @descriptor: a %GST_MTS_DESC_DVB_SERVICE #GstMpegtsDescriptor
471 * @service_type: (out) (allow-none): the service type
472 * @service_name: (out) (transfer full) (allow-none): the service name
473 * @provider_name: (out) (transfer full) (allow-none): the provider name
475 * Extracts the dvb service information from @descriptor.
477 * Returns: %TRUE if parsing succeeded, else %FALSE.
480 gst_mpegts_descriptor_parse_dvb_service (const GstMpegtsDescriptor *
481 descriptor, GstMpegtsDVBServiceType * service_type, gchar ** service_name,
482 gchar ** provider_name)
486 g_return_val_if_fail (descriptor != NULL, FALSE);
487 /* Need at least 3 bytes (type and 2 bytes for the string length) */
488 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SERVICE, 3, FALSE);
490 data = (guint8 *) descriptor->data + 2;
493 *service_type = *data;
496 *provider_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
499 *service_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
505 * gst_mpegts_descriptor_from_dvb_service:
506 * @service_type: Service type defined as a #GstMpegtsDVBServiceType
507 * @service_name: (allow-none): Name of the service
508 * @service_provider: (allow-none): Name of the service provider
510 * Fills a #GstMpegtsDescriptor to be a %GST_MTS_DESC_DVB_SERVICE.
511 * The data field of the #GstMpegtsDescriptor will be allocated,
512 * and transferred to the caller.
514 * Returns: (transfer full): the #GstMpegtsDescriptor or %NULL on fail
516 GstMpegtsDescriptor *
517 gst_mpegts_descriptor_from_dvb_service (GstMpegtsDVBServiceType service_type,
518 const gchar * service_name, const gchar * service_provider)
520 GstMpegtsDescriptor *descriptor = NULL;
521 guint8 *conv_provider_name = NULL, *conv_service_name = NULL;
522 gsize provider_size = 0, service_size = 0;
525 if (service_provider) {
526 conv_provider_name = dvb_text_from_utf8 (service_provider, &provider_size);
528 if (!conv_provider_name) {
529 GST_WARNING ("Could not find proper encoding for string `%s`",
535 if (provider_size >= 256) {
536 GST_WARNING ("Service provider string too big (%" G_GSIZE_FORMAT " > 256)",
542 conv_service_name = dvb_text_from_utf8 (service_name, &service_size);
544 if (!conv_service_name) {
545 GST_WARNING ("Could not find proper encoding for string `%s`",
551 if (service_size >= 256) {
552 GST_WARNING ("Service name string too big (%" G_GSIZE_FORMAT " > 256)",
558 _new_descriptor (GST_MTS_DESC_DVB_SERVICE,
559 3 + provider_size + service_size);
561 data = descriptor->data + 2;
562 *data++ = service_type;
563 *data++ = provider_size;
564 if (conv_provider_name)
565 memcpy (data, conv_provider_name, provider_size);
567 data += provider_size;
568 *data++ = service_size;
569 if (conv_service_name)
570 memcpy (data, conv_service_name, service_size);
573 g_free (conv_service_name);
574 g_free (conv_provider_name);
579 /* GST_MTS_DESC_DVB_LINKAGE (0x4A) */
580 static GstMpegtsDVBLinkageDescriptor *
581 _gst_mpegts_dvb_linkage_descriptor_copy (GstMpegtsDVBLinkageDescriptor * source)
583 GstMpegtsDVBLinkageDescriptor *copy;
585 copy = g_slice_dup (GstMpegtsDVBLinkageDescriptor, source);
587 switch (source->linkage_type) {
588 case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:
589 copy->linkage_data = g_slice_dup (GstMpegtsDVBLinkageMobileHandOver,
590 source->linkage_data);
592 case GST_MPEGTS_DVB_LINKAGE_EVENT:
593 copy->linkage_data = g_slice_dup (GstMpegtsDVBLinkageEvent,
594 source->linkage_data);
596 case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:
597 copy->linkage_data = g_ptr_array_ref (source->linkage_data);
603 copy->private_data_bytes = g_memdup (source->private_data_bytes,
604 source->private_data_length);
610 gst_mpegts_dvb_linkage_descriptor_free (GstMpegtsDVBLinkageDescriptor * source)
612 if (source->linkage_data)
613 switch (source->linkage_type) {
614 case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:
615 g_slice_free (GstMpegtsDVBLinkageMobileHandOver, source->linkage_data);
617 case GST_MPEGTS_DVB_LINKAGE_EVENT:
618 g_slice_free (GstMpegtsDVBLinkageEvent, source->linkage_data);
620 case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:
621 g_ptr_array_unref (source->linkage_data);
627 g_free (source->private_data_bytes);
628 g_slice_free (GstMpegtsDVBLinkageDescriptor, source);
631 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageDescriptor,
632 gst_mpegts_dvb_linkage_descriptor,
633 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_descriptor_copy,
634 (GFreeFunc) gst_mpegts_dvb_linkage_descriptor_free);
636 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBLinkageMobileHandOver,
637 gst_mpegts_dvb_linkage_mobile_hand_over);
639 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBLinkageMobileHandOver,
640 gst_mpegts_dvb_linkage_mobile_hand_over);
642 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageMobileHandOver,
643 gst_mpegts_dvb_linkage_mobile_hand_over,
644 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_mobile_hand_over_copy,
645 (GFreeFunc) _gst_mpegts_dvb_linkage_mobile_hand_over_free);
647 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBLinkageEvent,
648 gst_mpegts_dvb_linkage_event);
650 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBLinkageEvent,
651 gst_mpegts_dvb_linkage_event);
653 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageEvent,
654 gst_mpegts_dvb_linkage_event,
655 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_event_copy,
656 (GFreeFunc) _gst_mpegts_dvb_linkage_event_free);
658 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBLinkageExtendedEvent,
659 gst_mpegts_dvb_linkage_extended_event);
661 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBLinkageExtendedEvent,
662 gst_mpegts_dvb_linkage_extended_event);
664 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageExtendedEvent,
665 gst_mpegts_dvb_linkage_extended_event,
666 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_extended_event_copy,
667 (GFreeFunc) _gst_mpegts_dvb_linkage_extended_event_free);
670 * gst_mpegts_descriptor_parse_dvb_linkage:
671 * @descriptor: a %GST_MTS_DESC_DVB_LINKAGE #GstMpegtsDescriptor
672 * @res: (out) (transfer full): the #GstMpegtsDVBLinkageDescriptor to fill
674 * Extracts the DVB linkage information from @descriptor.
676 * Returns: %TRUE if parsing succeeded, else %FALSE.
679 gst_mpegts_descriptor_parse_dvb_linkage (const GstMpegtsDescriptor * descriptor,
680 GstMpegtsDVBLinkageDescriptor ** desc)
684 GstMpegtsDVBLinkageDescriptor *res;
686 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
687 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_LINKAGE, 7, FALSE);
689 data = (guint8 *) descriptor->data + 2;
690 end = data + descriptor->length;
692 res = g_slice_new0 (GstMpegtsDVBLinkageDescriptor);
694 res->transport_stream_id = GST_READ_UINT16_BE (data);
697 res->original_network_id = GST_READ_UINT16_BE (data);
700 res->service_id = GST_READ_UINT16_BE (data);
703 res->linkage_type = *data;
706 switch (res->linkage_type) {
707 case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:{
708 GstMpegtsDVBLinkageMobileHandOver *hand_over;
713 hand_over = g_slice_new0 (GstMpegtsDVBLinkageMobileHandOver);
714 res->linkage_data = (gpointer) hand_over;
716 hand_over->origin_type = (*data) & 0x01;
717 hand_over->hand_over_type = (*data >> 4) & 0x0f;
720 if (hand_over->hand_over_type ==
721 GST_MPEGTS_DVB_LINKAGE_HAND_OVER_IDENTICAL
722 || hand_over->hand_over_type ==
723 GST_MPEGTS_DVB_LINKAGE_HAND_OVER_LOCAL_VARIATION
724 || hand_over->hand_over_type ==
725 GST_MPEGTS_DVB_LINKAGE_HAND_OVER_ASSOCIATED) {
729 hand_over->network_id = GST_READ_UINT16_BE (data);
733 if (hand_over->origin_type == 0) {
737 hand_over->initial_service_id = GST_READ_UINT16_BE (data);
742 case GST_MPEGTS_DVB_LINKAGE_EVENT:{
743 GstMpegtsDVBLinkageEvent *event;
748 event = g_slice_new0 (GstMpegtsDVBLinkageEvent);
749 res->linkage_data = (gpointer) event;
751 event->target_event_id = GST_READ_UINT16_BE (data);
753 event->target_listed = *data & 0x01;
754 event->event_simulcast = (*data >> 1) & 0x01;
758 case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:{
759 GPtrArray *ext_events;
760 ext_events = g_ptr_array_new_with_free_func ((GDestroyNotify)
761 _gst_mpegts_dvb_linkage_extended_event_free);
763 res->linkage_data = (gpointer) ext_events;
765 for (i = 0; i < *data++;) {
766 GstMpegtsDVBLinkageExtendedEvent *ext_event;
771 ext_event = g_slice_new0 (GstMpegtsDVBLinkageExtendedEvent);
772 g_ptr_array_add (res->linkage_data, ext_event);
774 ext_event->target_event_id = GST_READ_UINT16_BE (data);
778 ext_event->target_listed = *data & 0x01;
779 ext_event->event_simulcast = (*data >> 1) & 0x01;
780 ext_event->link_type = (*data >> 3) & 0x03;
781 ext_event->target_id_type = (*data >> 5) & 0x03;
782 ext_event->original_network_id_flag = (*data >> 6) & 0x01;
783 ext_event->service_id_flag = (*data >> 7) & 0x01;
787 if (ext_event->target_id_type == 3) {
791 ext_event->user_defined_id = GST_READ_UINT16_BE (data);
795 if (ext_event->target_id_type == 1) {
799 ext_event->target_transport_stream_id = GST_READ_UINT16_BE (data);
803 if (ext_event->original_network_id_flag) {
807 ext_event->target_original_network_id = GST_READ_UINT16_BE (data);
811 if (ext_event->service_id_flag) {
815 ext_event->target_service_id = GST_READ_UINT16_BE (data);
827 res->private_data_length = end - data;
828 res->private_data_bytes = g_memdup (data, res->private_data_length);
835 gst_mpegts_dvb_linkage_descriptor_free (res);
840 * gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over:
841 * @desc: the #GstMpegtsDVBLinkageDescriptor
843 * Returns: The #GstMpegtsDVBLinkageMobileHandOver or %NULL if an error happened
845 const GstMpegtsDVBLinkageMobileHandOver *
846 gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over (const
847 GstMpegtsDVBLinkageDescriptor * desc)
849 g_return_val_if_fail (desc != NULL, NULL);
850 g_return_val_if_fail (desc->linkage_type ==
851 GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER, NULL);
853 return (const GstMpegtsDVBLinkageMobileHandOver *) desc->linkage_data;
857 * gst_mpegts_dvb_linkage_descriptor_get_event:
858 * @desc: the #GstMpegtsDVBLinkageDescriptor
860 * Returns: The #GstMpegtsDVBLinkageEvent or %NULL if an error happened
862 const GstMpegtsDVBLinkageEvent *
863 gst_mpegts_dvb_linkage_descriptor_get_event (const GstMpegtsDVBLinkageDescriptor
866 g_return_val_if_fail (desc != NULL, NULL);
867 g_return_val_if_fail (desc->linkage_type ==
868 GST_MPEGTS_DVB_LINKAGE_EVENT, NULL);
870 return (const GstMpegtsDVBLinkageEvent *) desc->linkage_data;
874 * gst_mpegts_dvb_linkage_descriptor_get_extended_event:
875 * @desc: the #GstMpegtsDVBLinkageDescriptor
877 * Returns: (element-type GstMpegtsDVBLinkageExtendedEvent): an #GstMpegtsDVBLinkageExtendedEvent array or %NULL if an error happened
880 gst_mpegts_dvb_linkage_descriptor_get_extended_event (const
881 GstMpegtsDVBLinkageDescriptor * desc)
883 g_return_val_if_fail (desc != NULL, NULL);
884 g_return_val_if_fail (desc->linkage_type ==
885 GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT, NULL);
887 return (const GPtrArray *) desc->linkage_data;
890 /* GST_MTS_DESC_DVB_SHORT_EVENT (0x4D) */
892 * gst_mpegts_descriptor_parse_dvb_short_event:
893 * @descriptor: a %GST_MTS_DESC_DVB_SHORT_EVENT #GstMpegtsDescriptor
894 * @language_code: (out) (transfer full) (allow-none): the language code
895 * @event_name: (out) (transfer full) (allow-none): the event name
896 * @text: (out) (transfer full) (allow-none): the event text
898 * Extracts the DVB short event information from @descriptor.
900 * Returns: %TRUE if parsing succeeded, else %FALSE.
903 gst_mpegts_descriptor_parse_dvb_short_event (const GstMpegtsDescriptor *
904 descriptor, gchar ** language_code, gchar ** event_name, gchar ** text)
908 g_return_val_if_fail (descriptor != NULL, FALSE);
909 /* Need at least 5 bytes (3 for language code, 2 for each string length) */
910 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SHORT_EVENT, 5, FALSE);
912 data = (guint8 *) descriptor->data + 2;
915 *language_code = convert_lang_code (data);
919 *event_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
922 *text = get_encoding_and_convert ((const gchar *) data + 1, *data);
926 /* GST_MTS_DESC_DVB_TELETEXT (0x56) */
928 * gst_mpegts_descriptor_parse_dvb_teletext_idx:
929 * @descriptor: a %GST_MTS_DESC_DVB_TELETEXT #GstMpegtsDescriptor
930 * @idx: The id of the teletext to get
931 * @language_code: (out) (transfer full) (allow-none): a null-terminated string
932 * @teletext_type: (out) (allow-none): #GstMpegtsDVBTeletextType
933 * @magazine_number: (out) (allow-none):
934 * @page_number: (out) (allow-none):
936 * Parses teletext number @idx in the @descriptor. The language is in ISO639 format.
938 * Returns: FALSE on out-of-bounds and errors
941 gst_mpegts_descriptor_parse_dvb_teletext_idx (const GstMpegtsDescriptor *
942 descriptor, guint idx, gchar ** language_code,
943 GstMpegtsDVBTeletextType * teletext_type, guint8 * magazine_number,
944 guint8 * page_number)
948 g_return_val_if_fail (descriptor != NULL, FALSE);
949 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_TELETEXT, FALSE);
951 if (descriptor->length / 5 <= idx)
954 data = (guint8 *) descriptor->data + 2 + idx * 5;
957 *language_code = convert_lang_code (data);
960 *teletext_type = data[3] >> 3;
963 *magazine_number = data[3] & 0x07;
966 *page_number = data[4];
972 * gst_mpegts_descriptor_parse_dvb_teletext_nb:
973 * @descriptor: a %GST_MTS_DESC_DVB_TELETEXT #GstMpegtsDescriptor
975 * Find the number of teletext entries in @descriptor
977 * Returns: Number of teletext entries
980 gst_mpegts_descriptor_parse_dvb_teletext_nb (const GstMpegtsDescriptor *
983 g_return_val_if_fail (descriptor != NULL, 0);
984 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_TELETEXT, FALSE);
986 return descriptor->length / 5;
989 /* GST_MTS_DESC_DVB_SUBTITLING (0x59) */
992 * gst_mpegts_descriptor_parse_dvb_subtitling_idx:
993 * @descriptor: a %GST_MTS_DESC_DVB_SUBTITLING #GstMpegtsDescriptor
994 * @idx: Table id of the entry to parse
995 * @lang: (out) (transfer full): the language code
996 * @type: (out) (transfer none) (allow-none): the type of subtitling
997 * @composition_page_id: (out) (transfer none) (allow-none): the composition page id
998 * @ancillary_page_id: (out) (transfer none) (allow-none): the ancillary page id
1000 * Extracts the DVB subtitling informatio from specific table id in @descriptor.
1002 * Note: Use #gst_tag_get_language_code if you want to get the the
1003 * ISO 639-1 language code from the returned ISO 639-2 one.
1005 * Returns: %TRUE if parsing succeeded, else %FALSE.
1008 gst_mpegts_descriptor_parse_dvb_subtitling_idx (const GstMpegtsDescriptor *
1009 descriptor, guint idx, gchar ** lang, guint8 * type,
1010 guint16 * composition_page_id, guint16 * ancillary_page_id)
1014 g_return_val_if_fail (descriptor != NULL && lang != NULL, FALSE);
1015 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_SUBTITLING, FALSE);
1017 /* If we went too far, return FALSE */
1018 if (descriptor->length / 8 <= idx)
1021 data = (guint8 *) descriptor->data + 2 + idx * 8;
1023 *lang = convert_lang_code (data);
1030 if (composition_page_id)
1031 *composition_page_id = GST_READ_UINT16_BE (data);
1033 if (ancillary_page_id)
1034 *ancillary_page_id = GST_READ_UINT16_BE (data);
1040 * gst_mpegts_descriptor_parse_dvb_subtitling_nb:
1041 * @descriptor: a %GST_MTS_DESC_DVB_SUBTITLING #GstMpegtsDescriptor
1043 * Returns: The number of entries in @descriptor
1046 gst_mpegts_descriptor_parse_dvb_subtitling_nb (const GstMpegtsDescriptor *
1049 g_return_val_if_fail (descriptor != NULL, FALSE);
1050 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_SUBTITLING, FALSE);
1052 return descriptor->length / 8;
1056 * gst_mpegts_descriptor_from_dvb_subtitling:
1057 * @lang: (transfer none): a string containing the ISO639 language
1058 * @type: subtitling type
1059 * @composition: composition page id
1060 * @ancillary: ancillary page id
1062 GstMpegtsDescriptor *
1063 gst_mpegts_descriptor_from_dvb_subtitling (const gchar * lang,
1064 guint8 type, guint16 composition, guint16 ancillary)
1066 GstMpegtsDescriptor *descriptor;
1069 g_return_val_if_fail (lang != NULL, NULL);
1071 descriptor = _new_descriptor (GST_MTS_DESC_DVB_SUBTITLING, 8);
1073 data = descriptor->data + 2;
1075 memcpy (data, lang, 3);
1080 GST_WRITE_UINT16_BE (data, composition);
1083 GST_WRITE_UINT16_BE (data, ancillary);
1088 /* GST_MTS_DESC_DVB_EXTENDED_EVENT (0x4E) */
1089 static GstMpegtsExtendedEventDescriptor *
1090 _gst_mpegts_extended_event_descriptor_copy (GstMpegtsExtendedEventDescriptor *
1093 GstMpegtsExtendedEventDescriptor *copy;
1095 copy = g_slice_dup (GstMpegtsExtendedEventDescriptor, source);
1096 copy->items = g_ptr_array_ref (source->items);
1097 copy->text = g_strdup (source->text);
1103 gst_mpegts_extended_event_descriptor_free (GstMpegtsExtendedEventDescriptor *
1106 g_free (source->text);
1107 g_free (source->language_code);
1108 g_ptr_array_unref (source->items);
1109 g_slice_free (GstMpegtsExtendedEventDescriptor, source);
1112 G_DEFINE_BOXED_TYPE (GstMpegtsExtendedEventDescriptor,
1113 gst_mpegts_extended_event_descriptor,
1114 (GBoxedCopyFunc) _gst_mpegts_extended_event_descriptor_copy,
1115 (GFreeFunc) gst_mpegts_extended_event_descriptor_free);
1117 static GstMpegtsExtendedEventItem *
1118 _gst_mpegts_extended_event_item_copy (GstMpegtsExtendedEventItem * source)
1120 GstMpegtsExtendedEventItem *copy =
1121 g_slice_dup (GstMpegtsExtendedEventItem, source);
1122 copy->item_description = g_strdup (source->item_description);
1123 copy->item = g_strdup (source->item);
1128 _gst_mpegts_extended_event_item_free (GstMpegtsExtendedEventItem * item)
1130 g_free (item->item);
1131 g_free (item->item_description);
1132 g_slice_free (GstMpegtsExtendedEventItem, item);
1135 G_DEFINE_BOXED_TYPE (GstMpegtsExtendedEventItem,
1136 gst_mpegts_extended_event_item,
1137 (GBoxedCopyFunc) _gst_mpegts_extended_event_item_copy,
1138 (GFreeFunc) _gst_mpegts_extended_event_item_free);
1141 * gst_mpegts_descriptor_parse_dvb_extended_event:
1142 * @descriptor: a %GST_MTS_DESC_DVB_EXTENDED_EVENT #GstMpegtsDescriptor
1143 * @res: (out) (transfer full): the #GstMpegtsExtendedEventDescriptor to fill
1145 * Extracts the DVB extended event information from @descriptor.
1147 * Returns: %TRUE if parsing succeeded, else %FALSE.
1150 gst_mpegts_descriptor_parse_dvb_extended_event (const GstMpegtsDescriptor
1151 * descriptor, GstMpegtsExtendedEventDescriptor ** desc)
1153 guint8 *data, *pdata;
1154 guint8 tmp, len_item;
1155 GstMpegtsExtendedEventItem *item;
1156 GstMpegtsExtendedEventDescriptor *res;
1158 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
1159 /* Need at least 6 bytes (1 for desc number, 3 for language code, 2 for the loop length) */
1160 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_EXTENDED_EVENT, 6, FALSE);
1162 res = g_slice_new0 (GstMpegtsExtendedEventDescriptor);
1164 data = (guint8 *) descriptor->data + 2;
1167 res->descriptor_number = tmp >> 4;
1168 res->last_descriptor_number = tmp & 0x0f;
1172 res->language_code = convert_lang_code (data);
1176 if (len_item > descriptor->length - 5) {
1177 gst_mpegts_extended_event_descriptor_free (res);
1183 res->items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1184 _gst_mpegts_extended_event_item_free);
1186 pdata = data + len_item;
1187 while (data < pdata) {
1188 item = g_slice_new0 (GstMpegtsExtendedEventItem);
1189 item->item_description =
1190 get_encoding_and_convert ((const gchar *) data + 1, *data);
1194 item->item = get_encoding_and_convert ((const gchar *) data + 1, *data);
1198 g_ptr_array_add (res->items, item);
1200 if (pdata != data) {
1201 gst_mpegts_extended_event_descriptor_free (res);
1204 res->text = get_encoding_and_convert ((const gchar *) data + 1, *data);
1211 /* GST_MTS_DESC_DVB_COMPONENT (0x50) */
1212 static GstMpegtsComponentDescriptor *
1213 _gst_mpegts_dvb_component_descriptor_copy (GstMpegtsComponentDescriptor *
1216 GstMpegtsComponentDescriptor *copy;
1218 copy = g_slice_dup (GstMpegtsComponentDescriptor, source);
1219 copy->language_code = g_strdup (source->language_code);
1220 copy->text = g_strdup (source->text);
1226 gst_mpegts_dvb_component_descriptor_free (GstMpegtsComponentDescriptor * source)
1228 g_free (source->language_code);
1229 g_free (source->text);
1230 g_slice_free (GstMpegtsComponentDescriptor, source);
1233 G_DEFINE_BOXED_TYPE (GstMpegtsComponentDescriptor,
1234 gst_mpegts_component_descriptor,
1235 (GBoxedCopyFunc) _gst_mpegts_dvb_component_descriptor_copy,
1236 (GFreeFunc) gst_mpegts_dvb_component_descriptor_free);
1239 * gst_mpegts_descriptor_parse_dvb_component:
1240 * @descriptor: a %GST_MTS_DESC_DVB_COMPONENT #GstMpegtsDescriptor
1241 * @res: (out) (transfer full): the #GstMpegtsComponentDescriptor to fill
1243 * Extracts the DVB component information from @descriptor.
1245 * Returns: %TRUE if parsing succeeded, else %FALSE.
1248 gst_mpegts_descriptor_parse_dvb_component (const GstMpegtsDescriptor
1249 * descriptor, GstMpegtsComponentDescriptor ** res)
1253 GstMpegtsComponentDescriptor *desc;
1255 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
1256 /* Need 6 bytes at least (1 for content, 1 for type, 1 for tag, 3 for language code) */
1257 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_COMPONENT, 6, FALSE);
1259 data = (guint8 *) descriptor->data + 2;
1261 desc = g_slice_new0 (GstMpegtsComponentDescriptor);
1263 desc->stream_content = *data & 0x0f;
1266 desc->component_type = *data;
1269 desc->component_tag = *data;
1272 desc->language_code = convert_lang_code (data);
1275 len = descriptor->length - 6;
1277 desc->text = get_encoding_and_convert ((const gchar *) data, len);
1284 /* GST_MTS_DESC_DVB_STREAM_IDENTIFIER (0x52) */
1286 * gst_mpegts_descriptor_parse_dvb_stream_identifier:
1287 * @descriptor: a %GST_MTS_DESC_DVB_CONTENT #GstMpegtsDescriptor
1288 * @component_tag: (out) (transfer none): the component tag
1290 * Extracts the component tag from @descriptor.
1292 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1295 gst_mpegts_descriptor_parse_dvb_stream_identifier (const GstMpegtsDescriptor
1296 * descriptor, guint8 * component_tag)
1300 g_return_val_if_fail (descriptor != NULL && component_tag != NULL, FALSE);
1301 __common_desc_checks_exact (descriptor, GST_MTS_DESC_DVB_STREAM_IDENTIFIER,
1304 data = (guint8 *) descriptor->data + 2;
1306 *component_tag = *data;
1311 /* GST_MTS_DESC_DVB_CA_IDENTIFIER (0x53) */
1313 * gst_mpegts_descriptor_parse_dvb_ca_identifier:
1314 * @descriptor: a %GST_MTS_DESC_DVB_CA_IDENTIFIER #GstMpegtsDescriptor
1315 * @list: (out) (transfer full) (element-type guint16): a list of ca identifier.
1316 * Edge entry identifies the CA system. Allocations of the value of this field
1317 * are found in http://www.dvbservices.com
1319 * Extracts ca id's from @descriptor.
1321 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1324 gst_mpegts_descriptor_parse_dvb_ca_identifier (const GstMpegtsDescriptor *
1325 descriptor, GArray ** list)
1331 g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE);
1332 /* 2 bytes = one entry */
1333 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_CA_IDENTIFIER, 2, FALSE);
1335 data = (guint8 *) descriptor->data + 2;
1337 *list = g_array_new (FALSE, FALSE, sizeof (guint16));
1339 for (i = 0; i < descriptor->length - 1; i += 2) {
1340 tmp = GST_READ_UINT16_BE (data);
1341 g_array_append_val (*list, tmp);
1348 /* GST_MTS_DESC_DVB_CONTENT (0x54) */
1350 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsContent, gst_mpegts_content);
1352 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsContent, gst_mpegts_content);
1354 G_DEFINE_BOXED_TYPE (GstMpegtsContent,
1356 (GBoxedCopyFunc) _gst_mpegts_content_copy,
1357 (GFreeFunc) _gst_mpegts_content_free);
1360 * gst_mpegts_descriptor_parse_dvb_content:
1361 * @descriptor: a %GST_MTS_DESC_DVB_CONTENT #GstMpegtsDescriptor
1362 * @content: (out) (transfer full) (element-type GstMpegtsContent): #GstMpegtsContent
1364 * Extracts the DVB content information from @descriptor.
1366 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1369 gst_mpegts_descriptor_parse_dvb_content (const GstMpegtsDescriptor
1370 * descriptor, GPtrArray ** content)
1376 g_return_val_if_fail (descriptor != NULL && content != NULL, FALSE);
1377 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_CONTENT, FALSE);
1379 data = (guint8 *) descriptor->data + 2;
1380 len = descriptor->length;
1382 *content = g_ptr_array_new_with_free_func ((GDestroyNotify)
1383 _gst_mpegts_content_free);
1384 for (i = 0; i < len;) {
1385 GstMpegtsContent *cont = g_slice_new0 (GstMpegtsContent);
1387 cont->content_nibble_1 = (tmp & 0xf0) >> 4;
1388 cont->content_nibble_2 = tmp & 0x0f;
1390 cont->user_byte = *data;
1393 g_ptr_array_add (*content, cont);
1399 /* GST_MTS_DESC_DVB_PARENTAL_RATING (0x55) */
1401 static GstMpegtsDVBParentalRatingItem *
1402 _gst_mpegts_dvb_parental_rating_item_copy (GstMpegtsDVBParentalRatingItem *
1405 GstMpegtsDVBParentalRatingItem *copy =
1406 g_slice_dup (GstMpegtsDVBParentalRatingItem, source);
1407 copy->country_code = g_strdup (source->country_code);
1412 _gst_mpegts_dvb_parental_rating_item_free (GstMpegtsDVBParentalRatingItem *
1415 g_free (item->country_code);
1416 g_slice_free (GstMpegtsDVBParentalRatingItem, item);
1419 G_DEFINE_BOXED_TYPE (GstMpegtsDVBParentalRatingItem,
1420 gst_mpegts_dvb_parental_rating_item,
1421 (GBoxedCopyFunc) _gst_mpegts_dvb_parental_rating_item_copy,
1422 (GFreeFunc) _gst_mpegts_dvb_parental_rating_item_free);
1425 * gst_mpegts_descriptor_parse_dvb_parental_rating:
1426 * @descriptor: a %GST_MTS_DESC_DVB_PARENTAL_RATING #GstMpegtsDescriptor
1427 * @rating: (out) (transfer full) (element-type GstMpegtsDVBParentalRatingItem):
1428 * #GstMpegtsDVBParentalRatingItem
1430 * Extracts the DVB parental rating information from @descriptor.
1432 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1435 gst_mpegts_descriptor_parse_dvb_parental_rating (const GstMpegtsDescriptor
1436 * descriptor, GPtrArray ** rating)
1441 g_return_val_if_fail (descriptor != NULL && rating != NULL, FALSE);
1442 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_PARENTAL_RATING,
1445 data = (guint8 *) descriptor->data + 2;
1447 *rating = g_ptr_array_new_with_free_func ((GDestroyNotify)
1448 _gst_mpegts_dvb_parental_rating_item_free);
1450 for (i = 0; i < descriptor->length - 3; i += 4) {
1451 GstMpegtsDVBParentalRatingItem *item =
1452 g_slice_new0 (GstMpegtsDVBParentalRatingItem);
1453 g_ptr_array_add (*rating, item);
1455 item->country_code = convert_lang_code (data);
1458 if (g_strcmp0 (item->country_code, "BRA") == 0) {
1460 switch (*data & 0xf) {
1484 item->rating = (*data & 0xf) + 3;
1493 /* GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM (0x5A) */
1495 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsTerrestrialDeliverySystemDescriptor,
1496 gst_mpegts_terrestrial_delivery_system_descriptor);
1498 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsTerrestrialDeliverySystemDescriptor,
1499 gst_mpegts_terrestrial_delivery_system_descriptor);
1501 G_DEFINE_BOXED_TYPE (GstMpegtsTerrestrialDeliverySystemDescriptor,
1502 gst_mpegts_terrestrial_delivery_system_descriptor,
1503 (GBoxedCopyFunc) _gst_mpegts_terrestrial_delivery_system_descriptor_copy,
1504 (GFreeFunc) _gst_mpegts_terrestrial_delivery_system_descriptor_free);
1508 * gst_mpegts_descriptor_parse_terrestrial_delivery_system:
1509 * @descriptor: a %GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM #GstMpegtsDescriptor
1510 * @res: (out) (transfer none): #GstMpegtsTerrestrialDeliverySystemDescriptor
1512 * Parses out the terrestrial delivery system from the @descriptor.
1514 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1517 gst_mpegts_descriptor_parse_terrestrial_delivery_system (const
1518 GstMpegtsDescriptor * descriptor,
1519 GstMpegtsTerrestrialDeliverySystemDescriptor * res)
1524 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
1525 /* Descriptor is always 11 bytes long */
1526 __common_desc_checks_exact (descriptor,
1527 GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM, 11, FALSE);
1529 data = (guint8 *) descriptor->data + 2;
1532 res->frequency = GST_READ_UINT32_BE (data);
1533 res->frequency *= 10;
1538 switch ((tmp >> 5) & 0x07) {
1540 res->bandwidth = 8000000;
1543 res->bandwidth = 7000000;
1546 res->bandwidth = 6000000;
1549 res->bandwidth = 5000000;
1556 res->priority = (tmp >> 4) & 0x01;
1557 res->time_slicing = (tmp >> 3) & 0x01;
1558 res->mpe_fec = (tmp >> 2) & 0x01;
1562 switch ((tmp >> 6) & 0x03) {
1564 res->constellation = GST_MPEGTS_MODULATION_QPSK;
1567 res->constellation = GST_MPEGTS_MODULATION_QAM_16;
1570 res->constellation = GST_MPEGTS_MODULATION_QAM_64;
1576 switch ((tmp >> 3) & 0x07) {
1578 res->hierarchy = GST_MPEGTS_HIERARCHY_NONE;
1581 res->hierarchy = GST_MPEGTS_HIERARCHY_1;
1584 res->hierarchy = GST_MPEGTS_HIERARCHY_2;
1587 res->hierarchy = GST_MPEGTS_HIERARCHY_4;
1590 res->hierarchy = GST_MPEGTS_HIERARCHY_NONE;
1593 res->hierarchy = GST_MPEGTS_HIERARCHY_1;
1596 res->hierarchy = GST_MPEGTS_HIERARCHY_2;
1599 res->hierarchy = GST_MPEGTS_HIERARCHY_4;
1605 switch (tmp & 0x07) {
1607 res->code_rate_hp = GST_MPEGTS_FEC_1_2;
1610 res->code_rate_hp = GST_MPEGTS_FEC_2_3;
1613 res->code_rate_hp = GST_MPEGTS_FEC_3_4;
1616 res->code_rate_hp = GST_MPEGTS_FEC_5_6;
1619 res->code_rate_hp = GST_MPEGTS_FEC_7_8;
1627 switch ((tmp >> 5) & 0x07) {
1629 res->code_rate_lp = GST_MPEGTS_FEC_1_2;
1632 res->code_rate_lp = GST_MPEGTS_FEC_2_3;
1635 res->code_rate_lp = GST_MPEGTS_FEC_3_4;
1638 res->code_rate_lp = GST_MPEGTS_FEC_5_6;
1641 res->code_rate_lp = GST_MPEGTS_FEC_7_8;
1647 switch ((tmp >> 3) & 0x03) {
1649 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_32;
1652 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_16;
1655 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_8;
1658 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_4;
1664 switch ((tmp >> 1) & 0x03) {
1666 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_2K;
1669 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_8K;
1672 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_4K;
1677 res->other_frequency = tmp & 0x01;
1682 /* GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME (0x5B) */
1684 static GstMpegtsDvbMultilingualNetworkNameItem
1685 * _gst_mpegts_dvb_multilingual_network_name_item_copy
1686 (GstMpegtsDvbMultilingualNetworkNameItem * source)
1688 GstMpegtsDvbMultilingualNetworkNameItem *copy =
1689 g_slice_dup (GstMpegtsDvbMultilingualNetworkNameItem, source);
1690 copy->language_code = g_strdup (source->language_code);
1691 copy->network_name = g_strdup (source->network_name);
1696 _gst_mpegts_dvb_multilingual_network_name_item_free
1697 (GstMpegtsDvbMultilingualNetworkNameItem * item)
1699 g_free (item->network_name);
1700 g_free (item->language_code);
1701 g_slice_free (GstMpegtsDvbMultilingualNetworkNameItem, item);
1704 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualNetworkNameItem,
1705 gst_mpegts_dvb_multilingual_network_name_item,
1706 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_network_name_item_copy,
1707 (GFreeFunc) _gst_mpegts_dvb_multilingual_network_name_item_free);
1710 * gst_mpegts_descriptor_parse_dvb_multilingual_network_name:
1711 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME
1712 * #GstMpegtsDescriptor
1713 * @network_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualNetworkNameItem):
1714 * a #GstMpegtsDvbMultilingualNetworkNameItem
1716 * Parses out the multilingual network name from the @descriptor.
1718 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1721 gst_mpegts_descriptor_parse_dvb_multilingual_network_name (const
1722 GstMpegtsDescriptor * descriptor, GPtrArray ** network_name_items)
1724 guint8 *data, i, len;
1725 GstMpegtsDvbMultilingualNetworkNameItem *item;
1727 g_return_val_if_fail (descriptor != NULL && network_name_items != NULL,
1729 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME,
1732 data = (guint8 *) descriptor->data + 2;
1734 *network_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1735 _gst_mpegts_dvb_multilingual_network_name_item_free);
1737 for (i = 0; i < descriptor->length - 3;) {
1738 item = g_slice_new0 (GstMpegtsDvbMultilingualNetworkNameItem);
1739 g_ptr_array_add (*network_name_items, item);
1740 item->language_code = convert_lang_code (data);
1745 item->network_name =
1746 get_encoding_and_convert ((const gchar *) data + 1, len);
1754 /* GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME (0x5C) */
1756 static GstMpegtsDvbMultilingualBouquetNameItem
1757 * _gst_mpegts_dvb_multilingual_bouquet_name_item_copy
1758 (GstMpegtsDvbMultilingualBouquetNameItem * source)
1760 GstMpegtsDvbMultilingualBouquetNameItem *copy =
1761 g_slice_dup (GstMpegtsDvbMultilingualBouquetNameItem, source);
1762 copy->bouquet_name = g_strdup (source->bouquet_name);
1763 copy->language_code = g_strdup (source->language_code);
1768 _gst_mpegts_dvb_multilingual_bouquet_name_item_free
1769 (GstMpegtsDvbMultilingualBouquetNameItem * item)
1771 g_free (item->language_code);
1772 g_free (item->bouquet_name);
1773 g_slice_free (GstMpegtsDvbMultilingualBouquetNameItem, item);
1776 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualBouquetNameItem,
1777 gst_mpegts_dvb_multilingual_bouquet_name_item,
1778 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_bouquet_name_item_copy,
1779 (GFreeFunc) _gst_mpegts_dvb_multilingual_bouquet_name_item_free);
1782 * gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name:
1783 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME
1784 * #GstMpegtsDescriptor
1785 * @bouquet_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualBouquetNameItem):
1786 * a #GstMpegtsDvbMultilingualBouquetNameItem
1788 * Parses out the multilingual bouquet name from the @descriptor.
1790 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1793 gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name (const
1794 GstMpegtsDescriptor * descriptor, GPtrArray ** bouquet_name_items)
1796 guint8 *data, i, len;
1797 GstMpegtsDvbMultilingualBouquetNameItem *item;
1799 g_return_val_if_fail (descriptor != NULL && bouquet_name_items != NULL,
1801 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME,
1804 data = (guint8 *) descriptor->data + 2;
1806 *bouquet_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1807 _gst_mpegts_dvb_multilingual_bouquet_name_item_free);
1809 for (i = 0; i < descriptor->length - 3;) {
1810 item = g_slice_new0 (GstMpegtsDvbMultilingualBouquetNameItem);
1811 g_ptr_array_add (*bouquet_name_items, item);
1812 item->language_code = convert_lang_code (data);
1817 item->bouquet_name =
1818 get_encoding_and_convert ((const gchar *) data + 1, len);
1826 /* GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME (0x5D) */
1828 static GstMpegtsDvbMultilingualServiceNameItem
1829 * _gst_mpegts_dvb_multilingual_service_name_item_copy
1830 (GstMpegtsDvbMultilingualServiceNameItem * source)
1832 GstMpegtsDvbMultilingualServiceNameItem *copy =
1833 g_slice_dup (GstMpegtsDvbMultilingualServiceNameItem, source);
1834 copy->language_code = g_strdup (source->language_code);
1835 copy->service_name = g_strdup (source->service_name);
1836 copy->provider_name = g_strdup (source->provider_name);
1841 _gst_mpegts_dvb_multilingual_service_name_item_free
1842 (GstMpegtsDvbMultilingualServiceNameItem * item)
1844 g_free (item->provider_name);
1845 g_free (item->service_name);
1846 g_free (item->language_code);
1847 g_slice_free (GstMpegtsDvbMultilingualServiceNameItem, item);
1850 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualServiceNameItem,
1851 gst_mpegts_dvb_multilingual_service_name_item,
1852 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_service_name_item_copy,
1853 (GFreeFunc) _gst_mpegts_dvb_multilingual_service_name_item_free);
1856 * gst_mpegts_descriptor_parse_dvb_multilingual_service_name:
1857 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME
1858 * #GstMpegtsDescriptor
1859 * @service_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualServiceNameItem):
1860 * a #GstMpegtsDvbMultilingualServiceNameItem
1862 * Parses out the multilingual service name from the @descriptor.
1864 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1867 gst_mpegts_descriptor_parse_dvb_multilingual_service_name (const
1868 GstMpegtsDescriptor * descriptor, GPtrArray ** service_name_items)
1870 guint8 *data, i, len;
1871 GstMpegtsDvbMultilingualServiceNameItem *item;
1873 g_return_val_if_fail (descriptor != NULL && service_name_items != NULL,
1875 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME,
1878 data = (guint8 *) descriptor->data + 2;
1880 *service_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1881 _gst_mpegts_dvb_multilingual_service_name_item_free);
1883 for (i = 0; i < descriptor->length - 3;) {
1884 item = g_slice_new0 (GstMpegtsDvbMultilingualServiceNameItem);
1885 g_ptr_array_add (*service_name_items, item);
1886 item->language_code = convert_lang_code (data);
1891 item->provider_name =
1892 get_encoding_and_convert ((const gchar *) data + 1, len);
1897 item->service_name =
1898 get_encoding_and_convert ((const gchar *) data + 1, len);
1906 /* GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT (0x5E) */
1908 static GstMpegtsDvbMultilingualComponentItem
1909 * _gst_mpegts_dvb_multilingual_component_item_copy
1910 (GstMpegtsDvbMultilingualComponentItem * source)
1912 GstMpegtsDvbMultilingualComponentItem *copy =
1913 g_slice_dup (GstMpegtsDvbMultilingualComponentItem, source);
1914 copy->description = g_strdup (source->description);
1915 copy->language_code = g_strdup (source->language_code);
1920 _gst_mpegts_dvb_multilingual_component_item_free
1921 (GstMpegtsDvbMultilingualComponentItem * item)
1923 g_free (item->language_code);
1924 g_free (item->description);
1925 g_slice_free (GstMpegtsDvbMultilingualComponentItem, item);
1928 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualComponentItem,
1929 gst_mpegts_dvb_multilingual_component_item,
1930 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_component_item_copy,
1931 (GFreeFunc) _gst_mpegts_dvb_multilingual_component_item_free);
1934 * gst_mpegts_descriptor_parse_dvb_multilingual_component:
1935 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT
1936 * #GstMpegtsDescriptor
1937 * @component_tag: (out): the component tag
1938 * @component_description_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualComponentItem):
1939 * a #GstMpegtsDvbMultilingualComponentItem
1941 * Parses out the multilingual component from the @descriptor.
1943 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1946 gst_mpegts_descriptor_parse_dvb_multilingual_component (const
1947 GstMpegtsDescriptor * descriptor, guint8 * component_tag,
1948 GPtrArray ** component_description_items)
1950 guint8 *data, i, len;
1951 GstMpegtsDvbMultilingualComponentItem *item;
1953 g_return_val_if_fail (descriptor != NULL
1954 && component_description_items != NULL && component_tag != NULL, FALSE);
1955 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT, 6,
1958 data = (guint8 *) descriptor->data + 2;
1960 *component_tag = *data;
1963 *component_description_items =
1964 g_ptr_array_new_with_free_func ((GDestroyNotify)
1965 _gst_mpegts_dvb_multilingual_component_item_free);
1967 for (i = 0; i < descriptor->length - 3;) {
1968 item = g_slice_new0 (GstMpegtsDvbMultilingualComponentItem);
1969 g_ptr_array_add (*component_description_items, item);
1970 item->language_code = convert_lang_code (data);
1976 get_encoding_and_convert ((const gchar *) data + 1, len);
1984 /* GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER (0x5F) */
1986 * gst_mpegts_descriptor_parse_dvb_private_data_specifier:
1987 * @descriptor: a %GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER #GstMpegtsDescriptor
1988 * @private_data_specifier: (out): the private data specifier id
1989 * registered by http://www.dvbservices.com/
1990 * @private_data: (out) (transfer full) (allow-none) (array length=length): additional data or NULL
1991 * @length: (out) (allow-none): length of @private_data
1993 * Parses out the private data specifier from the @descriptor.
1995 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1998 gst_mpegts_descriptor_parse_dvb_private_data_specifier (const
1999 GstMpegtsDescriptor * descriptor, guint32 * private_data_specifier,
2000 guint8 ** private_data, guint8 * length)
2004 g_return_val_if_fail (descriptor != NULL
2005 && private_data_specifier != NULL, FALSE);
2006 __common_desc_checks (descriptor,
2007 GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER, 4, FALSE);
2009 data = (guint8 *) descriptor->data + 2;
2011 *private_data_specifier = GST_READ_UINT32_BE (data);
2013 if (length && private_data) {
2014 *length = descriptor->length - 4;
2016 *private_data = g_memdup (data + 4, *length);
2021 /* GST_MTS_DESC_DVB_FREQUENCY_LIST (0x62) */
2023 * gst_mpegts_descriptor_parse_dvb_frequency_list:
2024 * @descriptor: a %GST_MTS_DESC_DVB_FREQUENCY_LIST #GstMpegtsDescriptor
2025 * @offset: (out): %FALSE in Hz, %TRUE in kHz
2026 * @list: (out) (transfer full) (element-type guint32): a list of all frequencies in Hz/kHz
2027 * depending on @offset
2029 * Parses out a list of frequencies from the @descriptor.
2031 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2034 gst_mpegts_descriptor_parse_dvb_frequency_list (const GstMpegtsDescriptor
2035 * descriptor, gboolean * offset, GArray ** list)
2037 guint8 *data, type, len;
2041 g_return_val_if_fail (descriptor != NULL && offset != NULL &&
2042 list != NULL, FALSE);
2043 /* 1 byte coding system, 4 bytes each frequency entry */
2044 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_FREQUENCY_LIST, 5, FALSE);
2046 data = (guint8 *) descriptor->data + 2;
2048 type = *data & 0x03;
2055 /* cable, terrestrial */
2059 *list = g_array_new (FALSE, FALSE, sizeof (guint32));
2061 len = descriptor->length - 1;
2063 for (i = 0; i < len - 3; i += 4) {
2066 freq = BCD_32 (data) * 10;
2069 freq = BCD_32 (data) * 100;
2072 freq = GST_READ_UINT32_BE (data) * 10;
2078 g_array_append_val (*list, freq);
2085 /* GST_MTS_DESC_DVB_DATA_BROADCAST (0x64) */
2086 static GstMpegtsDataBroadcastDescriptor *
2087 _gst_mpegts_dvb_data_broadcast_descriptor_copy (GstMpegtsDataBroadcastDescriptor
2090 GstMpegtsDataBroadcastDescriptor *copy;
2092 copy = g_slice_dup (GstMpegtsDataBroadcastDescriptor, source);
2094 copy->selector_bytes = g_memdup (source->selector_bytes, source->length);
2095 copy->language_code = g_strdup (source->language_code);
2096 copy->text = g_strdup (source->text);
2102 gst_mpegts_dvb_data_broadcast_descriptor_free (GstMpegtsDataBroadcastDescriptor
2105 g_free (source->selector_bytes);
2106 g_free (source->language_code);
2107 g_free (source->text);
2108 g_slice_free (GstMpegtsDataBroadcastDescriptor, source);
2111 G_DEFINE_BOXED_TYPE (GstMpegtsDataBroadcastDescriptor,
2112 gst_mpegts_dvb_data_broadcast_descriptor,
2113 (GBoxedCopyFunc) _gst_mpegts_dvb_data_broadcast_descriptor_copy,
2114 (GFreeFunc) gst_mpegts_dvb_data_broadcast_descriptor_free);
2117 * gst_mpegts_descriptor_parse_dvb_data_broadcast:
2118 * @descriptor: a %GST_MTS_DESC_DVB_DATA_BROADCAST #GstMpegtsDescriptor
2119 * @res: (out) (transfer full): #GstMpegtsDataBroadcastDescriptor
2121 * Parses out the data broadcast from the @descriptor.
2123 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2126 gst_mpegts_descriptor_parse_dvb_data_broadcast (const GstMpegtsDescriptor
2127 * descriptor, GstMpegtsDataBroadcastDescriptor ** desc)
2130 GstMpegtsDataBroadcastDescriptor *res;
2132 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
2133 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_DATA_BROADCAST, 8, FALSE);
2135 data = (guint8 *) descriptor->data + 2;
2137 res = g_slice_new0 (GstMpegtsDataBroadcastDescriptor);
2139 res->data_broadcast_id = GST_READ_UINT16_BE (data);
2142 res->component_tag = *data;
2145 res->length = *data;
2148 res->selector_bytes = g_memdup (data, res->length);
2149 data += res->length;
2151 res->language_code = convert_lang_code (data);
2154 res->text = get_encoding_and_convert ((const gchar *) data + 1, *data);
2161 /* GST_MTS_DESC_DVB_SCRAMBLING (0x65) */
2163 * gst_mpegts_descriptor_parse_dvb_scrambling:
2164 * @descriptor: a %GST_MTS_DESC_DVB_SCRAMBLING #GstMpegtsDescriptor
2165 * @scrambling_mode: (out): This 8-bit field identifies the selected
2166 * mode of the scrambling algorithm (#GstMpegtsDVBScramblingModeType).
2167 * The technical details of the scrambling algorithm are available only
2168 * to bona-fide users upon signature of a Non Disclosure Agreement (NDA)
2169 * administered by the DVB Common Scrambling Algorithm Custodian.
2171 * Parses out the scrambling mode from the @descriptor.
2173 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2176 gst_mpegts_descriptor_parse_dvb_scrambling (const GstMpegtsDescriptor *
2177 descriptor, GstMpegtsDVBScramblingModeType * scrambling_mode)
2181 g_return_val_if_fail (descriptor != NULL && scrambling_mode != NULL, FALSE);
2182 __common_desc_checks_exact (descriptor, GST_MTS_DESC_DVB_SCRAMBLING, 1,
2185 data = (guint8 *) descriptor->data + 2;
2187 *scrambling_mode = *data;
2192 /* GST_MTS_DESC_DVB_DATA_BROADCAST_ID (0x66) */
2194 * gst_mpegts_descriptor_parse_dvb_data_broadcast_id:
2195 * @descriptor: a %GST_MTS_DESC_DVB_DATA_BROADCAST_ID #GstMpegtsDescriptor
2196 * @data_broadcast_id: (out): the data broadcast id
2197 * @id_selector_bytes: (out) (transfer full) (array length=len): the selector bytes, if present
2198 * @len: (out): the length of @id_selector_bytes
2200 * Parses out the data broadcast id from the @descriptor.
2202 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2205 gst_mpegts_descriptor_parse_dvb_data_broadcast_id (const GstMpegtsDescriptor
2206 * descriptor, guint16 * data_broadcast_id, guint8 ** id_selector_bytes,
2211 g_return_val_if_fail (descriptor != NULL && data_broadcast_id != NULL &&
2212 id_selector_bytes != NULL, FALSE);
2213 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_DATA_BROADCAST_ID, 2,
2216 data = (guint8 *) descriptor->data + 2;
2218 *data_broadcast_id = GST_READ_UINT16_BE (data);
2221 *len = descriptor->length - 2;
2223 *id_selector_bytes = g_memdup (data, *len);
2228 /* GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM (0x7F && 0x04) */
2229 static GstMpegtsT2DeliverySystemDescriptor
2230 * _gst_mpegts_t2_delivery_system_descriptor_copy
2231 (GstMpegtsT2DeliverySystemDescriptor * source)
2233 GstMpegtsT2DeliverySystemDescriptor *copy;
2235 copy = g_slice_dup (GstMpegtsT2DeliverySystemDescriptor, source);
2236 copy->cells = g_ptr_array_ref (source->cells);
2241 void gst_mpegts_t2_delivery_system_descriptor_free
2242 (GstMpegtsT2DeliverySystemDescriptor * source)
2244 g_ptr_array_unref (source->cells);
2245 g_slice_free (GstMpegtsT2DeliverySystemDescriptor, source);
2248 G_DEFINE_BOXED_TYPE (GstMpegtsT2DeliverySystemDescriptor,
2249 gst_mpegts_t2_delivery_system_descriptor,
2250 (GBoxedCopyFunc) _gst_mpegts_t2_delivery_system_descriptor_copy,
2251 (GFreeFunc) gst_mpegts_t2_delivery_system_descriptor_free);
2253 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsT2DeliverySystemCellExtension,
2254 gst_mpegts_t2_delivery_system_cell_extension);
2256 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsT2DeliverySystemCellExtension,
2257 gst_mpegts_t2_delivery_system_cell_extension);
2259 G_DEFINE_BOXED_TYPE (GstMpegtsT2DeliverySystemCellExtension,
2260 gst_mpegts_t2_delivery_system_cell_extension,
2261 (GBoxedCopyFunc) _gst_mpegts_t2_delivery_system_cell_extension_copy,
2262 (GFreeFunc) _gst_mpegts_t2_delivery_system_cell_extension_free);
2264 static GstMpegtsT2DeliverySystemCell *
2265 _gst_mpegts_t2_delivery_system_cell_copy (GstMpegtsT2DeliverySystemCell
2268 GstMpegtsT2DeliverySystemCell *copy =
2269 g_slice_dup (GstMpegtsT2DeliverySystemCell, source);
2270 copy->centre_frequencies = g_array_ref (source->centre_frequencies);
2271 copy->sub_cells = g_ptr_array_ref (source->sub_cells);
2276 _gst_mpegts_t2_delivery_system_cell_free (GstMpegtsT2DeliverySystemCell * cell)
2278 g_ptr_array_unref (cell->sub_cells);
2279 g_array_unref (cell->centre_frequencies);
2280 g_slice_free (GstMpegtsT2DeliverySystemCell, cell);
2283 G_DEFINE_BOXED_TYPE (GstMpegtsT2DeliverySystemCell,
2284 gst_mpegts_t2_delivery_system_cell,
2285 (GBoxedCopyFunc) _gst_mpegts_t2_delivery_system_cell_copy,
2286 (GFreeFunc) _gst_mpegts_t2_delivery_system_cell_free);
2289 * gst_mpegts_descriptor_parse_dvb_t2_delivery_system:
2290 * @descriptor: a %GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM #GstMpegtsDescriptor
2291 * @res: (out) (transfer full): #GstMpegtsT2DeliverySystemDescriptor
2293 * Parses out the DVB-T2 delivery system from the @descriptor.
2295 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2298 gst_mpegts_descriptor_parse_dvb_t2_delivery_system (const GstMpegtsDescriptor
2299 * descriptor, GstMpegtsT2DeliverySystemDescriptor ** desc)
2302 guint8 len, freq_len, sub_cell_len;
2305 GstMpegtsT2DeliverySystemDescriptor *res;
2307 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
2308 __common_desc_ext_checks (descriptor, GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM,
2311 data = (guint8 *) descriptor->data + 3;
2313 res = g_slice_new0 (GstMpegtsT2DeliverySystemDescriptor);
2315 res->plp_id = *data;
2318 res->t2_system_id = GST_READ_UINT16_BE (data);
2321 if (descriptor->length > 4) {
2322 // FIXME: siso / miso
2323 res->siso_miso = (*data >> 6) & 0x03;
2324 switch ((*data >> 2) & 0x0f) {
2326 res->bandwidth = 8000000;
2329 res->bandwidth = 7000000;
2332 res->bandwidth = 6000000;
2335 res->bandwidth = 5000000;
2338 res->bandwidth = 10000000;
2341 res->bandwidth = 1712000;
2349 switch ((*data >> 5) & 0x07) {
2351 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_32;
2354 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_16;
2357 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_8;
2360 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_4;
2363 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_128;
2366 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_128;
2369 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_256;
2375 switch ((*data >> 2) & 0x07) {
2377 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_2K;
2380 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_8K;
2383 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_4K;
2386 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_1K;
2389 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_16K;
2392 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_32K;
2397 res->other_frequency = (*data >> 1) & 0x01;
2398 res->tfs = (*data) & 0x01;
2401 len = descriptor->length - 6;
2403 res->cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
2404 _gst_mpegts_t2_delivery_system_cell_free);
2406 for (i = 0; i < len;) {
2407 GstMpegtsT2DeliverySystemCell *cell;
2410 cell = g_slice_new0 (GstMpegtsT2DeliverySystemCell);
2411 g_ptr_array_add (res->cells, cell);
2413 cell->cell_id = GST_READ_UINT16_BE (data);
2417 cell->centre_frequencies = g_array_new (FALSE, FALSE, sizeof (guint32));
2419 if (res->tfs == TRUE) {
2424 for (j = 0; j < freq_len;) {
2425 tmp_freq = GST_READ_UINT32_BE (data) * 10;
2426 g_array_append_val (cell->centre_frequencies, tmp_freq);
2432 tmp_freq = GST_READ_UINT32_BE (data) * 10;
2433 g_array_append_val (cell->centre_frequencies, tmp_freq);
2437 sub_cell_len = (*data);
2441 cell->sub_cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
2442 _gst_mpegts_t2_delivery_system_cell_extension_free);
2444 for (k = 0; k < sub_cell_len;) {
2445 GstMpegtsT2DeliverySystemCellExtension *cell_ext;
2446 cell_ext = g_slice_new0 (GstMpegtsT2DeliverySystemCellExtension);
2448 g_ptr_array_add (cell->sub_cells, cell_ext);
2449 cell_ext->cell_id_extension = *data;
2452 cell_ext->transposer_frequency = GST_READ_UINT32_BE (data) * 10;