3 * Copyright (C) 2007, 2008 Alessandro Decina, Zaheer Merali
6 * Zaheer Merali <zaheerabbas at merali dot org>
7 * Alessandro Decina <alessandro@nnva.org>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
27 #include "mpegtspacketizer.h"
28 #include "gstmpegdesc.h"
30 GST_DEBUG_CATEGORY_STATIC (mpegts_packetizer_debug);
31 #define GST_CAT_DEFAULT mpegts_packetizer_debug
33 static GQuark QUARK_PAT;
34 static GQuark QUARK_TRANSPORT_STREAM_ID;
35 static GQuark QUARK_PROGRAM_NUMBER;
36 static GQuark QUARK_PID;
37 static GQuark QUARK_PROGRAMS;
39 static GQuark QUARK_PMT;
40 static GQuark QUARK_PCR_PID;
41 static GQuark QUARK_VERSION_NUMBER;
42 static GQuark QUARK_DESCRIPTORS;
43 static GQuark QUARK_STREAM_TYPE;
44 static GQuark QUARK_STREAMS;
46 static GQuark QUARK_NIT;
47 static GQuark QUARK_NETWORK_ID;
48 static GQuark QUARK_CURRENT_NEXT_INDICATOR;
49 static GQuark QUARK_ACTUAL_NETWORK;
50 static GQuark QUARK_NETWORK_NAME;
51 static GQuark QUARK_ORIGINAL_NETWORK_ID;
52 static GQuark QUARK_TRANSPORTS;
54 static GQuark QUARK_SDT;
55 static GQuark QUARK_ACTUAL_TRANSPORT_STREAM;
56 static GQuark QUARK_SERVICES;
58 static GQuark QUARK_EIT;
59 static GQuark QUARK_SERVICE_ID;
60 static GQuark QUARK_PRESENT_FOLLOWING;
61 static GQuark QUARK_SEGMENT_LAST_SECTION_NUMBER;
62 static GQuark QUARK_LAST_TABLE_ID;
63 static GQuark QUARK_EVENTS;
65 static void _init_local (void);
66 G_DEFINE_TYPE_EXTENDED (MpegTSPacketizer, mpegts_packetizer, G_TYPE_OBJECT, 0,
69 static void mpegts_packetizer_dispose (GObject * object);
70 static void mpegts_packetizer_finalize (GObject * object);
71 static gchar *convert_to_utf8 (const gchar * text, gint length, guint start,
72 const gchar * encoding, gboolean is_multibyte, GError ** error);
73 static gchar *get_encoding (const gchar * text, guint * start_text,
74 gboolean * is_multibyte);
75 static gchar *get_encoding_and_convert (const gchar * text, guint length);
77 #define CONTINUITY_UNSET 255
78 #define MAX_CONTINUITY 15
79 #define VERSION_NUMBER_UNSET 255
80 #define TABLE_ID_UNSET 0xFF
83 mpegts_packetizer_stream_subtable_compare (gconstpointer a, gconstpointer b)
85 MpegTSPacketizerStreamSubtable *asub, *bsub;
87 asub = (MpegTSPacketizerStreamSubtable *) a;
88 bsub = (MpegTSPacketizerStreamSubtable *) b;
90 if (asub->table_id == bsub->table_id &&
91 asub->subtable_extension == bsub->subtable_extension)
96 static MpegTSPacketizerStreamSubtable *
97 mpegts_packetizer_stream_subtable_new (guint8 table_id,
98 guint16 subtable_extension)
100 MpegTSPacketizerStreamSubtable *subtable;
102 subtable = g_new0 (MpegTSPacketizerStreamSubtable, 1);
103 subtable->version_number = VERSION_NUMBER_UNSET;
104 subtable->table_id = table_id;
105 subtable->subtable_extension = subtable_extension;
110 static MpegTSPacketizerStream *
111 mpegts_packetizer_stream_new (void)
113 MpegTSPacketizerStream *stream;
115 stream = (MpegTSPacketizerStream *) g_new0 (MpegTSPacketizerStream, 1);
116 stream->section_adapter = gst_adapter_new ();
117 stream->continuity_counter = CONTINUITY_UNSET;
118 stream->subtables = NULL;
119 stream->section_table_id = TABLE_ID_UNSET;
124 mpegts_packetizer_stream_free (MpegTSPacketizerStream * stream)
126 gst_adapter_clear (stream->section_adapter);
127 g_object_unref (stream->section_adapter);
128 g_slist_foreach (stream->subtables, (GFunc) g_free, NULL);
129 g_slist_free (stream->subtables);
134 mpegts_packetizer_clear_section (MpegTSPacketizer * packetizer,
135 MpegTSPacketizerStream * stream)
137 gst_adapter_clear (stream->section_adapter);
138 stream->continuity_counter = CONTINUITY_UNSET;
139 stream->section_length = 0;
140 stream->section_table_id = TABLE_ID_UNSET;
144 mpegts_packetizer_class_init (MpegTSPacketizerClass * klass)
146 GObjectClass *gobject_class;
148 gobject_class = G_OBJECT_CLASS (klass);
150 gobject_class->dispose = mpegts_packetizer_dispose;
151 gobject_class->finalize = mpegts_packetizer_finalize;
155 mpegts_packetizer_init (MpegTSPacketizer * packetizer)
157 packetizer->adapter = gst_adapter_new ();
158 packetizer->streams = g_new0 (MpegTSPacketizerStream *, 8192);
159 packetizer->know_packet_size = FALSE;
163 mpegts_packetizer_dispose (GObject * object)
165 MpegTSPacketizer *packetizer = GST_MPEGTS_PACKETIZER (object);
167 if (!packetizer->disposed) {
168 if (packetizer->know_packet_size && packetizer->caps != NULL) {
169 gst_caps_unref (packetizer->caps);
170 packetizer->caps = NULL;
171 packetizer->know_packet_size = FALSE;
173 if (packetizer->streams) {
175 for (i = 0; i < 8192; i++) {
176 if (packetizer->streams[i])
177 mpegts_packetizer_stream_free (packetizer->streams[i]);
179 g_free (packetizer->streams);
182 gst_adapter_clear (packetizer->adapter);
183 g_object_unref (packetizer->adapter);
184 packetizer->disposed = TRUE;
187 if (G_OBJECT_CLASS (mpegts_packetizer_parent_class)->dispose)
188 G_OBJECT_CLASS (mpegts_packetizer_parent_class)->dispose (object);
192 mpegts_packetizer_finalize (GObject * object)
194 if (G_OBJECT_CLASS (mpegts_packetizer_parent_class)->finalize)
195 G_OBJECT_CLASS (mpegts_packetizer_parent_class)->finalize (object);
199 mpegts_packetizer_parse_adaptation_field_control (MpegTSPacketizer * packetizer,
200 MpegTSPacketizerPacket * packet)
204 length = *packet->data;
207 if (packet->adaptation_field_control == 0x02) {
208 /* no payload, adaptation field of 183 bytes */
210 GST_DEBUG ("PID %d afc == 0x%x and length %d != 183",
211 packet->pid, packet->adaptation_field_control, length);
213 } else if (length > 182) {
214 GST_DEBUG ("PID %d afc == 0x%01x and length %d > 182",
215 packet->pid, packet->adaptation_field_control, length);
218 /* skip the adaptation field body for now */
219 if (packet->data + length > packet->data_end) {
220 GST_DEBUG ("PID %d afc length %d overflows the buffer current %d max %d",
221 packet->pid, length, (gint) (packet->data - packet->data_start),
222 (gint) (packet->data_end - packet->data_start));
226 packet->data += length;
232 mpegts_packetizer_parse_packet (MpegTSPacketizer * packetizer,
233 MpegTSPacketizerPacket * packet)
237 data = GST_BUFFER_DATA (packet->buffer);
241 packet->payload_unit_start_indicator = (*data >> 6) & 0x01;
242 packet->pid = GST_READ_UINT16_BE (data) & 0x1FFF;
245 packet->adaptation_field_control = (*data >> 4) & 0x03;
246 packet->continuity_counter = *data & 0x0F;
251 if (packet->adaptation_field_control & 0x02)
252 if (!mpegts_packetizer_parse_adaptation_field_control (packetizer, packet))
255 if (packet->adaptation_field_control & 0x01)
256 packet->payload = packet->data;
258 packet->payload = NULL;
264 mpegts_packetizer_parse_section_header (MpegTSPacketizer * packetizer,
265 MpegTSPacketizerStream * stream, MpegTSPacketizerSection * section)
268 guint8 *data, *crc_data;
269 MpegTSPacketizerStreamSubtable *subtable;
270 GSList *subtable_list = NULL;
272 section->complete = TRUE;
273 /* get the section buffer, pass the ownership to the caller */
274 section->buffer = gst_adapter_take_buffer (stream->section_adapter,
275 3 + stream->section_length);
276 data = GST_BUFFER_DATA (section->buffer);
278 section->table_id = *data++;
279 /* if table_id is 0 (pat) then ignore the subtable extension */
280 if ((data[0] & 0x80) == 0 || section->table_id == 0)
281 section->subtable_extension = 0;
283 section->subtable_extension = GST_READ_UINT16_BE (data + 2);
285 subtable = mpegts_packetizer_stream_subtable_new (section->table_id,
286 section->subtable_extension);
288 subtable_list = g_slist_find_custom (stream->subtables, subtable,
289 mpegts_packetizer_stream_subtable_compare);
292 subtable = (MpegTSPacketizerStreamSubtable *) (subtable_list->data);
294 stream->subtables = g_slist_prepend (stream->subtables, subtable);
297 section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
300 /* skip to the version byte */
304 section->version_number = (tmp >> 1) & 0x1F;
305 section->current_next_indicator = tmp & 0x01;
307 if (!section->current_next_indicator)
310 /* CRC is at the end of the section */
312 GST_BUFFER_DATA (section->buffer) + GST_BUFFER_SIZE (section->buffer) - 4;
313 section->crc = GST_READ_UINT32_BE (crc_data);
315 if (section->version_number == subtable->version_number &&
316 section->crc == subtable->crc)
319 subtable->version_number = section->version_number;
320 subtable->crc = section->crc;
321 stream->section_table_id = section->table_id;
327 ("not applicable pid %d table_id %d subtable_extension %d, current_next %d version %d, crc 0x%x",
328 section->pid, section->table_id, section->subtable_extension,
329 section->current_next_indicator, section->version_number, section->crc);
330 section->complete = FALSE;
331 gst_buffer_unref (section->buffer);
336 mpegts_packetizer_parse_descriptors (MpegTSPacketizer * packetizer,
337 guint8 ** buffer, guint8 * buffer_end, GValueArray * descriptors)
341 GValue value = { 0 };
346 while (data < buffer_end) {
347 data++; /* skip tag */
350 if (data + length > buffer_end) {
351 GST_WARNING ("invalid descriptor length %d now at %d max %d", length,
352 (gint) (data - *buffer), (gint) (buffer_end - *buffer));
357 desc = g_string_new_len ((gchar *) data - 2, length + 2);
359 /* G_TYPE_GSTRING is a GBoxed type and is used so properly marshalled from
360 * python (FIXME: should either be G_TYPE_STRING or GST_TYPE_BUFFFER) */
361 g_value_init (&value, G_TYPE_GSTRING);
362 g_value_take_boxed (&value, desc);
363 g_value_array_append (descriptors, &value);
364 g_value_unset (&value);
367 if (data != buffer_end) {
368 GST_WARNING ("descriptors size %d expected %d", (gint) (data - *buffer),
369 (gint) (buffer_end - *buffer));
381 mpegts_packetizer_parse_pat (MpegTSPacketizer * packetizer,
382 MpegTSPacketizerSection * section)
384 GstStructure *pat_info = NULL;
386 guint transport_stream_id;
388 guint program_number;
390 GValue entries = { 0 };
391 GValue value = { 0 };
392 GstStructure *entry = NULL;
395 data = GST_BUFFER_DATA (section->buffer);
397 section->table_id = *data++;
398 section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
401 transport_stream_id = GST_READ_UINT16_BE (data);
405 section->version_number = (tmp >> 1) & 0x1F;
406 section->current_next_indicator = tmp & 0x01;
408 /* skip section_number and last_section_number */
411 pat_info = gst_structure_id_new (QUARK_PAT,
412 QUARK_TRANSPORT_STREAM_ID, G_TYPE_UINT, transport_stream_id, NULL);
413 g_value_init (&entries, GST_TYPE_LIST);
414 /* stop at the CRC */
415 end = GST_BUFFER_DATA (section->buffer) + GST_BUFFER_SIZE (section->buffer);
416 while (data < end - 4) {
417 program_number = GST_READ_UINT16_BE (data);
420 pmt_pid = GST_READ_UINT16_BE (data) & 0x1FFF;
423 struct_name = g_strdup_printf ("program-%d", program_number);
424 entry = gst_structure_new (struct_name, NULL);
425 g_free (struct_name);
426 gst_structure_id_set (entry, QUARK_PROGRAM_NUMBER, G_TYPE_UINT,
427 program_number, QUARK_PID, G_TYPE_UINT, pmt_pid, NULL);
429 g_value_init (&value, GST_TYPE_STRUCTURE);
430 g_value_take_boxed (&value, entry);
431 gst_value_list_append_value (&entries, &value);
432 g_value_unset (&value);
435 gst_structure_id_set_value (pat_info, QUARK_PROGRAMS, &entries);
436 g_value_unset (&entries);
438 if (data != end - 4) {
439 /* FIXME: check the CRC before parsing the packet */
440 GST_ERROR ("at the end of PAT data != end - 4");
441 gst_structure_free (pat_info);
450 mpegts_packetizer_parse_pmt (MpegTSPacketizer * packetizer,
451 MpegTSPacketizerSection * section)
453 GstStructure *pmt = NULL;
455 guint16 program_number;
458 guint program_info_length;
461 guint stream_info_length;
462 GValueArray *descriptors;
463 GValue stream_value = { 0 };
464 GValue programs = { 0 };
465 GstStructure *stream_info = NULL;
468 /* fixed header + CRC == 16 */
469 if (GST_BUFFER_SIZE (section->buffer) < 16) {
470 GST_WARNING ("PID %d invalid PMT size %d",
471 section->pid, section->section_length);
475 data = GST_BUFFER_DATA (section->buffer);
476 end = data + GST_BUFFER_SIZE (section->buffer);
478 section->table_id = *data++;
479 section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
482 program_number = GST_READ_UINT16_BE (data);
486 section->version_number = (tmp >> 1) & 0x1F;
487 section->current_next_indicator = tmp & 0x01;
489 /* skip section_number and last_section_number */
492 pcr_pid = GST_READ_UINT16_BE (data) & 0x1FFF;
495 program_info_length = GST_READ_UINT16_BE (data) & 0x0FFF;
498 pmt = gst_structure_id_new (QUARK_PMT,
499 QUARK_PROGRAM_NUMBER, G_TYPE_UINT, program_number,
500 QUARK_PCR_PID, G_TYPE_UINT, pcr_pid,
501 QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number, NULL);
503 if (program_info_length) {
504 /* check that the buffer is large enough to contain at least
505 * program_info_length bytes + CRC */
506 if (data + program_info_length + 4 > end) {
507 GST_WARNING ("PID %d invalid program info length %d left %d",
508 section->pid, program_info_length, (gint) (end - data));
512 descriptors = g_value_array_new (0);
513 if (!mpegts_packetizer_parse_descriptors (packetizer,
514 &data, data + program_info_length, descriptors)) {
515 g_value_array_free (descriptors);
519 gst_structure_id_set (pmt, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
521 g_value_array_free (descriptors);
524 g_value_init (&programs, GST_TYPE_LIST);
525 /* parse entries, cycle until there's space for another entry (at least 5
526 * bytes) plus the CRC */
527 while (data <= end - 4 - 5) {
528 stream_type = *data++;
530 pid = GST_READ_UINT16_BE (data) & 0x1FFF;
533 stream_info_length = GST_READ_UINT16_BE (data) & 0x0FFF;
536 if (data + stream_info_length + 4 > end) {
537 GST_WARNING ("PID %d invalid stream info length %d left %d", section->pid,
538 stream_info_length, (gint) (end - data));
539 g_value_unset (&programs);
543 struct_name = g_strdup_printf ("pid-%d", pid);
544 stream_info = gst_structure_new (struct_name, NULL);
545 g_free (struct_name);
546 gst_structure_id_set (stream_info,
547 QUARK_PID, G_TYPE_UINT, pid, QUARK_STREAM_TYPE, G_TYPE_UINT,
550 if (stream_info_length) {
551 /* check for AC3 descriptor */
552 GstMPEGDescriptor *desc =
553 gst_mpeg_descriptor_parse (data, stream_info_length);
556 if (gst_mpeg_descriptor_find (desc, DESC_DVB_AC3)) {
557 gst_structure_set (stream_info, "has-ac3", G_TYPE_BOOLEAN, TRUE,
560 desc_data = gst_mpeg_descriptor_find (desc, DESC_DVB_DATA_BROADCAST_ID);
562 guint16 data_broadcast_id;
564 DESC_DVB_DATA_BROADCAST_ID_data_broadcast_id (desc_data);
565 gst_structure_set (stream_info, "data-broadcast-id", G_TYPE_UINT,
566 data_broadcast_id, NULL);
568 desc_data = gst_mpeg_descriptor_find (desc, DESC_DVB_DATA_BROADCAST);
570 GstStructure *databroadcast_info;
571 guint16 data_broadcast_id;
572 guint8 component_tag;
574 DESC_DVB_DATA_BROADCAST_data_broadcast_id (desc_data);
575 component_tag = DESC_DVB_DATA_BROADCAST_component_tag (desc_data);
576 databroadcast_info = gst_structure_new ("data-broadcast", "id",
577 G_TYPE_UINT, data_broadcast_id, "component-tag", component_tag,
579 gst_structure_set (stream_info, "data-broadcast", GST_TYPE_STRUCTURE,
580 databroadcast_info, NULL);
583 gst_mpeg_descriptor_find (desc, DESC_DVB_CAROUSEL_IDENTIFIER);
586 carousel_id = DESC_DVB_CAROUSEL_IDENTIFIER_carousel_id (desc_data);
587 gst_structure_set (stream_info, "carousel-id", G_TYPE_UINT,
590 desc_data = gst_mpeg_descriptor_find (desc, DESC_DVB_STREAM_IDENTIFIER);
592 guint8 component_tag;
593 component_tag = DESC_DVB_STREAM_IDENTIFIER_component_tag (desc_data);
594 gst_structure_set (stream_info, "component-tag", G_TYPE_UINT,
595 component_tag, NULL);
597 desc_data = gst_mpeg_descriptor_find (desc, DESC_ISO_639_LANGUAGE);
598 if (desc_data && DESC_ISO_639_LANGUAGE_codes_n (desc_data)) {
600 gchar *language_n = (gchar *)
601 DESC_ISO_639_LANGUAGE_language_code_nth (desc_data, 0);
602 lang_code = g_strndup (language_n, 3);
603 gst_structure_set (stream_info, "lang-code", G_TYPE_STRING,
608 gst_mpeg_descriptor_free (desc);
611 descriptors = g_value_array_new (0);
612 if (!mpegts_packetizer_parse_descriptors (packetizer,
613 &data, data + stream_info_length, descriptors)) {
614 g_value_unset (&programs);
615 gst_structure_free (stream_info);
616 g_value_array_free (descriptors);
620 gst_structure_id_set (stream_info,
621 QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY, descriptors, NULL);
622 g_value_array_free (descriptors);
626 g_value_init (&stream_value, GST_TYPE_STRUCTURE);
627 g_value_take_boxed (&stream_value, stream_info);
628 gst_value_list_append_value (&programs, &stream_value);
629 g_value_unset (&stream_value);
632 gst_structure_id_set_value (pmt, QUARK_STREAMS, &programs);
633 g_value_unset (&programs);
635 g_assert (data == end - 4);
641 gst_structure_free (pmt);
647 mpegts_packetizer_parse_nit (MpegTSPacketizer * packetizer,
648 MpegTSPacketizerSection * section)
650 GstStructure *nit = NULL, *transport = NULL, *delivery_structure = NULL;
651 guint8 *data, *end, *entry_begin;
652 guint16 network_id, transport_stream_id, original_network_id;
654 guint16 descriptors_loop_length, transport_stream_loop_length;
655 GValue transports = { 0 };
656 GValue transport_value = { 0 };
657 GValueArray *descriptors = NULL;
660 /* fixed header + CRC == 16 */
661 if (GST_BUFFER_SIZE (section->buffer) < 23) {
662 GST_WARNING ("PID %d invalid NIT size %d",
663 section->pid, section->section_length);
667 data = GST_BUFFER_DATA (section->buffer);
668 end = data + GST_BUFFER_SIZE (section->buffer);
670 section->table_id = *data++;
671 section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
674 if (data + section->section_length != end) {
675 GST_WARNING ("PID %d invalid NIT section length %d expected %d",
676 section->pid, section->section_length, (gint) (end - data));
680 network_id = GST_READ_UINT16_BE (data);
684 section->version_number = (tmp >> 1) & 0x1F;
685 section->current_next_indicator = tmp & 0x01;
687 /* skip section_number and last_section_number */
690 descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
693 nit = gst_structure_id_new (QUARK_NIT,
694 QUARK_NETWORK_ID, G_TYPE_UINT, network_id,
695 QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number,
696 QUARK_CURRENT_NEXT_INDICATOR, G_TYPE_UINT,
697 section->current_next_indicator, QUARK_ACTUAL_NETWORK, G_TYPE_BOOLEAN,
698 section->table_id == 0x40, NULL);
700 /* see if the buffer is large enough */
701 if (descriptors_loop_length) {
702 guint8 *networkname_descriptor;
703 GstMPEGDescriptor *mpegdescriptor;
705 if (data + descriptors_loop_length > end - 4) {
706 GST_WARNING ("PID %d invalid NIT descriptors loop length %d",
707 section->pid, descriptors_loop_length);
708 gst_structure_free (nit);
711 mpegdescriptor = gst_mpeg_descriptor_parse (data, descriptors_loop_length);
712 networkname_descriptor =
713 gst_mpeg_descriptor_find (mpegdescriptor, DESC_DVB_NETWORK_NAME);
714 if (networkname_descriptor != NULL) {
715 gchar *networkname_tmp;
717 /* No need to bounds check this value as it comes from the descriptor length itself */
718 guint8 networkname_length =
719 DESC_DVB_NETWORK_NAME_length (networkname_descriptor);
721 (gchar *) DESC_DVB_NETWORK_NAME_text (networkname_descriptor);
724 get_encoding_and_convert (networkname, networkname_length);
725 gst_structure_id_set (nit, QUARK_NETWORK_NAME, G_TYPE_STRING,
726 networkname_tmp, NULL);
727 g_free (networkname_tmp);
729 gst_mpeg_descriptor_free (mpegdescriptor);
731 descriptors = g_value_array_new (0);
732 if (!mpegts_packetizer_parse_descriptors (packetizer,
733 &data, data + descriptors_loop_length, descriptors)) {
734 gst_structure_free (nit);
735 g_value_array_free (descriptors);
739 gst_structure_id_set (nit, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
741 g_value_array_free (descriptors);
744 transport_stream_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
747 g_value_init (&transports, GST_TYPE_LIST);
748 /* read up to the CRC */
749 while (transport_stream_loop_length - 4 > 0) {
750 gchar *transport_name;
754 if (transport_stream_loop_length < 10) {
755 /* each entry must be at least 6 bytes (+ 4bytes CRC) */
756 GST_WARNING ("PID %d invalid NIT entry size %d",
757 section->pid, transport_stream_loop_length);
761 transport_stream_id = GST_READ_UINT16_BE (data);
764 original_network_id = GST_READ_UINT16_BE (data);
767 descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
770 transport_name = g_strdup_printf ("transport-%d", transport_stream_id);
771 transport = gst_structure_new (transport_name, NULL);
772 g_free (transport_name);
773 gst_structure_id_set (transport,
774 QUARK_TRANSPORT_STREAM_ID, G_TYPE_UINT, transport_stream_id,
775 QUARK_ORIGINAL_NETWORK_ID, G_TYPE_UINT, original_network_id, NULL);
777 if (descriptors_loop_length) {
778 GstMPEGDescriptor *mpegdescriptor;
781 if (data + descriptors_loop_length > end - 4) {
782 GST_WARNING ("PID %d invalid NIT entry %d descriptors loop length %d",
783 section->pid, transport_stream_id, descriptors_loop_length);
784 gst_structure_free (transport);
788 gst_mpeg_descriptor_parse (data, descriptors_loop_length);
791 gst_mpeg_descriptor_find (mpegdescriptor,
792 DESC_DVB_SATELLITE_DELIVERY_SYSTEM))) {
794 guint8 *frequency_bcd =
795 DESC_DVB_SATELLITE_DELIVERY_SYSTEM_frequency (delivery);
797 10 * ((frequency_bcd[3] & 0x0F) +
798 10 * ((frequency_bcd[3] & 0xF0) >> 4) +
799 100 * (frequency_bcd[2] & 0x0F) +
800 1000 * ((frequency_bcd[2] & 0xF0) >> 4) +
801 10000 * (frequency_bcd[1] & 0x0F) +
802 100000 * ((frequency_bcd[1] & 0xF0) >> 4) +
803 1000000 * (frequency_bcd[0] & 0x0F) +
804 10000000 * ((frequency_bcd[0] & 0xF0) >> 4));
805 guint8 *orbital_bcd =
806 DESC_DVB_SATELLITE_DELIVERY_SYSTEM_orbital_position (delivery);
808 (orbital_bcd[1] & 0x0F) / 10. + ((orbital_bcd[1] & 0xF0) >> 4) +
809 10 * (orbital_bcd[0] & 0x0F) + 100 * ((orbital_bcd[0] & 0xF0) >> 4);
811 DESC_DVB_SATELLITE_DELIVERY_SYSTEM_west_east_flag (delivery);
812 guint8 polarization =
813 DESC_DVB_SATELLITE_DELIVERY_SYSTEM_polarization (delivery);
814 const gchar *polarization_str;
816 DESC_DVB_SATELLITE_DELIVERY_SYSTEM_modulation (delivery);
817 const gchar *modulation_str;
818 guint8 *symbol_rate_bcd =
819 DESC_DVB_SATELLITE_DELIVERY_SYSTEM_symbol_rate (delivery);
820 guint32 symbol_rate =
821 (symbol_rate_bcd[2] & 0x0F) +
822 10 * ((symbol_rate_bcd[2] & 0xF0) >> 4) +
823 100 * (symbol_rate_bcd[1] & 0x0F) +
824 1000 * ((symbol_rate_bcd[1] & 0xF0) >> 4) +
825 10000 * (symbol_rate_bcd[0] & 0x0F) +
826 100000 * ((symbol_rate_bcd[0] & 0xF0) >> 4);
828 DESC_DVB_SATELLITE_DELIVERY_SYSTEM_fec_inner (delivery);
829 const gchar *fec_inner_str;
831 switch (polarization) {
833 polarization_str = "horizontal";
836 polarization_str = "vertical";
839 polarization_str = "left";
842 polarization_str = "right";
845 polarization_str = "";
849 fec_inner_str = "undefined";
852 fec_inner_str = "1/2";
855 fec_inner_str = "2/3";
858 fec_inner_str = "3/4";
861 fec_inner_str = "5/6";
864 fec_inner_str = "7/8";
867 fec_inner_str = "8/9";
870 fec_inner_str = "none";
873 fec_inner_str = "reserved";
875 switch (modulation) {
877 modulation_str = "undefined";
880 modulation_str = "QAM16";
883 modulation_str = "QAM32";
886 modulation_str = "QAM64";
889 modulation_str = "QAM128";
892 modulation_str = "QAM256";
895 modulation_str = "reserved";
897 delivery_structure = gst_structure_new ("satellite",
898 "orbital", G_TYPE_FLOAT, orbital,
899 "east-or-west", G_TYPE_STRING, east ? "east" : "west",
900 "modulation", G_TYPE_STRING, modulation_str,
901 "frequency", G_TYPE_UINT, frequency,
902 "polarization", G_TYPE_STRING, polarization_str,
903 "symbol-rate", G_TYPE_UINT, symbol_rate,
904 "inner-fec", G_TYPE_STRING, fec_inner_str, NULL);
905 gst_structure_set (transport, "delivery", GST_TYPE_STRUCTURE,
906 delivery_structure, NULL);
907 } else if ((delivery =
908 gst_mpeg_descriptor_find (mpegdescriptor,
909 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM))) {
912 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_frequency (delivery) * 10;
914 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_bandwidth (delivery);
915 guint8 constellation =
916 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_constellation (delivery);
918 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_hierarchy (delivery);
919 guint8 code_rate_hp =
920 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_code_rate_hp (delivery);
921 guint8 code_rate_lp =
922 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_code_rate_lp (delivery);
923 guint8 guard_interval =
924 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_guard_interval (delivery);
925 guint8 transmission_mode =
926 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_transmission_mode (delivery);
927 gboolean other_frequency =
928 DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_other_frequency (delivery);
929 const gchar *constellation_str, *code_rate_hp_str, *code_rate_lp_str,
930 *transmission_mode_str;
932 /* bandwidth is 8 if 0, 7 if 1, 6 if 2, reserved otherwise */
934 bandwidth = 8 - bandwidth;
937 switch (constellation) {
939 constellation_str = "QPSK";
942 constellation_str = "QAM16";
945 constellation_str = "QAM64";
948 constellation_str = "reserved";
950 /* hierarchy is 4 if 3, 2 if 2, 1 if 1, 0 if 0, reserved if > 3 */
951 if (hierarchy <= 3) {
958 switch (code_rate_hp) {
960 code_rate_hp_str = "1/2";
963 code_rate_hp_str = "2/3";
966 code_rate_hp_str = "3/4";
969 code_rate_hp_str = "5/6";
972 code_rate_hp_str = "7/8";
975 code_rate_hp_str = "reserved";
978 switch (code_rate_lp) {
980 code_rate_lp_str = "1/2";
983 code_rate_lp_str = "2/3";
986 code_rate_lp_str = "3/4";
989 code_rate_lp_str = "5/6";
992 code_rate_lp_str = "7/8";
995 code_rate_lp_str = "reserved";
997 /* guard is 32 if 0, 16 if 1, 8 if 2, 4 if 3 */
998 switch (guard_interval) {
1000 guard_interval = 32;
1003 guard_interval = 16;
1011 default: /* make it default to 32 */
1012 guard_interval = 32;
1014 switch (transmission_mode) {
1016 transmission_mode_str = "2k";
1019 transmission_mode_str = "8k";
1022 transmission_mode_str = "reserved";
1024 delivery_structure = gst_structure_new ("terrestrial",
1025 "frequency", G_TYPE_UINT, frequency,
1026 "bandwidth", G_TYPE_UINT, bandwidth,
1027 "constellation", G_TYPE_STRING, constellation_str,
1028 "hierarchy", G_TYPE_UINT, hierarchy,
1029 "code-rate-hp", G_TYPE_STRING, code_rate_hp_str,
1030 "code-rate-lp", G_TYPE_STRING, code_rate_lp_str,
1031 "guard-interval", G_TYPE_UINT, guard_interval,
1032 "transmission-mode", G_TYPE_STRING, transmission_mode_str,
1033 "other-frequency", G_TYPE_BOOLEAN, other_frequency, NULL);
1034 gst_structure_set (transport, "delivery", GST_TYPE_STRUCTURE,
1035 delivery_structure, NULL);
1036 } else if ((delivery =
1037 gst_mpeg_descriptor_find (mpegdescriptor,
1038 DESC_DVB_CABLE_DELIVERY_SYSTEM))) {
1040 guint8 *frequency_bcd =
1041 DESC_DVB_CABLE_DELIVERY_SYSTEM_frequency (delivery);
1042 /* see en 300 468 section 6.2.13.1 least significant bcd digit
1043 * is measured in 100Hz units so multiplier needs to be 100 to get
1045 guint32 frequency = 100 *
1046 ((frequency_bcd[3] & 0x0F) +
1047 10 * ((frequency_bcd[3] & 0xF0) >> 4) +
1048 100 * (frequency_bcd[2] & 0x0F) +
1049 1000 * ((frequency_bcd[2] & 0xF0) >> 4) +
1050 10000 * (frequency_bcd[1] & 0x0F) +
1051 100000 * ((frequency_bcd[1] & 0xF0) >> 4) +
1052 1000000 * (frequency_bcd[0] & 0x0F) +
1053 10000000 * ((frequency_bcd[0] & 0xF0) >> 4));
1055 DESC_DVB_CABLE_DELIVERY_SYSTEM_modulation (delivery);
1056 const gchar *modulation_str;
1057 guint8 *symbol_rate_bcd =
1058 DESC_DVB_CABLE_DELIVERY_SYSTEM_symbol_rate (delivery);
1059 guint32 symbol_rate =
1060 (symbol_rate_bcd[2] & 0x0F) +
1061 10 * ((symbol_rate_bcd[2] & 0xF0) >> 4) +
1062 100 * (symbol_rate_bcd[1] & 0x0F) +
1063 1000 * ((symbol_rate_bcd[1] & 0xF0) >> 4) +
1064 10000 * (symbol_rate_bcd[0] & 0x0F) +
1065 100000 * ((symbol_rate_bcd[0] & 0xF0) >> 4);
1066 guint8 fec_inner = DESC_DVB_CABLE_DELIVERY_SYSTEM_fec_inner (delivery);
1067 const gchar *fec_inner_str;
1069 switch (fec_inner) {
1071 fec_inner_str = "undefined";
1074 fec_inner_str = "1/2";
1077 fec_inner_str = "2/3";
1080 fec_inner_str = "3/4";
1083 fec_inner_str = "5/6";
1086 fec_inner_str = "7/8";
1089 fec_inner_str = "8/9";
1092 fec_inner_str = "none";
1095 fec_inner_str = "reserved";
1097 switch (modulation) {
1099 modulation_str = "undefined";
1102 modulation_str = "QAM16";
1105 modulation_str = "QAM32";
1108 modulation_str = "QAM64";
1111 modulation_str = "QAM128";
1114 modulation_str = "QAM256";
1117 modulation_str = "reserved";
1119 delivery_structure = gst_structure_new ("cable",
1120 "modulation", G_TYPE_STRING, modulation_str,
1121 "frequency", G_TYPE_UINT, frequency,
1122 "symbol-rate", G_TYPE_UINT, symbol_rate,
1123 "inner-fec", G_TYPE_STRING, fec_inner_str, NULL);
1124 gst_structure_set (transport, "delivery", GST_TYPE_STRUCTURE,
1125 delivery_structure, NULL);
1127 /* free the temporary delivery structure */
1128 if (delivery_structure != NULL) {
1129 gst_structure_free (delivery_structure);
1130 delivery_structure = NULL;
1133 gst_mpeg_descriptor_find (mpegdescriptor,
1134 DESC_DTG_LOGICAL_CHANNEL))) {
1135 guint8 *current_pos = delivery + 2;
1136 GValue channel_numbers = { 0 };
1138 g_value_init (&channel_numbers, GST_TYPE_LIST);
1139 while (current_pos < delivery + DESC_LENGTH (delivery)) {
1140 GstStructure *channel;
1141 GValue channel_value = { 0 };
1142 guint16 service_id = GST_READ_UINT16_BE (current_pos);
1143 guint16 logical_channel_number;
1146 logical_channel_number = GST_READ_UINT16_BE (current_pos) & 0x03ff;
1148 gst_structure_new ("channels", "service-id", G_TYPE_UINT,
1149 service_id, "logical-channel-number", G_TYPE_UINT,
1150 logical_channel_number, NULL);
1151 g_value_init (&channel_value, GST_TYPE_STRUCTURE);
1152 g_value_take_boxed (&channel_value, channel);
1153 gst_value_list_append_value (&channel_numbers, &channel_value);
1154 g_value_unset (&channel_value);
1157 gst_structure_set_value (transport, "channels", &channel_numbers);
1158 g_value_unset (&channel_numbers);
1161 gst_mpeg_descriptor_find (mpegdescriptor,
1162 DESC_DVB_FREQUENCY_LIST))) {
1163 guint8 *current_pos = delivery + 2;
1164 GValue frequencies = { 0 };
1167 type = *current_pos & 0x03;
1171 const gchar *fieldname = NULL;
1172 g_value_init (&frequencies, GST_TYPE_LIST);
1174 while (current_pos < delivery + DESC_LENGTH (delivery) - 3) {
1176 guint8 *frequency_bcd = current_pos;
1177 GValue frequency = { 0 };
1183 10 * ((frequency_bcd[3] & 0x0F) +
1184 10 * ((frequency_bcd[3] & 0xF0) >> 4) +
1185 100 * (frequency_bcd[2] & 0x0F) +
1186 1000 * ((frequency_bcd[2] & 0xF0) >> 4) +
1187 10000 * (frequency_bcd[1] & 0x0F) +
1188 100000 * ((frequency_bcd[1] & 0xF0) >> 4) +
1189 1000000 * (frequency_bcd[0] & 0x0F) +
1190 10000000 * ((frequency_bcd[0] & 0xF0) >> 4));
1195 ((frequency_bcd[3] & 0x0F) +
1196 10 * ((frequency_bcd[3] & 0xF0) >> 4) +
1197 100 * (frequency_bcd[2] & 0x0F) +
1198 1000 * ((frequency_bcd[2] & 0xF0) >> 4) +
1199 10000 * (frequency_bcd[1] & 0x0F) +
1200 100000 * ((frequency_bcd[1] & 0xF0) >> 4) +
1201 1000000 * (frequency_bcd[0] & 0x0F) +
1202 10000000 * ((frequency_bcd[0] & 0xF0) >> 4));
1206 freq = GST_READ_UINT32_BE (current_pos) * 10;
1209 g_value_init (&frequency, G_TYPE_UINT);
1210 g_value_set_uint (&frequency, freq);
1211 gst_value_list_append_value (&frequencies, &frequency);
1212 g_value_unset (&frequency);
1218 fieldname = "frequency-list-satellite";
1221 fieldname = "frequency-list-cable";
1224 fieldname = "frequency-list-terrestrial";
1228 gst_structure_set_value (transport, fieldname, &frequencies);
1229 g_value_unset (&frequencies);
1232 gst_mpeg_descriptor_free (mpegdescriptor);
1234 descriptors = g_value_array_new (0);
1235 if (!mpegts_packetizer_parse_descriptors (packetizer,
1236 &data, data + descriptors_loop_length, descriptors)) {
1237 gst_structure_free (transport);
1238 g_value_array_free (descriptors);
1242 gst_structure_id_set (transport, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
1244 g_value_array_free (descriptors);
1247 g_value_init (&transport_value, GST_TYPE_STRUCTURE);
1248 g_value_take_boxed (&transport_value, transport);
1249 gst_value_list_append_value (&transports, &transport_value);
1250 g_value_unset (&transport_value);
1252 transport_stream_loop_length -= data - entry_begin;
1255 if (data != end - 4) {
1256 GST_WARNING ("PID %d invalid NIT parsed %d length %d",
1257 section->pid, (gint) (data - GST_BUFFER_DATA (section->buffer)),
1258 GST_BUFFER_SIZE (section->buffer));
1262 gst_structure_id_set_value (nit, QUARK_TRANSPORTS, &transports);
1263 g_value_unset (&transports);
1265 GST_DEBUG ("NIT %" GST_PTR_FORMAT, nit);
1271 gst_structure_free (nit);
1273 if (GST_VALUE_HOLDS_LIST (&transports))
1274 g_value_unset (&transports);
1280 mpegts_packetizer_parse_sdt (MpegTSPacketizer * packetizer,
1281 MpegTSPacketizerSection * section)
1283 GstStructure *sdt = NULL, *service = NULL;
1284 guint8 *data, *end, *entry_begin;
1285 guint16 transport_stream_id, original_network_id, service_id;
1287 guint sdt_info_length;
1288 guint8 running_status;
1290 guint descriptors_loop_length;
1291 GValue services = { 0 };
1292 GValueArray *descriptors = NULL;
1293 GValue service_value = { 0 };
1296 /* fixed header + CRC == 16 */
1297 if (GST_BUFFER_SIZE (section->buffer) < 14) {
1298 GST_WARNING ("PID %d invalid SDT size %d",
1299 section->pid, section->section_length);
1303 data = GST_BUFFER_DATA (section->buffer);
1304 end = data + GST_BUFFER_SIZE (section->buffer);
1306 section->table_id = *data++;
1307 section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1310 if (data + section->section_length != end) {
1311 GST_WARNING ("PID %d invalid SDT section length %d expected %d",
1312 section->pid, section->section_length, (gint) (end - data));
1316 transport_stream_id = GST_READ_UINT16_BE (data);
1320 section->version_number = (tmp >> 1) & 0x1F;
1321 section->current_next_indicator = tmp & 0x01;
1323 /* skip section_number and last_section_number */
1326 original_network_id = GST_READ_UINT16_BE (data);
1329 /* skip reserved byte */
1332 sdt = gst_structure_id_new (QUARK_SDT,
1333 QUARK_TRANSPORT_STREAM_ID, G_TYPE_UINT, transport_stream_id,
1334 QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number,
1335 QUARK_CURRENT_NEXT_INDICATOR, G_TYPE_UINT,
1336 section->current_next_indicator, QUARK_ORIGINAL_NETWORK_ID, G_TYPE_UINT,
1337 original_network_id, QUARK_ACTUAL_TRANSPORT_STREAM, G_TYPE_BOOLEAN,
1338 section->table_id == 0x42, NULL);
1340 sdt_info_length = section->section_length - 8;
1341 g_value_init (&services, GST_TYPE_LIST);
1342 /* read up to the CRC */
1343 while (sdt_info_length - 4 > 0) {
1344 gchar *service_name;
1348 if (sdt_info_length < 9) {
1349 /* each entry must be at least 5 bytes (+4 bytes for the CRC) */
1350 GST_WARNING ("PID %d invalid SDT entry size %d",
1351 section->pid, sdt_info_length);
1355 service_id = GST_READ_UINT16_BE (data);
1358 /* EIT_schedule = ((*data & 0x02) == 2); */
1359 /* EIT_present_following = (*data & 0x01) == 1; */
1362 tmp = GST_READ_UINT16_BE (data);
1364 running_status = (*data >> 5) & 0x07;
1365 scrambled = (*data >> 4) & 0x01;
1366 descriptors_loop_length = tmp & 0x0FFF;
1369 /* TODO send tag event down relevant pad for channel name and provider */
1370 service_name = g_strdup_printf ("service-%d", service_id);
1371 service = gst_structure_new (service_name, NULL);
1372 g_free (service_name);
1374 if (descriptors_loop_length) {
1375 guint8 *service_descriptor;
1376 GstMPEGDescriptor *mpegdescriptor;
1378 if (data + descriptors_loop_length > end - 4) {
1379 GST_WARNING ("PID %d invalid SDT entry %d descriptors loop length %d",
1380 section->pid, service_id, descriptors_loop_length);
1381 gst_structure_free (service);
1385 gst_mpeg_descriptor_parse (data, descriptors_loop_length);
1386 service_descriptor =
1387 gst_mpeg_descriptor_find (mpegdescriptor, DESC_DVB_SERVICE);
1388 if (service_descriptor != NULL) {
1389 gchar *servicename_tmp, *serviceprovider_name_tmp;
1390 guint8 serviceprovider_name_length =
1391 DESC_DVB_SERVICE_provider_name_length (service_descriptor);
1392 gchar *serviceprovider_name =
1393 (gchar *) DESC_DVB_SERVICE_provider_name_text (service_descriptor);
1394 guint8 servicename_length =
1395 DESC_DVB_SERVICE_name_length (service_descriptor);
1396 gchar *servicename =
1397 (gchar *) DESC_DVB_SERVICE_name_text (service_descriptor);
1398 if (servicename_length + serviceprovider_name_length + 2 <=
1399 DESC_LENGTH (service_descriptor)) {
1400 const gchar *running_status_tmp;
1401 switch (running_status) {
1403 running_status_tmp = "undefined";
1406 running_status_tmp = "not running";
1409 running_status_tmp = "starts in a few seconds";
1412 running_status_tmp = "pausing";
1415 running_status_tmp = "running";
1418 running_status_tmp = "reserved";
1421 get_encoding_and_convert (servicename, servicename_length);
1422 serviceprovider_name_tmp =
1423 get_encoding_and_convert (serviceprovider_name,
1424 serviceprovider_name_length);
1426 gst_structure_set (service,
1427 "name", G_TYPE_STRING, servicename_tmp,
1428 "provider-name", G_TYPE_STRING, serviceprovider_name_tmp,
1429 "scrambled", G_TYPE_BOOLEAN, scrambled,
1430 "running-status", G_TYPE_STRING, running_status_tmp, NULL);
1432 g_free (servicename_tmp);
1433 g_free (serviceprovider_name_tmp);
1436 gst_mpeg_descriptor_free (mpegdescriptor);
1438 descriptors = g_value_array_new (0);
1439 if (!mpegts_packetizer_parse_descriptors (packetizer,
1440 &data, data + descriptors_loop_length, descriptors)) {
1441 gst_structure_free (service);
1442 g_value_array_free (descriptors);
1446 gst_structure_id_set (service, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
1449 g_value_array_free (descriptors);
1452 g_value_init (&service_value, GST_TYPE_STRUCTURE);
1453 g_value_take_boxed (&service_value, service);
1454 gst_value_list_append_value (&services, &service_value);
1455 g_value_unset (&service_value);
1457 sdt_info_length -= data - entry_begin;
1460 if (data != end - 4) {
1461 GST_WARNING ("PID %d invalid SDT parsed %d length %d",
1462 section->pid, (gint) (data - GST_BUFFER_DATA (section->buffer)),
1463 GST_BUFFER_SIZE (section->buffer));
1467 gst_structure_id_set_value (sdt, QUARK_SERVICES, &services);
1468 g_value_unset (&services);
1474 gst_structure_free (sdt);
1476 if (GST_VALUE_HOLDS_LIST (&services))
1477 g_value_unset (&services);
1483 mpegts_packetizer_parse_eit (MpegTSPacketizer * packetizer,
1484 MpegTSPacketizerSection * section)
1486 GstStructure *eit = NULL, *event = NULL;
1487 guint service_id, last_table_id, segment_last_section_number;
1488 guint transport_stream_id, original_network_id;
1489 gboolean free_ca_mode;
1490 guint event_id, running_status;
1492 guint year, month, day, hour, minute, second;
1494 guint8 *data, *end, *duration_ptr, *utc_ptr;
1495 guint16 descriptors_loop_length;
1496 GValue events = { 0 };
1497 GValue event_value = { 0 };
1498 GValueArray *descriptors = NULL;
1502 /* fixed header + CRC == 16 */
1503 if (GST_BUFFER_SIZE (section->buffer) < 18) {
1504 GST_WARNING ("PID %d invalid EIT size %d",
1505 section->pid, section->section_length);
1509 data = GST_BUFFER_DATA (section->buffer);
1510 end = data + GST_BUFFER_SIZE (section->buffer);
1512 section->table_id = *data++;
1513 section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1516 if (data + section->section_length != end) {
1517 GST_WARNING ("PID %d invalid EIT section length %d expected %d",
1518 section->pid, section->section_length, (gint) (end - data));
1522 service_id = GST_READ_UINT16_BE (data);
1526 section->version_number = (tmp >> 1) & 0x1F;
1527 section->current_next_indicator = tmp & 0x01;
1529 /* skip section_number and last_section_number */
1532 transport_stream_id = GST_READ_UINT16_BE (data);
1534 original_network_id = GST_READ_UINT16_BE (data);
1536 segment_last_section_number = *data;
1538 last_table_id = *data;
1541 eit = gst_structure_id_new (QUARK_EIT,
1542 QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number,
1543 QUARK_CURRENT_NEXT_INDICATOR, G_TYPE_UINT,
1544 section->current_next_indicator, QUARK_SERVICE_ID, G_TYPE_UINT,
1545 service_id, QUARK_ACTUAL_TRANSPORT_STREAM, G_TYPE_BOOLEAN,
1546 (section->table_id == 0x4E || (section->table_id >= 0x50
1547 && section->table_id <= 0x5F)), QUARK_PRESENT_FOLLOWING,
1548 G_TYPE_BOOLEAN, (section->table_id == 0x4E
1549 || section->table_id == 0x4F), QUARK_TRANSPORT_STREAM_ID, G_TYPE_UINT,
1550 transport_stream_id, QUARK_ORIGINAL_NETWORK_ID, G_TYPE_UINT,
1551 original_network_id, QUARK_SEGMENT_LAST_SECTION_NUMBER, G_TYPE_UINT,
1552 segment_last_section_number, QUARK_LAST_TABLE_ID, G_TYPE_UINT,
1553 last_table_id, NULL);
1555 g_value_init (&events, GST_TYPE_LIST);
1556 while (data < end - 4) {
1557 /* 12 is the minimum entry size + CRC */
1558 if (end - data < 12 + 4) {
1559 GST_WARNING ("PID %d invalid EIT entry length %d",
1560 section->pid, (gint) (end - 4 - data));
1561 gst_structure_free (eit);
1565 event_id = GST_READ_UINT16_BE (data);
1567 /* start_and_duration = GST_READ_UINT64_BE (data); */
1568 duration_ptr = data + 5;
1570 mjd = GST_READ_UINT16_BE (data);
1571 if (mjd == G_MAXUINT16) {
1573 month = day = hour = minute = second = 0;
1575 /* See EN 300 468 Annex C */
1576 year = (guint32) (((mjd - 15078.2) / 365.25));
1577 month = (guint8) ((mjd - 14956.1 - (guint) (year * 365.25)) / 30.6001);
1578 day = mjd - 14956 - (guint) (year * 365.25) - (guint) (month * 30.6001);
1579 if (month == 14 || month == 15) {
1581 month = month - 1 - 12;
1586 hour = ((utc_ptr[0] & 0xF0) >> 4) * 10 + (utc_ptr[0] & 0x0F);
1587 minute = ((utc_ptr[1] & 0xF0) >> 4) * 10 + (utc_ptr[1] & 0x0F);
1588 second = ((utc_ptr[2] & 0xF0) >> 4) * 10 + (utc_ptr[2] & 0x0F);
1591 duration = (((duration_ptr[0] & 0xF0) >> 4) * 10 +
1592 (duration_ptr[0] & 0x0F)) * 60 * 60 +
1593 (((duration_ptr[1] & 0xF0) >> 4) * 10 +
1594 (duration_ptr[1] & 0x0F)) * 60 +
1595 ((duration_ptr[2] & 0xF0) >> 4) * 10 + (duration_ptr[2] & 0x0F);
1598 running_status = *data >> 5;
1599 free_ca_mode = (*data >> 4) & 0x01;
1600 descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1603 /* TODO: send tag event down relevant pad saying what is currently playing */
1604 event_name = g_strdup_printf ("event-%d", event_id);
1605 event = gst_structure_new (event_name,
1606 "event-id", G_TYPE_UINT, event_id,
1607 "year", G_TYPE_UINT, year,
1608 "month", G_TYPE_UINT, month,
1609 "day", G_TYPE_UINT, day,
1610 "hour", G_TYPE_UINT, hour,
1611 "minute", G_TYPE_UINT, minute,
1612 "second", G_TYPE_UINT, second,
1613 "duration", G_TYPE_UINT, duration,
1614 "running-status", G_TYPE_UINT, running_status,
1615 "free-ca-mode", G_TYPE_BOOLEAN, free_ca_mode, NULL);
1616 g_free (event_name);
1618 if (descriptors_loop_length) {
1619 guint8 *event_descriptor;
1620 GArray *component_descriptors;
1621 GArray *extended_event_descriptors;
1622 GstMPEGDescriptor *mpegdescriptor;
1624 if (data + descriptors_loop_length > end - 4) {
1625 GST_WARNING ("PID %d invalid EIT descriptors loop length %d",
1626 section->pid, descriptors_loop_length);
1627 gst_structure_free (event);
1631 gst_mpeg_descriptor_parse (data, descriptors_loop_length);
1633 gst_mpeg_descriptor_find (mpegdescriptor, DESC_DVB_SHORT_EVENT);
1634 if (event_descriptor != NULL) {
1635 gchar *eventname_tmp, *eventdescription_tmp;
1636 guint8 eventname_length =
1637 DESC_DVB_SHORT_EVENT_name_length (event_descriptor);
1639 (gchar *) DESC_DVB_SHORT_EVENT_name_text (event_descriptor);
1640 guint8 eventdescription_length =
1641 DESC_DVB_SHORT_EVENT_description_length (event_descriptor);
1642 gchar *eventdescription =
1643 (gchar *) DESC_DVB_SHORT_EVENT_description_text (event_descriptor);
1644 if (eventname_length + eventdescription_length + 2 <=
1645 DESC_LENGTH (event_descriptor)) {
1648 get_encoding_and_convert (eventname, eventname_length);
1649 eventdescription_tmp =
1650 get_encoding_and_convert (eventdescription,
1651 eventdescription_length);
1653 gst_structure_set (event, "name", G_TYPE_STRING, eventname_tmp, NULL);
1654 gst_structure_set (event, "description", G_TYPE_STRING,
1655 eventdescription_tmp, NULL);
1656 g_free (eventname_tmp);
1657 g_free (eventdescription_tmp);
1660 extended_event_descriptors = gst_mpeg_descriptor_find_all (mpegdescriptor,
1661 DESC_DVB_EXTENDED_EVENT);
1662 if (extended_event_descriptors) {
1664 guint8 *extended_descriptor;
1665 /*GValue extended_items = { 0 }; */
1666 gchar *extended_text = NULL;
1667 /*g_value_init (&extended_items, GST_TYPE_LIST); */
1668 for (i = 0; i < extended_event_descriptors->len; i++) {
1669 extended_descriptor = g_array_index (extended_event_descriptors,
1671 if (DESC_DVB_EXTENDED_EVENT_descriptor_number (extended_descriptor) ==
1673 if (extended_text) {
1675 gchar *old_extended_text = extended_text;
1676 tmp = get_encoding_and_convert ((gchar *)
1677 DESC_DVB_EXTENDED_EVENT_text (extended_descriptor),
1678 DESC_DVB_EXTENDED_EVENT_text_length (extended_descriptor));
1679 extended_text = g_strdup_printf ("%s%s", extended_text, tmp);
1680 g_free (old_extended_text);
1683 extended_text = get_encoding_and_convert ((gchar *)
1684 DESC_DVB_EXTENDED_EVENT_text (extended_descriptor),
1685 DESC_DVB_EXTENDED_EVENT_text_length (extended_descriptor));
1689 if (extended_text) {
1690 gst_structure_set (event, "extended-text", G_TYPE_STRING,
1691 extended_text, NULL);
1692 g_free (extended_text);
1694 g_array_free (extended_event_descriptors, TRUE);
1697 component_descriptors = gst_mpeg_descriptor_find_all (mpegdescriptor,
1698 DESC_DVB_COMPONENT);
1699 if (component_descriptors) {
1701 guint8 *comp_descriptor;
1702 GValue components = { 0 };
1703 g_value_init (&components, GST_TYPE_LIST);
1704 /* FIXME: do the component descriptor parsing less verbosely
1705 * and better...a task for 0.10.6 */
1706 for (i = 0; i < component_descriptors->len; i++) {
1707 GstStructure *component = NULL;
1708 GValue component_value = { 0 };
1709 gint widescreen = 0; /* 0 for 4:3, 1 for 16:9, 2 for > 16:9 */
1710 gint freq = 25; /* 25 or 30 measured in Hertz */
1711 /* gboolean highdef = FALSE; */
1712 gboolean panvectors = FALSE;
1713 const gchar *comptype = "";
1715 comp_descriptor = g_array_index (component_descriptors, guint8 *, i);
1716 switch (DESC_DVB_COMPONENT_stream_content (comp_descriptor)) {
1719 switch (DESC_DVB_COMPONENT_type (comp_descriptor)) {
1758 /* highdef = TRUE; */
1763 /* highdef = TRUE; */
1769 /* highdef = TRUE; */
1775 /* highdef = TRUE; */
1780 /* highdef = TRUE; */
1785 /* highdef = TRUE; */
1791 /* highdef = TRUE; */
1797 /* highdef = TRUE; */
1801 component = gst_structure_new ("video", "high-definition",
1802 G_TYPE_BOOLEAN, TRUE, "frequency", G_TYPE_INT, freq,
1803 "tag", G_TYPE_INT, DESC_DVB_COMPONENT_tag (comp_descriptor),
1805 if (widescreen == 0) {
1806 gst_structure_set (component, "aspect-ratio",
1807 G_TYPE_STRING, "4:3", NULL);
1808 } else if (widescreen == 2) {
1809 gst_structure_set (component, "aspect-ratio", G_TYPE_STRING,
1812 gst_structure_set (component, "aspect-ratio", G_TYPE_STRING,
1813 "16:9", "pan-vectors", G_TYPE_BOOLEAN, panvectors, NULL);
1816 case 0x02: /* audio */
1817 comptype = "undefined";
1818 switch (DESC_DVB_COMPONENT_type (comp_descriptor)) {
1820 comptype = "single channel mono";
1823 comptype = "dual channel mono";
1826 comptype = "stereo";
1829 comptype = "multi-channel multi-lingual";
1832 comptype = "surround";
1835 comptype = "audio description for the visually impaired";
1838 comptype = "audio for the hard of hearing";
1841 component = gst_structure_new ("audio", "type", G_TYPE_STRING,
1842 comptype, "tag", G_TYPE_INT,
1843 DESC_DVB_COMPONENT_tag (comp_descriptor), NULL);
1845 case 0x03: /* subtitles/teletext/vbi */
1846 comptype = "reserved";
1847 switch (DESC_DVB_COMPONENT_type (comp_descriptor)) {
1849 comptype = "EBU Teletext subtitles";
1852 comptype = "associated EBU Teletext";
1855 comptype = "VBI data";
1858 comptype = "Normal DVB subtitles";
1861 comptype = "Normal DVB subtitles for 4:3";
1864 comptype = "Normal DVB subtitles for 16:9";
1867 comptype = "Normal DVB subtitles for 2.21:1";
1870 comptype = "Hard of hearing DVB subtitles";
1873 comptype = "Hard of hearing DVB subtitles for 4:3";
1876 comptype = "Hard of hearing DVB subtitles for 16:9";
1879 comptype = "Hard of hearing DVB subtitles for 2.21:1";
1882 component = gst_structure_new ("teletext", "type", G_TYPE_STRING,
1883 comptype, "tag", G_TYPE_INT,
1884 DESC_DVB_COMPONENT_tag (comp_descriptor), NULL);
1888 g_value_init (&component_value, GST_TYPE_STRUCTURE);
1889 g_value_take_boxed (&component_value, component);
1890 gst_value_list_append_value (&components, &component_value);
1891 g_value_unset (&component_value);
1895 gst_structure_set_value (event, "components", &components);
1896 g_value_unset (&components);
1897 g_array_free (component_descriptors, TRUE);
1899 gst_mpeg_descriptor_free (mpegdescriptor);
1901 descriptors = g_value_array_new (0);
1902 if (!mpegts_packetizer_parse_descriptors (packetizer,
1903 &data, data + descriptors_loop_length, descriptors)) {
1904 gst_structure_free (event);
1905 g_value_array_free (descriptors);
1908 gst_structure_id_set (event, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
1910 g_value_array_free (descriptors);
1913 g_value_init (&event_value, GST_TYPE_STRUCTURE);
1914 g_value_take_boxed (&event_value, event);
1915 gst_value_list_append_value (&events, &event_value);
1916 g_value_unset (&event_value);
1919 if (data != end - 4) {
1920 GST_WARNING ("PID %d invalid EIT parsed %d length %d",
1921 section->pid, (gint) (data - GST_BUFFER_DATA (section->buffer)),
1922 GST_BUFFER_SIZE (section->buffer));
1926 gst_structure_id_set_value (eit, QUARK_EVENTS, &events);
1927 g_value_unset (&events);
1929 GST_DEBUG ("EIT %" GST_PTR_FORMAT, eit);
1935 gst_structure_free (eit);
1937 if (GST_VALUE_HOLDS_LIST (&events))
1938 g_value_unset (&events);
1944 mpegts_packetizer_parse_tdt (MpegTSPacketizer * packetizer,
1945 MpegTSPacketizerSection * section)
1947 GstStructure *tdt = NULL;
1949 guint year, month, day, hour, minute, second;
1950 guint8 *data, *end, *utc_ptr;
1953 /* length always 8 */
1954 if (G_UNLIKELY (GST_BUFFER_SIZE (section->buffer) != 8)) {
1955 GST_WARNING ("PID %d invalid TDT size %d",
1956 section->pid, section->section_length);
1960 data = GST_BUFFER_DATA (section->buffer);
1961 end = data + GST_BUFFER_SIZE (section->buffer);
1963 section->table_id = *data++;
1964 section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1967 if (data + section->section_length != end) {
1968 GST_WARNING ("PID %d invalid TDT section length %d expected %d",
1969 section->pid, section->section_length, (gint) (end - data));
1973 mjd = GST_READ_UINT16_BE (data);
1976 if (mjd == G_MAXUINT16) {
1978 month = day = hour = minute = second = 0;
1980 /* See EN 300 468 Annex C */
1981 year = (guint32) (((mjd - 15078.2) / 365.25));
1982 month = (guint8) ((mjd - 14956.1 - (guint) (year * 365.25)) / 30.6001);
1983 day = mjd - 14956 - (guint) (year * 365.25) - (guint) (month * 30.6001);
1984 if (month == 14 || month == 15) {
1986 month = month - 1 - 12;
1991 hour = ((utc_ptr[0] & 0xF0) >> 4) * 10 + (utc_ptr[0] & 0x0F);
1992 minute = ((utc_ptr[1] & 0xF0) >> 4) * 10 + (utc_ptr[1] & 0x0F);
1993 second = ((utc_ptr[2] & 0xF0) >> 4) * 10 + (utc_ptr[2] & 0x0F);
1995 tdt = gst_structure_new ("tdt",
1996 "year", G_TYPE_UINT, year,
1997 "month", G_TYPE_UINT, month,
1998 "day", G_TYPE_UINT, day,
1999 "hour", G_TYPE_UINT, hour,
2000 "minute", G_TYPE_UINT, minute, "second", G_TYPE_UINT, second, NULL);
2006 gst_structure_free (tdt);
2013 mpegts_packetizer_clear (MpegTSPacketizer * packetizer)
2015 if (packetizer->know_packet_size) {
2016 packetizer->know_packet_size = FALSE;
2017 packetizer->packet_size = 0;
2018 if (packetizer->caps != NULL) {
2019 gst_caps_unref (packetizer->caps);
2020 packetizer->caps = NULL;
2023 if (packetizer->streams) {
2025 for (i = 0; i < 8192; i++) {
2026 if (packetizer->streams[i]) {
2027 mpegts_packetizer_stream_free (packetizer->streams[i]);
2028 packetizer->streams[i] = NULL;
2033 gst_adapter_clear (packetizer->adapter);
2037 mpegts_packetizer_remove_stream (MpegTSPacketizer * packetizer, gint16 pid)
2039 MpegTSPacketizerStream *stream = packetizer->streams[pid];
2041 GST_INFO ("Removing stream for PID %d", pid);
2042 mpegts_packetizer_stream_free (stream);
2043 packetizer->streams[pid] = NULL;
2048 mpegts_packetizer_new (void)
2050 MpegTSPacketizer *packetizer;
2053 GST_MPEGTS_PACKETIZER (g_object_new (GST_TYPE_MPEGTS_PACKETIZER, NULL));
2059 mpegts_packetizer_push (MpegTSPacketizer * packetizer, GstBuffer * buffer)
2061 gst_adapter_push (packetizer->adapter, buffer);
2065 mpegts_try_discover_packet_size (MpegTSPacketizer * packetizer)
2069 const guint psizes[] = { MPEGTS_NORMAL_PACKETSIZE,
2070 MPEGTS_M2TS_PACKETSIZE,
2071 MPEGTS_DVB_ASI_PACKETSIZE,
2072 MPEGTS_ATSC_PACKETSIZE
2074 /* wait for 3 sync bytes */
2075 /* so first return if there is not enough data for 4 * max packetsize */
2076 if (gst_adapter_available (packetizer->adapter) < MPEGTS_MAX_PACKETSIZE * 4)
2078 /* check for sync bytes */
2079 dest = g_malloc (MPEGTS_MAX_PACKETSIZE * 4);
2080 gst_adapter_copy (packetizer->adapter, dest, 0, MPEGTS_MAX_PACKETSIZE * 4);
2081 /* find first sync byte */
2083 for (i = 0; i < MPEGTS_MAX_PACKETSIZE; i++) {
2084 if (dest[i] == 0x47) {
2085 for (j = 0; j < 4; j++) {
2086 guint packetsize = psizes[j];
2087 /* check each of the packet size possibilities in turn */
2088 if (dest[i] == 0x47 && dest[i + packetsize] == 0x47 &&
2089 dest[i + packetsize * 2] == 0x47 &&
2090 dest[i + packetsize * 3] == 0x47) {
2091 packetizer->know_packet_size = TRUE;
2092 packetizer->packet_size = packetsize;
2093 packetizer->caps = gst_caps_new_simple ("video/mpegts",
2094 "systemstream", G_TYPE_BOOLEAN, TRUE,
2095 "packetsize", G_TYPE_INT, packetsize, NULL);
2103 GST_DEBUG ("have packetsize detected: %d of %u bytes",
2104 packetizer->know_packet_size, packetizer->packet_size);
2106 /* flush to sync byte */
2107 gst_adapter_flush (packetizer->adapter, pos);
2108 } else if (!packetizer->know_packet_size) {
2109 /* drop invalid data and move to the next possible packets */
2110 gst_adapter_flush (packetizer->adapter, MPEGTS_MAX_PACKETSIZE);
2117 mpegts_packetizer_has_packets (MpegTSPacketizer * packetizer)
2119 if (G_UNLIKELY (packetizer->know_packet_size == FALSE)) {
2120 mpegts_try_discover_packet_size (packetizer);
2121 if (!packetizer->know_packet_size)
2124 return gst_adapter_available (packetizer->adapter) >= packetizer->packet_size;
2127 MpegTSPacketizerPacketReturn
2128 mpegts_packetizer_next_packet (MpegTSPacketizer * packetizer,
2129 MpegTSPacketizerPacket * packet)
2134 packet->buffer = NULL;
2135 if (G_UNLIKELY (!packetizer->know_packet_size)) {
2136 mpegts_try_discover_packet_size (packetizer);
2137 if (!packetizer->know_packet_size)
2138 return PACKET_NEED_MORE;
2140 while ((avail = gst_adapter_available (packetizer->adapter)) >=
2141 packetizer->packet_size) {
2142 sync_byte = *gst_adapter_peek (packetizer->adapter, 1);
2143 if (G_UNLIKELY (sync_byte != 0x47)) {
2144 GST_DEBUG ("lost sync %02x", sync_byte);
2145 gst_adapter_flush (packetizer->adapter, 1);
2149 packet->buffer = gst_adapter_take_buffer (packetizer->adapter,
2150 packetizer->packet_size);
2151 packet->data_start = GST_BUFFER_DATA (packet->buffer);
2153 GST_BUFFER_DATA (packet->buffer) + GST_BUFFER_SIZE (packet->buffer);
2154 return mpegts_packetizer_parse_packet (packetizer, packet);
2157 return PACKET_NEED_MORE;
2161 mpegts_packetizer_clear_packet (MpegTSPacketizer * packetizer,
2162 MpegTSPacketizerPacket * packet)
2165 gst_buffer_unref (packet->buffer);
2166 memset (packet, 0, sizeof (MpegTSPacketizerPacket));
2170 mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
2171 MpegTSPacketizerPacket * packet, MpegTSPacketizerSection * section)
2173 gboolean res = FALSE;
2174 MpegTSPacketizerStream *stream;
2175 guint8 pointer, table_id;
2176 guint16 subtable_extension;
2177 guint section_length;
2181 data = packet->data;
2182 section->pid = packet->pid;
2184 if (packet->payload_unit_start_indicator == 1) {
2186 if (data + pointer > packet->data_end) {
2187 GST_WARNING ("PID %d PSI section pointer points past the end "
2188 "of the buffer", packet->pid);
2194 /* TDT and TOT sections (see ETSI EN 300 468 5.2.5)
2195 * these sections do not extend to several packets so we don't need to use the
2196 * sections filter. */
2197 if (packet->pid == 0x14) {
2199 section->section_length = GST_READ_UINT24_BE (data) & 0x000FFF;
2200 if (data - GST_BUFFER_DATA (packet->buffer) + section->section_length + 3 >
2201 GST_BUFFER_SIZE (packet->buffer)) {
2202 GST_WARNING ("PID %dd PSI section length extends past the end "
2203 "of the buffer", packet->pid);
2206 section->buffer = gst_buffer_create_sub (packet->buffer,
2207 data - GST_BUFFER_DATA (packet->buffer), section->section_length + 3);
2208 section->table_id = table_id;
2209 section->complete = TRUE;
2211 GST_DEBUG ("TDT section pid:%d table_id:%d section_length: %d\n",
2212 packet->pid, table_id, section->section_length);
2216 /* create a sub buffer from the start of the section (table_id and
2217 * section_length included) to the end */
2218 sub_buf = gst_buffer_create_sub (packet->buffer,
2219 data - GST_BUFFER_DATA (packet->buffer), packet->data_end - data);
2222 stream = packetizer->streams[packet->pid];
2223 if (stream == NULL) {
2224 stream = mpegts_packetizer_stream_new ();
2225 packetizer->streams[packet->pid] = stream;
2228 if (packet->payload_unit_start_indicator) {
2230 /* subtable_extension should be read from 4th and 5th bytes only if
2231 * section_syntax_indicator is 1 */
2232 if ((data[0] & 0x80) == 0)
2233 subtable_extension = 0;
2235 subtable_extension = GST_READ_UINT16_BE (data + 2);
2236 GST_DEBUG ("pid: %d table_id %d sub_table_extension %d",
2237 packet->pid, table_id, subtable_extension);
2239 section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
2241 if (stream->continuity_counter != CONTINUITY_UNSET) {
2243 ("PID %d table_id %d sub_table_extension %d payload_unit_start_indicator set but section "
2244 "not complete (last_continuity: %d continuity: %d sec len %d buffer %d avail %d",
2245 packet->pid, table_id, subtable_extension, stream->continuity_counter,
2246 packet->continuity_counter, section_length, GST_BUFFER_SIZE (sub_buf),
2247 gst_adapter_available (stream->section_adapter));
2248 mpegts_packetizer_clear_section (packetizer, stream);
2251 ("pusi set and new stream section is %d long and data we have is: %d",
2252 section_length, (gint) (packet->data_end - packet->data));
2254 stream->continuity_counter = packet->continuity_counter;
2255 stream->section_length = section_length;
2256 stream->section_table_id = table_id;
2257 gst_adapter_push (stream->section_adapter, sub_buf);
2260 } else if (stream->continuity_counter != CONTINUITY_UNSET &&
2261 (packet->continuity_counter == stream->continuity_counter + 1 ||
2262 (stream->continuity_counter == MAX_CONTINUITY &&
2263 packet->continuity_counter == 0))) {
2264 stream->continuity_counter = packet->continuity_counter;
2265 gst_adapter_push (stream->section_adapter, sub_buf);
2269 if (stream->continuity_counter == CONTINUITY_UNSET)
2270 GST_DEBUG ("PID %d waiting for pusi", packet->pid);
2272 GST_DEBUG ("PID %d section discontinuity "
2273 "(last_continuity: %d continuity: %d", packet->pid,
2274 stream->continuity_counter, packet->continuity_counter);
2275 mpegts_packetizer_clear_section (packetizer, stream);
2276 gst_buffer_unref (sub_buf);
2280 /* we pushed some data in the section adapter, see if the section is
2283 /* >= as sections can be padded and padding is not included in
2285 if (gst_adapter_available (stream->section_adapter) >=
2286 stream->section_length + 3) {
2287 res = mpegts_packetizer_parse_section_header (packetizer,
2290 /* flush stuffing bytes */
2291 mpegts_packetizer_clear_section (packetizer, stream);
2293 GST_DEBUG ("section not complete");
2294 /* section not complete yet */
2295 section->complete = FALSE;
2298 GST_WARNING ("section not complete");
2299 section->complete = FALSE;
2303 packet->data = data;
2304 GST_DEBUG ("result: %d complete: %d", res, section->complete);
2311 GST_DEBUG_CATEGORY_INIT (mpegts_packetizer_debug, "mpegtspacketizer", 0,
2312 "MPEG transport stream parser");
2314 QUARK_PAT = g_quark_from_string ("pat");
2315 QUARK_TRANSPORT_STREAM_ID = g_quark_from_string ("transport-stream-id");
2316 QUARK_PROGRAM_NUMBER = g_quark_from_string ("program-number");
2317 QUARK_PID = g_quark_from_string ("pid");
2318 QUARK_PROGRAMS = g_quark_from_string ("programs");
2320 QUARK_PMT = g_quark_from_string ("pmt");
2321 QUARK_PCR_PID = g_quark_from_string ("pcr-pid");
2322 QUARK_VERSION_NUMBER = g_quark_from_string ("version-number");
2323 QUARK_DESCRIPTORS = g_quark_from_string ("descriptors");
2324 QUARK_STREAM_TYPE = g_quark_from_string ("stream-type");
2325 QUARK_STREAMS = g_quark_from_string ("streams");
2327 QUARK_NIT = g_quark_from_string ("nit");
2328 QUARK_NETWORK_ID = g_quark_from_string ("network-id");
2329 QUARK_CURRENT_NEXT_INDICATOR = g_quark_from_string ("current-next-indicator");
2330 QUARK_ACTUAL_NETWORK = g_quark_from_string ("actual-network");
2331 QUARK_NETWORK_NAME = g_quark_from_string ("network-name");
2332 QUARK_ORIGINAL_NETWORK_ID = g_quark_from_string ("original-network-id");
2333 QUARK_TRANSPORTS = g_quark_from_string ("transports");
2335 QUARK_SDT = g_quark_from_string ("sdt");
2336 QUARK_ACTUAL_TRANSPORT_STREAM =
2337 g_quark_from_string ("actual-transport-stream");
2338 QUARK_SERVICES = g_quark_from_string ("services");
2340 QUARK_EIT = g_quark_from_string ("eit");
2341 QUARK_SERVICE_ID = g_quark_from_string ("service-id");
2342 QUARK_PRESENT_FOLLOWING = g_quark_from_string ("present-following");
2343 QUARK_SEGMENT_LAST_SECTION_NUMBER =
2344 g_quark_from_string ("segment-last-section-number");
2345 QUARK_LAST_TABLE_ID = g_quark_from_string ("last-table-id");
2346 QUARK_EVENTS = g_quark_from_string ("events");
2350 * @text: The text you want to get the encoding from
2351 * @start_text: Location where the beginning of the actual text is stored
2352 * @is_multibyte: Location where information whether it's a multibyte encoding
2354 * @returns: Name of encoding or NULL of encoding could not be detected.
2356 * The returned string should be freed with g_free () when no longer needed.
2359 get_encoding (const gchar * text, guint * start_text, gboolean * is_multibyte)
2364 g_return_val_if_fail (text != NULL, NULL);
2366 firstbyte = (guint8) text[0];
2368 /* ETSI EN 300 468, "Selection of character table" */
2369 if (firstbyte <= 0x0B) {
2370 encoding = g_strdup_printf ("iso8859-%u", firstbyte + 4);
2372 *is_multibyte = FALSE;
2373 } else if (firstbyte >= 0x20) {
2374 encoding = g_strdup ("iso6937");
2376 *is_multibyte = FALSE;
2377 } else if (firstbyte == 0x10) {
2382 table = GST_READ_UINT16_BE (text);
2383 g_snprintf (table_str, 6, "%d", table);
2385 encoding = g_strconcat ("iso8859-", table_str, NULL);
2387 *is_multibyte = FALSE;
2388 } else if (firstbyte == 0x11) {
2389 encoding = g_strdup ("ISO-10646/UCS2");
2391 *is_multibyte = TRUE;
2392 } else if (firstbyte == 0x12) {
2393 /* EUC-KR implements KSX1001 */
2394 encoding = g_strdup ("EUC-KR");
2396 *is_multibyte = TRUE;
2397 } else if (firstbyte == 0x13) {
2398 encoding = g_strdup ("GB2312");
2400 *is_multibyte = FALSE;
2401 } else if (firstbyte == 0x14) {
2402 encoding = g_strdup ("UTF-16BE");
2404 *is_multibyte = TRUE;
2405 } else if (firstbyte == 0x15) {
2406 encoding = g_strdup ("ISO-10646/UTF8");
2408 *is_multibyte = FALSE;
2413 *is_multibyte = FALSE;
2417 ("Found encoding %s, first byte is 0x%02x, start_text: %u, is_multibyte: %d",
2418 encoding, firstbyte, *start_text, *is_multibyte);
2424 * @text: The text to convert. It may include pango markup (<b> and </b>)
2425 * @length: The length of the string -1 if it's nul-terminated
2426 * @start: Where to start converting in the text
2427 * @encoding: The encoding of text
2428 * @is_multibyte: Whether the encoding is a multibyte encoding
2429 * @error: The location to store the error, or NULL to ignore errors
2430 * @returns: UTF-8 encoded string
2432 * Convert text to UTF-8.
2435 convert_to_utf8 (const gchar * text, gint length, guint start,
2436 const gchar * encoding, gboolean is_multibyte, GError ** error)
2442 g_return_val_if_fail (text != NULL, NULL);
2443 g_return_val_if_fail (encoding != NULL, NULL);
2447 sb = g_byte_array_sized_new (length * 1.1);
2451 while (*text != '\0') {
2452 guint16 code = GST_READ_UINT16_BE (text);
2455 case 0xE086: /* emphasis on */
2456 case 0xE087: /* emphasis off */
2460 guint8 nl[] = { 0x00, 0x0A }; /* new line */
2461 g_byte_array_append (sb, nl, 2);
2465 g_byte_array_append (sb, (guint8 *) text, 2);
2472 for (i = 0; i < length; i += 2) {
2473 guint16 code = GST_READ_UINT16_BE (text);
2476 case 0xE086: /* emphasis on */
2477 case 0xE087: /* emphasis off */
2481 guint8 nl[] = { 0x00, 0x0A }; /* new line */
2482 g_byte_array_append (sb, nl, 2);
2486 g_byte_array_append (sb, (guint8 *) text, 2);
2495 while (*text != '\0') {
2496 guint8 code = (guint8) (*text);
2499 case 0x86: /* emphasis on */
2500 case 0x87: /* emphasis off */
2504 g_byte_array_append (sb, (guint8 *) "\n", 1);
2507 g_byte_array_append (sb, &code, 1);
2514 for (i = 0; i < length; i++) {
2515 guint8 code = (guint8) (*text);
2518 case 0x86: /* emphasis on */
2519 case 0x87: /* emphasis off */
2523 g_byte_array_append (sb, (guint8 *) "\n", 1);
2526 g_byte_array_append (sb, &code, 1);
2537 g_convert ((gchar *) sb->data, sb->len, "utf-8", encoding, NULL, NULL,
2540 new_text = g_strdup ("");
2543 g_byte_array_free (sb, TRUE);
2549 get_encoding_and_convert (const gchar * text, guint length)
2551 GError *error = NULL;
2552 gchar *converted_str;
2554 guint start_text = 0;
2555 gboolean is_multibyte;
2557 g_return_val_if_fail (text != NULL, NULL);
2560 return g_strdup ("");
2562 encoding = get_encoding (text, &start_text, &is_multibyte);
2564 if (encoding == NULL) {
2565 GST_WARNING ("Could not detect encoding");
2566 converted_str = g_strndup (text, length);
2568 converted_str = convert_to_utf8 (text, length - start_text, start_text,
2569 encoding, is_multibyte, &error);
2570 if (error != NULL) {
2571 GST_WARNING ("Could not convert string, encoding is %s: %s",
2572 encoding, error->message);
2573 g_error_free (error);
2576 /* The first part of ISO 6937 is identical to ISO 8859-9, but
2577 * they differ in the second part. Some channels don't
2578 * provide the first byte that indicates ISO 8859-9 encoding.
2579 * If decoding from ISO 6937 failed, we try ISO 8859-9 here.
2581 if (strcmp (encoding, "iso6937") == 0) {
2582 GST_INFO ("Trying encoding ISO 8859-9");
2583 converted_str = convert_to_utf8 (text, length, 0,
2584 "iso8859-9", FALSE, &error);
2585 if (error != NULL) {
2587 ("Could not convert string while assuming encoding ISO 8859-9: %s",
2589 g_error_free (error);
2600 return converted_str;
2606 return g_strndup (text, length - start_text);