1 /* GStreamer
2 *
3 * ts-parser.c: sample application to display mpeg-ts info from any pipeline
4 * Copyright (C) 2013
5 * Edward Hervey <bilboed@gmail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #define DUMP_DESCRIPTORS 0
28
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <glib/gprintf.h>
32 #include <gst/gst.h>
33 #include <gst/mpegts/mpegts.h>
34 #define MPEGTIME_TO_GSTTIME(t) ((t) * (guint64)100000 / 9)
35
36 static void
gst_info_dump_mem_line(gchar * linebuf,gsize linebuf_size,const guint8 * mem,gsize mem_offset,gsize mem_size)37 gst_info_dump_mem_line (gchar * linebuf, gsize linebuf_size,
38 const guint8 * mem, gsize mem_offset, gsize mem_size)
39 {
40 gchar hexstr[50], ascstr[18], digitstr[4];
41
42 if (mem_size > 16)
43 mem_size = 16;
44
45 hexstr[0] = '\0';
46 ascstr[0] = '\0';
47
48 if (mem != NULL) {
49 guint i = 0;
50
51 mem += mem_offset;
52 while (i < mem_size) {
53 ascstr[i] = (g_ascii_isprint (mem[i])) ? mem[i] : '.';
54 g_snprintf (digitstr, sizeof (digitstr), "%02x ", mem[i]);
55 g_strlcat (hexstr, digitstr, sizeof (hexstr));
56 ++i;
57 }
58 ascstr[i] = '\0';
59 }
60
61 g_snprintf (linebuf, linebuf_size, "%08x: %-48.48s %-16.16s",
62 (guint) mem_offset, hexstr, ascstr);
63 }
64
65 static void
dump_memory_bytes(guint8 * data,guint len,guint spacing)66 dump_memory_bytes (guint8 * data, guint len, guint spacing)
67 {
68 gsize off = 0;
69
70 while (off < len) {
71 gchar buf[128];
72
73 /* gst_info_dump_mem_line will process 16 bytes at most */
74 gst_info_dump_mem_line (buf, sizeof (buf), data, off, len - off);
75 g_printf ("%*s %s\n", spacing, "", buf);
76 off += 16;
77 }
78 }
79
80 #define dump_memory_content(desc, spacing) dump_memory_bytes((desc)->data + 2, (desc)->length, spacing)
81
82 static const gchar *
descriptor_name(GstMpegtsDescriptor * desc)83 descriptor_name (GstMpegtsDescriptor * desc)
84 {
85 GEnumValue *en = NULL;
86 gint val = desc->tag;
87
88 /* Treat extended descriptors */
89 if (val == 0x7f) {
90 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
91 (GST_TYPE_MPEGTS_DVB_EXTENDED_DESCRIPTOR_TYPE)),
92 desc->tag_extension);
93 }
94 if (en == NULL)
95 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
96 (GST_TYPE_MPEGTS_DESCRIPTOR_TYPE)), val);
97 if (en == NULL)
98 /* Else try with DVB enum types */
99 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
100 (GST_TYPE_MPEGTS_DVB_DESCRIPTOR_TYPE)), val);
101 if (en == NULL)
102 /* Else try with ATSC enum types */
103 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
104 (GST_TYPE_MPEGTS_ATSC_DESCRIPTOR_TYPE)), val);
105 if (en == NULL)
106 /* Else try with ISB enum types */
107 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
108 (GST_TYPE_MPEGTS_ISDB_DESCRIPTOR_TYPE)), val);
109 if (en == NULL)
110 /* Else try with SCTE enum types */
111 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
112 (GST_TYPE_MPEGTS_SCTE_DESCRIPTOR_TYPE)), val);
113 if (en == NULL)
114 /* Else try with misc enum types */
115 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
116 (GST_TYPE_MPEGTS_MISC_DESCRIPTOR_TYPE)), val);
117 if (en == NULL)
118 return "UNKNOWN/PRIVATE";
119 return en->value_nick;
120 }
121
122 static const gchar *
table_id_name(gint val)123 table_id_name (gint val)
124 {
125 GEnumValue *en;
126
127 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
128 (GST_TYPE_MPEGTS_SECTION_TABLE_ID)), val);
129 if (en == NULL)
130 /* Else try with DVB enum types */
131 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
132 (GST_TYPE_MPEGTS_SECTION_DVB_TABLE_ID)), val);
133 if (en == NULL)
134 /* Else try with ATSC enum types */
135 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
136 (GST_TYPE_MPEGTS_SECTION_ATSC_TABLE_ID)), val);
137 if (en == NULL)
138 /* Else try with SCTE enum types */
139 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
140 (GST_TYPE_MPEGTS_SECTION_SCTE_TABLE_ID)), val);
141 if (en == NULL)
142 return "UNKNOWN/PRIVATE";
143 return en->value_nick;
144 }
145
146 static const gchar *
stream_type_name(gint val)147 stream_type_name (gint val)
148 {
149 GEnumValue *en;
150
151 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
152 (GST_TYPE_MPEGTS_STREAM_TYPE)), val);
153 if (en == NULL)
154 /* Else try with HDMV enum types */
155 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
156 (GST_TYPE_MPEGTS_HDMV_STREAM_TYPE)), val);
157 if (en == NULL)
158 /* Else try with SCTE enum types */
159 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek
160 (GST_TYPE_MPEGTS_SCTE_STREAM_TYPE)), val);
161 if (en == NULL)
162 return "UNKNOWN/PRIVATE";
163 return en->value_nick;
164 }
165
166 static const gchar *
enum_name(GType instance_type,gint val)167 enum_name (GType instance_type, gint val)
168 {
169 GEnumValue *en;
170
171 en = g_enum_get_value (G_ENUM_CLASS (g_type_class_peek (instance_type)), val);
172
173 if (!en)
174 return "UNKNOWN/PRIVATE";
175 return en->value_nick;
176 }
177
178 static void
dump_cable_delivery_descriptor(GstMpegtsDescriptor * desc,guint spacing)179 dump_cable_delivery_descriptor (GstMpegtsDescriptor * desc, guint spacing)
180 {
181 GstMpegtsCableDeliverySystemDescriptor res;
182
183 if (gst_mpegts_descriptor_parse_cable_delivery_system (desc, &res)) {
184 g_printf ("%*s Cable Delivery Descriptor\n", spacing, "");
185 g_printf ("%*s Frequency : %d Hz\n", spacing, "", res.frequency);
186 g_printf ("%*s Outer FEC : %d (%s)\n", spacing, "", res.outer_fec,
187 enum_name (GST_TYPE_MPEGTS_CABLE_OUTER_FEC_SCHEME, res.outer_fec));
188 g_printf ("%*s modulation : %d (%s)\n", spacing, "", res.modulation,
189 enum_name (GST_TYPE_MPEGTS_MODULATION_TYPE, res.modulation));
190 g_printf ("%*s Symbol rate : %d sym/s\n", spacing, "", res.symbol_rate);
191 g_printf ("%*s Inner FEC : %d (%s)\n", spacing, "", res.fec_inner,
192 enum_name (GST_TYPE_MPEGTS_DVB_CODE_RATE, res.fec_inner));
193 }
194 }
195
196 static void
dump_terrestrial_delivery(GstMpegtsDescriptor * desc,guint spacing)197 dump_terrestrial_delivery (GstMpegtsDescriptor * desc, guint spacing)
198 {
199 GstMpegtsTerrestrialDeliverySystemDescriptor res;
200
201 if (gst_mpegts_descriptor_parse_terrestrial_delivery_system (desc, &res)) {
202 g_printf ("%*s Terrestrial Delivery Descriptor\n", spacing, "");
203 g_printf ("%*s Frequency : %d Hz\n", spacing, "", res.frequency);
204 g_printf ("%*s Bandwidth : %d Hz\n", spacing, "", res.bandwidth);
205 g_printf ("%*s Priority : %s\n", spacing, "",
206 res.priority ? "TRUE" : "FALSE");
207 g_printf ("%*s Time slicing : %s\n", spacing, "",
208 res.time_slicing ? "TRUE" : "FALSE");
209 g_printf ("%*s MPE FEC : %s\n", spacing, "",
210 res.mpe_fec ? "TRUE" : "FALSE");
211 g_printf ("%*s Constellation : %d (%s)\n", spacing, "",
212 res.constellation, enum_name (GST_TYPE_MPEGTS_MODULATION_TYPE,
213 res.constellation));
214 g_printf ("%*s Hierarchy : %d (%s)\n", spacing, "",
215 res.hierarchy, enum_name (GST_TYPE_MPEGTS_TERRESTRIAL_HIERARCHY,
216 res.hierarchy));
217 g_printf ("%*s Code Rate HP : %d (%s)\n", spacing, "",
218 res.code_rate_hp, enum_name (GST_TYPE_MPEGTS_DVB_CODE_RATE,
219 res.code_rate_hp));
220 g_printf ("%*s Code Rate LP : %d (%s)\n", spacing, "",
221 res.code_rate_lp, enum_name (GST_TYPE_MPEGTS_DVB_CODE_RATE,
222 res.code_rate_lp));
223 g_printf ("%*s Guard Interval : %d (%s)\n", spacing, "",
224 res.guard_interval,
225 enum_name (GST_TYPE_MPEGTS_TERRESTRIAL_GUARD_INTERVAL,
226 res.guard_interval));
227 g_printf ("%*s Transmission Mode : %d (%s)\n", spacing, "",
228 res.transmission_mode,
229 enum_name (GST_TYPE_MPEGTS_TERRESTRIAL_TRANSMISSION_MODE,
230 res.transmission_mode));
231 g_printf ("%*s Other Frequency : %s\n", spacing, "",
232 res.other_frequency ? "TRUE" : "FALSE");
233 }
234 }
235
236 static void
dump_dvb_service_list(GstMpegtsDescriptor * desc,guint spacing)237 dump_dvb_service_list (GstMpegtsDescriptor * desc, guint spacing)
238 {
239 GPtrArray *res;
240
241 if (gst_mpegts_descriptor_parse_dvb_service_list (desc, &res)) {
242 guint i;
243 g_printf ("%*s DVB Service List Descriptor\n", spacing, "");
244 for (i = 0; i < res->len; i++) {
245 GstMpegtsDVBServiceListItem *item = g_ptr_array_index (res, i);
246 g_printf ("%*s Service #%d, id:0x%04x, type:0x%x (%s)\n",
247 spacing, "", i, item->service_id, item->type,
248 enum_name (GST_TYPE_MPEGTS_DVB_SERVICE_TYPE, item->type));
249 }
250 g_ptr_array_unref (res);
251 }
252 }
253
254 static void
dump_logical_channel_descriptor(GstMpegtsDescriptor * desc,guint spacing)255 dump_logical_channel_descriptor (GstMpegtsDescriptor * desc, guint spacing)
256 {
257 GstMpegtsLogicalChannelDescriptor res;
258 guint i;
259
260 if (gst_mpegts_descriptor_parse_logical_channel (desc, &res)) {
261 g_printf ("%*s Logical Channel Descriptor (%d channels)\n", spacing, "",
262 res.nb_channels);
263 for (i = 0; i < res.nb_channels; i++) {
264 GstMpegtsLogicalChannel *chann = &res.channels[i];
265 g_printf ("%*s service_id: 0x%04x, logical channel number:%4d\n",
266 spacing, "", chann->service_id, chann->logical_channel_number);
267 }
268 }
269 }
270
271 static void
dump_multiligual_network_name(GstMpegtsDescriptor * desc,guint spacing)272 dump_multiligual_network_name (GstMpegtsDescriptor * desc, guint spacing)
273 {
274 GPtrArray *items;
275 if (gst_mpegts_descriptor_parse_dvb_multilingual_network_name (desc, &items)) {
276 guint i;
277 for (i = 0; i < items->len; i++) {
278 GstMpegtsDvbMultilingualNetworkNameItem *item =
279 g_ptr_array_index (items, i);
280 g_printf ("%*s item : %u\n", spacing, "", i);
281 g_printf ("%*s language_code : %s\n", spacing, "", item->language_code);
282 g_printf ("%*s network_name : %s\n", spacing, "", item->network_name);
283 }
284 g_ptr_array_unref (items);
285 }
286 }
287
288 static void
dump_multiligual_bouquet_name(GstMpegtsDescriptor * desc,guint spacing)289 dump_multiligual_bouquet_name (GstMpegtsDescriptor * desc, guint spacing)
290 {
291 GPtrArray *items;
292 if (gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name (desc, &items)) {
293 guint i;
294 for (i = 0; i < items->len; i++) {
295 GstMpegtsDvbMultilingualBouquetNameItem *item =
296 g_ptr_array_index (items, i);
297 g_printf ("%*s item : %u\n", spacing, "", i);
298 g_printf ("%*s language_code : %s\n", spacing, "", item->language_code);
299 g_printf ("%*s bouguet_name : %s\n", spacing, "", item->bouquet_name);
300 }
301 g_ptr_array_unref (items);
302 }
303 }
304
305 static void
dump_multiligual_service_name(GstMpegtsDescriptor * desc,guint spacing)306 dump_multiligual_service_name (GstMpegtsDescriptor * desc, guint spacing)
307 {
308 GPtrArray *items;
309 if (gst_mpegts_descriptor_parse_dvb_multilingual_service_name (desc, &items)) {
310 guint i;
311 for (i = 0; i < items->len; i++) {
312 GstMpegtsDvbMultilingualServiceNameItem *item =
313 g_ptr_array_index (items, i);
314 g_printf ("%*s item : %u\n", spacing, "", i);
315 g_printf ("%*s language_code : %s\n", spacing, "", item->language_code);
316 g_printf ("%*s service_name : %s\n", spacing, "", item->service_name);
317 g_printf ("%*s provider_name : %s\n", spacing, "", item->provider_name);
318 }
319 g_ptr_array_unref (items);
320 }
321 }
322
323 static void
dump_multiligual_component(GstMpegtsDescriptor * desc,guint spacing)324 dump_multiligual_component (GstMpegtsDescriptor * desc, guint spacing)
325 {
326 GPtrArray *items;
327 guint8 tag;
328 if (gst_mpegts_descriptor_parse_dvb_multilingual_component (desc, &tag,
329 &items)) {
330 guint8 i;
331 g_printf ("%*s component_tag : 0x%02x\n", spacing, "", tag);
332 for (i = 0; i < items->len; i++) {
333 GstMpegtsDvbMultilingualComponentItem *item =
334 g_ptr_array_index (items, i);
335 g_printf ("%*s item : %u\n", spacing, "", i);
336 g_printf ("%*s language_code : %s\n", spacing, "",
337 item->language_code);
338 g_printf ("%*s description : %s\n", spacing, "", item->description);
339 }
340 g_ptr_array_unref (items);
341 }
342 }
343
344 static void
dump_linkage(GstMpegtsDescriptor * desc,guint spacing)345 dump_linkage (GstMpegtsDescriptor * desc, guint spacing)
346 {
347 GstMpegtsDVBLinkageDescriptor *res;
348
349 if (gst_mpegts_descriptor_parse_dvb_linkage (desc, &res)) {
350 g_printf ("%*s Linkage Descriptor : 0x%02x (%s)\n", spacing, "",
351 res->linkage_type, enum_name (GST_TYPE_MPEGTS_DVB_LINKAGE_TYPE,
352 res->linkage_type));
353
354 g_printf ("%*s Transport Stream ID : 0x%04x\n", spacing, "",
355 res->transport_stream_id);
356 g_printf ("%*s Original Network ID : 0x%04x\n", spacing, "",
357 res->original_network_id);
358 g_printf ("%*s Service ID : 0x%04x\n", spacing, "",
359 res->service_id);
360
361 switch (res->linkage_type) {
362 case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:
363 {
364 const GstMpegtsDVBLinkageMobileHandOver *linkage =
365 gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over (res);
366 g_printf ("%*s hand_over_type : 0x%02x (%s)\n", spacing,
367 "", linkage->hand_over_type,
368 enum_name (GST_TYPE_MPEGTS_DVB_LINKAGE_HAND_OVER_TYPE,
369 linkage->hand_over_type));
370 g_printf ("%*s origin_type : %s\n", spacing, "",
371 linkage->origin_type ? "SDT" : "NIT");
372 g_printf ("%*s network_id : 0x%04x\n", spacing, "",
373 linkage->network_id);
374 g_printf ("%*s initial_service_id: 0x%04x\n", spacing, "",
375 linkage->initial_service_id);
376 break;
377 }
378 case GST_MPEGTS_DVB_LINKAGE_EVENT:
379 {
380 const GstMpegtsDVBLinkageEvent *linkage =
381 gst_mpegts_dvb_linkage_descriptor_get_event (res);
382 g_printf ("%*s target_event_id : 0x%04x\n", spacing, "",
383 linkage->target_event_id);
384 g_printf ("%*s target_listed : %s\n", spacing, "",
385 linkage->target_listed ? "TRUE" : "FALSE");
386 g_printf ("%*s event_simulcast : %s\n", spacing, "",
387 linkage->event_simulcast ? "TRUE" : "FALSE");
388 break;
389 }
390 case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:
391 {
392 guint i;
393 const GPtrArray *items =
394 gst_mpegts_dvb_linkage_descriptor_get_extended_event (res);
395
396 for (i = 0; i < items->len; i++) {
397 GstMpegtsDVBLinkageExtendedEvent *linkage =
398 g_ptr_array_index (items, i);
399 g_printf ("%*s target_event_id : 0x%04x\n", spacing, "",
400 linkage->target_event_id);
401 g_printf ("%*s target_listed : %s\n", spacing, "",
402 linkage->target_listed ? "TRUE" : "FALSE");
403 g_printf ("%*s event_simulcast : %s\n", spacing, "",
404 linkage->event_simulcast ? "TRUE" : "FALSE");
405 g_printf ("%*s link_type : 0x%01x\n", spacing, "",
406 linkage->link_type);
407 g_printf ("%*s target_id_type : 0x%01x\n", spacing, "",
408 linkage->target_id_type);
409 g_printf ("%*s original_network_id_flag : %s\n", spacing, "",
410 linkage->original_network_id_flag ? "TRUE" : "FALSE");
411 g_printf ("%*s service_id_flag : %s\n", spacing, "",
412 linkage->service_id_flag ? "TRUE" : "FALSE");
413 if (linkage->target_id_type == 3) {
414 g_printf ("%*s user_defined_id : 0x%02x\n", spacing, "",
415 linkage->user_defined_id);
416 } else {
417 if (linkage->target_id_type == 1)
418 g_printf ("%*s target_transport_stream_id : 0x%04x\n",
419 spacing, "", linkage->target_transport_stream_id);
420 if (linkage->original_network_id_flag)
421 g_printf ("%*s target_original_network_id : 0x%04x\n",
422 spacing, "", linkage->target_original_network_id);
423 if (linkage->service_id_flag)
424 g_printf ("%*s target_service_id : 0x%04x\n",
425 spacing, "", linkage->target_service_id);
426 }
427 }
428 break;
429 }
430 default:
431 break;
432 }
433 if (res->private_data_length > 0) {
434 dump_memory_bytes (res->private_data_bytes, res->private_data_length,
435 spacing + 2);
436 }
437 gst_mpegts_dvb_linkage_descriptor_free (res);
438 }
439 }
440
441 static void
dump_component(GstMpegtsDescriptor * desc,guint spacing)442 dump_component (GstMpegtsDescriptor * desc, guint spacing)
443 {
444 GstMpegtsComponentDescriptor *res;
445
446 if (gst_mpegts_descriptor_parse_dvb_component (desc, &res)) {
447 g_printf ("%*s stream_content : 0x%02x (%s)\n", spacing, "",
448 res->stream_content,
449 enum_name (GST_TYPE_MPEGTS_COMPONENT_STREAM_CONTENT,
450 res->stream_content));
451 g_printf ("%*s component_type : 0x%02x\n", spacing, "",
452 res->component_type);
453 g_printf ("%*s component_tag : 0x%02x\n", spacing, "", res->component_tag);
454 g_printf ("%*s language_code : %s\n", spacing, "", res->language_code);
455 g_printf ("%*s text : %s\n", spacing, "",
456 res->text ? res->text : "NULL");
457 gst_mpegts_dvb_component_descriptor_free (res);
458 }
459 }
460
461 static void
dump_content(GstMpegtsDescriptor * desc,guint spacing)462 dump_content (GstMpegtsDescriptor * desc, guint spacing)
463 {
464 GPtrArray *contents;
465 guint i;
466
467 if (gst_mpegts_descriptor_parse_dvb_content (desc, &contents)) {
468 for (i = 0; i < contents->len; i++) {
469 GstMpegtsContent *item = g_ptr_array_index (contents, i);
470 g_printf ("%*s content nibble 1 : 0x%01x (%s)\n", spacing, "",
471 item->content_nibble_1,
472 enum_name (GST_TYPE_MPEGTS_CONTENT_NIBBLE_HI,
473 item->content_nibble_1));
474 g_printf ("%*s content nibble 2 : 0x%01x\n", spacing, "",
475 item->content_nibble_2);
476 g_printf ("%*s user_byte : 0x%02x\n", spacing, "",
477 item->user_byte);
478 }
479 g_ptr_array_unref (contents);
480 }
481 }
482
483 static void
dump_iso_639_language(GstMpegtsDescriptor * desc,guint spacing)484 dump_iso_639_language (GstMpegtsDescriptor * desc, guint spacing)
485 {
486 guint i;
487 GstMpegtsISO639LanguageDescriptor *res;
488
489 if (gst_mpegts_descriptor_parse_iso_639_language (desc, &res)) {
490 for (i = 0; i < res->nb_language; i++) {
491 g_print
492 ("%*s ISO 639 Language Descriptor %s , audio_type:0x%x (%s)\n",
493 spacing, "", res->language[i], res->audio_type[i],
494 enum_name (GST_TYPE_MPEGTS_ISO639_AUDIO_TYPE, res->audio_type[i]));
495 }
496 gst_mpegts_iso_639_language_descriptor_free (res);
497 }
498 }
499
500 static void
dump_dvb_extended_event(GstMpegtsDescriptor * desc,guint spacing)501 dump_dvb_extended_event (GstMpegtsDescriptor * desc, guint spacing)
502 {
503 GstMpegtsExtendedEventDescriptor *res;
504
505 if (gst_mpegts_descriptor_parse_dvb_extended_event (desc, &res)) {
506 guint i;
507 g_printf ("%*s DVB Extended Event\n", spacing, "");
508 g_printf ("%*s descriptor_number:%d, last_descriptor_number:%d\n",
509 spacing, "", res->descriptor_number, res->last_descriptor_number);
510 g_printf ("%*s language_code:%s\n", spacing, "", res->language_code);
511 g_printf ("%*s text : %s\n", spacing, "", res->text);
512 for (i = 0; i < res->items->len; i++) {
513 GstMpegtsExtendedEventItem *item = g_ptr_array_index (res->items, i);
514 g_printf ("%*s #%d [description:item] %s : %s\n",
515 spacing, "", i, item->item_description, item->item);
516 }
517 gst_mpegts_extended_event_descriptor_free (res);
518 }
519 }
520
521 #define SAFE_CHAR(a) (g_ascii_isprint(a) ? a : '.')
522
523 /* Single descriptor dump
524 * Descriptors that can only appear in specific tables should be handled before */
525 static void
dump_generic_descriptor(GstMpegtsDescriptor * desc,guint spacing)526 dump_generic_descriptor (GstMpegtsDescriptor * desc, guint spacing)
527 {
528 switch (desc->tag) {
529 case GST_MTS_DESC_REGISTRATION:
530 {
531 const guint8 *data = desc->data + 2;
532 g_printf ("%*s Registration : %c%c%c%c [%02x%02x%02x%02x]\n", spacing,
533 "", SAFE_CHAR (data[0]), SAFE_CHAR (data[1]), SAFE_CHAR (data[2]),
534 SAFE_CHAR (data[3]), data[0], data[1], data[2], data[3]);
535
536 break;
537 }
538 case GST_MTS_DESC_CA:
539 {
540 guint16 ca_pid, ca_system_id;
541 const guint8 *private_data;
542 gsize private_data_size;
543 if (gst_mpegts_descriptor_parse_ca (desc, &ca_system_id, &ca_pid,
544 &private_data, &private_data_size)) {
545 g_printf ("%*s CA system id : 0x%04x\n", spacing, "", ca_system_id);
546 g_printf ("%*s CA PID : 0x%04x\n", spacing, "", ca_pid);
547 if (private_data_size) {
548 g_printf ("%*s Private Data :\n", spacing, "");
549 dump_memory_bytes ((guint8 *) private_data, private_data_size,
550 spacing + 2);
551 }
552 }
553 break;
554 }
555 case GST_MTS_DESC_DVB_NETWORK_NAME:
556 {
557 gchar *network_name;
558 if (gst_mpegts_descriptor_parse_dvb_network_name (desc, &network_name)) {
559 g_printf ("%*s Network Name : %s\n", spacing, "", network_name);
560 g_free (network_name);
561 }
562 break;
563 }
564 case GST_MTS_DESC_DVB_SERVICE_LIST:
565 {
566 dump_dvb_service_list (desc, spacing + 2);
567 break;
568 }
569 case GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM:
570 dump_cable_delivery_descriptor (desc, spacing + 2);
571 break;
572 case GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM:
573 dump_terrestrial_delivery (desc, spacing + 2);
574 break;
575 case GST_MTS_DESC_DVB_BOUQUET_NAME:
576 {
577 gchar *bouquet_name;
578 if (gst_mpegts_descriptor_parse_dvb_bouquet_name (desc, &bouquet_name)) {
579 g_printf ("%*s Bouquet Name Descriptor, bouquet_name:%s\n", spacing,
580 "", bouquet_name);
581 g_free (bouquet_name);
582 }
583 break;
584 }
585 case GST_MTS_DESC_DVB_SERVICE:
586 {
587 gchar *service_name, *provider_name;
588 GstMpegtsDVBServiceType service_type;
589 if (gst_mpegts_descriptor_parse_dvb_service (desc, &service_type,
590 &service_name, &provider_name)) {
591 g_printf ("%*s Service Descriptor, type:0x%02x (%s)\n", spacing, "",
592 service_type, enum_name (GST_TYPE_MPEGTS_DVB_SERVICE_TYPE,
593 service_type));
594 g_printf ("%*s service_name : %s\n", spacing, "", service_name);
595 g_printf ("%*s provider_name : %s\n", spacing, "", provider_name);
596 g_free (service_name);
597 g_free (provider_name);
598
599 }
600 break;
601 }
602 case GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME:
603 {
604 dump_multiligual_bouquet_name (desc, spacing + 2);
605 break;
606 }
607 case GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME:
608 {
609 dump_multiligual_network_name (desc, spacing + 2);
610 break;
611 }
612 case GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME:
613 {
614 dump_multiligual_service_name (desc, spacing + 2);
615 break;
616 }
617 case GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT:
618 {
619 dump_multiligual_component (desc, spacing + 2);
620 break;
621 }
622 case GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER:
623 {
624 guint32 specifier;
625 guint8 len = 0, *data = NULL;
626
627 if (gst_mpegts_descriptor_parse_dvb_private_data_specifier (desc,
628 &specifier, &data, &len)) {
629 g_printf ("%*s private_data_specifier : 0x%08x\n", spacing, "",
630 specifier);
631 if (len > 0) {
632 dump_memory_bytes (data, len, spacing + 2);
633 g_free (data);
634 }
635 }
636 break;
637 }
638 case GST_MTS_DESC_DVB_FREQUENCY_LIST:
639 {
640 gboolean offset;
641 GArray *list;
642 if (gst_mpegts_descriptor_parse_dvb_frequency_list (desc, &offset, &list)) {
643 guint j;
644 for (j = 0; j < list->len; j++) {
645 guint32 freq = g_array_index (list, guint32, j);
646 g_printf ("%*s Frequency : %u %s\n", spacing, "", freq,
647 offset ? "kHz" : "Hz");
648 }
649 g_array_unref (list);
650 }
651 break;
652 }
653 case GST_MTS_DESC_DVB_LINKAGE:
654 dump_linkage (desc, spacing + 2);
655 break;
656 case GST_MTS_DESC_DVB_COMPONENT:
657 dump_component (desc, spacing + 2);
658 break;
659 case GST_MTS_DESC_DVB_STREAM_IDENTIFIER:
660 {
661 guint8 tag;
662 if (gst_mpegts_descriptor_parse_dvb_stream_identifier (desc, &tag)) {
663 g_printf ("%*s Component Tag : 0x%02x\n", spacing, "", tag);
664 }
665 break;
666 }
667 case GST_MTS_DESC_DVB_CA_IDENTIFIER:
668 {
669 GArray *list;
670 guint j;
671 guint16 ca_id;
672 if (gst_mpegts_descriptor_parse_dvb_ca_identifier (desc, &list)) {
673 for (j = 0; j < list->len; j++) {
674 ca_id = g_array_index (list, guint16, j);
675 g_printf ("%*s CA Identifier : 0x%04x\n", spacing, "", ca_id);
676 }
677 g_array_unref (list);
678 }
679 break;
680 }
681 case GST_MTS_DESC_DVB_CONTENT:
682 dump_content (desc, spacing + 2);
683 break;
684 case GST_MTS_DESC_DVB_PARENTAL_RATING:
685 {
686 GPtrArray *ratings;
687 guint j;
688
689 if (gst_mpegts_descriptor_parse_dvb_parental_rating (desc, &ratings)) {
690 for (j = 0; j < ratings->len; j++) {
691 GstMpegtsDVBParentalRatingItem *item = g_ptr_array_index (ratings, j);
692 g_printf ("%*s country_code : %s\n", spacing, "",
693 item->country_code);
694 g_printf ("%*s rating age : %d\n", spacing, "", item->rating);
695 }
696 g_ptr_array_unref (ratings);
697 }
698 break;
699 }
700 case GST_MTS_DESC_DVB_DATA_BROADCAST:
701 {
702 GstMpegtsDataBroadcastDescriptor *res;
703
704 if (gst_mpegts_descriptor_parse_dvb_data_broadcast (desc, &res)) {
705 g_printf ("%*s data_broadcast_id : 0x%04x\n", spacing, "",
706 res->data_broadcast_id);
707 g_printf ("%*s component_tag : 0x%02x\n", spacing, "",
708 res->component_tag);
709 if (res->length > 0) {
710 g_printf ("%*s selector_bytes:\n", spacing, "");
711 dump_memory_bytes (res->selector_bytes, res->length, spacing + 2);
712 }
713 g_printf ("%*s text : %s\n", spacing, "",
714 res->text ? res->text : "NULL");
715 gst_mpegts_dvb_data_broadcast_descriptor_free (res);
716 }
717 break;
718 }
719 case GST_MTS_DESC_ISO_639_LANGUAGE:
720 dump_iso_639_language (desc, spacing + 2);
721 break;
722 case GST_MTS_DESC_DVB_SHORT_EVENT:
723 {
724 gchar *language_code, *event_name, *text;
725 if (gst_mpegts_descriptor_parse_dvb_short_event (desc, &language_code,
726 &event_name, &text)) {
727 g_printf ("%*s Short Event, language_code:%s\n", spacing, "",
728 language_code);
729 g_printf ("%*s event_name : %s\n", spacing, "", event_name);
730 g_printf ("%*s text : %s\n", spacing, "", text);
731 g_free (language_code);
732 g_free (event_name);
733 g_free (text);
734 }
735 }
736 break;
737 case GST_MTS_DESC_DVB_EXTENDED_EVENT:
738 {
739 dump_dvb_extended_event (desc, spacing + 2);
740 break;
741 }
742 case GST_MTS_DESC_DVB_SUBTITLING:
743 {
744 gchar *lang;
745 guint8 type;
746 guint16 composition;
747 guint16 ancillary;
748 guint j;
749
750 for (j = 0;
751 gst_mpegts_descriptor_parse_dvb_subtitling_idx (desc, j, &lang,
752 &type, &composition, &ancillary); j++) {
753 g_printf ("%*s Subtitling, language_code:%s\n", spacing, "", lang);
754 g_printf ("%*s type : %u\n", spacing, "", type);
755 g_printf ("%*s composition page id : %u\n", spacing, "",
756 composition);
757 g_printf ("%*s ancillary page id : %u\n", spacing, "",
758 ancillary);
759 g_free (lang);
760 }
761 }
762 break;
763 case GST_MTS_DESC_DVB_TELETEXT:
764 {
765 GstMpegtsDVBTeletextType type;
766 gchar *lang;
767 guint8 magazine, page_number;
768 guint j;
769
770 for (j = 0;
771 gst_mpegts_descriptor_parse_dvb_teletext_idx (desc, j, &lang, &type,
772 &magazine, &page_number); j++) {
773 g_printf ("%*s Teletext, type:0x%02x (%s)\n", spacing, "", type,
774 enum_name (GST_TYPE_MPEGTS_DVB_TELETEXT_TYPE, type));
775 g_printf ("%*s language : %s\n", spacing, "", lang);
776 g_printf ("%*s magazine : %u\n", spacing, "", magazine);
777 g_printf ("%*s page number : %u\n", spacing, "", page_number);
778 g_free (lang);
779 }
780 }
781 break;
782 default:
783 break;
784 }
785 }
786
787 static void
dump_descriptors(GPtrArray * descriptors,guint spacing)788 dump_descriptors (GPtrArray * descriptors, guint spacing)
789 {
790 guint i;
791
792 for (i = 0; i < descriptors->len; i++) {
793 GstMpegtsDescriptor *desc = g_ptr_array_index (descriptors, i);
794 g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
795 desc->tag, descriptor_name (desc), desc->length);
796 if (DUMP_DESCRIPTORS)
797 dump_memory_content (desc, spacing + 2);
798 dump_generic_descriptor (desc, spacing + 2);
799 }
800 }
801
802 static void
dump_nit_descriptors(GPtrArray * descriptors,guint spacing)803 dump_nit_descriptors (GPtrArray * descriptors, guint spacing)
804 {
805 /* Descriptors that can only appear in NIT */
806 guint i;
807
808 for (i = 0; i < descriptors->len; i++) {
809 GstMpegtsDescriptor *desc = g_ptr_array_index (descriptors, i);
810 g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
811 desc->tag, descriptor_name (desc), desc->length);
812 if (DUMP_DESCRIPTORS)
813 dump_memory_content (desc, spacing + 2);
814 switch (desc->tag) {
815 case GST_MTS_DESC_DTG_LOGICAL_CHANNEL:
816 dump_logical_channel_descriptor (desc, spacing + 2);
817 break;
818 default:
819 dump_generic_descriptor (desc, spacing + 2);
820 break;
821 }
822 }
823 }
824
825
826 static void
dump_pat(GstMpegtsSection * section)827 dump_pat (GstMpegtsSection * section)
828 {
829 GPtrArray *pat = gst_mpegts_section_get_pat (section);
830 guint i, len;
831
832 len = pat->len;
833 g_printf (" %d program(s):\n", len);
834
835 for (i = 0; i < len; i++) {
836 GstMpegtsPatProgram *patp = g_ptr_array_index (pat, i);
837
838 g_print
839 (" program_number:%6d (0x%04x), network_or_program_map_PID:0x%04x\n",
840 patp->program_number, patp->program_number,
841 patp->network_or_program_map_PID);
842 }
843
844 g_ptr_array_unref (pat);
845 }
846
847 static void
dump_pmt(GstMpegtsSection * section)848 dump_pmt (GstMpegtsSection * section)
849 {
850 const GstMpegtsPMT *pmt = gst_mpegts_section_get_pmt (section);
851 guint i, len;
852
853 g_printf (" program_number : 0x%04x\n", section->subtable_extension);
854 g_printf (" pcr_pid : 0x%04x\n", pmt->pcr_pid);
855 dump_descriptors (pmt->descriptors, 7);
856 len = pmt->streams->len;
857 g_printf (" %d Streams:\n", len);
858 for (i = 0; i < len; i++) {
859 GstMpegtsPMTStream *stream = g_ptr_array_index (pmt->streams, i);
860 g_printf (" pid:0x%04x , stream_type:0x%02x (%s)\n", stream->pid,
861 stream->stream_type, stream_type_name (stream->stream_type));
862 dump_descriptors (stream->descriptors, 9);
863 }
864 }
865
866 static void
dump_eit(GstMpegtsSection * section)867 dump_eit (GstMpegtsSection * section)
868 {
869 const GstMpegtsEIT *eit = gst_mpegts_section_get_eit (section);
870 guint i, len;
871
872 g_assert (eit);
873
874 g_printf (" service_id : 0x%04x\n", section->subtable_extension);
875 g_printf (" transport_stream_id : 0x%04x\n", eit->transport_stream_id);
876 g_printf (" original_network_id : 0x%04x\n", eit->original_network_id);
877 g_printf (" segment_last_section_number:0x%02x, last_table_id:0x%02x\n",
878 eit->segment_last_section_number, eit->last_table_id);
879 g_printf (" actual_stream : %s, present_following : %s\n",
880 eit->actual_stream ? "TRUE" : "FALSE",
881 eit->present_following ? "TRUE" : "FALSE");
882
883 len = eit->events->len;
884 g_printf (" %d Event(s):\n", len);
885 for (i = 0; i < len; i++) {
886 gchar *tmp = (gchar *) "<NO TIME>";
887 GstMpegtsEITEvent *event = g_ptr_array_index (eit->events, i);
888
889 if (event->start_time)
890 tmp = gst_date_time_to_iso8601_string (event->start_time);
891 g_printf (" event_id:0x%04x, start_time:%s, duration:%"
892 GST_TIME_FORMAT "\n", event->event_id, tmp,
893 GST_TIME_ARGS (event->duration * GST_SECOND));
894 g_printf (" running_status:0x%02x (%s), free_CA_mode:%d (%s)\n",
895 event->running_status, enum_name (GST_TYPE_MPEGTS_RUNNING_STATUS,
896 event->running_status), event->free_CA_mode,
897 event->free_CA_mode ? "MAYBE SCRAMBLED" : "NOT SCRAMBLED");
898 if (event->start_time)
899 g_free (tmp);
900 dump_descriptors (event->descriptors, 9);
901 }
902 }
903
904 static void
dump_atsc_mult_string(GPtrArray * mstrings,guint spacing)905 dump_atsc_mult_string (GPtrArray * mstrings, guint spacing)
906 {
907 guint i;
908
909 for (i = 0; i < mstrings->len; i++) {
910 GstMpegtsAtscMultString *mstring = g_ptr_array_index (mstrings, i);
911 gint j, n;
912
913 n = mstring->segments->len;
914
915 g_printf ("%*s [multstring entry (%d) iso_639 langcode: %s]\n", spacing, "",
916 i, mstring->iso_639_langcode);
917 g_printf ("%*s segments:%d\n", spacing, "", n);
918 for (j = 0; j < n; j++) {
919 GstMpegtsAtscStringSegment *segment =
920 g_ptr_array_index (mstring->segments, j);
921
922 g_printf ("%*s Compression:0x%x\n", spacing, "",
923 segment->compression_type);
924 g_printf ("%*s Mode:0x%x\n", spacing, "", segment->mode);
925 g_printf ("%*s Len:%u\n", spacing, "", segment->compressed_data_size);
926 g_printf ("%*s %s\n", spacing, "",
927 gst_mpegts_atsc_string_segment_get_string (segment));
928 }
929 }
930 }
931
932 static void
dump_atsc_eit(GstMpegtsSection * section)933 dump_atsc_eit (GstMpegtsSection * section)
934 {
935 const GstMpegtsAtscEIT *eit = gst_mpegts_section_get_atsc_eit (section);
936 guint i, len;
937
938 g_assert (eit);
939
940 g_printf (" event_id : 0x%04x\n", eit->source_id);
941 g_printf (" protocol_version : %u\n", eit->protocol_version);
942
943 len = eit->events->len;
944 g_printf (" %d Event(s):\n", len);
945 for (i = 0; i < len; i++) {
946 GstMpegtsAtscEITEvent *event = g_ptr_array_index (eit->events, i);
947
948 g_printf (" %d)\n", i);
949 g_printf (" event_id: 0x%04x\n", event->event_id);
950 g_printf (" start_time: %u\n", event->start_time);
951 g_printf (" etm_location: 0x%x\n", event->etm_location);
952 g_printf (" length_in_seconds: %u\n", event->length_in_seconds);
953 g_printf (" Title(s):\n");
954 dump_atsc_mult_string (event->titles, 9);
955 dump_descriptors (event->descriptors, 9);
956 }
957 }
958
959 static void
dump_ett(GstMpegtsSection * section)960 dump_ett (GstMpegtsSection * section)
961 {
962 const GstMpegtsAtscETT *ett = gst_mpegts_section_get_atsc_ett (section);
963 guint len;
964
965 g_assert (ett);
966
967 g_printf (" ett_table_id_ext : 0x%04x\n", ett->ett_table_id_extension);
968 g_printf (" protocol_version : 0x%04x\n", ett->protocol_version);
969 g_printf (" etm_id : 0x%04x\n", ett->etm_id);
970
971 len = ett->messages->len;
972 g_printf (" %d Messages(s):\n", len);
973 dump_atsc_mult_string (ett->messages, 9);
974 }
975
976 static void
dump_stt(GstMpegtsSection * section)977 dump_stt (GstMpegtsSection * section)
978 {
979 const GstMpegtsAtscSTT *stt = gst_mpegts_section_get_atsc_stt (section);
980 GstDateTime *dt;
981 gchar *dt_str = NULL;
982
983 g_assert (stt);
984
985 dt = gst_mpegts_atsc_stt_get_datetime_utc ((GstMpegtsAtscSTT *) stt);
986 if (dt)
987 dt_str = gst_date_time_to_iso8601_string (dt);
988
989 g_printf (" protocol_version : 0x%04x\n", stt->protocol_version);
990 g_printf (" system_time : 0x%08x\n", stt->system_time);
991 g_printf (" gps_utc_offset : %d\n", stt->gps_utc_offset);
992 g_printf (" daylight saving : %d day:%d hour:%d\n", stt->ds_status,
993 stt->ds_dayofmonth, stt->ds_hour);
994 g_printf (" utc datetime : %s", dt_str);
995
996 g_free (dt_str);
997 gst_date_time_unref (dt);
998 }
999
1000 static void
dump_nit(GstMpegtsSection * section)1001 dump_nit (GstMpegtsSection * section)
1002 {
1003 const GstMpegtsNIT *nit = gst_mpegts_section_get_nit (section);
1004 guint i, len;
1005
1006 g_assert (nit);
1007
1008 g_printf (" network_id : 0x%04x\n", section->subtable_extension);
1009 g_printf (" actual_network : %s\n",
1010 nit->actual_network ? "TRUE" : "FALSE");
1011 dump_descriptors (nit->descriptors, 7);
1012 len = nit->streams->len;
1013 g_printf (" %d Streams:\n", len);
1014 for (i = 0; i < len; i++) {
1015 GstMpegtsNITStream *stream = g_ptr_array_index (nit->streams, i);
1016 g_printf
1017 (" transport_stream_id:0x%04x , original_network_id:0x%02x\n",
1018 stream->transport_stream_id, stream->original_network_id);
1019 dump_nit_descriptors (stream->descriptors, 9);
1020 }
1021 }
1022
1023 static void
dump_bat(GstMpegtsSection * section)1024 dump_bat (GstMpegtsSection * section)
1025 {
1026 const GstMpegtsBAT *bat = gst_mpegts_section_get_bat (section);
1027 guint i, len;
1028
1029 g_assert (bat);
1030
1031 g_printf (" bouquet_id : 0x%04x\n", section->subtable_extension);
1032 dump_descriptors (bat->descriptors, 7);
1033 len = bat->streams->len;
1034 g_printf (" %d Streams:\n", len);
1035 for (i = 0; i < len; i++) {
1036 GstMpegtsBATStream *stream = g_ptr_array_index (bat->streams, i);
1037 g_printf
1038 (" transport_stream_id:0x%04x , original_network_id:0x%02x\n",
1039 stream->transport_stream_id, stream->original_network_id);
1040 dump_descriptors (stream->descriptors, 9);
1041 }
1042 }
1043
1044 static void
dump_sdt(GstMpegtsSection * section)1045 dump_sdt (GstMpegtsSection * section)
1046 {
1047 const GstMpegtsSDT *sdt = gst_mpegts_section_get_sdt (section);
1048 guint i, len;
1049
1050 g_assert (sdt);
1051
1052 g_printf (" original_network_id : 0x%04x\n", sdt->original_network_id);
1053 g_printf (" actual_ts : %s\n",
1054 sdt->actual_ts ? "TRUE" : "FALSE");
1055 len = sdt->services->len;
1056 g_printf (" %d Services:\n", len);
1057 for (i = 0; i < len; i++) {
1058 GstMpegtsSDTService *service = g_ptr_array_index (sdt->services, i);
1059 g_print
1060 (" service_id:0x%04x, EIT_schedule_flag:%d, EIT_present_following_flag:%d\n",
1061 service->service_id, service->EIT_schedule_flag,
1062 service->EIT_present_following_flag);
1063 g_print
1064 (" running_status:0x%02x (%s), free_CA_mode:%d (%s)\n",
1065 service->running_status,
1066 enum_name (GST_TYPE_MPEGTS_RUNNING_STATUS, service->running_status),
1067 service->free_CA_mode,
1068 service->free_CA_mode ? "MAYBE SCRAMBLED" : "NOT SCRAMBLED");
1069 dump_descriptors (service->descriptors, 9);
1070 }
1071 }
1072
1073
1074 static void
dump_sit(GstMpegtsSection * section)1075 dump_sit (GstMpegtsSection * section)
1076 {
1077 const GstMpegtsSIT *sit = gst_mpegts_section_get_sit (section);
1078 guint i, len;
1079
1080 g_assert (sit);
1081
1082 dump_descriptors (sit->descriptors, 7);
1083 len = sit->services->len;
1084 g_printf (" %d Services:\n", len);
1085 for (i = 0; i < len; i++) {
1086 GstMpegtsSITService *service = g_ptr_array_index (sit->services, i);
1087 g_print
1088 (" service_id:0x%04x, running_status:0x%02x (%s)\n",
1089 service->service_id, service->running_status,
1090 enum_name (GST_TYPE_MPEGTS_RUNNING_STATUS, service->running_status));
1091 dump_descriptors (service->descriptors, 9);
1092 }
1093 }
1094
1095
1096 static void
dump_tdt(GstMpegtsSection * section)1097 dump_tdt (GstMpegtsSection * section)
1098 {
1099 GstDateTime *date = gst_mpegts_section_get_tdt (section);
1100
1101 if (date) {
1102 gchar *str = gst_date_time_to_iso8601_string (date);
1103 g_printf (" utc_time : %s\n", str);
1104 g_free (str);
1105 gst_date_time_unref (date);
1106 } else {
1107 g_printf (" No utc_time present\n");
1108 }
1109 }
1110
1111 static void
dump_tot(GstMpegtsSection * section)1112 dump_tot (GstMpegtsSection * section)
1113 {
1114 const GstMpegtsTOT *tot = gst_mpegts_section_get_tot (section);
1115 gchar *str = gst_date_time_to_iso8601_string (tot->utc_time);
1116
1117 g_printf (" utc_time : %s\n", str);
1118 dump_descriptors (tot->descriptors, 7);
1119 g_free (str);
1120 }
1121
1122 static void
dump_mgt(GstMpegtsSection * section)1123 dump_mgt (GstMpegtsSection * section)
1124 {
1125 const GstMpegtsAtscMGT *mgt = gst_mpegts_section_get_atsc_mgt (section);
1126 gint i;
1127
1128 g_printf (" protocol_version : %u\n", mgt->protocol_version);
1129 g_printf (" tables number : %d\n", mgt->tables->len);
1130 for (i = 0; i < mgt->tables->len; i++) {
1131 GstMpegtsAtscMGTTable *table = g_ptr_array_index (mgt->tables, i);
1132 g_printf (" table %d)\n", i);
1133 g_printf (" table_type : %u\n", table->table_type);
1134 g_printf (" pid : 0x%x\n", table->pid);
1135 g_printf (" version_number: %u\n", table->version_number);
1136 g_printf (" number_bytes : %u\n", table->number_bytes);
1137 dump_descriptors (table->descriptors, 9);
1138 }
1139 dump_descriptors (mgt->descriptors, 7);
1140 }
1141
1142 static void
dump_vct(GstMpegtsSection * section)1143 dump_vct (GstMpegtsSection * section)
1144 {
1145 const GstMpegtsAtscVCT *vct;
1146 gint i;
1147
1148 if (GST_MPEGTS_SECTION_TYPE (section) == GST_MPEGTS_SECTION_ATSC_CVCT) {
1149 vct = gst_mpegts_section_get_atsc_cvct (section);
1150 } else {
1151 /* GST_MPEGTS_SECTION_ATSC_TVCT */
1152 vct = gst_mpegts_section_get_atsc_tvct (section);
1153 }
1154
1155 g_assert (vct);
1156
1157 g_printf (" transport_stream_id : 0x%04x\n", vct->transport_stream_id);
1158 g_printf (" protocol_version : %u\n", vct->protocol_version);
1159 g_printf (" %d Sources:\n", vct->sources->len);
1160 for (i = 0; i < vct->sources->len; i++) {
1161 GstMpegtsAtscVCTSource *source = g_ptr_array_index (vct->sources, i);
1162 g_print (" short_name: %s\n", source->short_name);
1163 g_print (" major_channel_number: %u, minor_channel_number: %u\n",
1164 source->major_channel_number, source->minor_channel_number);
1165 g_print (" modulation_mode: %u\n", source->modulation_mode);
1166 g_print (" carrier_frequency: %u\n", source->carrier_frequency);
1167 g_print (" channel_tsid: %u\n", source->channel_TSID);
1168 g_print (" program_number: %u\n", source->program_number);
1169 g_print (" ETM_location: %u\n", source->ETM_location);
1170 g_print (" access_controlled: %u\n", source->access_controlled);
1171 g_print (" hidden: %u\n", source->hidden);
1172 if (section->table_id == GST_MPEGTS_SECTION_ATSC_CVCT) {
1173 g_print (" path_select: %u\n", source->path_select);
1174 g_print (" out_of_band: %u\n", source->out_of_band);
1175 }
1176 g_print (" hide_guide: %u\n", source->hide_guide);
1177 g_print (" service_type: %u\n", source->service_type);
1178 g_print (" source_id: %u\n", source->source_id);
1179
1180 dump_descriptors (source->descriptors, 9);
1181 }
1182 dump_descriptors (vct->descriptors, 7);
1183 }
1184
1185 static void
dump_cat(GstMpegtsSection * section)1186 dump_cat (GstMpegtsSection * section)
1187 {
1188 GPtrArray *descriptors;
1189
1190 descriptors = gst_mpegts_section_get_cat (section);
1191 g_assert (descriptors);
1192 dump_descriptors (descriptors, 7);
1193 g_ptr_array_unref (descriptors);
1194 }
1195
1196 static const gchar *
scte_descriptor_name(guint8 tag)1197 scte_descriptor_name (guint8 tag)
1198 {
1199 switch (tag) {
1200 case 0x00:
1201 return "avail";
1202 case 0x01:
1203 return "DTMF";
1204 case 0x02:
1205 return "segmentation";
1206 case 0x03:
1207 return "time";
1208 case 0x04:
1209 return "audio";
1210 default:
1211 return "UNKNOWN";
1212 }
1213 }
1214
1215 static void
dump_scte_descriptors(GPtrArray * descriptors,guint spacing)1216 dump_scte_descriptors (GPtrArray * descriptors, guint spacing)
1217 {
1218 guint i;
1219
1220 for (i = 0; i < descriptors->len; i++) {
1221 GstMpegtsDescriptor *desc = g_ptr_array_index (descriptors, i);
1222 g_printf ("%*s [scte descriptor 0x%02x (%s) length:%d]\n", spacing, "",
1223 desc->tag, scte_descriptor_name (desc->tag), desc->length);
1224 if (DUMP_DESCRIPTORS)
1225 dump_memory_content (desc, spacing + 2);
1226 /* FIXME : Add parsing of SCTE descriptors */
1227 }
1228 }
1229
1230
1231 static void
dump_scte_sit(GstMpegtsSection * section)1232 dump_scte_sit (GstMpegtsSection * section)
1233 {
1234 const GstMpegtsSCTESIT *sit = gst_mpegts_section_get_scte_sit (section);
1235 guint i, len;
1236
1237 g_assert (sit);
1238
1239 g_printf (" encrypted_packet : %d\n", sit->encrypted_packet);
1240 if (sit->encrypted_packet) {
1241 g_printf (" encryption_algorithm: %d\n", sit->encryption_algorithm);
1242 g_printf (" cw_index : %d\n", sit->cw_index);
1243 g_printf (" tier : %d\n", sit->tier);
1244 }
1245 g_printf (" pts_adjustment : %" G_GUINT64_FORMAT " (%"
1246 GST_TIME_FORMAT ")\n", sit->pts_adjustment,
1247 GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (sit->pts_adjustment)));
1248 g_printf (" command_type : %d\n", sit->splice_command_type);
1249
1250 if ((len = sit->splices->len)) {
1251 g_printf (" %d splice(s):\n", len);
1252 for (i = 0; i < len; i++) {
1253 GstMpegtsSCTESpliceEvent *event = g_ptr_array_index (sit->splices, i);
1254 g_printf (" event_id:%d event_cancel_indicator:%d\n",
1255 event->splice_event_id, event->splice_event_cancel_indicator);
1256 if (!event->splice_event_cancel_indicator) {
1257 g_printf (" out_of_network_indicator:%d\n",
1258 event->out_of_network_indicator);
1259 if (event->program_splice_flag) {
1260 if (event->program_splice_time_specified)
1261 g_printf (" program_splice_time:%" G_GUINT64_FORMAT " (%"
1262 GST_TIME_FORMAT ")\n", event->program_splice_time,
1263 GST_TIME_ARGS (MPEGTIME_TO_GSTTIME
1264 (event->program_splice_time)));
1265 else
1266 g_printf (" program_splice_time not specified\n");
1267 }
1268 if (event->duration_flag) {
1269 g_printf (" break_duration_auto_return:%d\n",
1270 event->break_duration_auto_return);
1271 g_printf (" break_duration:%" G_GUINT64_FORMAT " (%"
1272 GST_TIME_FORMAT ")\n", event->break_duration,
1273 GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (event->break_duration)));
1274
1275 }
1276 g_printf (" unique_program_id : %d\n", event->unique_program_id);
1277 g_printf (" avail num/expected : %d/%d\n",
1278 event->avail_num, event->avails_expected);
1279 }
1280 }
1281 }
1282
1283 dump_scte_descriptors (sit->descriptors, 4);
1284 }
1285
1286 static void
dump_section(GstMpegtsSection * section)1287 dump_section (GstMpegtsSection * section)
1288 {
1289 switch (GST_MPEGTS_SECTION_TYPE (section)) {
1290 case GST_MPEGTS_SECTION_PAT:
1291 dump_pat (section);
1292 break;
1293 case GST_MPEGTS_SECTION_PMT:
1294 dump_pmt (section);
1295 break;
1296 case GST_MPEGTS_SECTION_CAT:
1297 dump_cat (section);
1298 break;
1299 case GST_MPEGTS_SECTION_TDT:
1300 dump_tdt (section);
1301 break;
1302 case GST_MPEGTS_SECTION_TOT:
1303 dump_tot (section);
1304 break;
1305 case GST_MPEGTS_SECTION_SDT:
1306 dump_sdt (section);
1307 break;
1308 case GST_MPEGTS_SECTION_NIT:
1309 dump_nit (section);
1310 break;
1311 case GST_MPEGTS_SECTION_BAT:
1312 dump_bat (section);
1313 break;
1314 case GST_MPEGTS_SECTION_EIT:
1315 dump_eit (section);
1316 break;
1317 case GST_MPEGTS_SECTION_SIT:
1318 dump_sit (section);
1319 break;
1320 case GST_MPEGTS_SECTION_ATSC_MGT:
1321 dump_mgt (section);
1322 break;
1323 case GST_MPEGTS_SECTION_ATSC_CVCT:
1324 case GST_MPEGTS_SECTION_ATSC_TVCT:
1325 dump_vct (section);
1326 break;
1327 case GST_MPEGTS_SECTION_ATSC_EIT:
1328 dump_atsc_eit (section);
1329 break;
1330 case GST_MPEGTS_SECTION_ATSC_ETT:
1331 dump_ett (section);
1332 break;
1333 case GST_MPEGTS_SECTION_ATSC_STT:
1334 dump_stt (section);
1335 break;
1336 case GST_MPEGTS_SECTION_SCTE_SIT:
1337 dump_scte_sit (section);
1338 break;
1339 default:
1340 g_printf (" Unknown section type\n");
1341 break;
1342 }
1343 }
1344
1345 static void
_on_bus_message(GstBus * bus,GstMessage * message,GMainLoop * mainloop)1346 _on_bus_message (GstBus * bus, GstMessage * message, GMainLoop * mainloop)
1347 {
1348 /* g_printf ("Got message %s\n", GST_MESSAGE_TYPE_NAME (message)); */
1349
1350 switch (GST_MESSAGE_TYPE (message)) {
1351 case GST_MESSAGE_ERROR:
1352 case GST_MESSAGE_EOS:
1353 g_main_loop_quit (mainloop);
1354 break;
1355 case GST_MESSAGE_ELEMENT:
1356 {
1357 GstMpegtsSection *section;
1358 if ((section = gst_message_parse_mpegts_section (message))) {
1359 const gchar *table_name;
1360
1361 table_name = table_id_name (section->table_id);
1362 g_print
1363 ("Got section: PID:0x%04x type:%s (table_id 0x%02x (%s)) at offset %"
1364 G_GUINT64_FORMAT "\n", section->pid,
1365 enum_name (GST_TYPE_MPEGTS_SECTION_TYPE, section->section_type),
1366 section->table_id, table_name, section->offset);
1367 if (!section->short_section) {
1368 g_print
1369 (" subtable_extension:0x%04x, version_number:0x%02x\n",
1370 section->subtable_extension, section->version_number);
1371 g_print
1372 (" section_number:0x%02x last_section_number:0x%02x crc:0x%08x\n",
1373 section->section_number, section->last_section_number,
1374 section->crc);
1375 }
1376 dump_section (section);
1377 g_printf ("\n\n");
1378 gst_mpegts_section_unref (section);
1379 }
1380 break;
1381 }
1382 default:
1383 break;
1384 }
1385 }
1386
1387 int
main(int argc,gchar ** argv)1388 main (int argc, gchar ** argv)
1389 {
1390 GstElement *pipeline = NULL;
1391 GError *error = NULL;
1392 GstBus *bus;
1393 GMainLoop *mainloop;
1394
1395 gst_init (&argc, &argv);
1396
1397 gst_mpegts_initialize ();
1398
1399 pipeline = gst_parse_launchv ((const gchar **) &argv[1], &error);
1400 if (error) {
1401 g_printf ("pipeline could not be constructed: %s\n", error->message);
1402 g_error_free (error);
1403 return 1;
1404 }
1405
1406 /* Hack: ensure all enum type classes are loaded */
1407 g_type_class_ref (GST_TYPE_MPEGTS_SECTION_TYPE);
1408 g_type_class_ref (GST_TYPE_MPEGTS_SECTION_TABLE_ID);
1409 g_type_class_ref (GST_TYPE_MPEGTS_RUNNING_STATUS);
1410 g_type_class_ref (GST_TYPE_MPEGTS_DESCRIPTOR_TYPE);
1411 g_type_class_ref (GST_TYPE_MPEGTS_DVB_DESCRIPTOR_TYPE);
1412 g_type_class_ref (GST_TYPE_MPEGTS_DVB_EXTENDED_DESCRIPTOR_TYPE);
1413 g_type_class_ref (GST_TYPE_MPEGTS_ATSC_DESCRIPTOR_TYPE);
1414 g_type_class_ref (GST_TYPE_MPEGTS_ISDB_DESCRIPTOR_TYPE);
1415 g_type_class_ref (GST_TYPE_MPEGTS_SCTE_DESCRIPTOR_TYPE);
1416 g_type_class_ref (GST_TYPE_MPEGTS_MISC_DESCRIPTOR_TYPE);
1417 g_type_class_ref (GST_TYPE_MPEGTS_ISO639_AUDIO_TYPE);
1418 g_type_class_ref (GST_TYPE_MPEGTS_DVB_SERVICE_TYPE);
1419 g_type_class_ref (GST_TYPE_MPEGTS_DVB_TELETEXT_TYPE);
1420 g_type_class_ref (GST_TYPE_MPEGTS_STREAM_TYPE);
1421 g_type_class_ref (GST_TYPE_MPEGTS_SECTION_DVB_TABLE_ID);
1422 g_type_class_ref (GST_TYPE_MPEGTS_SECTION_ATSC_TABLE_ID);
1423 g_type_class_ref (GST_TYPE_MPEGTS_SECTION_SCTE_TABLE_ID);
1424 g_type_class_ref (GST_TYPE_MPEGTS_MODULATION_TYPE);
1425 g_type_class_ref (GST_TYPE_MPEGTS_DVB_CODE_RATE);
1426 g_type_class_ref (GST_TYPE_MPEGTS_CABLE_OUTER_FEC_SCHEME);
1427 g_type_class_ref (GST_TYPE_MPEGTS_TERRESTRIAL_TRANSMISSION_MODE);
1428 g_type_class_ref (GST_TYPE_MPEGTS_TERRESTRIAL_GUARD_INTERVAL);
1429 g_type_class_ref (GST_TYPE_MPEGTS_TERRESTRIAL_HIERARCHY);
1430 g_type_class_ref (GST_TYPE_MPEGTS_DVB_LINKAGE_TYPE);
1431 g_type_class_ref (GST_TYPE_MPEGTS_DVB_LINKAGE_HAND_OVER_TYPE);
1432 g_type_class_ref (GST_TYPE_MPEGTS_COMPONENT_STREAM_CONTENT);
1433 g_type_class_ref (GST_TYPE_MPEGTS_CONTENT_NIBBLE_HI);
1434 g_type_class_ref (GST_TYPE_MPEGTS_SCTE_STREAM_TYPE);
1435 g_type_class_ref (GST_TYPE_MPEGTS_HDMV_STREAM_TYPE);
1436 g_type_class_ref (GST_TYPE_MPEGTS_SECTION_SCTE_TABLE_ID);
1437
1438 mainloop = g_main_loop_new (NULL, FALSE);
1439
1440 /* Put a bus handler */
1441 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
1442 gst_bus_add_signal_watch (bus);
1443 g_signal_connect (bus, "message", (GCallback) _on_bus_message, mainloop);
1444
1445 /* Start pipeline */
1446 gst_element_set_state (pipeline, GST_STATE_PLAYING);
1447 g_main_loop_run (mainloop);
1448
1449 gst_element_set_state (pipeline, GST_STATE_NULL);
1450
1451 gst_object_unref (pipeline);
1452 gst_object_unref (bus);
1453
1454 return 0;
1455 }
1456