1 /*
2 * gstmpegtsdescriptor.c -
3 * Copyright (C) 2013 Edward Hervey
4 *
5 * Authors:
6 * Edward Hervey <edward@collabora.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "mpegts.h"
31 #include "gstmpegts-private.h"
32
33
34 /**
35 * SECTION:gst-dvb-descriptor
36 * @title: DVB variants of MPEG-TS descriptors
37 * @short_description: Descriptors for the various DVB specifications
38 * @include: gst/mpegts/mpegts.h
39 *
40 */
41
42 /*
43 * TODO
44 *
45 * * Add common validation code for data presence and minimum/maximum expected
46 * size.
47 * * Add parsing methods for the following descriptors that were previously
48 * handled in mpegtsbase:
49 * * GST_MTS_DESC_DVB_DATA_BROADCAST_ID
50 * * GST_MTS_DESC_DVB_CAROUSEL_IDENTIFIER
51 */
52
53 #define BCD_UN(a) ((a) & 0x0f)
54 #define BCD_DEC(a) (((a) >> 4) & 0x0f)
55 #define BCD(a) (BCD_UN(a) + 10 * BCD_DEC(a))
56 #define BCD_16(a) (BCD(a[1]) + 100 * BCD(a[0]))
57 #define BCD_28(a) (BCD_DEC(a[3]) + 10 * BCD(a[2]) + 1000 * BCD(a[1]) + 100000 * BCD(a[0]))
58 #define BCD_32(a) (BCD(a[3]) + 100 * BCD(a[2]) + 10000 * BCD(a[1]) + 1000000 * BCD(a[0]))
59
60 #define DEFINE_STATIC_COPY_FUNCTION(type, name) \
61 static type * _##name##_copy (type * source) \
62 { \
63 return g_slice_dup (type, source); \
64 }
65
66 #define DEFINE_STATIC_FREE_FUNCTION(type, name) \
67 static void _##name##_free (type * source) \
68 { \
69 g_slice_free (type, source); \
70 }
71
72 /* GST_MTS_DESC_DVB_NETWORK_NAME (0x40) */
73 /**
74 * gst_mpegts_descriptor_parse_dvb_network_name:
75 * @descriptor: a %GST_MTS_DESC_DVB_NETWORK_NAME #GstMpegtsDescriptor
76 * @name: (out) (transfer full): the extracted name
77 *
78 * Parses out the dvb network name from the @descriptor:
79 *
80 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
81 */
82 gboolean
gst_mpegts_descriptor_parse_dvb_network_name(const GstMpegtsDescriptor * descriptor,gchar ** name)83 gst_mpegts_descriptor_parse_dvb_network_name (const GstMpegtsDescriptor *
84 descriptor, gchar ** name)
85 {
86 g_return_val_if_fail (descriptor != NULL && name != NULL, FALSE);
87 /* We need at least one byte of data for the string */
88 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_NETWORK_NAME, 1, FALSE);
89
90 *name = get_encoding_and_convert ((gchar *) descriptor->data + 2,
91 descriptor->data[1]);
92 return TRUE;
93 }
94
95 /**
96 * gst_mpegts_descriptor_from_dvb_network_name:
97 * @name: the network name to set
98 *
99 * Creates a #GstMpegtsDescriptor to be a %GST_MTS_DESC_DVB_NETWORK_NAME,
100 * with the network name @name. The data field of the #GstMpegtsDescriptor
101 * will be allocated, and transferred to the caller.
102 *
103 * Returns: (transfer full): the #GstMpegtsDescriptor or %NULL on fail
104 */
105 GstMpegtsDescriptor *
gst_mpegts_descriptor_from_dvb_network_name(const gchar * name)106 gst_mpegts_descriptor_from_dvb_network_name (const gchar * name)
107 {
108 GstMpegtsDescriptor *descriptor;
109 guint8 *converted_name;
110 gsize size;
111
112 g_return_val_if_fail (name != NULL, NULL);
113
114 converted_name = dvb_text_from_utf8 (name, &size);
115
116 if (size >= 256) {
117 g_free (converted_name);
118 return NULL;
119 }
120
121 if (!converted_name) {
122 GST_WARNING ("Could not find proper encoding for string `%s`", name);
123 return NULL;
124 }
125
126 descriptor = _new_descriptor (GST_MTS_DESC_DVB_NETWORK_NAME, size);
127 memcpy (descriptor->data + 2, converted_name, size);
128 g_free (converted_name);
129
130 return descriptor;
131 }
132
133 /* GST_MTS_DESC_DVB_SERVICE_LIST (0x41) */
134
135 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBServiceListItem,
136 gst_mpegts_dvb_service_list_item);
137
138 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBServiceListItem,
139 gst_mpegts_dvb_service_list_item);
140
141 G_DEFINE_BOXED_TYPE (GstMpegtsDVBServiceListItem,
142 gst_mpegts_dvb_service_list_item,
143 (GBoxedCopyFunc) _gst_mpegts_dvb_service_list_item_copy,
144 (GFreeFunc) _gst_mpegts_dvb_service_list_item_free);
145
146 /**
147 * gst_mpegts_descriptor_parse_dvb_service_list:
148 * @descriptor: a %GST_MTS_DESC_DVB_SERVICE_LIST #GstMpegtsDescriptor
149 * @list: (out) (transfer full) (element-type GstMpegtsDVBServiceListItem):
150 * the list of services
151 *
152 * Parses out a list of services from the @descriptor:
153 *
154 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
155 */
156 gboolean
gst_mpegts_descriptor_parse_dvb_service_list(const GstMpegtsDescriptor * descriptor,GPtrArray ** list)157 gst_mpegts_descriptor_parse_dvb_service_list (const GstMpegtsDescriptor *
158 descriptor, GPtrArray ** list)
159 {
160 guint8 *data, i;
161
162 g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE);
163 /* a entry has 3 bytes, 2 for service id, 1 for service type */
164 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SERVICE_LIST, 3, FALSE);
165
166 data = (guint8 *) descriptor->data + 2;
167
168 *list = g_ptr_array_new_with_free_func ((GDestroyNotify)
169 _gst_mpegts_dvb_service_list_item_free);
170
171 for (i = 0; i < descriptor->length - 2; i += 3) {
172 GstMpegtsDVBServiceListItem *item =
173 g_slice_new0 (GstMpegtsDVBServiceListItem);
174
175 g_ptr_array_add (*list, item);
176 item->service_id = GST_READ_UINT16_BE (data);
177 data += 2;
178
179 item->type = *data;
180 data += 1;
181 }
182
183 return TRUE;
184 }
185
186 /* GST_MTS_DESC_DVB_STUFFING (0x42) */
187 /**
188 * gst_mpegts_descriptor_parse_dvb_stuffing:
189 * @descriptor: a %GST_MTS_DESC_DVB_STUFFING #GstMpegtsDescriptor
190 * @stuffing_bytes: (out) (transfer full): the stuffing bytes
191 *
192 * Parses out the stuffing bytes from the @descriptor.
193 *
194 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
195 */
196 gboolean
gst_mpegts_descriptor_parse_dvb_stuffing(const GstMpegtsDescriptor * descriptor,guint8 ** stuffing_bytes)197 gst_mpegts_descriptor_parse_dvb_stuffing (const GstMpegtsDescriptor *
198 descriptor, guint8 ** stuffing_bytes)
199 {
200 guint8 *data;
201
202 g_return_val_if_fail (descriptor != NULL && stuffing_bytes != NULL, FALSE);
203 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_STUFFING, FALSE);
204
205 data = (guint8 *) descriptor->data + 2;
206
207 *stuffing_bytes = g_memdup2 (data, descriptor->length);
208
209 return TRUE;
210 }
211
212 /* GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM (0x43) */
213
214 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsSatelliteDeliverySystemDescriptor,
215 gst_mpegts_satellite_delivery_system_descriptor);
216
217 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsSatelliteDeliverySystemDescriptor,
218 gst_mpegts_satellite_delivery_system_descriptor);
219
220 G_DEFINE_BOXED_TYPE (GstMpegtsSatelliteDeliverySystemDescriptor,
221 gst_mpegts_satellite_delivery_system_descriptor,
222 (GBoxedCopyFunc) _gst_mpegts_satellite_delivery_system_descriptor_copy,
223 (GFreeFunc) _gst_mpegts_satellite_delivery_system_descriptor_free);
224
225 /**
226 * gst_mpegts_descriptor_parse_satellite_delivery_system:
227 * @descriptor: a %GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM #GstMpegtsDescriptor
228 * @res: (out) (transfer none): the #GstMpegtsSatelliteDeliverySystemDescriptor to fill
229 *
230 * Extracts the satellite delivery system information from @descriptor.
231 *
232 * Returns: %TRUE if parsing succeeded, else %FALSE.
233 */
234 gboolean
gst_mpegts_descriptor_parse_satellite_delivery_system(const GstMpegtsDescriptor * descriptor,GstMpegtsSatelliteDeliverySystemDescriptor * res)235 gst_mpegts_descriptor_parse_satellite_delivery_system (const GstMpegtsDescriptor
236 * descriptor, GstMpegtsSatelliteDeliverySystemDescriptor * res)
237 {
238 guint8 *data;
239 guint8 tmp;
240
241 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
242 /* This descriptor is always 11 bytes long */
243 __common_desc_checks_exact (descriptor,
244 GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM, 11, FALSE);
245
246 data = (guint8 *) descriptor->data + 2;
247
248 /* BCD coded frequency in GHz (decimal point occurs after the 3rd character)
249 * So direct BCD gives us units of (GHz / 100 000) = 10 kHz*/
250 res->frequency = BCD_32 (data) * 10;
251 data += 4;
252 /* BCD codec position in degrees (float pointer after the 3rd character) */
253 res->orbital_position = (BCD_16 (data)) / 10.0;
254 data += 2;
255
256 tmp = *data;
257 res->west_east = (tmp & 0x80) == 0x80;
258 res->polarization = (tmp >> 7) & 0x03;
259 res->modulation_system = (tmp & 0x04) == 0x04;
260 if (res->modulation_system)
261 res->roll_off = (tmp >> 3 & 0x03);
262 else
263 res->roll_off = GST_MPEGTS_ROLLOFF_AUTO;
264 switch (tmp & 0x03) {
265 case 0x00:
266 res->modulation_type = GST_MPEGTS_MODULATION_QAM_AUTO;
267 break;
268 case 0x01:
269 res->modulation_type = GST_MPEGTS_MODULATION_QPSK;
270 break;
271 case 0x02:
272 res->modulation_type = GST_MPEGTS_MODULATION_PSK_8;
273 break;
274 case 0x03:
275 res->modulation_type = GST_MPEGTS_MODULATION_QAM_16;
276 break;
277 default:
278 res->modulation_type = GST_MPEGTS_MODULATION_QAM_AUTO;
279 break;
280 }
281 data += 1;
282 /* symbol_rate is in Msymbols/ (decimal point occurs after 3rd character) */
283 /* So direct BCD gives us units of (Msymbol / 10 000) = 100 sym/s */
284 res->symbol_rate = BCD_28 (data) * 100;
285 data += 3;
286 /* fec_inner */
287 switch (*data >> 4) {
288 case 0x01:
289 res->fec_inner = GST_MPEGTS_FEC_1_2;
290 break;
291 case 0x02:
292 res->fec_inner = GST_MPEGTS_FEC_2_3;
293 break;
294 case 0x03:
295 res->fec_inner = GST_MPEGTS_FEC_3_4;
296 break;
297 case 0x04:
298 res->fec_inner = GST_MPEGTS_FEC_5_6;
299 break;
300 case 0x05:
301 res->fec_inner = GST_MPEGTS_FEC_7_8;
302 break;
303 case 0x06:
304 res->fec_inner = GST_MPEGTS_FEC_8_9;
305 break;
306 case 0x07:
307 res->fec_inner = GST_MPEGTS_FEC_3_5;
308 break;
309 case 0x08:
310 res->fec_inner = GST_MPEGTS_FEC_4_5;
311 break;
312 case 0x09:
313 res->fec_inner = GST_MPEGTS_FEC_9_10;
314 break;
315 case 0x0f:
316 res->fec_inner = GST_MPEGTS_FEC_NONE;
317 break;
318 default:
319 res->fec_inner = GST_MPEGTS_FEC_AUTO;
320 break;
321 }
322
323 return TRUE;
324 }
325
326 /* GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM (0x44) */
327
328 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsCableDeliverySystemDescriptor,
329 gst_mpegts_dvb_cable_delivery_system_descriptor);
330
gst_mpegts_dvb_cable_delivery_system_descriptor_free(GstMpegtsCableDeliverySystemDescriptor * source)331 void gst_mpegts_dvb_cable_delivery_system_descriptor_free
332 (GstMpegtsCableDeliverySystemDescriptor * source)
333 {
334 g_slice_free (GstMpegtsCableDeliverySystemDescriptor, source);
335 }
336
337 G_DEFINE_BOXED_TYPE (GstMpegtsCableDeliverySystemDescriptor,
338 gst_mpegts_dvb_cable_delivery_system_descriptor,
339 (GBoxedCopyFunc) _gst_mpegts_dvb_cable_delivery_system_descriptor_copy,
340 (GFreeFunc) gst_mpegts_dvb_cable_delivery_system_descriptor_free);
341
342 /**
343 * gst_mpegts_descriptor_parse_cable_delivery_system:
344 * @descriptor: a %GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM #GstMpegtsDescriptor
345 * @res: (out) (transfer none): the #GstMpegtsCableDeliverySystemDescriptor to fill
346 *
347 * Extracts the cable delivery system information from @descriptor.
348 *
349 * Returns: %TRUE if parsing succeeded, else %FALSE.
350 */
351 gboolean
gst_mpegts_descriptor_parse_cable_delivery_system(const GstMpegtsDescriptor * descriptor,GstMpegtsCableDeliverySystemDescriptor * res)352 gst_mpegts_descriptor_parse_cable_delivery_system (const GstMpegtsDescriptor *
353 descriptor, GstMpegtsCableDeliverySystemDescriptor * res)
354 {
355 guint8 *data;
356
357 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
358 /* This descriptor is always 11 bytes long */
359 __common_desc_checks_exact (descriptor,
360 GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM, 11, FALSE);
361
362 data = (guint8 *) descriptor->data + 2;
363 /* BCD in MHz, decimal place after the fourth character */
364 res->frequency = BCD_32 (data) * 100;
365 data += 5;
366 /* fec_out (4bits) */
367 res->outer_fec = *data++ & 0x0f;
368 switch (*data) {
369 case 0x00:
370 res->modulation = GST_MPEGTS_MODULATION_NONE;
371 break;
372 case 0x01:
373 res->modulation = GST_MPEGTS_MODULATION_QAM_16;
374 break;
375 case 0x02:
376 res->modulation = GST_MPEGTS_MODULATION_QAM_32;
377 break;
378 case 0x03:
379 res->modulation = GST_MPEGTS_MODULATION_QAM_64;
380 break;
381 case 0x04:
382 res->modulation = GST_MPEGTS_MODULATION_QAM_128;
383 break;
384 case 0x05:
385 res->modulation = GST_MPEGTS_MODULATION_QAM_256;
386 break;
387 default:
388 GST_WARNING ("Unsupported cable modulation type: 0x%02x", *data);
389 res->modulation = GST_MPEGTS_MODULATION_NONE;
390 break;
391 }
392
393 data += 1;
394 /* symbol_rate is in Msymbols/ (decimal point occurs after 3rd character) */
395 /* So direct BCD gives us units of (Msymbol / 10 000) = 100 sym/s */
396 res->symbol_rate = BCD_28 (data) * 100;
397 data += 3;
398 /* fec_inner */
399 switch (*data & 0xf) {
400 case 0x00:
401 res->fec_inner = GST_MPEGTS_FEC_AUTO;
402 break;
403 case 0x01:
404 res->fec_inner = GST_MPEGTS_FEC_1_2;
405 break;
406 case 0x02:
407 res->fec_inner = GST_MPEGTS_FEC_2_3;
408 break;
409 case 0x03:
410 res->fec_inner = GST_MPEGTS_FEC_3_4;
411 break;
412 case 0x04:
413 res->fec_inner = GST_MPEGTS_FEC_5_6;
414 break;
415 case 0x05:
416 res->fec_inner = GST_MPEGTS_FEC_7_8;
417 break;
418 case 0x06:
419 res->fec_inner = GST_MPEGTS_FEC_8_9;
420 break;
421 case 0x07:
422 res->fec_inner = GST_MPEGTS_FEC_3_5;
423 break;
424 case 0x08:
425 res->fec_inner = GST_MPEGTS_FEC_4_5;
426 break;
427 case 0x09:
428 res->fec_inner = GST_MPEGTS_FEC_9_10;
429 break;
430 case 0x0f:
431 res->fec_inner = GST_MPEGTS_FEC_NONE;
432 break;
433 default:
434 res->fec_inner = GST_MPEGTS_FEC_AUTO;
435 break;
436 }
437
438 return TRUE;
439 }
440
441 /* GST_MTS_DESC_DVB_BOUQUET_NAME (0x47) */
442 /**
443 * gst_mpegts_descriptor_parse_dvb_bouquet_name:
444 * @bouquet_name: (out) (transfer full) (allow-none): the bouquet name
445 *
446 * Extracts the bouquet name from @descriptor.
447 *
448 * Returns: %TRUE if parsing succeeded, else %FALSE.
449 */
450 gboolean
gst_mpegts_descriptor_parse_dvb_bouquet_name(const GstMpegtsDescriptor * descriptor,gchar ** bouquet_name)451 gst_mpegts_descriptor_parse_dvb_bouquet_name (const GstMpegtsDescriptor *
452 descriptor, gchar ** bouquet_name)
453 {
454 guint8 *data;
455
456 g_return_val_if_fail (descriptor != NULL && bouquet_name != NULL, FALSE);
457 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_BOUQUET_NAME, 1, FALSE);
458
459 data = (guint8 *) descriptor->data + 2;
460
461 *bouquet_name =
462 get_encoding_and_convert ((const gchar *) data, descriptor->length);
463
464 return TRUE;
465 }
466
467 /* GST_MTS_DESC_DVB_SERVICE (0x48) */
468 /**
469 * gst_mpegts_descriptor_parse_dvb_service:
470 * @descriptor: a %GST_MTS_DESC_DVB_SERVICE #GstMpegtsDescriptor
471 * @service_type: (out) (allow-none): the service type
472 * @service_name: (out) (transfer full) (allow-none): the service name
473 * @provider_name: (out) (transfer full) (allow-none): the provider name
474 *
475 * Extracts the dvb service information from @descriptor.
476 *
477 * Returns: %TRUE if parsing succeeded, else %FALSE.
478 */
479 gboolean
gst_mpegts_descriptor_parse_dvb_service(const GstMpegtsDescriptor * descriptor,GstMpegtsDVBServiceType * service_type,gchar ** service_name,gchar ** provider_name)480 gst_mpegts_descriptor_parse_dvb_service (const GstMpegtsDescriptor *
481 descriptor, GstMpegtsDVBServiceType * service_type, gchar ** service_name,
482 gchar ** provider_name)
483 {
484 guint8 *data;
485
486 g_return_val_if_fail (descriptor != NULL, FALSE);
487 /* Need at least 3 bytes (type and 2 bytes for the string length) */
488 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SERVICE, 3, FALSE);
489
490 data = (guint8 *) descriptor->data + 2;
491
492 if (service_type)
493 *service_type = *data;
494 data += 1;
495 if (provider_name)
496 *provider_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
497 data += *data + 1;
498 if (service_name)
499 *service_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
500
501 return TRUE;
502 }
503
504 /**
505 * gst_mpegts_descriptor_from_dvb_service:
506 * @service_type: Service type defined as a #GstMpegtsDVBServiceType
507 * @service_name: (allow-none): Name of the service
508 * @service_provider: (allow-none): Name of the service provider
509 *
510 * Fills a #GstMpegtsDescriptor to be a %GST_MTS_DESC_DVB_SERVICE.
511 * The data field of the #GstMpegtsDescriptor will be allocated,
512 * and transferred to the caller.
513 *
514 * Returns: (transfer full): the #GstMpegtsDescriptor or %NULL on fail
515 */
516 GstMpegtsDescriptor *
gst_mpegts_descriptor_from_dvb_service(GstMpegtsDVBServiceType service_type,const gchar * service_name,const gchar * service_provider)517 gst_mpegts_descriptor_from_dvb_service (GstMpegtsDVBServiceType service_type,
518 const gchar * service_name, const gchar * service_provider)
519 {
520 GstMpegtsDescriptor *descriptor = NULL;
521 guint8 *conv_provider_name = NULL, *conv_service_name = NULL;
522 gsize provider_size = 0, service_size = 0;
523 guint8 *data;
524
525 if (service_provider) {
526 conv_provider_name = dvb_text_from_utf8 (service_provider, &provider_size);
527
528 if (!conv_provider_name) {
529 GST_WARNING ("Could not find proper encoding for string `%s`",
530 service_provider);
531 goto beach;
532 }
533 }
534
535 if (provider_size >= 256) {
536 GST_WARNING ("Service provider string too big (%" G_GSIZE_FORMAT " > 256)",
537 provider_size);
538 goto beach;
539 }
540
541 if (service_name) {
542 conv_service_name = dvb_text_from_utf8 (service_name, &service_size);
543
544 if (!conv_service_name) {
545 GST_WARNING ("Could not find proper encoding for string `%s`",
546 service_name);
547 goto beach;
548 }
549 }
550
551 if (service_size >= 256) {
552 GST_WARNING ("Service name string too big (%" G_GSIZE_FORMAT " > 256)",
553 service_size);
554 goto beach;
555 }
556
557 descriptor =
558 _new_descriptor (GST_MTS_DESC_DVB_SERVICE,
559 3 + provider_size + service_size);
560
561 data = descriptor->data + 2;
562 *data++ = service_type;
563 *data++ = provider_size;
564 if (conv_provider_name)
565 memcpy (data, conv_provider_name, provider_size);
566
567 data += provider_size;
568 *data++ = service_size;
569 if (conv_service_name)
570 memcpy (data, conv_service_name, service_size);
571
572 beach:
573 g_free (conv_service_name);
574 g_free (conv_provider_name);
575
576 return descriptor;
577 }
578
579 /* GST_MTS_DESC_DVB_LINKAGE (0x4A) */
580 static GstMpegtsDVBLinkageDescriptor *
_gst_mpegts_dvb_linkage_descriptor_copy(GstMpegtsDVBLinkageDescriptor * source)581 _gst_mpegts_dvb_linkage_descriptor_copy (GstMpegtsDVBLinkageDescriptor * source)
582 {
583 GstMpegtsDVBLinkageDescriptor *copy;
584
585 copy = g_slice_dup (GstMpegtsDVBLinkageDescriptor, source);
586
587 switch (source->linkage_type) {
588 case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:
589 copy->linkage_data = g_slice_dup (GstMpegtsDVBLinkageMobileHandOver,
590 source->linkage_data);
591 break;
592 case GST_MPEGTS_DVB_LINKAGE_EVENT:
593 copy->linkage_data = g_slice_dup (GstMpegtsDVBLinkageEvent,
594 source->linkage_data);
595 break;
596 case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:
597 copy->linkage_data = g_ptr_array_ref (source->linkage_data);
598 break;
599 default:
600 break;
601 }
602
603 copy->private_data_bytes = g_memdup2 (source->private_data_bytes,
604 source->private_data_length);
605
606 return copy;
607 }
608
609 void
gst_mpegts_dvb_linkage_descriptor_free(GstMpegtsDVBLinkageDescriptor * source)610 gst_mpegts_dvb_linkage_descriptor_free (GstMpegtsDVBLinkageDescriptor * source)
611 {
612 if (source->linkage_data)
613 switch (source->linkage_type) {
614 case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:
615 g_slice_free (GstMpegtsDVBLinkageMobileHandOver, source->linkage_data);
616 break;
617 case GST_MPEGTS_DVB_LINKAGE_EVENT:
618 g_slice_free (GstMpegtsDVBLinkageEvent, source->linkage_data);
619 break;
620 case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:
621 g_ptr_array_unref (source->linkage_data);
622 break;
623 default:
624 break;
625 }
626
627 g_free (source->private_data_bytes);
628 g_slice_free (GstMpegtsDVBLinkageDescriptor, source);
629 }
630
631 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageDescriptor,
632 gst_mpegts_dvb_linkage_descriptor,
633 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_descriptor_copy,
634 (GFreeFunc) gst_mpegts_dvb_linkage_descriptor_free);
635
636 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBLinkageMobileHandOver,
637 gst_mpegts_dvb_linkage_mobile_hand_over);
638
639 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBLinkageMobileHandOver,
640 gst_mpegts_dvb_linkage_mobile_hand_over);
641
642 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageMobileHandOver,
643 gst_mpegts_dvb_linkage_mobile_hand_over,
644 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_mobile_hand_over_copy,
645 (GFreeFunc) _gst_mpegts_dvb_linkage_mobile_hand_over_free);
646
647 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBLinkageEvent,
648 gst_mpegts_dvb_linkage_event);
649
650 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBLinkageEvent,
651 gst_mpegts_dvb_linkage_event);
652
653 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageEvent,
654 gst_mpegts_dvb_linkage_event,
655 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_event_copy,
656 (GFreeFunc) _gst_mpegts_dvb_linkage_event_free);
657
658 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsDVBLinkageExtendedEvent,
659 gst_mpegts_dvb_linkage_extended_event);
660
661 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsDVBLinkageExtendedEvent,
662 gst_mpegts_dvb_linkage_extended_event);
663
664 G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageExtendedEvent,
665 gst_mpegts_dvb_linkage_extended_event,
666 (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_extended_event_copy,
667 (GFreeFunc) _gst_mpegts_dvb_linkage_extended_event_free);
668
669 /**
670 * gst_mpegts_descriptor_parse_dvb_linkage:
671 * @descriptor: a %GST_MTS_DESC_DVB_LINKAGE #GstMpegtsDescriptor
672 * @res: (out) (transfer full): the #GstMpegtsDVBLinkageDescriptor to fill
673 *
674 * Extracts the DVB linkage information from @descriptor.
675 *
676 * Returns: %TRUE if parsing succeeded, else %FALSE.
677 */
678 gboolean
gst_mpegts_descriptor_parse_dvb_linkage(const GstMpegtsDescriptor * descriptor,GstMpegtsDVBLinkageDescriptor ** desc)679 gst_mpegts_descriptor_parse_dvb_linkage (const GstMpegtsDescriptor * descriptor,
680 GstMpegtsDVBLinkageDescriptor ** desc)
681 {
682 guint i;
683 guint8 *data, *end;
684 GstMpegtsDVBLinkageDescriptor *res;
685
686 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
687 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_LINKAGE, 7, FALSE);
688
689 data = (guint8 *) descriptor->data + 2;
690 end = data + descriptor->length;
691
692 res = g_slice_new0 (GstMpegtsDVBLinkageDescriptor);
693
694 res->transport_stream_id = GST_READ_UINT16_BE (data);
695 data += 2;
696
697 res->original_network_id = GST_READ_UINT16_BE (data);
698 data += 2;
699
700 res->service_id = GST_READ_UINT16_BE (data);
701 data += 2;
702
703 res->linkage_type = *data;
704 data += 1;
705
706 switch (res->linkage_type) {
707 case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:{
708 GstMpegtsDVBLinkageMobileHandOver *hand_over;
709
710 if (end - data < 1)
711 goto fail;
712
713 hand_over = g_slice_new0 (GstMpegtsDVBLinkageMobileHandOver);
714 res->linkage_data = (gpointer) hand_over;
715
716 hand_over->origin_type = (*data) & 0x01;
717 hand_over->hand_over_type = (*data >> 4) & 0x0f;
718 data += 1;
719
720 if (hand_over->hand_over_type ==
721 GST_MPEGTS_DVB_LINKAGE_HAND_OVER_IDENTICAL
722 || hand_over->hand_over_type ==
723 GST_MPEGTS_DVB_LINKAGE_HAND_OVER_LOCAL_VARIATION
724 || hand_over->hand_over_type ==
725 GST_MPEGTS_DVB_LINKAGE_HAND_OVER_ASSOCIATED) {
726 if (end - data < 2)
727 goto fail;
728
729 hand_over->network_id = GST_READ_UINT16_BE (data);
730 data += 2;
731 }
732
733 if (hand_over->origin_type == 0) {
734 if (end - data < 2)
735 goto fail;
736
737 hand_over->initial_service_id = GST_READ_UINT16_BE (data);
738 data += 2;
739 }
740 break;
741 }
742 case GST_MPEGTS_DVB_LINKAGE_EVENT:{
743 GstMpegtsDVBLinkageEvent *event;
744
745 if (end - data < 3)
746 goto fail;
747
748 event = g_slice_new0 (GstMpegtsDVBLinkageEvent);
749 res->linkage_data = (gpointer) event;
750
751 event->target_event_id = GST_READ_UINT16_BE (data);
752 data += 2;
753 event->target_listed = *data & 0x01;
754 event->event_simulcast = (*data >> 1) & 0x01;
755 data += 1;
756 break;
757 }
758 case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:{
759 GPtrArray *ext_events;
760 ext_events = g_ptr_array_new_with_free_func ((GDestroyNotify)
761 _gst_mpegts_dvb_linkage_extended_event_free);
762
763 res->linkage_data = (gpointer) ext_events;
764
765 for (i = 0; i < *data++;) {
766 GstMpegtsDVBLinkageExtendedEvent *ext_event;
767
768 if (end - data < 3)
769 goto fail;
770
771 ext_event = g_slice_new0 (GstMpegtsDVBLinkageExtendedEvent);
772 g_ptr_array_add (res->linkage_data, ext_event);
773
774 ext_event->target_event_id = GST_READ_UINT16_BE (data);
775 data += 2;
776 i += 2;
777
778 ext_event->target_listed = *data & 0x01;
779 ext_event->event_simulcast = (*data >> 1) & 0x01;
780 ext_event->link_type = (*data >> 3) & 0x03;
781 ext_event->target_id_type = (*data >> 5) & 0x03;
782 ext_event->original_network_id_flag = (*data >> 6) & 0x01;
783 ext_event->service_id_flag = (*data >> 7) & 0x01;
784 data += 1;
785 i += 1;
786
787 if (ext_event->target_id_type == 3) {
788 if (end - data < 2)
789 goto fail;
790
791 ext_event->user_defined_id = GST_READ_UINT16_BE (data);
792 data += 2;
793 i += 2;
794 } else {
795 if (ext_event->target_id_type == 1) {
796 if (end - data < 2)
797 goto fail;
798
799 ext_event->target_transport_stream_id = GST_READ_UINT16_BE (data);
800 data += 2;
801 i += 2;
802 }
803 if (ext_event->original_network_id_flag) {
804 if (end - data < 2)
805 goto fail;
806
807 ext_event->target_original_network_id = GST_READ_UINT16_BE (data);
808 data += 2;
809 i += 2;
810 }
811 if (ext_event->service_id_flag) {
812 if (end - data < 2)
813 goto fail;
814
815 ext_event->target_service_id = GST_READ_UINT16_BE (data);
816 data += 2;
817 i += 2;
818 }
819 }
820 }
821 break;
822 }
823 default:
824 break;
825 }
826
827 res->private_data_length = end - data;
828 res->private_data_bytes = g_memdup2 (data, res->private_data_length);
829
830 *desc = res;
831
832 return TRUE;
833
834 fail:
835 gst_mpegts_dvb_linkage_descriptor_free (res);
836 return FALSE;
837 }
838
839 /**
840 * gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over:
841 * @desc: the #GstMpegtsDVBLinkageDescriptor
842 *
843 * Returns: The #GstMpegtsDVBLinkageMobileHandOver or %NULL if an error happened
844 */
845 const GstMpegtsDVBLinkageMobileHandOver *
gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over(const GstMpegtsDVBLinkageDescriptor * desc)846 gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over (const
847 GstMpegtsDVBLinkageDescriptor * desc)
848 {
849 g_return_val_if_fail (desc != NULL, NULL);
850 g_return_val_if_fail (desc->linkage_type ==
851 GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER, NULL);
852
853 return (const GstMpegtsDVBLinkageMobileHandOver *) desc->linkage_data;
854 }
855
856 /**
857 * gst_mpegts_dvb_linkage_descriptor_get_event:
858 * @desc: the #GstMpegtsDVBLinkageDescriptor
859 *
860 * Returns: The #GstMpegtsDVBLinkageEvent or %NULL if an error happened
861 */
862 const GstMpegtsDVBLinkageEvent *
gst_mpegts_dvb_linkage_descriptor_get_event(const GstMpegtsDVBLinkageDescriptor * desc)863 gst_mpegts_dvb_linkage_descriptor_get_event (const GstMpegtsDVBLinkageDescriptor
864 * desc)
865 {
866 g_return_val_if_fail (desc != NULL, NULL);
867 g_return_val_if_fail (desc->linkage_type ==
868 GST_MPEGTS_DVB_LINKAGE_EVENT, NULL);
869
870 return (const GstMpegtsDVBLinkageEvent *) desc->linkage_data;
871 }
872
873 /**
874 * gst_mpegts_dvb_linkage_descriptor_get_extended_event:
875 * @desc: the #GstMpegtsDVBLinkageDescriptor
876 *
877 * Returns: (element-type GstMpegtsDVBLinkageExtendedEvent): an #GstMpegtsDVBLinkageExtendedEvent array or %NULL if an error happened
878 */
879 const GPtrArray *
gst_mpegts_dvb_linkage_descriptor_get_extended_event(const GstMpegtsDVBLinkageDescriptor * desc)880 gst_mpegts_dvb_linkage_descriptor_get_extended_event (const
881 GstMpegtsDVBLinkageDescriptor * desc)
882 {
883 g_return_val_if_fail (desc != NULL, NULL);
884 g_return_val_if_fail (desc->linkage_type ==
885 GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT, NULL);
886
887 return (const GPtrArray *) desc->linkage_data;
888 }
889
890 /* GST_MTS_DESC_DVB_SHORT_EVENT (0x4D) */
891 /**
892 * gst_mpegts_descriptor_parse_dvb_short_event:
893 * @descriptor: a %GST_MTS_DESC_DVB_SHORT_EVENT #GstMpegtsDescriptor
894 * @language_code: (out) (transfer full) (allow-none): the language code
895 * @event_name: (out) (transfer full) (allow-none): the event name
896 * @text: (out) (transfer full) (allow-none): the event text
897 *
898 * Extracts the DVB short event information from @descriptor.
899 *
900 * Returns: %TRUE if parsing succeeded, else %FALSE.
901 */
902 gboolean
gst_mpegts_descriptor_parse_dvb_short_event(const GstMpegtsDescriptor * descriptor,gchar ** language_code,gchar ** event_name,gchar ** text)903 gst_mpegts_descriptor_parse_dvb_short_event (const GstMpegtsDescriptor *
904 descriptor, gchar ** language_code, gchar ** event_name, gchar ** text)
905 {
906 guint8 *data;
907
908 g_return_val_if_fail (descriptor != NULL, FALSE);
909 /* Need at least 5 bytes (3 for language code, 2 for each string length) */
910 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SHORT_EVENT, 5, FALSE);
911
912 data = (guint8 *) descriptor->data + 2;
913
914 if (language_code)
915 *language_code = convert_lang_code (data);
916
917 data += 3;
918 if (event_name)
919 *event_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
920 data += *data + 1;
921 if (text)
922 *text = get_encoding_and_convert ((const gchar *) data + 1, *data);
923 return TRUE;
924 }
925
926 /* GST_MTS_DESC_DVB_TELETEXT (0x56) */
927 /**
928 * gst_mpegts_descriptor_parse_dvb_teletext_idx:
929 * @descriptor: a %GST_MTS_DESC_DVB_TELETEXT #GstMpegtsDescriptor
930 * @idx: The id of the teletext to get
931 * @language_code: (out) (transfer full) (allow-none): a null-terminated string
932 * @teletext_type: (out) (allow-none): #GstMpegtsDVBTeletextType
933 * @magazine_number: (out) (allow-none):
934 * @page_number: (out) (allow-none):
935 *
936 * Parses teletext number @idx in the @descriptor. The language is in ISO639 format.
937 *
938 * Returns: FALSE on out-of-bounds and errors
939 */
940 gboolean
gst_mpegts_descriptor_parse_dvb_teletext_idx(const GstMpegtsDescriptor * descriptor,guint idx,gchar ** language_code,GstMpegtsDVBTeletextType * teletext_type,guint8 * magazine_number,guint8 * page_number)941 gst_mpegts_descriptor_parse_dvb_teletext_idx (const GstMpegtsDescriptor *
942 descriptor, guint idx, gchar ** language_code,
943 GstMpegtsDVBTeletextType * teletext_type, guint8 * magazine_number,
944 guint8 * page_number)
945 {
946 guint8 *data;
947
948 g_return_val_if_fail (descriptor != NULL, FALSE);
949 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_TELETEXT, FALSE);
950
951 if (descriptor->length / 5 <= idx)
952 return FALSE;
953
954 data = (guint8 *) descriptor->data + 2 + idx * 5;
955
956 if (language_code)
957 *language_code = convert_lang_code (data);
958
959 if (teletext_type)
960 *teletext_type = data[3] >> 3;
961
962 if (magazine_number)
963 *magazine_number = data[3] & 0x07;
964
965 if (page_number)
966 *page_number = data[4];
967
968 return TRUE;
969 }
970
971 /**
972 * gst_mpegts_descriptor_parse_dvb_teletext_nb:
973 * @descriptor: a %GST_MTS_DESC_DVB_TELETEXT #GstMpegtsDescriptor
974 *
975 * Find the number of teletext entries in @descriptor
976 *
977 * Returns: Number of teletext entries
978 */
979 guint
gst_mpegts_descriptor_parse_dvb_teletext_nb(const GstMpegtsDescriptor * descriptor)980 gst_mpegts_descriptor_parse_dvb_teletext_nb (const GstMpegtsDescriptor *
981 descriptor)
982 {
983 g_return_val_if_fail (descriptor != NULL, 0);
984 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_TELETEXT, FALSE);
985
986 return descriptor->length / 5;
987 }
988
989 /* GST_MTS_DESC_DVB_SUBTITLING (0x59) */
990
991 /**
992 * gst_mpegts_descriptor_parse_dvb_subtitling_idx:
993 * @descriptor: a %GST_MTS_DESC_DVB_SUBTITLING #GstMpegtsDescriptor
994 * @idx: Table id of the entry to parse
995 * @lang: (out) (transfer full): the language code
996 * @type: (out) (transfer none) (allow-none): the type of subtitling
997 * @composition_page_id: (out) (transfer none) (allow-none): the composition page id
998 * @ancillary_page_id: (out) (transfer none) (allow-none): the ancillary page id
999 *
1000 * Extracts the DVB subtitling informatio from specific table id in @descriptor.
1001 *
1002 * Note: Use #gst_tag_get_language_code if you want to get the the
1003 * ISO 639-1 language code from the returned ISO 639-2 one.
1004 *
1005 * Returns: %TRUE if parsing succeeded, else %FALSE.
1006 */
1007 gboolean
gst_mpegts_descriptor_parse_dvb_subtitling_idx(const GstMpegtsDescriptor * descriptor,guint idx,gchar ** lang,guint8 * type,guint16 * composition_page_id,guint16 * ancillary_page_id)1008 gst_mpegts_descriptor_parse_dvb_subtitling_idx (const GstMpegtsDescriptor *
1009 descriptor, guint idx, gchar ** lang, guint8 * type,
1010 guint16 * composition_page_id, guint16 * ancillary_page_id)
1011 {
1012 guint8 *data;
1013
1014 g_return_val_if_fail (descriptor != NULL && lang != NULL, FALSE);
1015 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_SUBTITLING, FALSE);
1016
1017 /* If we went too far, return FALSE */
1018 if (descriptor->length / 8 <= idx)
1019 return FALSE;
1020
1021 data = (guint8 *) descriptor->data + 2 + idx * 8;
1022
1023 *lang = convert_lang_code (data);
1024
1025 data += 3;
1026
1027 if (type)
1028 *type = *data;
1029 data += 1;
1030 if (composition_page_id)
1031 *composition_page_id = GST_READ_UINT16_BE (data);
1032 data += 2;
1033 if (ancillary_page_id)
1034 *ancillary_page_id = GST_READ_UINT16_BE (data);
1035
1036 return TRUE;
1037 }
1038
1039 /**
1040 * gst_mpegts_descriptor_parse_dvb_subtitling_nb:
1041 * @descriptor: a %GST_MTS_DESC_DVB_SUBTITLING #GstMpegtsDescriptor
1042 *
1043 * Returns: The number of entries in @descriptor
1044 */
1045 guint
gst_mpegts_descriptor_parse_dvb_subtitling_nb(const GstMpegtsDescriptor * descriptor)1046 gst_mpegts_descriptor_parse_dvb_subtitling_nb (const GstMpegtsDescriptor *
1047 descriptor)
1048 {
1049 g_return_val_if_fail (descriptor != NULL, FALSE);
1050 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_SUBTITLING, FALSE);
1051
1052 return descriptor->length / 8;
1053 }
1054
1055 /**
1056 * gst_mpegts_descriptor_from_dvb_subtitling:
1057 * @lang: (transfer none): a string containing the ISO639 language
1058 * @type: subtitling type
1059 * @composition: composition page id
1060 * @ancillary: ancillary page id
1061 */
1062 GstMpegtsDescriptor *
gst_mpegts_descriptor_from_dvb_subtitling(const gchar * lang,guint8 type,guint16 composition,guint16 ancillary)1063 gst_mpegts_descriptor_from_dvb_subtitling (const gchar * lang,
1064 guint8 type, guint16 composition, guint16 ancillary)
1065 {
1066 GstMpegtsDescriptor *descriptor;
1067 guint8 *data;
1068
1069 g_return_val_if_fail (lang != NULL, NULL);
1070
1071 descriptor = _new_descriptor (GST_MTS_DESC_DVB_SUBTITLING, 8);
1072
1073 data = descriptor->data + 2;
1074
1075 memcpy (data, lang, 3);
1076 data += 3;
1077
1078 *data++ = type;
1079
1080 GST_WRITE_UINT16_BE (data, composition);
1081 data += 2;
1082
1083 GST_WRITE_UINT16_BE (data, ancillary);
1084
1085 return descriptor;
1086 }
1087
1088 /* GST_MTS_DESC_DVB_EXTENDED_EVENT (0x4E) */
1089 static GstMpegtsExtendedEventDescriptor *
_gst_mpegts_extended_event_descriptor_copy(GstMpegtsExtendedEventDescriptor * source)1090 _gst_mpegts_extended_event_descriptor_copy (GstMpegtsExtendedEventDescriptor *
1091 source)
1092 {
1093 GstMpegtsExtendedEventDescriptor *copy;
1094
1095 copy = g_slice_dup (GstMpegtsExtendedEventDescriptor, source);
1096 copy->items = g_ptr_array_ref (source->items);
1097 copy->text = g_strdup (source->text);
1098
1099 return copy;
1100 }
1101
1102 void
gst_mpegts_extended_event_descriptor_free(GstMpegtsExtendedEventDescriptor * source)1103 gst_mpegts_extended_event_descriptor_free (GstMpegtsExtendedEventDescriptor *
1104 source)
1105 {
1106 g_free (source->text);
1107 g_free (source->language_code);
1108 g_ptr_array_unref (source->items);
1109 g_slice_free (GstMpegtsExtendedEventDescriptor, source);
1110 }
1111
1112 G_DEFINE_BOXED_TYPE (GstMpegtsExtendedEventDescriptor,
1113 gst_mpegts_extended_event_descriptor,
1114 (GBoxedCopyFunc) _gst_mpegts_extended_event_descriptor_copy,
1115 (GFreeFunc) gst_mpegts_extended_event_descriptor_free);
1116
1117 static GstMpegtsExtendedEventItem *
_gst_mpegts_extended_event_item_copy(GstMpegtsExtendedEventItem * source)1118 _gst_mpegts_extended_event_item_copy (GstMpegtsExtendedEventItem * source)
1119 {
1120 GstMpegtsExtendedEventItem *copy =
1121 g_slice_dup (GstMpegtsExtendedEventItem, source);
1122 copy->item_description = g_strdup (source->item_description);
1123 copy->item = g_strdup (source->item);
1124 return copy;
1125 }
1126
1127 static void
_gst_mpegts_extended_event_item_free(GstMpegtsExtendedEventItem * item)1128 _gst_mpegts_extended_event_item_free (GstMpegtsExtendedEventItem * item)
1129 {
1130 g_free (item->item);
1131 g_free (item->item_description);
1132 g_slice_free (GstMpegtsExtendedEventItem, item);
1133 }
1134
1135 G_DEFINE_BOXED_TYPE (GstMpegtsExtendedEventItem,
1136 gst_mpegts_extended_event_item,
1137 (GBoxedCopyFunc) _gst_mpegts_extended_event_item_copy,
1138 (GFreeFunc) _gst_mpegts_extended_event_item_free);
1139
1140 /**
1141 * gst_mpegts_descriptor_parse_dvb_extended_event:
1142 * @descriptor: a %GST_MTS_DESC_DVB_EXTENDED_EVENT #GstMpegtsDescriptor
1143 * @res: (out) (transfer full): the #GstMpegtsExtendedEventDescriptor to fill
1144 *
1145 * Extracts the DVB extended event information from @descriptor.
1146 *
1147 * Returns: %TRUE if parsing succeeded, else %FALSE.
1148 */
1149 gboolean
gst_mpegts_descriptor_parse_dvb_extended_event(const GstMpegtsDescriptor * descriptor,GstMpegtsExtendedEventDescriptor ** desc)1150 gst_mpegts_descriptor_parse_dvb_extended_event (const GstMpegtsDescriptor
1151 * descriptor, GstMpegtsExtendedEventDescriptor ** desc)
1152 {
1153 guint8 *data, *pdata;
1154 guint8 tmp, len_item;
1155 GstMpegtsExtendedEventItem *item;
1156 GstMpegtsExtendedEventDescriptor *res;
1157
1158 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
1159 /* Need at least 6 bytes (1 for desc number, 3 for language code, 2 for the loop length) */
1160 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_EXTENDED_EVENT, 6, FALSE);
1161
1162 res = g_slice_new0 (GstMpegtsExtendedEventDescriptor);
1163
1164 data = (guint8 *) descriptor->data + 2;
1165
1166 tmp = *data;
1167 res->descriptor_number = tmp >> 4;
1168 res->last_descriptor_number = tmp & 0x0f;
1169
1170 data += 1;
1171
1172 res->language_code = convert_lang_code (data);
1173 data += 3;
1174
1175 len_item = *data;
1176 if (len_item > descriptor->length - 5) {
1177 gst_mpegts_extended_event_descriptor_free (res);
1178 return FALSE;
1179 }
1180
1181 data += 1;
1182
1183 res->items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1184 _gst_mpegts_extended_event_item_free);
1185
1186 pdata = data + len_item;
1187 while (data < pdata) {
1188 item = g_slice_new0 (GstMpegtsExtendedEventItem);
1189 item->item_description =
1190 get_encoding_and_convert ((const gchar *) data + 1, *data);
1191
1192 data += *data + 1;
1193
1194 item->item = get_encoding_and_convert ((const gchar *) data + 1, *data);
1195
1196 data += *data + 1;
1197
1198 g_ptr_array_add (res->items, item);
1199 }
1200 if (pdata != data) {
1201 gst_mpegts_extended_event_descriptor_free (res);
1202 return FALSE;
1203 }
1204 res->text = get_encoding_and_convert ((const gchar *) data + 1, *data);
1205
1206 *desc = res;
1207
1208 return TRUE;
1209 }
1210
1211 /* GST_MTS_DESC_DVB_COMPONENT (0x50) */
1212 static GstMpegtsComponentDescriptor *
_gst_mpegts_dvb_component_descriptor_copy(GstMpegtsComponentDescriptor * source)1213 _gst_mpegts_dvb_component_descriptor_copy (GstMpegtsComponentDescriptor *
1214 source)
1215 {
1216 GstMpegtsComponentDescriptor *copy;
1217
1218 copy = g_slice_dup (GstMpegtsComponentDescriptor, source);
1219 copy->language_code = g_strdup (source->language_code);
1220 copy->text = g_strdup (source->text);
1221
1222 return copy;
1223 }
1224
1225 void
gst_mpegts_dvb_component_descriptor_free(GstMpegtsComponentDescriptor * source)1226 gst_mpegts_dvb_component_descriptor_free (GstMpegtsComponentDescriptor * source)
1227 {
1228 g_free (source->language_code);
1229 g_free (source->text);
1230 g_slice_free (GstMpegtsComponentDescriptor, source);
1231 }
1232
1233 G_DEFINE_BOXED_TYPE (GstMpegtsComponentDescriptor,
1234 gst_mpegts_component_descriptor,
1235 (GBoxedCopyFunc) _gst_mpegts_dvb_component_descriptor_copy,
1236 (GFreeFunc) gst_mpegts_dvb_component_descriptor_free);
1237
1238 /**
1239 * gst_mpegts_descriptor_parse_dvb_component:
1240 * @descriptor: a %GST_MTS_DESC_DVB_COMPONENT #GstMpegtsDescriptor
1241 * @res: (out) (transfer full): the #GstMpegtsComponentDescriptor to fill
1242 *
1243 * Extracts the DVB component information from @descriptor.
1244 *
1245 * Returns: %TRUE if parsing succeeded, else %FALSE.
1246 */
1247 gboolean
gst_mpegts_descriptor_parse_dvb_component(const GstMpegtsDescriptor * descriptor,GstMpegtsComponentDescriptor ** res)1248 gst_mpegts_descriptor_parse_dvb_component (const GstMpegtsDescriptor
1249 * descriptor, GstMpegtsComponentDescriptor ** res)
1250 {
1251 guint8 *data;
1252 guint8 len;
1253 GstMpegtsComponentDescriptor *desc;
1254
1255 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
1256 /* Need 6 bytes at least (1 for content, 1 for type, 1 for tag, 3 for language code) */
1257 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_COMPONENT, 6, FALSE);
1258
1259 data = (guint8 *) descriptor->data + 2;
1260
1261 desc = g_slice_new0 (GstMpegtsComponentDescriptor);
1262
1263 desc->stream_content = *data & 0x0f;
1264 data += 1;
1265
1266 desc->component_type = *data;
1267 data += 1;
1268
1269 desc->component_tag = *data;
1270 data += 1;
1271
1272 desc->language_code = convert_lang_code (data);
1273 data += 3;
1274
1275 len = descriptor->length - 6;
1276 if (len)
1277 desc->text = get_encoding_and_convert ((const gchar *) data, len);
1278
1279 *res = desc;
1280
1281 return TRUE;
1282 }
1283
1284 /* GST_MTS_DESC_DVB_STREAM_IDENTIFIER (0x52) */
1285 /**
1286 * gst_mpegts_descriptor_parse_dvb_stream_identifier:
1287 * @descriptor: a %GST_MTS_DESC_DVB_CONTENT #GstMpegtsDescriptor
1288 * @component_tag: (out) (transfer none): the component tag
1289 *
1290 * Extracts the component tag from @descriptor.
1291 *
1292 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1293 */
1294 gboolean
gst_mpegts_descriptor_parse_dvb_stream_identifier(const GstMpegtsDescriptor * descriptor,guint8 * component_tag)1295 gst_mpegts_descriptor_parse_dvb_stream_identifier (const GstMpegtsDescriptor
1296 * descriptor, guint8 * component_tag)
1297 {
1298 guint8 *data;
1299
1300 g_return_val_if_fail (descriptor != NULL && component_tag != NULL, FALSE);
1301 __common_desc_checks_exact (descriptor, GST_MTS_DESC_DVB_STREAM_IDENTIFIER,
1302 1, FALSE);
1303
1304 data = (guint8 *) descriptor->data + 2;
1305
1306 *component_tag = *data;
1307
1308 return TRUE;
1309 }
1310
1311 /* GST_MTS_DESC_DVB_CA_IDENTIFIER (0x53) */
1312 /**
1313 * gst_mpegts_descriptor_parse_dvb_ca_identifier:
1314 * @descriptor: a %GST_MTS_DESC_DVB_CA_IDENTIFIER #GstMpegtsDescriptor
1315 * @list: (out) (transfer full) (element-type guint16): a list of ca identifier.
1316 * Edge entry identifies the CA system. Allocations of the value of this field
1317 * are found in http://www.dvbservices.com
1318 *
1319 * Extracts ca id's from @descriptor.
1320 *
1321 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1322 */
1323 gboolean
gst_mpegts_descriptor_parse_dvb_ca_identifier(const GstMpegtsDescriptor * descriptor,GArray ** list)1324 gst_mpegts_descriptor_parse_dvb_ca_identifier (const GstMpegtsDescriptor *
1325 descriptor, GArray ** list)
1326 {
1327 guint8 *data;
1328 guint16 tmp;
1329 guint i;
1330
1331 g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE);
1332 /* 2 bytes = one entry */
1333 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_CA_IDENTIFIER, 2, FALSE);
1334
1335 data = (guint8 *) descriptor->data + 2;
1336
1337 *list = g_array_new (FALSE, FALSE, sizeof (guint16));
1338
1339 for (i = 0; i < descriptor->length - 1; i += 2) {
1340 tmp = GST_READ_UINT16_BE (data);
1341 g_array_append_val (*list, tmp);
1342 data += 2;
1343 }
1344
1345 return TRUE;
1346 }
1347
1348 /* GST_MTS_DESC_DVB_CONTENT (0x54) */
1349
1350 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsContent, gst_mpegts_content);
1351
1352 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsContent, gst_mpegts_content);
1353
1354 G_DEFINE_BOXED_TYPE (GstMpegtsContent,
1355 gst_mpegts_content,
1356 (GBoxedCopyFunc) _gst_mpegts_content_copy,
1357 (GFreeFunc) _gst_mpegts_content_free);
1358
1359 /**
1360 * gst_mpegts_descriptor_parse_dvb_content:
1361 * @descriptor: a %GST_MTS_DESC_DVB_CONTENT #GstMpegtsDescriptor
1362 * @content: (out) (transfer full) (element-type GstMpegtsContent): #GstMpegtsContent
1363 *
1364 * Extracts the DVB content information from @descriptor.
1365 *
1366 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1367 */
1368 gboolean
gst_mpegts_descriptor_parse_dvb_content(const GstMpegtsDescriptor * descriptor,GPtrArray ** content)1369 gst_mpegts_descriptor_parse_dvb_content (const GstMpegtsDescriptor
1370 * descriptor, GPtrArray ** content)
1371 {
1372 guint8 *data;
1373 guint8 len, tmp;
1374 guint8 i;
1375
1376 g_return_val_if_fail (descriptor != NULL && content != NULL, FALSE);
1377 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_CONTENT, FALSE);
1378
1379 data = (guint8 *) descriptor->data + 2;
1380 len = descriptor->length;
1381
1382 *content = g_ptr_array_new_with_free_func ((GDestroyNotify)
1383 _gst_mpegts_content_free);
1384 for (i = 0; i < len;) {
1385 GstMpegtsContent *cont = g_slice_new0 (GstMpegtsContent);
1386 tmp = *data;
1387 cont->content_nibble_1 = (tmp & 0xf0) >> 4;
1388 cont->content_nibble_2 = tmp & 0x0f;
1389 data += 1;
1390 cont->user_byte = *data;
1391 data += 1;
1392 i += 2;
1393 g_ptr_array_add (*content, cont);
1394 }
1395
1396 return TRUE;
1397 }
1398
1399 /* GST_MTS_DESC_DVB_PARENTAL_RATING (0x55) */
1400
1401 static GstMpegtsDVBParentalRatingItem *
_gst_mpegts_dvb_parental_rating_item_copy(GstMpegtsDVBParentalRatingItem * source)1402 _gst_mpegts_dvb_parental_rating_item_copy (GstMpegtsDVBParentalRatingItem *
1403 source)
1404 {
1405 GstMpegtsDVBParentalRatingItem *copy =
1406 g_slice_dup (GstMpegtsDVBParentalRatingItem, source);
1407 copy->country_code = g_strdup (source->country_code);
1408 return copy;
1409 }
1410
1411 static void
_gst_mpegts_dvb_parental_rating_item_free(GstMpegtsDVBParentalRatingItem * item)1412 _gst_mpegts_dvb_parental_rating_item_free (GstMpegtsDVBParentalRatingItem *
1413 item)
1414 {
1415 g_free (item->country_code);
1416 g_slice_free (GstMpegtsDVBParentalRatingItem, item);
1417 }
1418
1419 G_DEFINE_BOXED_TYPE (GstMpegtsDVBParentalRatingItem,
1420 gst_mpegts_dvb_parental_rating_item,
1421 (GBoxedCopyFunc) _gst_mpegts_dvb_parental_rating_item_copy,
1422 (GFreeFunc) _gst_mpegts_dvb_parental_rating_item_free);
1423
1424 /**
1425 * gst_mpegts_descriptor_parse_dvb_parental_rating:
1426 * @descriptor: a %GST_MTS_DESC_DVB_PARENTAL_RATING #GstMpegtsDescriptor
1427 * @rating: (out) (transfer full) (element-type GstMpegtsDVBParentalRatingItem):
1428 * #GstMpegtsDVBParentalRatingItem
1429 *
1430 * Extracts the DVB parental rating information from @descriptor.
1431 *
1432 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1433 */
1434 gboolean
gst_mpegts_descriptor_parse_dvb_parental_rating(const GstMpegtsDescriptor * descriptor,GPtrArray ** rating)1435 gst_mpegts_descriptor_parse_dvb_parental_rating (const GstMpegtsDescriptor
1436 * descriptor, GPtrArray ** rating)
1437 {
1438 guint8 *data;
1439 guint i;
1440
1441 g_return_val_if_fail (descriptor != NULL && rating != NULL, FALSE);
1442 __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_PARENTAL_RATING,
1443 FALSE);
1444
1445 data = (guint8 *) descriptor->data + 2;
1446
1447 *rating = g_ptr_array_new_with_free_func ((GDestroyNotify)
1448 _gst_mpegts_dvb_parental_rating_item_free);
1449
1450 for (i = 0; i < descriptor->length - 3; i += 4) {
1451 GstMpegtsDVBParentalRatingItem *item =
1452 g_slice_new0 (GstMpegtsDVBParentalRatingItem);
1453 g_ptr_array_add (*rating, item);
1454
1455 item->country_code = convert_lang_code (data);
1456 data += 3;
1457
1458 if (g_strcmp0 (item->country_code, "BRA") == 0) {
1459 /* brasil */
1460 switch (*data & 0xf) {
1461 case 1:
1462 item->rating = 6;
1463 break;
1464 case 2:
1465 item->rating = 10;
1466 break;
1467 case 3:
1468 item->rating = 12;
1469 break;
1470 case 4:
1471 item->rating = 14;
1472 break;
1473 case 5:
1474 item->rating = 16;
1475 break;
1476 case 6:
1477 item->rating = 18;
1478 break;
1479 default:
1480 item->rating = 0;
1481 break;
1482 }
1483 } else {
1484 item->rating = (*data & 0xf) + 3;
1485 }
1486
1487 data += 1;
1488 }
1489
1490 return TRUE;
1491 }
1492
1493 /* GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM (0x5A) */
1494
1495 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsTerrestrialDeliverySystemDescriptor,
1496 gst_mpegts_terrestrial_delivery_system_descriptor);
1497
1498 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsTerrestrialDeliverySystemDescriptor,
1499 gst_mpegts_terrestrial_delivery_system_descriptor);
1500
1501 G_DEFINE_BOXED_TYPE (GstMpegtsTerrestrialDeliverySystemDescriptor,
1502 gst_mpegts_terrestrial_delivery_system_descriptor,
1503 (GBoxedCopyFunc) _gst_mpegts_terrestrial_delivery_system_descriptor_copy,
1504 (GFreeFunc) _gst_mpegts_terrestrial_delivery_system_descriptor_free);
1505
1506
1507 /**
1508 * gst_mpegts_descriptor_parse_terrestrial_delivery_system:
1509 * @descriptor: a %GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM #GstMpegtsDescriptor
1510 * @res: (out) (transfer none): #GstMpegtsTerrestrialDeliverySystemDescriptor
1511 *
1512 * Parses out the terrestrial delivery system from the @descriptor.
1513 *
1514 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1515 */
1516 gboolean
gst_mpegts_descriptor_parse_terrestrial_delivery_system(const GstMpegtsDescriptor * descriptor,GstMpegtsTerrestrialDeliverySystemDescriptor * res)1517 gst_mpegts_descriptor_parse_terrestrial_delivery_system (const
1518 GstMpegtsDescriptor * descriptor,
1519 GstMpegtsTerrestrialDeliverySystemDescriptor * res)
1520 {
1521 guint8 *data;
1522 guint8 tmp;
1523
1524 g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
1525 /* Descriptor is always 11 bytes long */
1526 __common_desc_checks_exact (descriptor,
1527 GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM, 11, FALSE);
1528
1529 data = (guint8 *) descriptor->data + 2;
1530
1531 res->frequency = 0;
1532 res->frequency = GST_READ_UINT32_BE (data);
1533 res->frequency *= 10;
1534
1535 data += 4;
1536
1537 tmp = *data;
1538 switch ((tmp >> 5) & 0x07) {
1539 case 0:
1540 res->bandwidth = 8000000;
1541 break;
1542 case 1:
1543 res->bandwidth = 7000000;
1544 break;
1545 case 2:
1546 res->bandwidth = 6000000;
1547 break;
1548 case 3:
1549 res->bandwidth = 5000000;
1550 break;
1551 default:
1552 res->bandwidth = 0;
1553 break;
1554 }
1555
1556 res->priority = (tmp >> 4) & 0x01;
1557 res->time_slicing = (tmp >> 3) & 0x01;
1558 res->mpe_fec = (tmp >> 2) & 0x01;
1559 data += 1;
1560
1561 tmp = *data;
1562 switch ((tmp >> 6) & 0x03) {
1563 case 0:
1564 res->constellation = GST_MPEGTS_MODULATION_QPSK;
1565 break;
1566 case 1:
1567 res->constellation = GST_MPEGTS_MODULATION_QAM_16;
1568 break;
1569 case 2:
1570 res->constellation = GST_MPEGTS_MODULATION_QAM_64;
1571 break;
1572 default:
1573 break;
1574 }
1575
1576 switch ((tmp >> 3) & 0x07) {
1577 case 0:
1578 res->hierarchy = GST_MPEGTS_HIERARCHY_NONE;
1579 break;
1580 case 1:
1581 res->hierarchy = GST_MPEGTS_HIERARCHY_1;
1582 break;
1583 case 2:
1584 res->hierarchy = GST_MPEGTS_HIERARCHY_2;
1585 break;
1586 case 3:
1587 res->hierarchy = GST_MPEGTS_HIERARCHY_4;
1588 break;
1589 case 4:
1590 res->hierarchy = GST_MPEGTS_HIERARCHY_NONE;
1591 break;
1592 case 5:
1593 res->hierarchy = GST_MPEGTS_HIERARCHY_1;
1594 break;
1595 case 6:
1596 res->hierarchy = GST_MPEGTS_HIERARCHY_2;
1597 break;
1598 case 7:
1599 res->hierarchy = GST_MPEGTS_HIERARCHY_4;
1600 break;
1601 default:
1602 break;
1603 }
1604
1605 switch (tmp & 0x07) {
1606 case 0:
1607 res->code_rate_hp = GST_MPEGTS_FEC_1_2;
1608 break;
1609 case 1:
1610 res->code_rate_hp = GST_MPEGTS_FEC_2_3;
1611 break;
1612 case 2:
1613 res->code_rate_hp = GST_MPEGTS_FEC_3_4;
1614 break;
1615 case 3:
1616 res->code_rate_hp = GST_MPEGTS_FEC_5_6;
1617 break;
1618 case 4:
1619 res->code_rate_hp = GST_MPEGTS_FEC_7_8;
1620 break;
1621 default:
1622 break;
1623 }
1624 data += 1;
1625
1626 tmp = *data;
1627 switch ((tmp >> 5) & 0x07) {
1628 case 0:
1629 res->code_rate_lp = GST_MPEGTS_FEC_1_2;
1630 break;
1631 case 1:
1632 res->code_rate_lp = GST_MPEGTS_FEC_2_3;
1633 break;
1634 case 2:
1635 res->code_rate_lp = GST_MPEGTS_FEC_3_4;
1636 break;
1637 case 3:
1638 res->code_rate_lp = GST_MPEGTS_FEC_5_6;
1639 break;
1640 case 4:
1641 res->code_rate_lp = GST_MPEGTS_FEC_7_8;
1642 break;
1643 default:
1644 break;
1645 }
1646
1647 switch ((tmp >> 3) & 0x03) {
1648 case 0:
1649 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_32;
1650 break;
1651 case 1:
1652 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_16;
1653 break;
1654 case 2:
1655 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_8;
1656 break;
1657 case 3:
1658 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_4;
1659 break;
1660 default:
1661 break;
1662 }
1663
1664 switch ((tmp >> 1) & 0x03) {
1665 case 0:
1666 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_2K;
1667 break;
1668 case 1:
1669 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_8K;
1670 break;
1671 case 2:
1672 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_4K;
1673 break;
1674 default:
1675 break;
1676 }
1677 res->other_frequency = tmp & 0x01;
1678
1679 return TRUE;
1680 }
1681
1682 /* GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME (0x5B) */
1683
1684 static GstMpegtsDvbMultilingualNetworkNameItem
_gst_mpegts_dvb_multilingual_network_name_item_copy(GstMpegtsDvbMultilingualNetworkNameItem * source)1685 * _gst_mpegts_dvb_multilingual_network_name_item_copy
1686 (GstMpegtsDvbMultilingualNetworkNameItem * source)
1687 {
1688 GstMpegtsDvbMultilingualNetworkNameItem *copy =
1689 g_slice_dup (GstMpegtsDvbMultilingualNetworkNameItem, source);
1690 copy->language_code = g_strdup (source->language_code);
1691 copy->network_name = g_strdup (source->network_name);
1692 return copy;
1693 }
1694
1695 static void
_gst_mpegts_dvb_multilingual_network_name_item_free(GstMpegtsDvbMultilingualNetworkNameItem * item)1696 _gst_mpegts_dvb_multilingual_network_name_item_free
1697 (GstMpegtsDvbMultilingualNetworkNameItem * item)
1698 {
1699 g_free (item->network_name);
1700 g_free (item->language_code);
1701 g_slice_free (GstMpegtsDvbMultilingualNetworkNameItem, item);
1702 }
1703
1704 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualNetworkNameItem,
1705 gst_mpegts_dvb_multilingual_network_name_item,
1706 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_network_name_item_copy,
1707 (GFreeFunc) _gst_mpegts_dvb_multilingual_network_name_item_free);
1708
1709 /**
1710 * gst_mpegts_descriptor_parse_dvb_multilingual_network_name:
1711 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME
1712 * #GstMpegtsDescriptor
1713 * @network_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualNetworkNameItem):
1714 * a #GstMpegtsDvbMultilingualNetworkNameItem
1715 *
1716 * Parses out the multilingual network name from the @descriptor.
1717 *
1718 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1719 */
1720 gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_network_name(const GstMpegtsDescriptor * descriptor,GPtrArray ** network_name_items)1721 gst_mpegts_descriptor_parse_dvb_multilingual_network_name (const
1722 GstMpegtsDescriptor * descriptor, GPtrArray ** network_name_items)
1723 {
1724 guint8 *data, i, len;
1725 GstMpegtsDvbMultilingualNetworkNameItem *item;
1726
1727 g_return_val_if_fail (descriptor != NULL && network_name_items != NULL,
1728 FALSE);
1729 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME,
1730 5, FALSE);
1731
1732 data = (guint8 *) descriptor->data + 2;
1733
1734 *network_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1735 _gst_mpegts_dvb_multilingual_network_name_item_free);
1736
1737 for (i = 0; i < descriptor->length - 3;) {
1738 item = g_slice_new0 (GstMpegtsDvbMultilingualNetworkNameItem);
1739 g_ptr_array_add (*network_name_items, item);
1740 item->language_code = convert_lang_code (data);
1741 data += 3;
1742 i += 3;
1743
1744 len = *data;
1745 item->network_name =
1746 get_encoding_and_convert ((const gchar *) data + 1, len);
1747 data += len + 1;
1748 i += len + 1;
1749 }
1750
1751 return TRUE;
1752 }
1753
1754 /* GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME (0x5C) */
1755
1756 static GstMpegtsDvbMultilingualBouquetNameItem
_gst_mpegts_dvb_multilingual_bouquet_name_item_copy(GstMpegtsDvbMultilingualBouquetNameItem * source)1757 * _gst_mpegts_dvb_multilingual_bouquet_name_item_copy
1758 (GstMpegtsDvbMultilingualBouquetNameItem * source)
1759 {
1760 GstMpegtsDvbMultilingualBouquetNameItem *copy =
1761 g_slice_dup (GstMpegtsDvbMultilingualBouquetNameItem, source);
1762 copy->bouquet_name = g_strdup (source->bouquet_name);
1763 copy->language_code = g_strdup (source->language_code);
1764 return copy;
1765 }
1766
1767 static void
_gst_mpegts_dvb_multilingual_bouquet_name_item_free(GstMpegtsDvbMultilingualBouquetNameItem * item)1768 _gst_mpegts_dvb_multilingual_bouquet_name_item_free
1769 (GstMpegtsDvbMultilingualBouquetNameItem * item)
1770 {
1771 g_free (item->language_code);
1772 g_free (item->bouquet_name);
1773 g_slice_free (GstMpegtsDvbMultilingualBouquetNameItem, item);
1774 }
1775
1776 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualBouquetNameItem,
1777 gst_mpegts_dvb_multilingual_bouquet_name_item,
1778 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_bouquet_name_item_copy,
1779 (GFreeFunc) _gst_mpegts_dvb_multilingual_bouquet_name_item_free);
1780
1781 /**
1782 * gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name:
1783 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME
1784 * #GstMpegtsDescriptor
1785 * @bouquet_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualBouquetNameItem):
1786 * a #GstMpegtsDvbMultilingualBouquetNameItem
1787 *
1788 * Parses out the multilingual bouquet name from the @descriptor.
1789 *
1790 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1791 */
1792 gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name(const GstMpegtsDescriptor * descriptor,GPtrArray ** bouquet_name_items)1793 gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name (const
1794 GstMpegtsDescriptor * descriptor, GPtrArray ** bouquet_name_items)
1795 {
1796 guint8 *data, i, len;
1797 GstMpegtsDvbMultilingualBouquetNameItem *item;
1798
1799 g_return_val_if_fail (descriptor != NULL && bouquet_name_items != NULL,
1800 FALSE);
1801 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME,
1802 5, FALSE);
1803
1804 data = (guint8 *) descriptor->data + 2;
1805
1806 *bouquet_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1807 _gst_mpegts_dvb_multilingual_bouquet_name_item_free);
1808
1809 for (i = 0; i < descriptor->length - 3;) {
1810 item = g_slice_new0 (GstMpegtsDvbMultilingualBouquetNameItem);
1811 g_ptr_array_add (*bouquet_name_items, item);
1812 item->language_code = convert_lang_code (data);
1813 data += 3;
1814 i += 3;
1815
1816 len = *data;
1817 item->bouquet_name =
1818 get_encoding_and_convert ((const gchar *) data + 1, len);
1819 data += len + 1;
1820 i += len + 1;
1821 }
1822
1823 return TRUE;
1824 }
1825
1826 /* GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME (0x5D) */
1827
1828 static GstMpegtsDvbMultilingualServiceNameItem
_gst_mpegts_dvb_multilingual_service_name_item_copy(GstMpegtsDvbMultilingualServiceNameItem * source)1829 * _gst_mpegts_dvb_multilingual_service_name_item_copy
1830 (GstMpegtsDvbMultilingualServiceNameItem * source)
1831 {
1832 GstMpegtsDvbMultilingualServiceNameItem *copy =
1833 g_slice_dup (GstMpegtsDvbMultilingualServiceNameItem, source);
1834 copy->language_code = g_strdup (source->language_code);
1835 copy->service_name = g_strdup (source->service_name);
1836 copy->provider_name = g_strdup (source->provider_name);
1837 return copy;
1838 }
1839
1840 static void
_gst_mpegts_dvb_multilingual_service_name_item_free(GstMpegtsDvbMultilingualServiceNameItem * item)1841 _gst_mpegts_dvb_multilingual_service_name_item_free
1842 (GstMpegtsDvbMultilingualServiceNameItem * item)
1843 {
1844 g_free (item->provider_name);
1845 g_free (item->service_name);
1846 g_free (item->language_code);
1847 g_slice_free (GstMpegtsDvbMultilingualServiceNameItem, item);
1848 }
1849
1850 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualServiceNameItem,
1851 gst_mpegts_dvb_multilingual_service_name_item,
1852 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_service_name_item_copy,
1853 (GFreeFunc) _gst_mpegts_dvb_multilingual_service_name_item_free);
1854
1855 /**
1856 * gst_mpegts_descriptor_parse_dvb_multilingual_service_name:
1857 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME
1858 * #GstMpegtsDescriptor
1859 * @service_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualServiceNameItem):
1860 * a #GstMpegtsDvbMultilingualServiceNameItem
1861 *
1862 * Parses out the multilingual service name from the @descriptor.
1863 *
1864 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1865 */
1866 gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_service_name(const GstMpegtsDescriptor * descriptor,GPtrArray ** service_name_items)1867 gst_mpegts_descriptor_parse_dvb_multilingual_service_name (const
1868 GstMpegtsDescriptor * descriptor, GPtrArray ** service_name_items)
1869 {
1870 guint8 *data, i, len;
1871 GstMpegtsDvbMultilingualServiceNameItem *item;
1872
1873 g_return_val_if_fail (descriptor != NULL && service_name_items != NULL,
1874 FALSE);
1875 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME,
1876 7, FALSE);
1877
1878 data = (guint8 *) descriptor->data + 2;
1879
1880 *service_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
1881 _gst_mpegts_dvb_multilingual_service_name_item_free);
1882
1883 for (i = 0; i < descriptor->length - 3;) {
1884 item = g_slice_new0 (GstMpegtsDvbMultilingualServiceNameItem);
1885 g_ptr_array_add (*service_name_items, item);
1886 item->language_code = convert_lang_code (data);
1887 data += 3;
1888 i += 3;
1889
1890 len = *data;
1891 item->provider_name =
1892 get_encoding_and_convert ((const gchar *) data + 1, len);
1893 data += len + 1;
1894 i += len + 1;
1895
1896 len = *data;
1897 item->service_name =
1898 get_encoding_and_convert ((const gchar *) data + 1, len);
1899 data += len + 1;
1900 i += len + 1;
1901 }
1902
1903 return TRUE;
1904 }
1905
1906 /* GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT (0x5E) */
1907
1908 static GstMpegtsDvbMultilingualComponentItem
_gst_mpegts_dvb_multilingual_component_item_copy(GstMpegtsDvbMultilingualComponentItem * source)1909 * _gst_mpegts_dvb_multilingual_component_item_copy
1910 (GstMpegtsDvbMultilingualComponentItem * source)
1911 {
1912 GstMpegtsDvbMultilingualComponentItem *copy =
1913 g_slice_dup (GstMpegtsDvbMultilingualComponentItem, source);
1914 copy->description = g_strdup (source->description);
1915 copy->language_code = g_strdup (source->language_code);
1916 return copy;
1917 }
1918
1919 static void
_gst_mpegts_dvb_multilingual_component_item_free(GstMpegtsDvbMultilingualComponentItem * item)1920 _gst_mpegts_dvb_multilingual_component_item_free
1921 (GstMpegtsDvbMultilingualComponentItem * item)
1922 {
1923 g_free (item->language_code);
1924 g_free (item->description);
1925 g_slice_free (GstMpegtsDvbMultilingualComponentItem, item);
1926 }
1927
1928 G_DEFINE_BOXED_TYPE (GstMpegtsDvbMultilingualComponentItem,
1929 gst_mpegts_dvb_multilingual_component_item,
1930 (GBoxedCopyFunc) _gst_mpegts_dvb_multilingual_component_item_copy,
1931 (GFreeFunc) _gst_mpegts_dvb_multilingual_component_item_free);
1932
1933 /**
1934 * gst_mpegts_descriptor_parse_dvb_multilingual_component:
1935 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT
1936 * #GstMpegtsDescriptor
1937 * @component_tag: (out): the component tag
1938 * @component_description_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualComponentItem):
1939 * a #GstMpegtsDvbMultilingualComponentItem
1940 *
1941 * Parses out the multilingual component from the @descriptor.
1942 *
1943 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1944 */
1945 gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_component(const GstMpegtsDescriptor * descriptor,guint8 * component_tag,GPtrArray ** component_description_items)1946 gst_mpegts_descriptor_parse_dvb_multilingual_component (const
1947 GstMpegtsDescriptor * descriptor, guint8 * component_tag,
1948 GPtrArray ** component_description_items)
1949 {
1950 guint8 *data, i, len;
1951 GstMpegtsDvbMultilingualComponentItem *item;
1952
1953 g_return_val_if_fail (descriptor != NULL
1954 && component_description_items != NULL && component_tag != NULL, FALSE);
1955 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT, 6,
1956 FALSE);
1957
1958 data = (guint8 *) descriptor->data + 2;
1959
1960 *component_tag = *data;
1961 data += 1;
1962
1963 *component_description_items =
1964 g_ptr_array_new_with_free_func ((GDestroyNotify)
1965 _gst_mpegts_dvb_multilingual_component_item_free);
1966
1967 for (i = 0; i < descriptor->length - 3;) {
1968 item = g_slice_new0 (GstMpegtsDvbMultilingualComponentItem);
1969 g_ptr_array_add (*component_description_items, item);
1970 item->language_code = convert_lang_code (data);
1971 data += 3;
1972 i += 3;
1973
1974 len = *data;
1975 item->description =
1976 get_encoding_and_convert ((const gchar *) data + 1, len);
1977 data += len + 1;
1978 i += len + 1;
1979 }
1980
1981 return TRUE;
1982 }
1983
1984 /* GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER (0x5F) */
1985 /**
1986 * gst_mpegts_descriptor_parse_dvb_private_data_specifier:
1987 * @descriptor: a %GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER #GstMpegtsDescriptor
1988 * @private_data_specifier: (out): the private data specifier id
1989 * registered by http://www.dvbservices.com/
1990 * @private_data: (out) (transfer full) (allow-none) (array length=length): additional data or NULL
1991 * @length: (out) (allow-none): length of @private_data
1992 *
1993 * Parses out the private data specifier from the @descriptor.
1994 *
1995 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
1996 */
1997 gboolean
gst_mpegts_descriptor_parse_dvb_private_data_specifier(const GstMpegtsDescriptor * descriptor,guint32 * private_data_specifier,guint8 ** private_data,guint8 * length)1998 gst_mpegts_descriptor_parse_dvb_private_data_specifier (const
1999 GstMpegtsDescriptor * descriptor, guint32 * private_data_specifier,
2000 guint8 ** private_data, guint8 * length)
2001 {
2002 guint8 *data;
2003
2004 g_return_val_if_fail (descriptor != NULL
2005 && private_data_specifier != NULL, FALSE);
2006 __common_desc_checks (descriptor,
2007 GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER, 4, FALSE);
2008
2009 data = (guint8 *) descriptor->data + 2;
2010
2011 *private_data_specifier = GST_READ_UINT32_BE (data);
2012
2013 if (length && private_data) {
2014 *length = descriptor->length - 4;
2015
2016 *private_data = g_memdup2 (data + 4, *length);
2017 }
2018 return TRUE;
2019 }
2020
2021 /* GST_MTS_DESC_DVB_FREQUENCY_LIST (0x62) */
2022 /**
2023 * gst_mpegts_descriptor_parse_dvb_frequency_list:
2024 * @descriptor: a %GST_MTS_DESC_DVB_FREQUENCY_LIST #GstMpegtsDescriptor
2025 * @offset: (out): %FALSE in Hz, %TRUE in kHz
2026 * @list: (out) (transfer full) (element-type guint32): a list of all frequencies in Hz/kHz
2027 * depending on @offset
2028 *
2029 * Parses out a list of frequencies from the @descriptor.
2030 *
2031 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2032 */
2033 gboolean
gst_mpegts_descriptor_parse_dvb_frequency_list(const GstMpegtsDescriptor * descriptor,gboolean * offset,GArray ** list)2034 gst_mpegts_descriptor_parse_dvb_frequency_list (const GstMpegtsDescriptor
2035 * descriptor, gboolean * offset, GArray ** list)
2036 {
2037 guint8 *data, type, len;
2038 guint32 freq;
2039 guint i;
2040
2041 g_return_val_if_fail (descriptor != NULL && offset != NULL &&
2042 list != NULL, FALSE);
2043 /* 1 byte coding system, 4 bytes each frequency entry */
2044 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_FREQUENCY_LIST, 5, FALSE);
2045
2046 data = (guint8 *) descriptor->data + 2;
2047
2048 type = *data & 0x03;
2049 data += 1;
2050
2051 if (type == 1) {
2052 /* satellite */
2053 *offset = TRUE;
2054 } else {
2055 /* cable, terrestrial */
2056 *offset = FALSE;
2057 }
2058
2059 *list = g_array_new (FALSE, FALSE, sizeof (guint32));
2060
2061 len = descriptor->length - 1;
2062
2063 for (i = 0; i < len - 3; i += 4) {
2064 switch (type) {
2065 case 1:
2066 freq = BCD_32 (data) * 10;
2067 break;
2068 case 2:
2069 freq = BCD_32 (data) * 100;
2070 break;
2071 case 3:
2072 freq = GST_READ_UINT32_BE (data) * 10;
2073 break;
2074 default:
2075 break;
2076 }
2077
2078 g_array_append_val (*list, freq);
2079 data += 4;
2080 }
2081
2082 return TRUE;
2083 }
2084
2085 /* GST_MTS_DESC_DVB_DATA_BROADCAST (0x64) */
2086 static GstMpegtsDataBroadcastDescriptor *
_gst_mpegts_dvb_data_broadcast_descriptor_copy(GstMpegtsDataBroadcastDescriptor * source)2087 _gst_mpegts_dvb_data_broadcast_descriptor_copy (GstMpegtsDataBroadcastDescriptor
2088 * source)
2089 {
2090 GstMpegtsDataBroadcastDescriptor *copy;
2091
2092 copy = g_slice_dup (GstMpegtsDataBroadcastDescriptor, source);
2093
2094 copy->selector_bytes = g_memdup2 (source->selector_bytes, source->length);
2095 copy->language_code = g_strdup (source->language_code);
2096 copy->text = g_strdup (source->text);
2097
2098 return copy;
2099 }
2100
2101 void
gst_mpegts_dvb_data_broadcast_descriptor_free(GstMpegtsDataBroadcastDescriptor * source)2102 gst_mpegts_dvb_data_broadcast_descriptor_free (GstMpegtsDataBroadcastDescriptor
2103 * source)
2104 {
2105 g_free (source->selector_bytes);
2106 g_free (source->language_code);
2107 g_free (source->text);
2108 g_slice_free (GstMpegtsDataBroadcastDescriptor, source);
2109 }
2110
2111 G_DEFINE_BOXED_TYPE (GstMpegtsDataBroadcastDescriptor,
2112 gst_mpegts_dvb_data_broadcast_descriptor,
2113 (GBoxedCopyFunc) _gst_mpegts_dvb_data_broadcast_descriptor_copy,
2114 (GFreeFunc) gst_mpegts_dvb_data_broadcast_descriptor_free);
2115
2116 /**
2117 * gst_mpegts_descriptor_parse_dvb_data_broadcast:
2118 * @descriptor: a %GST_MTS_DESC_DVB_DATA_BROADCAST #GstMpegtsDescriptor
2119 * @res: (out) (transfer full): #GstMpegtsDataBroadcastDescriptor
2120 *
2121 * Parses out the data broadcast from the @descriptor.
2122 *
2123 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2124 */
2125 gboolean
gst_mpegts_descriptor_parse_dvb_data_broadcast(const GstMpegtsDescriptor * descriptor,GstMpegtsDataBroadcastDescriptor ** desc)2126 gst_mpegts_descriptor_parse_dvb_data_broadcast (const GstMpegtsDescriptor
2127 * descriptor, GstMpegtsDataBroadcastDescriptor ** desc)
2128 {
2129 guint8 *data;
2130 GstMpegtsDataBroadcastDescriptor *res;
2131
2132 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
2133 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_DATA_BROADCAST, 8, FALSE);
2134
2135 data = (guint8 *) descriptor->data + 2;
2136
2137 res = g_slice_new0 (GstMpegtsDataBroadcastDescriptor);
2138
2139 res->data_broadcast_id = GST_READ_UINT16_BE (data);
2140 data += 2;
2141
2142 res->component_tag = *data;
2143 data += 1;
2144
2145 res->length = *data;
2146 data += 1;
2147
2148 res->selector_bytes = g_memdup2 (data, res->length);
2149 data += res->length;
2150
2151 res->language_code = convert_lang_code (data);
2152 data += 3;
2153
2154 res->text = get_encoding_and_convert ((const gchar *) data + 1, *data);
2155
2156 *desc = res;
2157
2158 return TRUE;
2159 }
2160
2161 /* GST_MTS_DESC_DVB_SCRAMBLING (0x65) */
2162 /**
2163 * gst_mpegts_descriptor_parse_dvb_scrambling:
2164 * @descriptor: a %GST_MTS_DESC_DVB_SCRAMBLING #GstMpegtsDescriptor
2165 * @scrambling_mode: (out): This 8-bit field identifies the selected
2166 * mode of the scrambling algorithm (#GstMpegtsDVBScramblingModeType).
2167 * The technical details of the scrambling algorithm are available only
2168 * to bona-fide users upon signature of a Non Disclosure Agreement (NDA)
2169 * administered by the DVB Common Scrambling Algorithm Custodian.
2170 *
2171 * Parses out the scrambling mode from the @descriptor.
2172 *
2173 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2174 */
2175 gboolean
gst_mpegts_descriptor_parse_dvb_scrambling(const GstMpegtsDescriptor * descriptor,GstMpegtsDVBScramblingModeType * scrambling_mode)2176 gst_mpegts_descriptor_parse_dvb_scrambling (const GstMpegtsDescriptor *
2177 descriptor, GstMpegtsDVBScramblingModeType * scrambling_mode)
2178 {
2179 guint8 *data;
2180
2181 g_return_val_if_fail (descriptor != NULL && scrambling_mode != NULL, FALSE);
2182 __common_desc_checks_exact (descriptor, GST_MTS_DESC_DVB_SCRAMBLING, 1,
2183 FALSE);
2184
2185 data = (guint8 *) descriptor->data + 2;
2186
2187 *scrambling_mode = *data;
2188
2189 return TRUE;
2190 }
2191
2192 /* GST_MTS_DESC_DVB_DATA_BROADCAST_ID (0x66) */
2193 /**
2194 * gst_mpegts_descriptor_parse_dvb_data_broadcast_id:
2195 * @descriptor: a %GST_MTS_DESC_DVB_DATA_BROADCAST_ID #GstMpegtsDescriptor
2196 * @data_broadcast_id: (out): the data broadcast id
2197 * @id_selector_bytes: (out) (transfer full) (array length=len): the selector bytes, if present
2198 * @len: (out): the length of @id_selector_bytes
2199 *
2200 * Parses out the data broadcast id from the @descriptor.
2201 *
2202 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2203 */
2204 gboolean
gst_mpegts_descriptor_parse_dvb_data_broadcast_id(const GstMpegtsDescriptor * descriptor,guint16 * data_broadcast_id,guint8 ** id_selector_bytes,guint8 * len)2205 gst_mpegts_descriptor_parse_dvb_data_broadcast_id (const GstMpegtsDescriptor
2206 * descriptor, guint16 * data_broadcast_id, guint8 ** id_selector_bytes,
2207 guint8 * len)
2208 {
2209 guint8 *data;
2210
2211 g_return_val_if_fail (descriptor != NULL && data_broadcast_id != NULL &&
2212 id_selector_bytes != NULL, FALSE);
2213 __common_desc_checks (descriptor, GST_MTS_DESC_DVB_DATA_BROADCAST_ID, 2,
2214 FALSE);
2215
2216 data = (guint8 *) descriptor->data + 2;
2217
2218 *data_broadcast_id = GST_READ_UINT16_BE (data);
2219 data += 2;
2220
2221 *len = descriptor->length - 2;
2222
2223 *id_selector_bytes = g_memdup2 (data, *len);
2224
2225 return TRUE;
2226 }
2227
2228 /* GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM (0x7F && 0x04) */
2229 static GstMpegtsT2DeliverySystemDescriptor
_gst_mpegts_t2_delivery_system_descriptor_copy(GstMpegtsT2DeliverySystemDescriptor * source)2230 * _gst_mpegts_t2_delivery_system_descriptor_copy
2231 (GstMpegtsT2DeliverySystemDescriptor * source)
2232 {
2233 GstMpegtsT2DeliverySystemDescriptor *copy;
2234
2235 copy = g_slice_dup (GstMpegtsT2DeliverySystemDescriptor, source);
2236 copy->cells = g_ptr_array_ref (source->cells);
2237
2238 return copy;
2239 }
2240
gst_mpegts_t2_delivery_system_descriptor_free(GstMpegtsT2DeliverySystemDescriptor * source)2241 void gst_mpegts_t2_delivery_system_descriptor_free
2242 (GstMpegtsT2DeliverySystemDescriptor * source)
2243 {
2244 g_ptr_array_unref (source->cells);
2245 g_slice_free (GstMpegtsT2DeliverySystemDescriptor, source);
2246 }
2247
2248 G_DEFINE_BOXED_TYPE (GstMpegtsT2DeliverySystemDescriptor,
2249 gst_mpegts_t2_delivery_system_descriptor,
2250 (GBoxedCopyFunc) _gst_mpegts_t2_delivery_system_descriptor_copy,
2251 (GFreeFunc) gst_mpegts_t2_delivery_system_descriptor_free);
2252
2253 DEFINE_STATIC_COPY_FUNCTION (GstMpegtsT2DeliverySystemCellExtension,
2254 gst_mpegts_t2_delivery_system_cell_extension);
2255
2256 DEFINE_STATIC_FREE_FUNCTION (GstMpegtsT2DeliverySystemCellExtension,
2257 gst_mpegts_t2_delivery_system_cell_extension);
2258
2259 G_DEFINE_BOXED_TYPE (GstMpegtsT2DeliverySystemCellExtension,
2260 gst_mpegts_t2_delivery_system_cell_extension,
2261 (GBoxedCopyFunc) _gst_mpegts_t2_delivery_system_cell_extension_copy,
2262 (GFreeFunc) _gst_mpegts_t2_delivery_system_cell_extension_free);
2263
2264 static GstMpegtsT2DeliverySystemCell *
_gst_mpegts_t2_delivery_system_cell_copy(GstMpegtsT2DeliverySystemCell * source)2265 _gst_mpegts_t2_delivery_system_cell_copy (GstMpegtsT2DeliverySystemCell
2266 * source)
2267 {
2268 GstMpegtsT2DeliverySystemCell *copy =
2269 g_slice_dup (GstMpegtsT2DeliverySystemCell, source);
2270 copy->centre_frequencies = g_array_ref (source->centre_frequencies);
2271 copy->sub_cells = g_ptr_array_ref (source->sub_cells);
2272 return copy;
2273 }
2274
2275 static void
_gst_mpegts_t2_delivery_system_cell_free(GstMpegtsT2DeliverySystemCell * cell)2276 _gst_mpegts_t2_delivery_system_cell_free (GstMpegtsT2DeliverySystemCell * cell)
2277 {
2278 g_ptr_array_unref (cell->sub_cells);
2279 g_array_unref (cell->centre_frequencies);
2280 g_slice_free (GstMpegtsT2DeliverySystemCell, cell);
2281 }
2282
2283 G_DEFINE_BOXED_TYPE (GstMpegtsT2DeliverySystemCell,
2284 gst_mpegts_t2_delivery_system_cell,
2285 (GBoxedCopyFunc) _gst_mpegts_t2_delivery_system_cell_copy,
2286 (GFreeFunc) _gst_mpegts_t2_delivery_system_cell_free);
2287
2288 /**
2289 * gst_mpegts_descriptor_parse_dvb_t2_delivery_system:
2290 * @descriptor: a %GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM #GstMpegtsDescriptor
2291 * @res: (out) (transfer full): #GstMpegtsT2DeliverySystemDescriptor
2292 *
2293 * Parses out the DVB-T2 delivery system from the @descriptor.
2294 *
2295 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2296 */
2297 gboolean
gst_mpegts_descriptor_parse_dvb_t2_delivery_system(const GstMpegtsDescriptor * descriptor,GstMpegtsT2DeliverySystemDescriptor ** desc)2298 gst_mpegts_descriptor_parse_dvb_t2_delivery_system (const GstMpegtsDescriptor
2299 * descriptor, GstMpegtsT2DeliverySystemDescriptor ** desc)
2300 {
2301 guint8 *data;
2302 guint8 len, freq_len, sub_cell_len;
2303 guint32 tmp_freq;
2304 guint8 i;
2305 GstMpegtsT2DeliverySystemDescriptor *res;
2306
2307 g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
2308 __common_desc_ext_checks (descriptor, GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM,
2309 4, FALSE);
2310
2311 data = (guint8 *) descriptor->data + 3;
2312
2313 res = g_slice_new0 (GstMpegtsT2DeliverySystemDescriptor);
2314
2315 res->plp_id = *data;
2316 data += 1;
2317
2318 res->t2_system_id = GST_READ_UINT16_BE (data);
2319 data += 2;
2320
2321 if (descriptor->length > 4) {
2322 // FIXME: siso / miso
2323 res->siso_miso = (*data >> 6) & 0x03;
2324 switch ((*data >> 2) & 0x0f) {
2325 case 0:
2326 res->bandwidth = 8000000;
2327 break;
2328 case 1:
2329 res->bandwidth = 7000000;
2330 break;
2331 case 2:
2332 res->bandwidth = 6000000;
2333 break;
2334 case 3:
2335 res->bandwidth = 5000000;
2336 break;
2337 case 4:
2338 res->bandwidth = 10000000;
2339 break;
2340 case 5:
2341 res->bandwidth = 1712000;
2342 break;
2343 default:
2344 res->bandwidth = 0;
2345 break;
2346 }
2347 data += 1;
2348
2349 switch ((*data >> 5) & 0x07) {
2350 case 0:
2351 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_32;
2352 break;
2353 case 1:
2354 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_16;
2355 break;
2356 case 2:
2357 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_8;
2358 break;
2359 case 3:
2360 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_4;
2361 break;
2362 case 4:
2363 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_128;
2364 break;
2365 case 5:
2366 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_128;
2367 break;
2368 case 6:
2369 res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_256;
2370 break;
2371 default:
2372 break;
2373 }
2374
2375 switch ((*data >> 2) & 0x07) {
2376 case 0:
2377 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_2K;
2378 break;
2379 case 1:
2380 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_8K;
2381 break;
2382 case 2:
2383 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_4K;
2384 break;
2385 case 3:
2386 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_1K;
2387 break;
2388 case 4:
2389 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_16K;
2390 break;
2391 case 5:
2392 res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_32K;
2393 break;
2394 default:
2395 break;
2396 }
2397 res->other_frequency = (*data >> 1) & 0x01;
2398 res->tfs = (*data) & 0x01;
2399 data += 1;
2400
2401 len = descriptor->length - 6;
2402
2403 res->cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
2404 _gst_mpegts_t2_delivery_system_cell_free);
2405
2406 for (i = 0; i < len;) {
2407 GstMpegtsT2DeliverySystemCell *cell;
2408 guint8 j, k;
2409
2410 cell = g_slice_new0 (GstMpegtsT2DeliverySystemCell);
2411 g_ptr_array_add (res->cells, cell);
2412
2413 cell->cell_id = GST_READ_UINT16_BE (data);
2414 data += 2;
2415 i += 2;
2416
2417 cell->centre_frequencies = g_array_new (FALSE, FALSE, sizeof (guint32));
2418
2419 if (res->tfs == TRUE) {
2420 freq_len = *data;
2421 data += 1;
2422 i += 1;
2423
2424 for (j = 0; j < freq_len;) {
2425 tmp_freq = GST_READ_UINT32_BE (data) * 10;
2426 g_array_append_val (cell->centre_frequencies, tmp_freq);
2427 data += 4;
2428 j += 4;
2429 i += 4;
2430 }
2431 } else {
2432 tmp_freq = GST_READ_UINT32_BE (data) * 10;
2433 g_array_append_val (cell->centre_frequencies, tmp_freq);
2434 data += 4;
2435 i += 4;
2436 }
2437 sub_cell_len = (*data);
2438 data += 1;
2439 i += 1;
2440
2441 cell->sub_cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
2442 _gst_mpegts_t2_delivery_system_cell_extension_free);
2443
2444 for (k = 0; k < sub_cell_len;) {
2445 GstMpegtsT2DeliverySystemCellExtension *cell_ext;
2446 cell_ext = g_slice_new0 (GstMpegtsT2DeliverySystemCellExtension);
2447
2448 g_ptr_array_add (cell->sub_cells, cell_ext);
2449 cell_ext->cell_id_extension = *data;
2450 data += 1;
2451
2452 cell_ext->transposer_frequency = GST_READ_UINT32_BE (data) * 10;
2453 data += 4;
2454 i += 5;
2455 k += 5;
2456 }
2457 }
2458 }
2459
2460 *desc = res;
2461 return TRUE;
2462 }
2463
2464 /**
2465 * gst_mpegts_descriptor_parse_audio_preselection_list:
2466 * @descriptor: a %GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION #GstMpegtsDescriptor
2467 * @list: (out) (transfer full) (element-type GstMpegtsAudioPreselectionDescriptor):
2468 * the list of audio preselection
2469 *
2470 * Parses out a list of audio preselection from the @descriptor.
2471 *
2472 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
2473 *
2474 * Since: 1.20
2475 */
2476 gboolean
gst_mpegts_descriptor_parse_audio_preselection_list(const GstMpegtsDescriptor * descriptor,GPtrArray ** list)2477 gst_mpegts_descriptor_parse_audio_preselection_list (const GstMpegtsDescriptor
2478 * descriptor, GPtrArray ** list)
2479 {
2480 guint8 *data;
2481 guint8 i, num_preselections, num_aux_components, future_extension_length;
2482 GstMpegtsAudioPreselectionDescriptor *item;
2483
2484 g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE);
2485 __common_desc_ext_check_base (descriptor,
2486 GST_MTS_DESC_EXT_DVB_AUDIO_PRESELECTION, FALSE);
2487
2488 *list = g_ptr_array_new_with_free_func ((GDestroyNotify)
2489 gst_mpegts_descriptor_parse_audio_preselection_free);
2490
2491 data = (guint8 *) descriptor->data + 3;
2492 num_preselections = (guint8) ((*data & 0xF8) >> 3);
2493 data += 1;
2494
2495 for (i = 0; i < num_preselections; i++) {
2496 item = g_slice_new0 (GstMpegtsAudioPreselectionDescriptor);
2497 g_ptr_array_add (*list, item);
2498
2499 item->preselection_id = (*data & 0xF8) >> 3;
2500 item->audio_rendering_indication = *data & 0x7;
2501 data += 1;
2502
2503 item->audio_description = (*data & 0x80) >> 7;
2504 item->spoken_subtitles = (*data & 0x40) >> 6;
2505 item->dialogue_enhancement = (*data & 0x20) >> 5;
2506 item->interactivity_enabled = (*data & 0x10) >> 4;
2507 item->language_code_present = (*data & 0x08) >> 3;
2508 item->text_label_present = (*data & 0x04) >> 2;
2509 item->multi_stream_info_present = (*data & 0x02) >> 1;
2510 item->future_extension = (*data) & 0x01;
2511 data += 1;
2512
2513 if (item->language_code_present == 1) {
2514 item->language_code = convert_lang_code (data);
2515 data += 3;
2516 }
2517
2518 if (item->text_label_present == 1) {
2519 item->message_id = *data;
2520 data += 1;
2521 }
2522
2523 if (item->multi_stream_info_present == 1) {
2524 num_aux_components = (*data & 0xE0) >> 5;
2525 data += 1;
2526 for (i = 0; i < num_aux_components; i++) {
2527 data += 1;
2528 }
2529 }
2530
2531 if (item->future_extension == 1) {
2532 future_extension_length = *data & 0x1F;
2533 data += 1;
2534 for (i = 0; i < future_extension_length; i++) {
2535 data += 1;
2536 }
2537 }
2538 }
2539
2540 return TRUE;
2541 }
2542
gst_mpegts_descriptor_parse_audio_preselection_free(GstMpegtsAudioPreselectionDescriptor * source)2543 void gst_mpegts_descriptor_parse_audio_preselection_free
2544 (GstMpegtsAudioPreselectionDescriptor * source)
2545 {
2546 if (source->language_code_present == 1) {
2547 g_free (source->language_code);
2548 }
2549 g_slice_free (GstMpegtsAudioPreselectionDescriptor, source);
2550 }
2551
gst_mpegts_descriptor_parse_audio_preselection_dump(GstMpegtsAudioPreselectionDescriptor * source)2552 void gst_mpegts_descriptor_parse_audio_preselection_dump
2553 (GstMpegtsAudioPreselectionDescriptor * source)
2554 {
2555 GST_DEBUG ("[Audio Preselection Descriptor]");
2556 GST_DEBUG (" preselection_id: 0x%02x", source->preselection_id);
2557 GST_DEBUG ("audio_rendering_indication: 0x%02x",
2558 source->audio_rendering_indication);
2559 GST_DEBUG (" audio_description: %d", source->audio_description);
2560 GST_DEBUG (" spoken_subtitles: %d", source->spoken_subtitles);
2561 GST_DEBUG (" dialogue_enhancement: %d", source->dialogue_enhancement);
2562 GST_DEBUG (" interactivity_enabled: %d", source->interactivity_enabled);
2563 GST_DEBUG (" language_code_present: %d", source->language_code_present);
2564 GST_DEBUG (" text_label_present: %d", source->text_label_present);
2565 GST_DEBUG (" multi_stream_info_present: %d",
2566 source->multi_stream_info_present);
2567 GST_DEBUG (" future_extension: %d", source->future_extension);
2568
2569 if (source->language_code_present == 1) {
2570 GST_DEBUG (" language_code: %s", source->language_code);
2571 }
2572 if (source->text_label_present == 1) {
2573 GST_DEBUG (" message_id: 0x%02x", source->message_id);
2574 }
2575 GST_DEBUG ("-------------------------------");
2576 }
2577