ed1d0ac0e67140b727b5e3c56c315a81f443fa02
[platform/upstream/gstreamer.git] / gst / mpegdemux / mpegtspacketizer.c
1 /*
2  * mpegtspacketizer.c - 
3  * Copyright (C) 2007, 2008 Alessandro Decina, Zaheer Merali
4  * 
5  * Authors:
6  *   Zaheer Merali <zaheerabbas at merali dot org>
7  *   Alessandro Decina <alessandro@nnva.org>
8  *
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.
13  *
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.
18  *
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.
23  */
24
25 #include <string.h>
26
27 #include "mpegtspacketizer.h"
28 #include "gstmpegdesc.h"
29
30 GST_DEBUG_CATEGORY_STATIC (mpegts_packetizer_debug);
31 #define GST_CAT_DEFAULT mpegts_packetizer_debug
32
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;
38
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;
45
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;
53
54 static GQuark QUARK_SDT;
55 static GQuark QUARK_ACTUAL_TRANSPORT_STREAM;
56 static GQuark QUARK_SERVICES;
57
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;
64
65 static void _init_local (void);
66 G_DEFINE_TYPE_EXTENDED (MpegTSPacketizer, mpegts_packetizer, G_TYPE_OBJECT, 0,
67     _init_local ());
68
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);
76
77 #define CONTINUITY_UNSET 255
78 #define MAX_CONTINUITY 15
79 #define VERSION_NUMBER_UNSET 255
80 #define TABLE_ID_UNSET 0xFF
81
82 static gint
83 mpegts_packetizer_stream_subtable_compare (gconstpointer a, gconstpointer b)
84 {
85   MpegTSPacketizerStreamSubtable *asub, *bsub;
86
87   asub = (MpegTSPacketizerStreamSubtable *) a;
88   bsub = (MpegTSPacketizerStreamSubtable *) b;
89
90   if (asub->table_id == bsub->table_id &&
91       asub->subtable_extension == bsub->subtable_extension)
92     return 0;
93   return -1;
94 }
95
96 static MpegTSPacketizerStreamSubtable *
97 mpegts_packetizer_stream_subtable_new (guint8 table_id,
98     guint16 subtable_extension)
99 {
100   MpegTSPacketizerStreamSubtable *subtable;
101
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;
106   subtable->crc = 0;
107   return subtable;
108 }
109
110 static MpegTSPacketizerStream *
111 mpegts_packetizer_stream_new (void)
112 {
113   MpegTSPacketizerStream *stream;
114
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;
120   return stream;
121 }
122
123 static void
124 mpegts_packetizer_stream_free (MpegTSPacketizerStream * stream)
125 {
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);
130   g_free (stream);
131 }
132
133 static void
134 mpegts_packetizer_clear_section (MpegTSPacketizer * packetizer,
135     MpegTSPacketizerStream * stream)
136 {
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;
141 }
142
143 static void
144 mpegts_packetizer_class_init (MpegTSPacketizerClass * klass)
145 {
146   GObjectClass *gobject_class;
147
148   gobject_class = G_OBJECT_CLASS (klass);
149
150   gobject_class->dispose = mpegts_packetizer_dispose;
151   gobject_class->finalize = mpegts_packetizer_finalize;
152 }
153
154 static void
155 mpegts_packetizer_init (MpegTSPacketizer * packetizer)
156 {
157   packetizer->adapter = gst_adapter_new ();
158   packetizer->streams = g_new0 (MpegTSPacketizerStream *, 8192);
159   packetizer->know_packet_size = FALSE;
160 }
161
162 static void
163 mpegts_packetizer_dispose (GObject * object)
164 {
165   MpegTSPacketizer *packetizer = GST_MPEGTS_PACKETIZER (object);
166
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;
172     }
173     if (packetizer->streams) {
174       int i;
175       for (i = 0; i < 8192; i++) {
176         if (packetizer->streams[i])
177           mpegts_packetizer_stream_free (packetizer->streams[i]);
178       }
179       g_free (packetizer->streams);
180     }
181
182     gst_adapter_clear (packetizer->adapter);
183     g_object_unref (packetizer->adapter);
184     packetizer->disposed = TRUE;
185   }
186
187   if (G_OBJECT_CLASS (mpegts_packetizer_parent_class)->dispose)
188     G_OBJECT_CLASS (mpegts_packetizer_parent_class)->dispose (object);
189 }
190
191 static void
192 mpegts_packetizer_finalize (GObject * object)
193 {
194   if (G_OBJECT_CLASS (mpegts_packetizer_parent_class)->finalize)
195     G_OBJECT_CLASS (mpegts_packetizer_parent_class)->finalize (object);
196 }
197
198 static gboolean
199 mpegts_packetizer_parse_adaptation_field_control (MpegTSPacketizer * packetizer,
200     MpegTSPacketizerPacket * packet)
201 {
202   guint8 length;
203
204   length = *packet->data;
205   packet->data += 1;
206
207   if (packet->adaptation_field_control == 0x02) {
208     /* no payload, adaptation field of 183 bytes */
209     if (length != 183) {
210       GST_DEBUG ("PID %d afc == 0x%x and length %d != 183",
211           packet->pid, packet->adaptation_field_control, length);
212     }
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);
216   }
217
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));
223     return FALSE;
224   }
225
226   packet->data += length;
227
228   return TRUE;
229 }
230
231 static gboolean
232 mpegts_packetizer_parse_packet (MpegTSPacketizer * packetizer,
233     MpegTSPacketizerPacket * packet)
234 {
235   guint8 *data;
236
237   data = GST_BUFFER_DATA (packet->buffer);
238   /* skip sync_byte */
239   data++;
240
241   packet->payload_unit_start_indicator = (*data >> 6) & 0x01;
242   packet->pid = GST_READ_UINT16_BE (data) & 0x1FFF;
243   data += 2;
244
245   packet->adaptation_field_control = (*data >> 4) & 0x03;
246   packet->continuity_counter = *data & 0x0F;
247   data += 1;
248
249   packet->data = data;
250
251   if (packet->adaptation_field_control & 0x02)
252     if (!mpegts_packetizer_parse_adaptation_field_control (packetizer, packet))
253       return FALSE;
254
255   if (packet->adaptation_field_control & 0x01)
256     packet->payload = packet->data;
257   else
258     packet->payload = NULL;
259
260   return TRUE;
261 }
262
263 static gboolean
264 mpegts_packetizer_parse_section_header (MpegTSPacketizer * packetizer,
265     MpegTSPacketizerStream * stream, MpegTSPacketizerSection * section)
266 {
267   guint8 tmp;
268   guint8 *data, *crc_data;
269   MpegTSPacketizerStreamSubtable *subtable;
270   GSList *subtable_list = NULL;
271
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);
277
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;
282   else
283     section->subtable_extension = GST_READ_UINT16_BE (data + 2);
284
285   subtable = mpegts_packetizer_stream_subtable_new (section->table_id,
286       section->subtable_extension);
287
288   subtable_list = g_slist_find_custom (stream->subtables, subtable,
289       mpegts_packetizer_stream_subtable_compare);
290   if (subtable_list) {
291     g_free (subtable);
292     subtable = (MpegTSPacketizerStreamSubtable *) (subtable_list->data);
293   } else {
294     stream->subtables = g_slist_prepend (stream->subtables, subtable);
295   }
296
297   section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
298   data += 2;
299
300   /* skip to the version byte */
301   data += 2;
302
303   tmp = *data++;
304   section->version_number = (tmp >> 1) & 0x1F;
305   section->current_next_indicator = tmp & 0x01;
306
307   if (!section->current_next_indicator)
308     goto not_applicable;
309
310   /* CRC is at the end of the section */
311   crc_data =
312       GST_BUFFER_DATA (section->buffer) + GST_BUFFER_SIZE (section->buffer) - 4;
313   section->crc = GST_READ_UINT32_BE (crc_data);
314
315   if (section->version_number == subtable->version_number &&
316       section->crc == subtable->crc)
317     goto not_applicable;
318
319   subtable->version_number = section->version_number;
320   subtable->crc = section->crc;
321   stream->section_table_id = section->table_id;
322
323   return TRUE;
324
325 not_applicable:
326   GST_LOG
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);
332   return TRUE;
333 }
334
335 static gboolean
336 mpegts_packetizer_parse_descriptors (MpegTSPacketizer * packetizer,
337     guint8 ** buffer, guint8 * buffer_end, GValueArray * descriptors)
338 {
339   guint8 length;
340   guint8 *data;
341   GValue value = { 0 };
342   GString *desc;
343
344   data = *buffer;
345
346   while (data < buffer_end) {
347     data++;                     /* skip tag */
348     length = *data++;
349
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));
353       goto error;
354     }
355
356     /* include length */
357     desc = g_string_new_len ((gchar *) data - 2, length + 2);
358     data += length;
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);
365   }
366
367   if (data != buffer_end) {
368     GST_WARNING ("descriptors size %d expected %d", (gint) (data - *buffer),
369         (gint) (buffer_end - *buffer));
370     goto error;
371   }
372
373   *buffer = data;
374
375   return TRUE;
376 error:
377   return FALSE;
378 }
379
380 GstStructure *
381 mpegts_packetizer_parse_pat (MpegTSPacketizer * packetizer,
382     MpegTSPacketizerSection * section)
383 {
384   GstStructure *pat_info = NULL;
385   guint8 *data, *end;
386   guint transport_stream_id;
387   guint8 tmp;
388   guint program_number;
389   guint pmt_pid;
390   GValue entries = { 0 };
391   GValue value = { 0 };
392   GstStructure *entry = NULL;
393   gchar *struct_name;
394
395   data = GST_BUFFER_DATA (section->buffer);
396
397   section->table_id = *data++;
398   section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
399   data += 2;
400
401   transport_stream_id = GST_READ_UINT16_BE (data);
402   data += 2;
403
404   tmp = *data++;
405   section->version_number = (tmp >> 1) & 0x1F;
406   section->current_next_indicator = tmp & 0x01;
407
408   /* skip section_number and last_section_number */
409   data += 2;
410
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);
418     data += 2;
419
420     pmt_pid = GST_READ_UINT16_BE (data) & 0x1FFF;
421     data += 2;
422
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);
428
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);
433   }
434
435   gst_structure_id_set_value (pat_info, QUARK_PROGRAMS, &entries);
436   g_value_unset (&entries);
437
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);
442
443     return NULL;
444   }
445
446   return pat_info;
447 }
448
449 GstStructure *
450 mpegts_packetizer_parse_pmt (MpegTSPacketizer * packetizer,
451     MpegTSPacketizerSection * section)
452 {
453   GstStructure *pmt = NULL;
454   guint8 *data, *end;
455   guint16 program_number;
456   guint8 tmp;
457   guint pcr_pid;
458   guint program_info_length;
459   guint8 stream_type;
460   guint16 pid;
461   guint stream_info_length;
462   GValueArray *descriptors;
463   GValue stream_value = { 0 };
464   GValue programs = { 0 };
465   GstStructure *stream_info = NULL;
466   gchar *struct_name;
467
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);
472     goto error;
473   }
474
475   data = GST_BUFFER_DATA (section->buffer);
476   end = data + GST_BUFFER_SIZE (section->buffer);
477
478   section->table_id = *data++;
479   section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
480   data += 2;
481
482   program_number = GST_READ_UINT16_BE (data);
483   data += 2;
484
485   tmp = *data++;
486   section->version_number = (tmp >> 1) & 0x1F;
487   section->current_next_indicator = tmp & 0x01;
488
489   /* skip section_number and last_section_number */
490   data += 2;
491
492   pcr_pid = GST_READ_UINT16_BE (data) & 0x1FFF;
493   data += 2;
494
495   program_info_length = GST_READ_UINT16_BE (data) & 0x0FFF;
496   data += 2;
497
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);
502
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));
509       goto error;
510     }
511
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);
516       goto error;
517     }
518
519     gst_structure_id_set (pmt, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
520         descriptors, NULL);
521     g_value_array_free (descriptors);
522   }
523
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++;
529
530     pid = GST_READ_UINT16_BE (data) & 0x1FFF;
531     data += 2;
532
533     stream_info_length = GST_READ_UINT16_BE (data) & 0x0FFF;
534     data += 2;
535
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);
540       goto error;
541     }
542
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,
548         stream_type, NULL);
549
550     if (stream_info_length) {
551       /* check for AC3 descriptor */
552       GstMPEGDescriptor *desc =
553           gst_mpeg_descriptor_parse (data, stream_info_length);
554       if (desc != NULL) {
555         guint8 *desc_data;
556         if (gst_mpeg_descriptor_find (desc, DESC_DVB_AC3)) {
557           gst_structure_set (stream_info, "has-ac3", G_TYPE_BOOLEAN, TRUE,
558               NULL);
559         }
560         desc_data = gst_mpeg_descriptor_find (desc, DESC_DVB_DATA_BROADCAST_ID);
561         if (desc_data) {
562           guint16 data_broadcast_id;
563           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);
567         }
568         desc_data = gst_mpeg_descriptor_find (desc, DESC_DVB_DATA_BROADCAST);
569         if (desc_data) {
570           GstStructure *databroadcast_info;
571           guint16 data_broadcast_id;
572           guint8 component_tag;
573           data_broadcast_id =
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,
578               NULL);
579           gst_structure_set (stream_info, "data-broadcast", GST_TYPE_STRUCTURE,
580               databroadcast_info, NULL);
581         }
582         desc_data =
583             gst_mpeg_descriptor_find (desc, DESC_DVB_CAROUSEL_IDENTIFIER);
584         if (desc_data) {
585           guint32 carousel_id;
586           carousel_id = DESC_DVB_CAROUSEL_IDENTIFIER_carousel_id (desc_data);
587           gst_structure_set (stream_info, "carousel-id", G_TYPE_UINT,
588               carousel_id, NULL);
589         }
590         desc_data = gst_mpeg_descriptor_find (desc, DESC_DVB_STREAM_IDENTIFIER);
591         if (desc_data) {
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);
596         }
597         desc_data = gst_mpeg_descriptor_find (desc, DESC_ISO_639_LANGUAGE);
598         if (desc_data && DESC_ISO_639_LANGUAGE_codes_n (desc_data)) {
599           gchar *lang_code;
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,
604               lang_code, NULL);
605           g_free (lang_code);
606         }
607
608         gst_mpeg_descriptor_free (desc);
609       }
610
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);
617         goto error;
618       }
619
620       gst_structure_id_set (stream_info,
621           QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY, descriptors, NULL);
622       g_value_array_free (descriptors);
623
624     }
625
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);
630   }
631
632   gst_structure_id_set_value (pmt, QUARK_STREAMS, &programs);
633   g_value_unset (&programs);
634
635   g_assert (data == end - 4);
636
637   return pmt;
638
639 error:
640   if (pmt)
641     gst_structure_free (pmt);
642
643   return NULL;
644 }
645
646 GstStructure *
647 mpegts_packetizer_parse_nit (MpegTSPacketizer * packetizer,
648     MpegTSPacketizerSection * section)
649 {
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;
653   guint tmp;
654   guint16 descriptors_loop_length, transport_stream_loop_length;
655   GValue transports = { 0 };
656   GValue transport_value = { 0 };
657   GValueArray *descriptors = NULL;
658
659   GST_DEBUG ("NIT");
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);
664     goto error;
665   }
666
667   data = GST_BUFFER_DATA (section->buffer);
668   end = data + GST_BUFFER_SIZE (section->buffer);
669
670   section->table_id = *data++;
671   section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
672   data += 2;
673
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));
677     goto error;
678   }
679
680   network_id = GST_READ_UINT16_BE (data);
681   data += 2;
682
683   tmp = *data++;
684   section->version_number = (tmp >> 1) & 0x1F;
685   section->current_next_indicator = tmp & 0x01;
686
687   /* skip section_number and last_section_number */
688   data += 2;
689
690   descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
691   data += 2;
692
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);
699
700   /* see if the buffer is large enough */
701   if (descriptors_loop_length) {
702     guint8 *networkname_descriptor;
703     GstMPEGDescriptor *mpegdescriptor;
704
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);
709       goto error;
710     }
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;
716
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);
720       gchar *networkname =
721           (gchar *) DESC_DVB_NETWORK_NAME_text (networkname_descriptor);
722
723       networkname_tmp =
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);
728     }
729     gst_mpeg_descriptor_free (mpegdescriptor);
730
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);
736       goto error;
737     }
738
739     gst_structure_id_set (nit, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
740         descriptors, NULL);
741     g_value_array_free (descriptors);
742   }
743
744   transport_stream_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
745   data += 2;
746
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;
751
752     entry_begin = data;
753
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);
758       goto error;
759     }
760
761     transport_stream_id = GST_READ_UINT16_BE (data);
762     data += 2;
763
764     original_network_id = GST_READ_UINT16_BE (data);
765     data += 2;
766
767     descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
768     data += 2;
769
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);
776
777     if (descriptors_loop_length) {
778       GstMPEGDescriptor *mpegdescriptor;
779       guint8 *delivery;
780
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);
785         goto error;
786       }
787       mpegdescriptor =
788           gst_mpeg_descriptor_parse (data, descriptors_loop_length);
789
790       if ((delivery =
791               gst_mpeg_descriptor_find (mpegdescriptor,
792                   DESC_DVB_SATELLITE_DELIVERY_SYSTEM))) {
793
794         guint8 *frequency_bcd =
795             DESC_DVB_SATELLITE_DELIVERY_SYSTEM_frequency (delivery);
796         guint32 frequency =
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);
807         gfloat orbital =
808             (orbital_bcd[1] & 0x0F) / 10. + ((orbital_bcd[1] & 0xF0) >> 4) +
809             10 * (orbital_bcd[0] & 0x0F) + 100 * ((orbital_bcd[0] & 0xF0) >> 4);
810         gboolean east =
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;
815         guint8 modulation =
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);
827         guint8 fec_inner =
828             DESC_DVB_SATELLITE_DELIVERY_SYSTEM_fec_inner (delivery);
829         const gchar *fec_inner_str;
830
831         switch (polarization) {
832           case 0:
833             polarization_str = "horizontal";
834             break;
835           case 1:
836             polarization_str = "vertical";
837             break;
838           case 2:
839             polarization_str = "left";
840             break;
841           case 3:
842             polarization_str = "right";
843             break;
844           default:
845             polarization_str = "";
846         }
847         switch (fec_inner) {
848           case 0:
849             fec_inner_str = "undefined";
850             break;
851           case 1:
852             fec_inner_str = "1/2";
853             break;
854           case 2:
855             fec_inner_str = "2/3";
856             break;
857           case 3:
858             fec_inner_str = "3/4";
859             break;
860           case 4:
861             fec_inner_str = "5/6";
862             break;
863           case 5:
864             fec_inner_str = "7/8";
865             break;
866           case 6:
867             fec_inner_str = "8/9";
868             break;
869           case 0xF:
870             fec_inner_str = "none";
871             break;
872           default:
873             fec_inner_str = "reserved";
874         }
875         switch (modulation) {
876           case 0x00:
877             modulation_str = "undefined";
878             break;
879           case 0x01:
880             modulation_str = "QAM16";
881             break;
882           case 0x02:
883             modulation_str = "QAM32";
884             break;
885           case 0x03:
886             modulation_str = "QAM64";
887             break;
888           case 0x04:
889             modulation_str = "QAM128";
890             break;
891           case 0x05:
892             modulation_str = "QAM256";
893             break;
894           default:
895             modulation_str = "reserved";
896         }
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))) {
910
911         guint32 frequency =
912             DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_frequency (delivery) * 10;
913         guint8 bandwidth =
914             DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_bandwidth (delivery);
915         guint8 constellation =
916             DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM_constellation (delivery);
917         guint8 hierarchy =
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;
931         /* do the stuff */
932         /* bandwidth is 8 if 0, 7 if 1, 6 if 2, reserved otherwise */
933         if (bandwidth <= 2)
934           bandwidth = 8 - bandwidth;
935         else
936           bandwidth = 0;
937         switch (constellation) {
938           case 0:
939             constellation_str = "QPSK";
940             break;
941           case 1:
942             constellation_str = "QAM16";
943             break;
944           case 2:
945             constellation_str = "QAM64";
946             break;
947           default:
948             constellation_str = "reserved";
949         }
950         /* hierarchy is 4 if 3, 2 if 2, 1 if 1, 0 if 0, reserved if > 3 */
951         if (hierarchy <= 3) {
952           if (hierarchy == 3)
953             hierarchy = 4;
954         } else {
955           hierarchy = 0;
956         }
957
958         switch (code_rate_hp) {
959           case 0:
960             code_rate_hp_str = "1/2";
961             break;
962           case 1:
963             code_rate_hp_str = "2/3";
964             break;
965           case 2:
966             code_rate_hp_str = "3/4";
967             break;
968           case 3:
969             code_rate_hp_str = "5/6";
970             break;
971           case 4:
972             code_rate_hp_str = "7/8";
973             break;
974           default:
975             code_rate_hp_str = "reserved";
976         }
977
978         switch (code_rate_lp) {
979           case 0:
980             code_rate_lp_str = "1/2";
981             break;
982           case 1:
983             code_rate_lp_str = "2/3";
984             break;
985           case 2:
986             code_rate_lp_str = "3/4";
987             break;
988           case 3:
989             code_rate_lp_str = "5/6";
990             break;
991           case 4:
992             code_rate_lp_str = "7/8";
993             break;
994           default:
995             code_rate_lp_str = "reserved";
996         }
997         /* guard is 32 if 0, 16 if 1, 8 if 2, 4 if 3 */
998         switch (guard_interval) {
999           case 0:
1000             guard_interval = 32;
1001             break;
1002           case 1:
1003             guard_interval = 16;
1004             break;
1005           case 2:
1006             guard_interval = 8;
1007             break;
1008           case 3:
1009             guard_interval = 4;
1010             break;
1011           default:             /* make it default to 32 */
1012             guard_interval = 32;
1013         }
1014         switch (transmission_mode) {
1015           case 0:
1016             transmission_mode_str = "2k";
1017             break;
1018           case 1:
1019             transmission_mode_str = "8k";
1020             break;
1021           default:
1022             transmission_mode_str = "reserved";
1023         }
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))) {
1039
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
1044          * into Hz */
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));
1054         guint8 modulation =
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;
1068
1069         switch (fec_inner) {
1070           case 0:
1071             fec_inner_str = "undefined";
1072             break;
1073           case 1:
1074             fec_inner_str = "1/2";
1075             break;
1076           case 2:
1077             fec_inner_str = "2/3";
1078             break;
1079           case 3:
1080             fec_inner_str = "3/4";
1081             break;
1082           case 4:
1083             fec_inner_str = "5/6";
1084             break;
1085           case 5:
1086             fec_inner_str = "7/8";
1087             break;
1088           case 6:
1089             fec_inner_str = "8/9";
1090             break;
1091           case 0xF:
1092             fec_inner_str = "none";
1093             break;
1094           default:
1095             fec_inner_str = "reserved";
1096         }
1097         switch (modulation) {
1098           case 0x00:
1099             modulation_str = "undefined";
1100             break;
1101           case 0x01:
1102             modulation_str = "QAM16";
1103             break;
1104           case 0x02:
1105             modulation_str = "QAM32";
1106             break;
1107           case 0x03:
1108             modulation_str = "QAM64";
1109             break;
1110           case 0x04:
1111             modulation_str = "QAM128";
1112             break;
1113           case 0x05:
1114             modulation_str = "QAM256";
1115             break;
1116           default:
1117             modulation_str = "reserved";
1118         }
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);
1126       }
1127       /* free the temporary delivery structure */
1128       if (delivery_structure != NULL) {
1129         gst_structure_free (delivery_structure);
1130         delivery_structure = NULL;
1131       }
1132       if ((delivery =
1133               gst_mpeg_descriptor_find (mpegdescriptor,
1134                   DESC_DTG_LOGICAL_CHANNEL))) {
1135         guint8 *current_pos = delivery + 2;
1136         GValue channel_numbers = { 0 };
1137
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;
1144
1145           current_pos += 2;
1146           logical_channel_number = GST_READ_UINT16_BE (current_pos) & 0x03ff;
1147           channel =
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);
1155           current_pos += 2;
1156         }
1157         gst_structure_set_value (transport, "channels", &channel_numbers);
1158         g_value_unset (&channel_numbers);
1159       }
1160       if ((delivery =
1161               gst_mpeg_descriptor_find (mpegdescriptor,
1162                   DESC_DVB_FREQUENCY_LIST))) {
1163         guint8 *current_pos = delivery + 2;
1164         GValue frequencies = { 0 };
1165         guint8 type;
1166
1167         type = *current_pos & 0x03;
1168         current_pos++;
1169
1170         if (type) {
1171           const gchar *fieldname = NULL;
1172           g_value_init (&frequencies, GST_TYPE_LIST);
1173
1174           while (current_pos < delivery + DESC_LENGTH (delivery) - 3) {
1175             guint32 freq = 0;
1176             guint8 *frequency_bcd = current_pos;
1177             GValue frequency = { 0 };
1178
1179             switch (type) {
1180               case 0x01:
1181                 /* satellite */
1182                 freq =
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));
1191                 break;
1192               case 0x02:
1193                 /* cable */
1194                 freq = 100 *
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));
1203                 break;
1204               case 0x03:
1205                 /* terrestrial */
1206                 freq = GST_READ_UINT32_BE (current_pos) * 10;
1207                 break;
1208             }
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);
1213             current_pos += 4;
1214           }
1215
1216           switch (type) {
1217             case 0x01:
1218               fieldname = "frequency-list-satellite";
1219               break;
1220             case 0x02:
1221               fieldname = "frequency-list-cable";
1222               break;
1223             case 0x03:
1224               fieldname = "frequency-list-terrestrial";
1225               break;
1226           }
1227
1228           gst_structure_set_value (transport, fieldname, &frequencies);
1229           g_value_unset (&frequencies);
1230         }
1231       }
1232       gst_mpeg_descriptor_free (mpegdescriptor);
1233
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);
1239         goto error;
1240       }
1241
1242       gst_structure_id_set (transport, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
1243           descriptors, NULL);
1244       g_value_array_free (descriptors);
1245     }
1246
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);
1251
1252     transport_stream_loop_length -= data - entry_begin;
1253   }
1254
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));
1259     goto error;
1260   }
1261
1262   gst_structure_id_set_value (nit, QUARK_TRANSPORTS, &transports);
1263   g_value_unset (&transports);
1264
1265   GST_DEBUG ("NIT %" GST_PTR_FORMAT, nit);
1266
1267   return nit;
1268
1269 error:
1270   if (nit)
1271     gst_structure_free (nit);
1272
1273   if (GST_VALUE_HOLDS_LIST (&transports))
1274     g_value_unset (&transports);
1275
1276   return NULL;
1277 }
1278
1279 GstStructure *
1280 mpegts_packetizer_parse_sdt (MpegTSPacketizer * packetizer,
1281     MpegTSPacketizerSection * section)
1282 {
1283   GstStructure *sdt = NULL, *service = NULL;
1284   guint8 *data, *end, *entry_begin;
1285   guint16 transport_stream_id, original_network_id, service_id;
1286   guint tmp;
1287   guint sdt_info_length;
1288   guint8 running_status;
1289   gboolean scrambled;
1290   guint descriptors_loop_length;
1291   GValue services = { 0 };
1292   GValueArray *descriptors = NULL;
1293   GValue service_value = { 0 };
1294
1295   GST_DEBUG ("SDT");
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);
1300     goto error;
1301   }
1302
1303   data = GST_BUFFER_DATA (section->buffer);
1304   end = data + GST_BUFFER_SIZE (section->buffer);
1305
1306   section->table_id = *data++;
1307   section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1308   data += 2;
1309
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));
1313     goto error;
1314   }
1315
1316   transport_stream_id = GST_READ_UINT16_BE (data);
1317   data += 2;
1318
1319   tmp = *data++;
1320   section->version_number = (tmp >> 1) & 0x1F;
1321   section->current_next_indicator = tmp & 0x01;
1322
1323   /* skip section_number and last_section_number */
1324   data += 2;
1325
1326   original_network_id = GST_READ_UINT16_BE (data);
1327   data += 2;
1328
1329   /* skip reserved byte */
1330   data += 1;
1331
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);
1339
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;
1345
1346     entry_begin = data;
1347
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);
1352       goto error;
1353     }
1354
1355     service_id = GST_READ_UINT16_BE (data);
1356     data += 2;
1357
1358     /* EIT_schedule = ((*data & 0x02) == 2); */
1359     /* EIT_present_following = (*data & 0x01) == 1; */
1360
1361     data += 1;
1362     tmp = GST_READ_UINT16_BE (data);
1363
1364     running_status = (*data >> 5) & 0x07;
1365     scrambled = (*data >> 4) & 0x01;
1366     descriptors_loop_length = tmp & 0x0FFF;
1367     data += 2;
1368
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);
1373
1374     if (descriptors_loop_length) {
1375       guint8 *service_descriptor;
1376       GstMPEGDescriptor *mpegdescriptor;
1377
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);
1382         goto error;
1383       }
1384       mpegdescriptor =
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) {
1402             case 0:
1403               running_status_tmp = "undefined";
1404               break;
1405             case 1:
1406               running_status_tmp = "not running";
1407               break;
1408             case 2:
1409               running_status_tmp = "starts in a few seconds";
1410               break;
1411             case 3:
1412               running_status_tmp = "pausing";
1413               break;
1414             case 4:
1415               running_status_tmp = "running";
1416               break;
1417             default:
1418               running_status_tmp = "reserved";
1419           }
1420           servicename_tmp =
1421               get_encoding_and_convert (servicename, servicename_length);
1422           serviceprovider_name_tmp =
1423               get_encoding_and_convert (serviceprovider_name,
1424               serviceprovider_name_length);
1425
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);
1431
1432           g_free (servicename_tmp);
1433           g_free (serviceprovider_name_tmp);
1434         }
1435       }
1436       gst_mpeg_descriptor_free (mpegdescriptor);
1437
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);
1443         goto error;
1444       }
1445
1446       gst_structure_id_set (service, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
1447           descriptors, NULL);
1448
1449       g_value_array_free (descriptors);
1450     }
1451
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);
1456
1457     sdt_info_length -= data - entry_begin;
1458   }
1459
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));
1464     goto error;
1465   }
1466
1467   gst_structure_id_set_value (sdt, QUARK_SERVICES, &services);
1468   g_value_unset (&services);
1469
1470   return sdt;
1471
1472 error:
1473   if (sdt)
1474     gst_structure_free (sdt);
1475
1476   if (GST_VALUE_HOLDS_LIST (&services))
1477     g_value_unset (&services);
1478
1479   return NULL;
1480 }
1481
1482 GstStructure *
1483 mpegts_packetizer_parse_eit (MpegTSPacketizer * packetizer,
1484     MpegTSPacketizerSection * section)
1485 {
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;
1491   guint16 mjd;
1492   guint year, month, day, hour, minute, second;
1493   guint duration;
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;
1499   gchar *event_name;
1500   guint tmp;
1501
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);
1506     goto error;
1507   }
1508
1509   data = GST_BUFFER_DATA (section->buffer);
1510   end = data + GST_BUFFER_SIZE (section->buffer);
1511
1512   section->table_id = *data++;
1513   section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1514   data += 2;
1515
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));
1519     goto error;
1520   }
1521
1522   service_id = GST_READ_UINT16_BE (data);
1523   data += 2;
1524
1525   tmp = *data++;
1526   section->version_number = (tmp >> 1) & 0x1F;
1527   section->current_next_indicator = tmp & 0x01;
1528
1529   /* skip section_number and last_section_number */
1530   data += 2;
1531
1532   transport_stream_id = GST_READ_UINT16_BE (data);
1533   data += 2;
1534   original_network_id = GST_READ_UINT16_BE (data);
1535   data += 2;
1536   segment_last_section_number = *data;
1537   data += 1;
1538   last_table_id = *data;
1539   data += 1;
1540
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);
1554
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);
1562       goto error;
1563     }
1564
1565     event_id = GST_READ_UINT16_BE (data);
1566     data += 2;
1567     /* start_and_duration = GST_READ_UINT64_BE (data); */
1568     duration_ptr = data + 5;
1569     utc_ptr = data + 2;
1570     mjd = GST_READ_UINT16_BE (data);
1571     if (mjd == G_MAXUINT16) {
1572       year = 1900;
1573       month = day = hour = minute = second = 0;
1574     } else {
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) {
1580         year++;
1581         month = month - 1 - 12;
1582       } else {
1583         month--;
1584       }
1585       year += 1900;
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);
1589     }
1590
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);
1596
1597     data += 8;
1598     running_status = *data >> 5;
1599     free_ca_mode = (*data >> 4) & 0x01;
1600     descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1601     data += 2;
1602
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);
1617
1618     if (descriptors_loop_length) {
1619       guint8 *event_descriptor;
1620       GArray *component_descriptors;
1621       GArray *extended_event_descriptors;
1622       GstMPEGDescriptor *mpegdescriptor;
1623
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);
1628         goto error;
1629       }
1630       mpegdescriptor =
1631           gst_mpeg_descriptor_parse (data, descriptors_loop_length);
1632       event_descriptor =
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);
1638         gchar *eventname =
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)) {
1646
1647           eventname_tmp =
1648               get_encoding_and_convert (eventname, eventname_length);
1649           eventdescription_tmp =
1650               get_encoding_and_convert (eventdescription,
1651               eventdescription_length);
1652
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);
1658         }
1659       }
1660       extended_event_descriptors = gst_mpeg_descriptor_find_all (mpegdescriptor,
1661           DESC_DVB_EXTENDED_EVENT);
1662       if (extended_event_descriptors) {
1663         int i;
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,
1670               guint8 *, i);
1671           if (DESC_DVB_EXTENDED_EVENT_descriptor_number (extended_descriptor) ==
1672               i) {
1673             if (extended_text) {
1674               gchar *tmp;
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);
1681               g_free (tmp);
1682             } else {
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));
1686             }
1687           }
1688         }
1689         if (extended_text) {
1690           gst_structure_set (event, "extended-text", G_TYPE_STRING,
1691               extended_text, NULL);
1692           g_free (extended_text);
1693         }
1694         g_array_free (extended_event_descriptors, TRUE);
1695       }
1696
1697       component_descriptors = gst_mpeg_descriptor_find_all (mpegdescriptor,
1698           DESC_DVB_COMPONENT);
1699       if (component_descriptors) {
1700         int i;
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 = "";
1714
1715           comp_descriptor = g_array_index (component_descriptors, guint8 *, i);
1716           switch (DESC_DVB_COMPONENT_stream_content (comp_descriptor)) {
1717             case 0x01:
1718               /* video */
1719               switch (DESC_DVB_COMPONENT_type (comp_descriptor)) {
1720                 case 0x01:
1721                   widescreen = 0;
1722                   freq = 25;
1723                   break;
1724                 case 0x02:
1725                   widescreen = 1;
1726                   panvectors = TRUE;
1727                   freq = 25;
1728                   break;
1729                 case 0x03:
1730                   widescreen = 1;
1731                   panvectors = FALSE;
1732                   freq = 25;
1733                   break;
1734                 case 0x04:
1735                   widescreen = 2;
1736                   freq = 25;
1737                   break;
1738                 case 0x05:
1739                   widescreen = 0;
1740                   freq = 30;
1741                   break;
1742                 case 0x06:
1743                   widescreen = 1;
1744                   panvectors = TRUE;
1745                   freq = 30;
1746                   break;
1747                 case 0x07:
1748                   widescreen = 1;
1749                   panvectors = FALSE;
1750                   freq = 30;
1751                   break;
1752                 case 0x08:
1753                   widescreen = 2;
1754                   freq = 30;
1755                   break;
1756                 case 0x09:
1757                   widescreen = 0;
1758                   /* highdef = TRUE; */
1759                   freq = 25;
1760                   break;
1761                 case 0x0A:
1762                   widescreen = 1;
1763                   /* highdef = TRUE; */
1764                   panvectors = TRUE;
1765                   freq = 25;
1766                   break;
1767                 case 0x0B:
1768                   widescreen = 1;
1769                   /* highdef = TRUE; */
1770                   panvectors = FALSE;
1771                   freq = 25;
1772                   break;
1773                 case 0x0C:
1774                   widescreen = 2;
1775                   /* highdef = TRUE; */
1776                   freq = 25;
1777                   break;
1778                 case 0x0D:
1779                   widescreen = 0;
1780                   /* highdef = TRUE; */
1781                   freq = 30;
1782                   break;
1783                 case 0x0E:
1784                   widescreen = 1;
1785                   /* highdef = TRUE; */
1786                   panvectors = TRUE;
1787                   freq = 30;
1788                   break;
1789                 case 0x0F:
1790                   widescreen = 1;
1791                   /* highdef = TRUE; */
1792                   panvectors = FALSE;
1793                   freq = 30;
1794                   break;
1795                 case 0x10:
1796                   widescreen = 2;
1797                   /* highdef = TRUE; */
1798                   freq = 30;
1799                   break;
1800               }
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),
1804                   NULL);
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,
1810                     "> 16:9", NULL);
1811               } else {
1812                 gst_structure_set (component, "aspect-ratio", G_TYPE_STRING,
1813                     "16:9", "pan-vectors", G_TYPE_BOOLEAN, panvectors, NULL);
1814               }
1815               break;
1816             case 0x02:         /* audio */
1817               comptype = "undefined";
1818               switch (DESC_DVB_COMPONENT_type (comp_descriptor)) {
1819                 case 0x01:
1820                   comptype = "single channel mono";
1821                   break;
1822                 case 0x02:
1823                   comptype = "dual channel mono";
1824                   break;
1825                 case 0x03:
1826                   comptype = "stereo";
1827                   break;
1828                 case 0x04:
1829                   comptype = "multi-channel multi-lingual";
1830                   break;
1831                 case 0x05:
1832                   comptype = "surround";
1833                   break;
1834                 case 0x40:
1835                   comptype = "audio description for the visually impaired";
1836                   break;
1837                 case 0x41:
1838                   comptype = "audio for the hard of hearing";
1839                   break;
1840               }
1841               component = gst_structure_new ("audio", "type", G_TYPE_STRING,
1842                   comptype, "tag", G_TYPE_INT,
1843                   DESC_DVB_COMPONENT_tag (comp_descriptor), NULL);
1844               break;
1845             case 0x03:         /* subtitles/teletext/vbi */
1846               comptype = "reserved";
1847               switch (DESC_DVB_COMPONENT_type (comp_descriptor)) {
1848                 case 0x01:
1849                   comptype = "EBU Teletext subtitles";
1850                   break;
1851                 case 0x02:
1852                   comptype = "associated EBU Teletext";
1853                   break;
1854                 case 0x03:
1855                   comptype = "VBI data";
1856                   break;
1857                 case 0x10:
1858                   comptype = "Normal DVB subtitles";
1859                   break;
1860                 case 0x11:
1861                   comptype = "Normal DVB subtitles for 4:3";
1862                   break;
1863                 case 0x12:
1864                   comptype = "Normal DVB subtitles for 16:9";
1865                   break;
1866                 case 0x13:
1867                   comptype = "Normal DVB subtitles for 2.21:1";
1868                   break;
1869                 case 0x20:
1870                   comptype = "Hard of hearing DVB subtitles";
1871                   break;
1872                 case 0x21:
1873                   comptype = "Hard of hearing DVB subtitles for 4:3";
1874                   break;
1875                 case 0x22:
1876                   comptype = "Hard of hearing DVB subtitles for 16:9";
1877                   break;
1878                 case 0x23:
1879                   comptype = "Hard of hearing DVB subtitles for 2.21:1";
1880                   break;
1881               }
1882               component = gst_structure_new ("teletext", "type", G_TYPE_STRING,
1883                   comptype, "tag", G_TYPE_INT,
1884                   DESC_DVB_COMPONENT_tag (comp_descriptor), NULL);
1885               break;
1886           }
1887           if (component) {
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);
1892             component = NULL;
1893           }
1894         }
1895         gst_structure_set_value (event, "components", &components);
1896         g_value_unset (&components);
1897         g_array_free (component_descriptors, TRUE);
1898       }
1899       gst_mpeg_descriptor_free (mpegdescriptor);
1900
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);
1906         goto error;
1907       }
1908       gst_structure_id_set (event, QUARK_DESCRIPTORS, G_TYPE_VALUE_ARRAY,
1909           descriptors, NULL);
1910       g_value_array_free (descriptors);
1911     }
1912
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);
1917   }
1918
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));
1923     goto error;
1924   }
1925
1926   gst_structure_id_set_value (eit, QUARK_EVENTS, &events);
1927   g_value_unset (&events);
1928
1929   GST_DEBUG ("EIT %" GST_PTR_FORMAT, eit);
1930
1931   return eit;
1932
1933 error:
1934   if (eit)
1935     gst_structure_free (eit);
1936
1937   if (GST_VALUE_HOLDS_LIST (&events))
1938     g_value_unset (&events);
1939
1940   return NULL;
1941 }
1942
1943 GstStructure *
1944 mpegts_packetizer_parse_tdt (MpegTSPacketizer * packetizer,
1945     MpegTSPacketizerSection * section)
1946 {
1947   GstStructure *tdt = NULL;
1948   guint16 mjd;
1949   guint year, month, day, hour, minute, second;
1950   guint8 *data, *end, *utc_ptr;
1951
1952   GST_DEBUG ("TDT");
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);
1957     goto error;
1958   }
1959
1960   data = GST_BUFFER_DATA (section->buffer);
1961   end = data + GST_BUFFER_SIZE (section->buffer);
1962
1963   section->table_id = *data++;
1964   section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
1965   data += 2;
1966
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));
1970     goto error;
1971   }
1972
1973   mjd = GST_READ_UINT16_BE (data);
1974   data += 2;
1975   utc_ptr = data;
1976   if (mjd == G_MAXUINT16) {
1977     year = 1900;
1978     month = day = hour = minute = second = 0;
1979   } else {
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) {
1985       year++;
1986       month = month - 1 - 12;
1987     } else {
1988       month--;
1989     }
1990     year += 1900;
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);
1994   }
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);
2001
2002   return tdt;
2003
2004 error:
2005   if (tdt)
2006     gst_structure_free (tdt);
2007
2008   return NULL;
2009 }
2010
2011
2012 void
2013 mpegts_packetizer_clear (MpegTSPacketizer * packetizer)
2014 {
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;
2021     }
2022   }
2023   if (packetizer->streams) {
2024     int i;
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;
2029       }
2030     }
2031   }
2032
2033   gst_adapter_clear (packetizer->adapter);
2034 }
2035
2036 void
2037 mpegts_packetizer_remove_stream (MpegTSPacketizer * packetizer, gint16 pid)
2038 {
2039   MpegTSPacketizerStream *stream = packetizer->streams[pid];
2040   if (stream) {
2041     GST_INFO ("Removing stream for PID %d", pid);
2042     mpegts_packetizer_stream_free (stream);
2043     packetizer->streams[pid] = NULL;
2044   }
2045 }
2046
2047 MpegTSPacketizer *
2048 mpegts_packetizer_new (void)
2049 {
2050   MpegTSPacketizer *packetizer;
2051
2052   packetizer =
2053       GST_MPEGTS_PACKETIZER (g_object_new (GST_TYPE_MPEGTS_PACKETIZER, NULL));
2054
2055   return packetizer;
2056 }
2057
2058 void
2059 mpegts_packetizer_push (MpegTSPacketizer * packetizer, GstBuffer * buffer)
2060 {
2061   gst_adapter_push (packetizer->adapter, buffer);
2062 }
2063
2064 static void
2065 mpegts_try_discover_packet_size (MpegTSPacketizer * packetizer)
2066 {
2067   guint8 *dest;
2068   int i, pos, j;
2069   const guint psizes[] = { MPEGTS_NORMAL_PACKETSIZE,
2070     MPEGTS_M2TS_PACKETSIZE,
2071     MPEGTS_DVB_ASI_PACKETSIZE,
2072     MPEGTS_ATSC_PACKETSIZE
2073   };
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)
2077     return;
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 */
2082   pos = -1;
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);
2096           pos = i;
2097           break;
2098         }
2099       }
2100       break;
2101     }
2102   }
2103   GST_DEBUG ("have packetsize detected: %d of %u bytes",
2104       packetizer->know_packet_size, packetizer->packet_size);
2105   if (pos > 0) {
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);
2111   }
2112   g_free (dest);
2113 }
2114
2115
2116 gboolean
2117 mpegts_packetizer_has_packets (MpegTSPacketizer * packetizer)
2118 {
2119   if (G_UNLIKELY (packetizer->know_packet_size == FALSE)) {
2120     mpegts_try_discover_packet_size (packetizer);
2121     if (!packetizer->know_packet_size)
2122       return FALSE;
2123   }
2124   return gst_adapter_available (packetizer->adapter) >= packetizer->packet_size;
2125 }
2126
2127 MpegTSPacketizerPacketReturn
2128 mpegts_packetizer_next_packet (MpegTSPacketizer * packetizer,
2129     MpegTSPacketizerPacket * packet)
2130 {
2131   guint8 sync_byte;
2132   guint avail;
2133
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;
2139   }
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);
2146       continue;
2147     }
2148
2149     packet->buffer = gst_adapter_take_buffer (packetizer->adapter,
2150         packetizer->packet_size);
2151     packet->data_start = GST_BUFFER_DATA (packet->buffer);
2152     packet->data_end =
2153         GST_BUFFER_DATA (packet->buffer) + GST_BUFFER_SIZE (packet->buffer);
2154     return mpegts_packetizer_parse_packet (packetizer, packet);
2155   }
2156
2157   return PACKET_NEED_MORE;
2158 }
2159
2160 void
2161 mpegts_packetizer_clear_packet (MpegTSPacketizer * packetizer,
2162     MpegTSPacketizerPacket * packet)
2163 {
2164   if (packet->buffer)
2165     gst_buffer_unref (packet->buffer);
2166   memset (packet, 0, sizeof (MpegTSPacketizerPacket));
2167 }
2168
2169 gboolean
2170 mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
2171     MpegTSPacketizerPacket * packet, MpegTSPacketizerSection * section)
2172 {
2173   gboolean res = FALSE;
2174   MpegTSPacketizerStream *stream;
2175   guint8 pointer, table_id;
2176   guint16 subtable_extension;
2177   guint section_length;
2178   GstBuffer *sub_buf;
2179   guint8 *data;
2180
2181   data = packet->data;
2182   section->pid = packet->pid;
2183
2184   if (packet->payload_unit_start_indicator == 1) {
2185     pointer = *data++;
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);
2189       goto out;
2190     }
2191
2192     data += pointer;
2193   }
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) {
2198     table_id = data[0];
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);
2204       goto out;
2205     }
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;
2210     res = TRUE;
2211     GST_DEBUG ("TDT section pid:%d table_id:%d section_length: %d\n",
2212         packet->pid, table_id, section->section_length);
2213     goto out;
2214   }
2215
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);
2220
2221
2222   stream = packetizer->streams[packet->pid];
2223   if (stream == NULL) {
2224     stream = mpegts_packetizer_stream_new ();
2225     packetizer->streams[packet->pid] = stream;
2226   }
2227
2228   if (packet->payload_unit_start_indicator) {
2229     table_id = *data++;
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;
2234     else
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);
2238
2239     section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
2240
2241     if (stream->continuity_counter != CONTINUITY_UNSET) {
2242       GST_DEBUG
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);
2249     } else {
2250       GST_DEBUG
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));
2253     }
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);
2258
2259     res = TRUE;
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);
2266
2267     res = TRUE;
2268   } else {
2269     if (stream->continuity_counter == CONTINUITY_UNSET)
2270       GST_DEBUG ("PID %d waiting for pusi", packet->pid);
2271     else
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);
2277   }
2278
2279   if (res) {
2280     /* we pushed some data in the section adapter, see if the section is
2281      * complete now */
2282
2283     /* >= as sections can be padded and padding is not included in
2284      * section_length */
2285     if (gst_adapter_available (stream->section_adapter) >=
2286         stream->section_length + 3) {
2287       res = mpegts_packetizer_parse_section_header (packetizer,
2288           stream, section);
2289
2290       /* flush stuffing bytes */
2291       mpegts_packetizer_clear_section (packetizer, stream);
2292     } else {
2293       GST_DEBUG ("section not complete");
2294       /* section not complete yet */
2295       section->complete = FALSE;
2296     }
2297   } else {
2298     GST_WARNING ("section not complete");
2299     section->complete = FALSE;
2300   }
2301
2302 out:
2303   packet->data = data;
2304   GST_DEBUG ("result: %d complete: %d", res, section->complete);
2305   return res;
2306 }
2307
2308 static void
2309 _init_local (void)
2310 {
2311   GST_DEBUG_CATEGORY_INIT (mpegts_packetizer_debug, "mpegtspacketizer", 0,
2312       "MPEG transport stream parser");
2313
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");
2319
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");
2326
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");
2334
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");
2339
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");
2347 }
2348
2349 /**
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
2353  * or not is stored
2354  * @returns: Name of encoding or NULL of encoding could not be detected.
2355  * 
2356  * The returned string should be freed with g_free () when no longer needed.
2357  */
2358 static gchar *
2359 get_encoding (const gchar * text, guint * start_text, gboolean * is_multibyte)
2360 {
2361   gchar *encoding;
2362   guint8 firstbyte;
2363
2364   g_return_val_if_fail (text != NULL, NULL);
2365
2366   firstbyte = (guint8) text[0];
2367
2368   /* ETSI EN 300 468, "Selection of character table" */
2369   if (firstbyte <= 0x0B) {
2370     encoding = g_strdup_printf ("iso8859-%u", firstbyte + 4);
2371     *start_text = 1;
2372     *is_multibyte = FALSE;
2373   } else if (firstbyte >= 0x20) {
2374     encoding = g_strdup ("iso6937");
2375     *start_text = 0;
2376     *is_multibyte = FALSE;
2377   } else if (firstbyte == 0x10) {
2378     guint16 table;
2379     gchar table_str[6];
2380
2381     text++;
2382     table = GST_READ_UINT16_BE (text);
2383     g_snprintf (table_str, 6, "%d", table);
2384
2385     encoding = g_strconcat ("iso8859-", table_str, NULL);
2386     *start_text = 3;
2387     *is_multibyte = FALSE;
2388   } else if (firstbyte == 0x11) {
2389     encoding = g_strdup ("ISO-10646/UCS2");
2390     *start_text = 1;
2391     *is_multibyte = TRUE;
2392   } else if (firstbyte == 0x12) {
2393     /* EUC-KR implements KSX1001 */
2394     encoding = g_strdup ("EUC-KR");
2395     *start_text = 1;
2396     *is_multibyte = TRUE;
2397   } else if (firstbyte == 0x13) {
2398     encoding = g_strdup ("GB2312");
2399     *start_text = 1;
2400     *is_multibyte = FALSE;
2401   } else if (firstbyte == 0x14) {
2402     encoding = g_strdup ("UTF-16BE");
2403     *start_text = 1;
2404     *is_multibyte = TRUE;
2405   } else if (firstbyte == 0x15) {
2406     encoding = g_strdup ("ISO-10646/UTF8");
2407     *start_text = 1;
2408     *is_multibyte = FALSE;
2409   } else {
2410     /* reserved */
2411     encoding = NULL;
2412     *start_text = 0;
2413     *is_multibyte = FALSE;
2414   }
2415
2416   GST_DEBUG
2417       ("Found encoding %s, first byte is 0x%02x, start_text: %u, is_multibyte: %d",
2418       encoding, firstbyte, *start_text, *is_multibyte);
2419
2420   return encoding;
2421 }
2422
2423 /**
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
2431  *
2432  * Convert text to UTF-8.
2433  */
2434 static gchar *
2435 convert_to_utf8 (const gchar * text, gint length, guint start,
2436     const gchar * encoding, gboolean is_multibyte, GError ** error)
2437 {
2438   gchar *new_text;
2439   GByteArray *sb;
2440   gint i;
2441
2442   g_return_val_if_fail (text != NULL, NULL);
2443   g_return_val_if_fail (encoding != NULL, NULL);
2444
2445   text += start;
2446
2447   sb = g_byte_array_sized_new (length * 1.1);
2448
2449   if (is_multibyte) {
2450     if (length == -1) {
2451       while (*text != '\0') {
2452         guint16 code = GST_READ_UINT16_BE (text);
2453
2454         switch (code) {
2455           case 0xE086:         /* emphasis on */
2456           case 0xE087:         /* emphasis off */
2457             /* skip it */
2458             break;
2459           case 0xE08A:{
2460             guint8 nl[] = { 0x00, 0x0A };       /* new line */
2461             g_byte_array_append (sb, nl, 2);
2462             break;
2463           }
2464           default:
2465             g_byte_array_append (sb, (guint8 *) text, 2);
2466             break;
2467         }
2468
2469         text += 2;
2470       }
2471     } else {
2472       for (i = 0; i < length; i += 2) {
2473         guint16 code = GST_READ_UINT16_BE (text);
2474
2475         switch (code) {
2476           case 0xE086:         /* emphasis on */
2477           case 0xE087:         /* emphasis off */
2478             /* skip it */
2479             break;
2480           case 0xE08A:{
2481             guint8 nl[] = { 0x00, 0x0A };       /* new line */
2482             g_byte_array_append (sb, nl, 2);
2483             break;
2484           }
2485           default:
2486             g_byte_array_append (sb, (guint8 *) text, 2);
2487             break;
2488         }
2489
2490         text += 2;
2491       }
2492     }
2493   } else {
2494     if (length == -1) {
2495       while (*text != '\0') {
2496         guint8 code = (guint8) (*text);
2497
2498         switch (code) {
2499           case 0x86:           /* emphasis on */
2500           case 0x87:           /* emphasis off */
2501             /* skip it */
2502             break;
2503           case 0x8A:
2504             g_byte_array_append (sb, (guint8 *) "\n", 1);
2505             break;
2506           default:
2507             g_byte_array_append (sb, &code, 1);
2508             break;
2509         }
2510
2511         text++;
2512       }
2513     } else {
2514       for (i = 0; i < length; i++) {
2515         guint8 code = (guint8) (*text);
2516
2517         switch (code) {
2518           case 0x86:           /* emphasis on */
2519           case 0x87:           /* emphasis off */
2520             /* skip it */
2521             break;
2522           case 0x8A:
2523             g_byte_array_append (sb, (guint8 *) "\n", 1);
2524             break;
2525           default:
2526             g_byte_array_append (sb, &code, 1);
2527             break;
2528         }
2529
2530         text++;
2531       }
2532     }
2533   }
2534
2535   if (sb->len > 0) {
2536     new_text =
2537         g_convert ((gchar *) sb->data, sb->len, "utf-8", encoding, NULL, NULL,
2538         error);
2539   } else {
2540     new_text = g_strdup ("");
2541   }
2542
2543   g_byte_array_free (sb, TRUE);
2544
2545   return new_text;
2546 }
2547
2548 static gchar *
2549 get_encoding_and_convert (const gchar * text, guint length)
2550 {
2551   GError *error = NULL;
2552   gchar *converted_str;
2553   gchar *encoding;
2554   guint start_text = 0;
2555   gboolean is_multibyte;
2556
2557   g_return_val_if_fail (text != NULL, NULL);
2558
2559   if (length == 0)
2560     return g_strdup ("");
2561
2562   encoding = get_encoding (text, &start_text, &is_multibyte);
2563
2564   if (encoding == NULL) {
2565     GST_WARNING ("Could not detect encoding");
2566     converted_str = g_strndup (text, length);
2567   } else {
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);
2574       error = NULL;
2575
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.
2580        */
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) {
2586           GST_WARNING
2587               ("Could not convert string while assuming encoding ISO 8859-9: %s",
2588               error->message);
2589           g_error_free (error);
2590           goto failed;
2591         }
2592       } else {
2593         goto failed;
2594       }
2595     }
2596
2597     g_free (encoding);
2598   }
2599
2600   return converted_str;
2601
2602 failed:
2603   {
2604     g_free (encoding);
2605     text += start_text;
2606     return g_strndup (text, length - start_text);
2607   }
2608 }