/*
 * gstmpegtsdescriptor.c - 
 * Copyright (C) 2013 Edward Hervey
 * 
 * Authors:
 *   Edward Hervey <edward@collabora.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include <stdlib.h>
#include <string.h>

#include "mpegts.h"
#include "gstmpegts-private.h"


/**
 * SECTION:gst-dvb-descriptor
 * @title: DVB variants of MPEG-TS descriptors
 * @short_description: Descriptors for the various DVB specifications
 * @include: gst/mpegts/mpegts.h
 *
 */

/*
 * TODO
 *
 * * Add common validation code for data presence and minimum/maximum expected
 *   size.
 * * Add parsing methods for the following descriptors that were previously 
 *   handled in mpegtsbase:
 *   * GST_MTS_DESC_DVB_DATA_BROADCAST_ID
 *   * GST_MTS_DESC_DVB_CAROUSEL_IDENTIFIER
 */

#define BCD_UN(a) ((a) & 0x0f)
#define BCD_DEC(a) (((a) >> 4) & 0x0f)
#define BCD(a) (BCD_UN(a) + 10 * BCD_DEC(a))
#define BCD_16(a) (BCD(a[1]) + 100 * BCD(a[0]))
#define BCD_28(a) (BCD_DEC(a[3]) + 10 * BCD(a[2]) + 1000 * BCD(a[1]) + 100000 * BCD(a[0]))
#define BCD_32(a) (BCD(a[3]) + 100 * BCD(a[2]) + 10000 * BCD(a[1]) + 1000000 * BCD(a[0]))

/* GST_MTS_DESC_DVB_NETWORK_NAME (0x40) */
/**
 * gst_mpegts_descriptor_parse_dvb_network_name:
 * @descriptor: a %GST_MTS_DESC_DVB_NETWORK_NAME #GstMpegtsDescriptor
 * @name: (out) (transfer full): the extracted name
 *
 * Parses out the dvb network name from the @descriptor:
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_network_name (const GstMpegtsDescriptor *
    descriptor, gchar ** name)
{
  g_return_val_if_fail (descriptor != NULL && name != NULL, FALSE);
  /* We need at least one byte of data for the string */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_NETWORK_NAME, 1, FALSE);

  *name = get_encoding_and_convert ((gchar *) descriptor->data + 2,
      descriptor->data[1]);
  return TRUE;
}

/**
 * gst_mpegts_descriptor_from_dvb_network_name:
 * @name: the network name to set
 *
 * Creates a #GstMpegtsDescriptor to be a %GST_MTS_DESC_DVB_NETWORK_NAME,
 * with the network name @name. The data field of the #GstMpegtsDescriptor
 * will be allocated, and transferred to the caller.
 *
 * Returns: (transfer full): the #GstMpegtsDescriptor or %NULL on fail
 */
GstMpegtsDescriptor *
gst_mpegts_descriptor_from_dvb_network_name (const gchar * name)
{
  GstMpegtsDescriptor *descriptor;
  guint8 *converted_name;
  gsize size;

  g_return_val_if_fail (name != NULL, NULL);

  converted_name = dvb_text_from_utf8 (name, &size);

  if (size >= 256) {
    g_free (converted_name);
    return NULL;
  }

  if (!converted_name) {
    GST_WARNING ("Could not find proper encoding for string `%s`", name);
    return NULL;
  }

  descriptor = _new_descriptor (GST_MTS_DESC_DVB_NETWORK_NAME, size);
  memcpy (descriptor->data + 2, converted_name, size);
  g_free (converted_name);

  return descriptor;
}

/* GST_MTS_DESC_DVB_SERVICE_LIST (0x41) */
static void
_gst_mpegts_dvb_service_list_item_free (GstMpegtsDVBServiceListItem * item)
{
  g_slice_free (GstMpegtsDVBServiceListItem, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_service_list:
 * @descriptor: a %GST_MTS_DESC_DVB_SERVICE_LIST #GstMpegtsDescriptor
 * @list: (out) (transfer full) (element-type GstMpegtsDVBServiceListItem):
 * the list of services
 *
 * Parses out a list of services from the @descriptor:
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_service_list (const GstMpegtsDescriptor *
    descriptor, GPtrArray ** list)
{
  guint8 *data, i;

  g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE);
  /* a entry has 3 bytes, 2 for service id, 1 for service type */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SERVICE_LIST, 3, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *list = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_dvb_service_list_item_free);

  for (i = 0; i < descriptor->length - 2; i += 3) {
    GstMpegtsDVBServiceListItem *item =
        g_slice_new0 (GstMpegtsDVBServiceListItem);

    g_ptr_array_add (*list, item);
    item->service_id = GST_READ_UINT16_BE (data);
    data += 2;

    item->type = *data;
    data += 1;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_STUFFING (0x42) */
/**
 * gst_mpegts_descriptor_parse_dvb_stuffing:
 * @descriptor: a %GST_MTS_DESC_DVB_STUFFING #GstMpegtsDescriptor
 * @stuffing_bytes: (out) (transfer full): the stuffing bytes
 *
 * Parses out the stuffing bytes from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_stuffing (const GstMpegtsDescriptor *
    descriptor, guint8 ** stuffing_bytes)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL && stuffing_bytes != NULL, FALSE);
  __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_STUFFING, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *stuffing_bytes = g_memdup (data, descriptor->length);

  return TRUE;
}

/* GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM (0x43) */
/**
 * gst_mpegts_descriptor_parse_satellite_delivery_system:
 * @descriptor: a %GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM #GstMpegtsDescriptor
 * @res: (out) (transfer none): the #GstMpegtsSatelliteDeliverySystemDescriptor to fill
 *
 * Extracts the satellite delivery system information from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_satellite_delivery_system (const GstMpegtsDescriptor
    * descriptor, GstMpegtsSatelliteDeliverySystemDescriptor * res)
{
  guint8 *data;
  guint8 tmp;

  g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
  /* This descriptor is always 11 bytes long */
  __common_desc_checks_exact (descriptor,
      GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM, 11, FALSE);

  data = (guint8 *) descriptor->data + 2;

  /* BCD coded frequency in GHz (decimal point occurs after the 3rd character)
   * So direct BCD gives us units of (GHz / 100 000) = 10 kHz*/
  res->frequency = BCD_32 (data) * 10;
  data += 4;
  /* BCD codec position in degrees (float pointer after the 3rd character) */
  res->orbital_position = (BCD_16 (data)) / 10.0;
  data += 2;

  tmp = *data;
  res->west_east = (tmp & 0x80) == 0x80;
  res->polarization = (tmp >> 7) & 0x03;
  res->modulation_system = (tmp & 0x04) == 0x04;
  if (res->modulation_system)
    res->roll_off = (tmp >> 3 & 0x03);
  else
    res->roll_off = GST_MPEGTS_ROLLOFF_AUTO;
  switch (tmp & 0x03) {
    case 0x00:
      res->modulation_type = GST_MPEGTS_MODULATION_QAM_AUTO;
      break;
    case 0x01:
      res->modulation_type = GST_MPEGTS_MODULATION_QPSK;
      break;
    case 0x02:
      res->modulation_type = GST_MPEGTS_MODULATION_PSK_8;
      break;
    case 0x03:
      res->modulation_type = GST_MPEGTS_MODULATION_QAM_16;
      break;
    default:
      res->modulation_type = GST_MPEGTS_MODULATION_QAM_AUTO;
      break;
  }
  data += 1;
  /* symbol_rate is in Msymbols/ (decimal point occurs after 3rd character) */
  /* So direct BCD gives us units of (Msymbol / 10 000) = 100 sym/s */
  res->symbol_rate = BCD_28 (data) * 100;
  data += 3;
  /* fec_inner */
  switch (*data >> 4) {
    case 0x01:
      res->fec_inner = GST_MPEGTS_FEC_1_2;
      break;
    case 0x02:
      res->fec_inner = GST_MPEGTS_FEC_2_3;
      break;
    case 0x03:
      res->fec_inner = GST_MPEGTS_FEC_3_4;
      break;
    case 0x04:
      res->fec_inner = GST_MPEGTS_FEC_5_6;
      break;
    case 0x05:
      res->fec_inner = GST_MPEGTS_FEC_7_8;
      break;
    case 0x06:
      res->fec_inner = GST_MPEGTS_FEC_8_9;
      break;
    case 0x07:
      res->fec_inner = GST_MPEGTS_FEC_3_5;
      break;
    case 0x08:
      res->fec_inner = GST_MPEGTS_FEC_4_5;
      break;
    case 0x09:
      res->fec_inner = GST_MPEGTS_FEC_9_10;
      break;
    case 0x0f:
      res->fec_inner = GST_MPEGTS_FEC_NONE;
      break;
    default:
      res->fec_inner = GST_MPEGTS_FEC_AUTO;
      break;
  }

  return TRUE;
}


/* GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM (0x44) */
/**
 * gst_mpegts_descriptor_parse_cable_delivery_system:
 * @descriptor: a %GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM #GstMpegtsDescriptor
 * @res: (out) (transfer none): the #GstMpegtsCableDeliverySystemDescriptor to fill
 *
 * Extracts the cable delivery system information from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_cable_delivery_system (const GstMpegtsDescriptor *
    descriptor, GstMpegtsCableDeliverySystemDescriptor * res)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
  /* This descriptor is always 11 bytes long */
  __common_desc_checks_exact (descriptor,
      GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM, 11, FALSE);

  data = (guint8 *) descriptor->data + 2;
  /* BCD in MHz, decimal place after the fourth character */
  res->frequency = BCD_32 (data) * 100;
  data += 5;
  /* fec_out (4bits) */
  res->outer_fec = *data++ & 0x0f;
  switch (*data) {
    case 0x00:
      res->modulation = GST_MPEGTS_MODULATION_NONE;
      break;
    case 0x01:
      res->modulation = GST_MPEGTS_MODULATION_QAM_16;
      break;
    case 0x02:
      res->modulation = GST_MPEGTS_MODULATION_QAM_32;
      break;
    case 0x03:
      res->modulation = GST_MPEGTS_MODULATION_QAM_64;
      break;
    case 0x04:
      res->modulation = GST_MPEGTS_MODULATION_QAM_128;
      break;
    case 0x05:
      res->modulation = GST_MPEGTS_MODULATION_QAM_256;
      break;
    default:
      GST_WARNING ("Unsupported cable modulation type: 0x%02x", *data);
      res->modulation = GST_MPEGTS_MODULATION_NONE;
      break;
  }

  data += 1;
  /* symbol_rate is in Msymbols/ (decimal point occurs after 3rd character) */
  /* So direct BCD gives us units of (Msymbol / 10 000) = 100 sym/s */
  res->symbol_rate = BCD_28 (data) * 100;
  data += 3;
  /* fec_inner */
  switch (*data & 0xf) {
    case 0x00:
      res->fec_inner = GST_MPEGTS_FEC_AUTO;
      break;
    case 0x01:
      res->fec_inner = GST_MPEGTS_FEC_1_2;
      break;
    case 0x02:
      res->fec_inner = GST_MPEGTS_FEC_2_3;
      break;
    case 0x03:
      res->fec_inner = GST_MPEGTS_FEC_3_4;
      break;
    case 0x04:
      res->fec_inner = GST_MPEGTS_FEC_5_6;
      break;
    case 0x05:
      res->fec_inner = GST_MPEGTS_FEC_7_8;
      break;
    case 0x06:
      res->fec_inner = GST_MPEGTS_FEC_8_9;
      break;
    case 0x07:
      res->fec_inner = GST_MPEGTS_FEC_3_5;
      break;
    case 0x08:
      res->fec_inner = GST_MPEGTS_FEC_4_5;
      break;
    case 0x09:
      res->fec_inner = GST_MPEGTS_FEC_9_10;
      break;
    case 0x0f:
      res->fec_inner = GST_MPEGTS_FEC_NONE;
      break;
    default:
      res->fec_inner = GST_MPEGTS_FEC_AUTO;
      break;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_BOUQUET_NAME (0x47) */
/**
 * gst_mpegts_descriptor_parse_dvb_bouquet_name:
 * @bouquet_name: (out) (transfer full) (allow-none): the bouquet name
 *
 * Extracts the bouquet name from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_bouquet_name (const GstMpegtsDescriptor *
    descriptor, gchar ** bouquet_name)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL && bouquet_name != NULL, FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_BOUQUET_NAME, 1, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *bouquet_name =
      get_encoding_and_convert ((const gchar *) data, descriptor->length);

  return TRUE;
}

/* GST_MTS_DESC_DVB_SERVICE (0x48) */
/**
 * gst_mpegts_descriptor_parse_dvb_service:
 * @descriptor: a %GST_MTS_DESC_DVB_SERVICE #GstMpegtsDescriptor
 * @service_type: (out) (allow-none): the service type
 * @service_name: (out) (transfer full) (allow-none): the service name
 * @provider_name: (out) (transfer full) (allow-none): the provider name
 *
 * Extracts the dvb service information from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_service (const GstMpegtsDescriptor *
    descriptor, GstMpegtsDVBServiceType * service_type, gchar ** service_name,
    gchar ** provider_name)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL, FALSE);
  /* Need at least 3 bytes (type and 2 bytes for the string length) */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SERVICE, 3, FALSE);

  data = (guint8 *) descriptor->data + 2;

  if (service_type)
    *service_type = *data;
  data += 1;
  if (provider_name)
    *provider_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
  data += *data + 1;
  if (service_name)
    *service_name = get_encoding_and_convert ((const gchar *) data + 1, *data);

  return TRUE;
}

/**
 * gst_mpegts_descriptor_from_dvb_service:
 * @service_type: Service type defined as a #GstMpegtsDVBServiceType
 * @service_name: (allow-none): Name of the service
 * @service_provider: (allow-none): Name of the service provider
 *
 * Fills a #GstMpegtsDescriptor to be a %GST_MTS_DESC_DVB_SERVICE.
 * The data field of the #GstMpegtsDescriptor will be allocated,
 * and transferred to the caller.
 *
 * Returns: (transfer full): the #GstMpegtsDescriptor or %NULL on fail
 */
GstMpegtsDescriptor *
gst_mpegts_descriptor_from_dvb_service (GstMpegtsDVBServiceType service_type,
    const gchar * service_name, const gchar * service_provider)
{
  GstMpegtsDescriptor *descriptor = NULL;
  guint8 *conv_provider_name = NULL, *conv_service_name = NULL;
  gsize provider_size = 0, service_size = 0;
  guint8 *data;

  if (service_provider) {
    conv_provider_name = dvb_text_from_utf8 (service_provider, &provider_size);

    if (!conv_provider_name) {
      GST_WARNING ("Could not find proper encoding for string `%s`",
          service_provider);
      goto beach;
    }
  }

  if (provider_size >= 256) {
    GST_WARNING ("Service provider string too big (%" G_GSIZE_FORMAT " > 256)",
        provider_size);
    goto beach;
  }

  if (service_name) {
    conv_service_name = dvb_text_from_utf8 (service_name, &service_size);

    if (!conv_service_name) {
      GST_WARNING ("Could not find proper encoding for string `%s`",
          service_name);
      goto beach;
    }
  }

  if (service_size >= 256) {
    GST_WARNING ("Service name string too big (%" G_GSIZE_FORMAT " > 256)",
        service_size);
    goto beach;
  }

  descriptor =
      _new_descriptor (GST_MTS_DESC_DVB_SERVICE,
      3 + provider_size + service_size);

  data = descriptor->data + 2;
  *data++ = service_type;
  *data++ = provider_size;
  if (conv_provider_name)
    memcpy (data, conv_provider_name, provider_size);

  data += provider_size;
  *data++ = service_size;
  if (conv_service_name)
    memcpy (data, conv_service_name, service_size);

beach:
  g_free (conv_service_name);
  g_free (conv_provider_name);

  return descriptor;
}

/* GST_MTS_DESC_DVB_LINKAGE (0x4A) */
static GstMpegtsDVBLinkageDescriptor *
_gst_mpegts_dvb_linkage_descriptor_copy (GstMpegtsDVBLinkageDescriptor * source)
{
  GstMpegtsDVBLinkageDescriptor *copy;

  copy = g_slice_dup (GstMpegtsDVBLinkageDescriptor, source);

  switch (source->linkage_type) {
    case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:
      copy->linkage_data = g_slice_dup (GstMpegtsDVBLinkageMobileHandOver,
          source->linkage_data);
      break;
    case GST_MPEGTS_DVB_LINKAGE_EVENT:
      copy->linkage_data = g_slice_dup (GstMpegtsDVBLinkageEvent,
          source->linkage_data);
      break;
    case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:
      copy->linkage_data = g_ptr_array_ref (source->linkage_data);
      break;
    default:
      break;
  }

  copy->private_data_bytes = g_memdup (source->private_data_bytes,
      source->private_data_length);

  return copy;
}

void
gst_mpegts_dvb_linkage_descriptor_free (GstMpegtsDVBLinkageDescriptor * source)
{
  if (source->linkage_data)
    switch (source->linkage_type) {
      case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:
        g_slice_free (GstMpegtsDVBLinkageMobileHandOver, source->linkage_data);
        break;
      case GST_MPEGTS_DVB_LINKAGE_EVENT:
        g_slice_free (GstMpegtsDVBLinkageEvent, source->linkage_data);
        break;
      case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:
        g_ptr_array_unref (source->linkage_data);
        break;
      default:
        break;
    }

  g_free (source->private_data_bytes);
  g_slice_free (GstMpegtsDVBLinkageDescriptor, source);
}

G_DEFINE_BOXED_TYPE (GstMpegtsDVBLinkageDescriptor,
    gst_mpegts_dvb_linkage_descriptor,
    (GBoxedCopyFunc) _gst_mpegts_dvb_linkage_descriptor_copy,
    (GFreeFunc) gst_mpegts_dvb_linkage_descriptor_free);

static void
_gst_mpegts_dvb_linkage_extened_event_free (GstMpegtsDVBLinkageExtendedEvent *
    item)
{
  g_slice_free (GstMpegtsDVBLinkageExtendedEvent, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_linkage:
 * @descriptor: a %GST_MTS_DESC_DVB_LINKAGE #GstMpegtsDescriptor
 * @res: (out) (transfer full): the #GstMpegtsDVBLinkageDescriptor to fill
 *
 * Extracts the DVB linkage information from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_linkage (const GstMpegtsDescriptor * descriptor,
    GstMpegtsDVBLinkageDescriptor ** desc)
{
  guint i;
  guint8 *data, *end;
  GstMpegtsDVBLinkageDescriptor *res;

  g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_LINKAGE, 7, FALSE);

  data = (guint8 *) descriptor->data + 2;
  end = data + descriptor->length;

  res = g_slice_new0 (GstMpegtsDVBLinkageDescriptor);

  res->transport_stream_id = GST_READ_UINT16_BE (data);
  data += 2;

  res->original_network_id = GST_READ_UINT16_BE (data);
  data += 2;

  res->service_id = GST_READ_UINT16_BE (data);
  data += 2;

  res->linkage_type = *data;
  data += 1;

  switch (res->linkage_type) {
    case GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER:{
      GstMpegtsDVBLinkageMobileHandOver *hand_over;

      if (end - data < 1)
        goto fail;

      hand_over = g_slice_new0 (GstMpegtsDVBLinkageMobileHandOver);
      res->linkage_data = (gpointer) hand_over;

      hand_over->origin_type = (*data) & 0x01;
      hand_over->hand_over_type = (*data >> 4) & 0x0f;
      data += 1;

      if (hand_over->hand_over_type ==
          GST_MPEGTS_DVB_LINKAGE_HAND_OVER_IDENTICAL
          || hand_over->hand_over_type ==
          GST_MPEGTS_DVB_LINKAGE_HAND_OVER_LOCAL_VARIATION
          || hand_over->hand_over_type ==
          GST_MPEGTS_DVB_LINKAGE_HAND_OVER_ASSOCIATED) {
        if (end - data < 2)
          goto fail;

        hand_over->network_id = GST_READ_UINT16_BE (data);
        data += 2;
      }

      if (hand_over->origin_type == 0) {
        if (end - data < 2)
          goto fail;

        hand_over->initial_service_id = GST_READ_UINT16_BE (data);
        data += 2;
      }
      break;
    }
    case GST_MPEGTS_DVB_LINKAGE_EVENT:{
      GstMpegtsDVBLinkageEvent *event;

      if (end - data < 3)
        goto fail;

      event = g_slice_new0 (GstMpegtsDVBLinkageEvent);
      res->linkage_data = (gpointer) event;

      event->target_event_id = GST_READ_UINT16_BE (data);
      data += 2;
      event->target_listed = *data & 0x01;
      event->event_simulcast = (*data >> 1) & 0x01;
      data += 1;
      break;
    }
    case GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT:{
      GPtrArray *ext_events;
      ext_events = g_ptr_array_new_with_free_func ((GDestroyNotify)
          _gst_mpegts_dvb_linkage_extened_event_free);

      res->linkage_data = (gpointer) ext_events;

      for (i = 0; i < *data++;) {
        GstMpegtsDVBLinkageExtendedEvent *ext_event;

        if (end - data < 3)
          goto fail;

        ext_event = g_slice_new0 (GstMpegtsDVBLinkageExtendedEvent);
        g_ptr_array_add (res->linkage_data, ext_event);

        ext_event->target_event_id = GST_READ_UINT16_BE (data);
        data += 2;
        i += 2;

        ext_event->target_listed = *data & 0x01;
        ext_event->event_simulcast = (*data >> 1) & 0x01;
        ext_event->link_type = (*data >> 3) & 0x03;
        ext_event->target_id_type = (*data >> 5) & 0x03;
        ext_event->original_network_id_flag = (*data >> 6) & 0x01;
        ext_event->service_id_flag = (*data >> 7) & 0x01;
        data += 1;
        i += 1;

        if (ext_event->target_id_type == 3) {
          if (end - data < 2)
            goto fail;

          ext_event->user_defined_id = GST_READ_UINT16_BE (data);
          data += 2;
          i += 2;
        } else {
          if (ext_event->target_id_type == 1) {
            if (end - data < 2)
              goto fail;

            ext_event->target_transport_stream_id = GST_READ_UINT16_BE (data);
            data += 2;
            i += 2;
          }
          if (ext_event->original_network_id_flag) {
            if (end - data < 2)
              goto fail;

            ext_event->target_original_network_id = GST_READ_UINT16_BE (data);
            data += 2;
            i += 2;
          }
          if (ext_event->service_id_flag) {
            if (end - data < 2)
              goto fail;

            ext_event->target_service_id = GST_READ_UINT16_BE (data);
            data += 2;
            i += 2;
          }
        }
      }
      break;
    }
    default:
      break;
  }

  res->private_data_length = end - data;
  res->private_data_bytes = g_memdup (data, res->private_data_length);

  *desc = res;

  return TRUE;

fail:
  gst_mpegts_dvb_linkage_descriptor_free (res);
  return FALSE;
}

/**
 * gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over:
 * @desc: the #GstMpegtsDVBLinkageDescriptor
 *
 * Returns: The #GstMpegtsDVBLinkageMobileHandOver or %NULL if an error happened
 */
const GstMpegtsDVBLinkageMobileHandOver *
gst_mpegts_dvb_linkage_descriptor_get_mobile_hand_over (const
    GstMpegtsDVBLinkageDescriptor * desc)
{
  g_return_val_if_fail (desc != NULL, NULL);
  g_return_val_if_fail (desc->linkage_type ==
      GST_MPEGTS_DVB_LINKAGE_MOBILE_HAND_OVER, NULL);

  return (const GstMpegtsDVBLinkageMobileHandOver *) desc->linkage_data;
}

/**
 * gst_mpegts_dvb_linkage_descriptor_get_event:
 * @desc: the #GstMpegtsDVBLinkageDescriptor
 *
 * Returns: The #GstMpegtsDVBLinkageEvent or %NULL if an error happened
 */
const GstMpegtsDVBLinkageEvent *
gst_mpegts_dvb_linkage_descriptor_get_event (const GstMpegtsDVBLinkageDescriptor
    * desc)
{
  g_return_val_if_fail (desc != NULL, NULL);
  g_return_val_if_fail (desc->linkage_type ==
      GST_MPEGTS_DVB_LINKAGE_EVENT, NULL);

  return (const GstMpegtsDVBLinkageEvent *) desc->linkage_data;
}

/**
 * gst_mpegts_dvb_linkage_descriptor_get_extended_event:
 * @desc: the #GstMpegtsDVBLinkageDescriptor
 *
 * Returns: (element-type GstMpegtsDVBLinkageExtendedEvent): an #GstMpegtsDVBLinkageExtendedEvent array or %NULL if an error happened
 */
const GPtrArray *
gst_mpegts_dvb_linkage_descriptor_get_extended_event (const
    GstMpegtsDVBLinkageDescriptor * desc)
{
  g_return_val_if_fail (desc != NULL, NULL);
  g_return_val_if_fail (desc->linkage_type ==
      GST_MPEGTS_DVB_LINKAGE_EXTENDED_EVENT, NULL);

  return (const GPtrArray *) desc->linkage_data;
}

/* GST_MTS_DESC_DVB_SHORT_EVENT (0x4D) */
/**
 * gst_mpegts_descriptor_parse_dvb_short_event:
 * @descriptor: a %GST_MTS_DESC_DVB_SHORT_EVENT #GstMpegtsDescriptor
 * @language_code: (out) (transfer full) (allow-none): the language code
 * @event_name: (out) (transfer full) (allow-none): the event name
 * @text: (out) (transfer full) (allow-none): the event text
 *
 * Extracts the DVB short event information from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_short_event (const GstMpegtsDescriptor *
    descriptor, gchar ** language_code, gchar ** event_name, gchar ** text)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL, FALSE);
  /* Need at least 5 bytes (3 for language code, 2 for each string length) */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_SHORT_EVENT, 5, FALSE);

  data = (guint8 *) descriptor->data + 2;

  if (language_code)
    *language_code = convert_lang_code (data);

  data += 3;
  if (event_name)
    *event_name = get_encoding_and_convert ((const gchar *) data + 1, *data);
  data += *data + 1;
  if (text)
    *text = get_encoding_and_convert ((const gchar *) data + 1, *data);
  return TRUE;
}

/* GST_MTS_DESC_DVB_TELETEXT (0x56) */
/**
 * gst_mpegts_descriptor_parse_dvb_teletext_idx:
 * @descriptor: a %GST_MTS_DESC_DVB_TELETEXT #GstMpegtsDescriptor
 * @idx: The id of the teletext to get
 * @language_code: (out) (transfer full) (allow-none): a null-terminated string
 * @teletext_type: (out) (allow-none): #GstMpegtsDVBTeletextType
 * @magazine_number: (out) (allow-none):
 * @page_number: (out) (allow-none):
 *
 * Parses teletext number @idx in the @descriptor. The language is in ISO639 format.
 *
 * Returns: FALSE on out-of-bounds and errors
 */
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)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL, FALSE);
  __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_TELETEXT, FALSE);

  if (descriptor->length / 5 <= idx)
    return FALSE;

  data = (guint8 *) descriptor->data + 2 + idx * 5;

  if (language_code)
    *language_code = convert_lang_code (data);

  if (teletext_type)
    *teletext_type = data[3] >> 3;

  if (magazine_number)
    *magazine_number = data[3] & 0x07;

  if (page_number)
    *page_number = data[4];

  return TRUE;
}

/**
 * gst_mpegts_descriptor_parse_dvb_teletext_nb:
 * @descriptor: a %GST_MTS_DESC_DVB_TELETEXT #GstMpegtsDescriptor
 *
 * Find the number of teletext entries in @descriptor
 *
 * Returns: Number of teletext entries
 */
guint
gst_mpegts_descriptor_parse_dvb_teletext_nb (const GstMpegtsDescriptor *
    descriptor)
{
  g_return_val_if_fail (descriptor != NULL, 0);
  __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_TELETEXT, FALSE);

  return descriptor->length / 5;
}

/* GST_MTS_DESC_DVB_SUBTITLING (0x59) */

/**
 * gst_mpegts_descriptor_parse_dvb_subtitling_idx:
 * @descriptor: a %GST_MTS_DESC_DVB_SUBTITLING #GstMpegtsDescriptor
 * @idx: Table id of the entry to parse
 * @lang: (out) (transfer full): the language code
 * @type: (out) (transfer none) (allow-none): the type of subtitling
 * @composition_page_id: (out) (transfer none) (allow-none): the composition page id
 * @ancillary_page_id: (out) (transfer none) (allow-none): the ancillary page id
 *
 * Extracts the DVB subtitling informatio from specific table id in @descriptor.
 *
 * Note: Use #gst_tag_get_language_code if you want to get the the
 * ISO 639-1 language code from the returned ISO 639-2 one.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
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)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL && lang != NULL, FALSE);
  __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_SUBTITLING, FALSE);

  /* If we went too far, return FALSE */
  if (descriptor->length / 8 <= idx)
    return FALSE;

  data = (guint8 *) descriptor->data + 2 + idx * 8;

  *lang = convert_lang_code (data);

  data += 3;

  if (type)
    *type = *data;
  data += 1;
  if (composition_page_id)
    *composition_page_id = GST_READ_UINT16_BE (data);
  data += 2;
  if (ancillary_page_id)
    *ancillary_page_id = GST_READ_UINT16_BE (data);

  return TRUE;
}

/**
 * gst_mpegts_descriptor_parse_dvb_subtitling_nb:
 * @descriptor: a %GST_MTS_DESC_DVB_SUBTITLING #GstMpegtsDescriptor
 *
 * Returns: The number of entries in @descriptor
 */
guint
gst_mpegts_descriptor_parse_dvb_subtitling_nb (const GstMpegtsDescriptor *
    descriptor)
{
  g_return_val_if_fail (descriptor != NULL, FALSE);
  __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_SUBTITLING, FALSE);

  return descriptor->length / 8;
}

/**
 * gst_mpegts_descriptor_from_dvb_subtitling:
 * @lang: (transfer none): a string containing the ISO639 language
 * @type: subtitling type
 * @composition: composition page id
 * @ancillary: ancillary page id
 */
GstMpegtsDescriptor *
gst_mpegts_descriptor_from_dvb_subtitling (const gchar * lang,
    guint8 type, guint16 composition, guint16 ancillary)
{
  GstMpegtsDescriptor *descriptor;
  guint8 *data;

  g_return_val_if_fail (lang != NULL, NULL);

  descriptor = _new_descriptor (GST_MTS_DESC_DVB_SUBTITLING, 8);

  data = descriptor->data + 2;

  memcpy (data, lang, 3);
  data += 3;

  *data++ = type;

  GST_WRITE_UINT16_BE (data, composition);
  data += 2;

  GST_WRITE_UINT16_BE (data, ancillary);

  return descriptor;
}

/* GST_MTS_DESC_DVB_EXTENDED_EVENT (0x4E) */
static GstMpegtsExtendedEventDescriptor *
_gst_mpegts_extended_event_descriptor_copy (GstMpegtsExtendedEventDescriptor *
    source)
{
  GstMpegtsExtendedEventDescriptor *copy;

  copy = g_slice_dup (GstMpegtsExtendedEventDescriptor, source);
  copy->items = g_ptr_array_ref (source->items);
  copy->text = g_strdup (source->text);

  return copy;
}

void
gst_mpegts_extended_event_descriptor_free (GstMpegtsExtendedEventDescriptor *
    source)
{
  g_free (source->text);
  g_free (source->language_code);
  g_ptr_array_unref (source->items);
  g_slice_free (GstMpegtsExtendedEventDescriptor, source);
}

G_DEFINE_BOXED_TYPE (GstMpegtsExtendedEventDescriptor,
    gst_mpegts_extended_event_descriptor,
    (GBoxedCopyFunc) _gst_mpegts_extended_event_descriptor_copy,
    (GFreeFunc) gst_mpegts_extended_event_descriptor_free);

static void
_gst_mpegts_extended_event_item_free (GstMpegtsExtendedEventItem * item)
{
  g_free (item->item);
  g_free (item->item_description);
  g_slice_free (GstMpegtsExtendedEventItem, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_extended_event:
 * @descriptor: a %GST_MTS_DESC_DVB_EXTENDED_EVENT #GstMpegtsDescriptor
 * @res: (out) (transfer full): the #GstMpegtsExtendedEventDescriptor to fill
 *
 * Extracts the DVB extended event information from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_extended_event (const GstMpegtsDescriptor
    * descriptor, GstMpegtsExtendedEventDescriptor ** desc)
{
  guint8 *data, *pdata;
  guint8 tmp, len_item;
  GstMpegtsExtendedEventItem *item;
  GstMpegtsExtendedEventDescriptor *res;

  g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
  /* Need at least 6 bytes (1 for desc number, 3 for language code, 2 for the loop length) */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_EXTENDED_EVENT, 6, FALSE);

  res = g_slice_new0 (GstMpegtsExtendedEventDescriptor);

  data = (guint8 *) descriptor->data + 2;

  tmp = *data;
  res->descriptor_number = tmp >> 4;
  res->last_descriptor_number = tmp & 0x0f;

  data += 1;

  res->language_code = convert_lang_code (data);
  data += 3;

  len_item = *data;
  if (len_item > descriptor->length - 5) {
    gst_mpegts_extended_event_descriptor_free (res);
    return FALSE;
  }

  data += 1;

  res->items = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_extended_event_item_free);

  pdata = data + len_item;
  while (data < pdata) {
    item = g_slice_new0 (GstMpegtsExtendedEventItem);
    item->item_description =
        get_encoding_and_convert ((const gchar *) data + 1, *data);

    data += *data + 1;

    item->item = get_encoding_and_convert ((const gchar *) data + 1, *data);

    data += *data + 1;

    g_ptr_array_add (res->items, item);
  }
  if (pdata != data) {
    gst_mpegts_extended_event_descriptor_free (res);
    return FALSE;
  }
  res->text = get_encoding_and_convert ((const gchar *) data + 1, *data);

  *desc = res;

  return TRUE;
}

/* GST_MTS_DESC_DVB_COMPONENT (0x50) */
static GstMpegtsComponentDescriptor *
_gst_mpegts_dvb_component_descriptor_copy (GstMpegtsComponentDescriptor *
    source)
{
  GstMpegtsComponentDescriptor *copy;

  copy = g_slice_dup (GstMpegtsComponentDescriptor, source);
  copy->language_code = g_strdup (source->language_code);
  copy->text = g_strdup (source->text);

  return copy;
}

void
gst_mpegts_dvb_component_descriptor_free (GstMpegtsComponentDescriptor * source)
{
  g_free (source->language_code);
  g_free (source->text);
  g_slice_free (GstMpegtsComponentDescriptor, source);
}

G_DEFINE_BOXED_TYPE (GstMpegtsComponentDescriptor,
    gst_mpegts_component_descriptor,
    (GBoxedCopyFunc) _gst_mpegts_dvb_component_descriptor_copy,
    (GFreeFunc) gst_mpegts_dvb_component_descriptor_free);

/**
 * gst_mpegts_descriptor_parse_dvb_component:
 * @descriptor: a %GST_MTS_DESC_DVB_COMPONENT #GstMpegtsDescriptor
 * @res: (out) (transfer full): the #GstMpegtsComponentDescriptor to fill
 *
 * Extracts the DVB component information from @descriptor.
 *
 * Returns: %TRUE if parsing succeeded, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_component (const GstMpegtsDescriptor
    * descriptor, GstMpegtsComponentDescriptor ** res)
{
  guint8 *data;
  guint8 len;
  GstMpegtsComponentDescriptor *desc;

  g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
  /* Need 6 bytes at least (1 for content, 1 for type, 1 for tag, 3 for language code) */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_COMPONENT, 6, FALSE);

  data = (guint8 *) descriptor->data + 2;

  desc = g_slice_new0 (GstMpegtsComponentDescriptor);

  desc->stream_content = *data & 0x0f;
  data += 1;

  desc->component_type = *data;
  data += 1;

  desc->component_tag = *data;
  data += 1;

  desc->language_code = convert_lang_code (data);
  data += 3;

  len = descriptor->length - 6;
  if (len)
    desc->text = get_encoding_and_convert ((const gchar *) data, len);

  *res = desc;

  return TRUE;
}

/* GST_MTS_DESC_DVB_STREAM_IDENTIFIER (0x52) */
/**
 * gst_mpegts_descriptor_parse_dvb_stream_identifier:
 * @descriptor: a %GST_MTS_DESC_DVB_CONTENT #GstMpegtsDescriptor
 * @component_tag: (out) (transfer none): the component tag
 *
 * Extracts the component tag from @descriptor.
 *
 * Returns: %TRUE if the parsing happended correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_stream_identifier (const GstMpegtsDescriptor
    * descriptor, guint8 * component_tag)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL && component_tag != NULL, FALSE);
  __common_desc_checks_exact (descriptor, GST_MTS_DESC_DVB_STREAM_IDENTIFIER,
      1, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *component_tag = *data;

  return TRUE;
}

/* GST_MTS_DESC_DVB_CA_IDENTIFIER (0x53) */
/**
 * gst_mpegts_descriptor_parse_dvb_ca_identifier:
 * @descriptor: a %GST_MTS_DESC_DVB_CA_IDENTIFIER #GstMpegtsDescriptor
 * @list: (out) (transfer full) (element-type guint16): a list of ca identifier.
 * Edge entry identifies the CA system. Allocations of the value of this field
 * are found in http://www.dvbservices.com
 *
 * Extracts ca id's from @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_ca_identifier (const GstMpegtsDescriptor *
    descriptor, GArray ** list)
{
  guint8 *data;
  guint16 tmp;
  guint i;

  g_return_val_if_fail (descriptor != NULL && list != NULL, FALSE);
  /* 2 bytes = one entry */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_CA_IDENTIFIER, 2, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *list = g_array_new (FALSE, FALSE, sizeof (guint16));

  for (i = 0; i < descriptor->length - 1; i += 2) {
    tmp = GST_READ_UINT16_BE (data);
    g_array_append_val (*list, tmp);
    data += 2;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_CONTENT (0x54) */
static void
_gst_mpegts_content_free (GstMpegtsContent * content)
{
  g_slice_free (GstMpegtsContent, content);
}

/**
 * gst_mpegts_descriptor_parse_dvb_content:
 * @descriptor: a %GST_MTS_DESC_DVB_CONTENT #GstMpegtsDescriptor
 * @content: (out) (transfer full) (element-type GstMpegtsContent): #GstMpegtsContent
 *
 * Extracts the DVB content information from @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_content (const GstMpegtsDescriptor
    * descriptor, GPtrArray ** content)
{
  guint8 *data;
  guint8 len, tmp;
  guint8 i;

  g_return_val_if_fail (descriptor != NULL && content != NULL, FALSE);
  __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_CONTENT, FALSE);

  data = (guint8 *) descriptor->data + 2;
  len = descriptor->length;

  *content = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_content_free);
  for (i = 0; i < len;) {
    GstMpegtsContent *cont = g_slice_new0 (GstMpegtsContent);
    tmp = *data;
    cont->content_nibble_1 = (tmp & 0xf0) >> 4;
    cont->content_nibble_2 = tmp & 0x0f;
    data += 1;
    cont->user_byte = *data;
    data += 1;
    i += 2;
    g_ptr_array_add (*content, cont);
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_PARENTAL_RATING (0x55) */
static void
_gst_mpegts_dvb_parental_rating_item_free (GstMpegtsDVBParentalRatingItem *
    item)
{
  g_free (item->country_code);
  g_slice_free (GstMpegtsDVBParentalRatingItem, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_parental_rating:
 * @descriptor: a %GST_MTS_DESC_DVB_PARENTAL_RATING #GstMpegtsDescriptor
 * @rating: (out) (transfer full) (element-type GstMpegtsDVBParentalRatingItem):
 * #GstMpegtsDVBParentalRatingItem
 *
 * Extracts the DVB parental rating information from @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_parental_rating (const GstMpegtsDescriptor
    * descriptor, GPtrArray ** rating)
{
  guint8 *data;
  guint i;

  g_return_val_if_fail (descriptor != NULL && rating != NULL, FALSE);
  __common_desc_check_base (descriptor, GST_MTS_DESC_DVB_PARENTAL_RATING,
      FALSE);

  data = (guint8 *) descriptor->data + 2;

  *rating = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_dvb_parental_rating_item_free);

  for (i = 0; i < descriptor->length - 3; i += 4) {
    GstMpegtsDVBParentalRatingItem *item =
        g_slice_new0 (GstMpegtsDVBParentalRatingItem);
    g_ptr_array_add (*rating, item);

    item->country_code = convert_lang_code (data);
    data += 3;

    if (g_strcmp0 (item->country_code, "BRA") == 0) {
      /* brasil */
      switch (*data & 0xf) {
        case 1:
          item->rating = 6;
          break;
        case 2:
          item->rating = 10;
          break;
        case 3:
          item->rating = 12;
          break;
        case 4:
          item->rating = 14;
          break;
        case 5:
          item->rating = 16;
          break;
        case 6:
          item->rating = 18;
          break;
        default:
          item->rating = 0;
          break;
      }
    } else {
      item->rating = (*data & 0xf) + 3;
    }

    data += 1;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM (0x5A) */
/**
 * gst_mpegts_descriptor_parse_terrestrial_delivery_system:
 * @descriptor: a %GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM #GstMpegtsDescriptor
 * @res: (out) (transfer none): #GstMpegtsTerrestrialDeliverySystemDescriptor
 *
 * Parses out the terrestrial delivery system from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_terrestrial_delivery_system (const
    GstMpegtsDescriptor * descriptor,
    GstMpegtsTerrestrialDeliverySystemDescriptor * res)
{
  guint8 *data;
  guint8 tmp;

  g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
  /* Descriptor is always 11 bytes long */
  __common_desc_checks_exact (descriptor,
      GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM, 11, FALSE);

  data = (guint8 *) descriptor->data + 2;

  res->frequency = 0;
  res->frequency = GST_READ_UINT32_BE (data);
  res->frequency *= 10;

  data += 4;

  tmp = *data;
  switch ((tmp >> 5) & 0x07) {
    case 0:
      res->bandwidth = 8000000;
      break;
    case 1:
      res->bandwidth = 7000000;
      break;
    case 2:
      res->bandwidth = 6000000;
      break;
    case 3:
      res->bandwidth = 5000000;
      break;
    default:
      res->bandwidth = 0;
      break;
  }

  res->priority = (tmp >> 4) & 0x01;
  res->time_slicing = (tmp >> 3) & 0x01;
  res->mpe_fec = (tmp >> 2) & 0x01;
  data += 1;

  tmp = *data;
  switch ((tmp >> 6) & 0x03) {
    case 0:
      res->constellation = GST_MPEGTS_MODULATION_QPSK;
      break;
    case 1:
      res->constellation = GST_MPEGTS_MODULATION_QAM_16;
      break;
    case 2:
      res->constellation = GST_MPEGTS_MODULATION_QAM_64;
      break;
    default:
      break;
  }

  switch ((tmp >> 3) & 0x07) {
    case 0:
      res->hierarchy = GST_MPEGTS_HIERARCHY_NONE;
      break;
    case 1:
      res->hierarchy = GST_MPEGTS_HIERARCHY_1;
      break;
    case 2:
      res->hierarchy = GST_MPEGTS_HIERARCHY_2;
      break;
    case 3:
      res->hierarchy = GST_MPEGTS_HIERARCHY_4;
      break;
    case 4:
      res->hierarchy = GST_MPEGTS_HIERARCHY_NONE;
      break;
    case 5:
      res->hierarchy = GST_MPEGTS_HIERARCHY_1;
      break;
    case 6:
      res->hierarchy = GST_MPEGTS_HIERARCHY_2;
      break;
    case 7:
      res->hierarchy = GST_MPEGTS_HIERARCHY_4;
      break;
    default:
      break;
  }

  switch (tmp & 0x07) {
    case 0:
      res->code_rate_hp = GST_MPEGTS_FEC_1_2;
      break;
    case 1:
      res->code_rate_hp = GST_MPEGTS_FEC_2_3;
      break;
    case 2:
      res->code_rate_hp = GST_MPEGTS_FEC_3_4;
      break;
    case 3:
      res->code_rate_hp = GST_MPEGTS_FEC_5_6;
      break;
    case 4:
      res->code_rate_hp = GST_MPEGTS_FEC_7_8;
      break;
    default:
      break;
  }
  data += 1;

  tmp = *data;
  switch ((tmp >> 5) & 0x07) {
    case 0:
      res->code_rate_lp = GST_MPEGTS_FEC_1_2;
      break;
    case 1:
      res->code_rate_lp = GST_MPEGTS_FEC_2_3;
      break;
    case 2:
      res->code_rate_lp = GST_MPEGTS_FEC_3_4;
      break;
    case 3:
      res->code_rate_lp = GST_MPEGTS_FEC_5_6;
      break;
    case 4:
      res->code_rate_lp = GST_MPEGTS_FEC_7_8;
      break;
    default:
      break;
  }

  switch ((tmp >> 3) & 0x03) {
    case 0:
      res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_32;
      break;
    case 1:
      res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_16;
      break;
    case 2:
      res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_8;
      break;
    case 3:
      res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_4;
      break;
    default:
      break;
  }

  switch ((tmp >> 1) & 0x03) {
    case 0:
      res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_2K;
      break;
    case 1:
      res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_8K;
      break;
    case 2:
      res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_4K;
      break;
    default:
      break;
  }
  res->other_frequency = tmp & 0x01;

  return TRUE;
}

/* GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME (0x5B) */
static void
    _gst_mpegts_dvb_multilingual_network_name_item_free
    (GstMpegtsDvbMultilingualNetworkNameItem * item)
{
  g_free (item->network_name);
  g_free (item->language_code);
  g_slice_free (GstMpegtsDvbMultilingualNetworkNameItem, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_multilingual_network_name:
 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME
 * #GstMpegtsDescriptor
 * @network_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualNetworkNameItem):
 * a #GstMpegtsDvbMultilingualNetworkNameItem
 *
 * Parses out the multilingual network name from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_network_name (const
    GstMpegtsDescriptor * descriptor, GPtrArray ** network_name_items)
{
  guint8 *data, i, len;
  GstMpegtsDvbMultilingualNetworkNameItem *item;

  g_return_val_if_fail (descriptor != NULL && network_name_items != NULL,
      FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME,
      5, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *network_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_dvb_multilingual_network_name_item_free);

  for (i = 0; i < descriptor->length - 3;) {
    item = g_slice_new0 (GstMpegtsDvbMultilingualNetworkNameItem);
    g_ptr_array_add (*network_name_items, item);
    item->language_code = convert_lang_code (data);
    data += 3;
    i += 3;

    len = *data;
    item->network_name =
        get_encoding_and_convert ((const gchar *) data + 1, len);
    data += len + 1;
    i += len + 1;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME (0x5C) */
static void
    _gst_mpegts_dvb_multilingual_bouquet_name_item_free
    (GstMpegtsDvbMultilingualBouquetNameItem * item)
{
  g_free (item->language_code);
  g_free (item->bouquet_name);
  g_slice_free (GstMpegtsDvbMultilingualBouquetNameItem, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name:
 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME
 * #GstMpegtsDescriptor
 * @bouquet_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualBouquetNameItem):
 * a #GstMpegtsDvbMultilingualBouquetNameItem
 *
 * Parses out the multilingual bouquet name from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_bouquet_name (const
    GstMpegtsDescriptor * descriptor, GPtrArray ** bouquet_name_items)
{
  guint8 *data, i, len;
  GstMpegtsDvbMultilingualBouquetNameItem *item;

  g_return_val_if_fail (descriptor != NULL && bouquet_name_items != NULL,
      FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME,
      5, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *bouquet_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_dvb_multilingual_bouquet_name_item_free);

  for (i = 0; i < descriptor->length - 3;) {
    item = g_slice_new0 (GstMpegtsDvbMultilingualBouquetNameItem);
    g_ptr_array_add (*bouquet_name_items, item);
    item->language_code = convert_lang_code (data);
    data += 3;
    i += 3;

    len = *data;
    item->bouquet_name =
        get_encoding_and_convert ((const gchar *) data + 1, len);
    data += len + 1;
    i += len + 1;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME (0x5D) */
static void
    _gst_mpegts_dvb_multilingual_service_name_item_free
    (GstMpegtsDvbMultilingualServiceNameItem * item)
{
  g_free (item->provider_name);
  g_free (item->service_name);
  g_free (item->language_code);
  g_slice_free (GstMpegtsDvbMultilingualServiceNameItem, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_multilingual_service_name:
 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME
 * #GstMpegtsDescriptor
 * @service_name_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualServiceNameItem):
 * a #GstMpegtsDvbMultilingualServiceNameItem
 *
 * Parses out the multilingual service name from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_service_name (const
    GstMpegtsDescriptor * descriptor, GPtrArray ** service_name_items)
{
  guint8 *data, i, len;
  GstMpegtsDvbMultilingualServiceNameItem *item;

  g_return_val_if_fail (descriptor != NULL && service_name_items != NULL,
      FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME,
      7, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *service_name_items = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_dvb_multilingual_service_name_item_free);

  for (i = 0; i < descriptor->length - 3;) {
    item = g_slice_new0 (GstMpegtsDvbMultilingualServiceNameItem);
    g_ptr_array_add (*service_name_items, item);
    item->language_code = convert_lang_code (data);
    data += 3;
    i += 3;

    len = *data;
    item->provider_name =
        get_encoding_and_convert ((const gchar *) data + 1, len);
    data += len + 1;
    i += len + 1;

    len = *data;
    item->service_name =
        get_encoding_and_convert ((const gchar *) data + 1, len);
    data += len + 1;
    i += len + 1;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT (0x5E) */
static void
    _gst_mpegts_dvb_multilingual_component_item_free
    (GstMpegtsDvbMultilingualComponentItem * item)
{
  g_free (item->language_code);
  g_free (item->description);
  g_slice_free (GstMpegtsDvbMultilingualComponentItem, item);
}

/**
 * gst_mpegts_descriptor_parse_dvb_multilingual_component:
 * @descriptor: a %GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT
 * #GstMpegtsDescriptor
 * @component_tag: the component tag
 * @component_description_items: (out) (transfer full) (element-type GstMpegtsDvbMultilingualComponentItem):
 * a #GstMpegtsDvbMultilingualComponentItem
 *
 * Parses out the multilingual component from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_multilingual_component (const
    GstMpegtsDescriptor * descriptor, guint8 * component_tag,
    GPtrArray ** component_description_items)
{
  guint8 *data, i, len;
  GstMpegtsDvbMultilingualComponentItem *item;

  g_return_val_if_fail (descriptor != NULL
      && component_description_items != NULL && component_tag != NULL, FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT, 6,
      FALSE);

  data = (guint8 *) descriptor->data + 2;

  *component_tag = *data;
  data += 1;

  *component_description_items =
      g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_dvb_multilingual_component_item_free);

  for (i = 0; i < descriptor->length - 3;) {
    item = g_slice_new0 (GstMpegtsDvbMultilingualComponentItem);
    g_ptr_array_add (*component_description_items, item);
    item->language_code = convert_lang_code (data);
    data += 3;
    i += 3;

    len = *data;
    item->description =
        get_encoding_and_convert ((const gchar *) data + 1, len);
    data += len + 1;
    i += len + 1;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER (0x5F) */
/**
 * gst_mpegts_descriptor_parse_dvb_private_data_specifier:
 * @descriptor: a %GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER #GstMpegtsDescriptor
 * @private_data_specifier: (out): the private data specifier id
 * registered by http://www.dvbservices.com/
 * @private_data: (out) (transfer full)(allow-none): additional data or NULL
 * @length: (out) (allow-none): length of %private_data
 *
 * Parses out the private data specifier from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_private_data_specifier (const
    GstMpegtsDescriptor * descriptor, guint32 * private_data_specifier,
    guint8 ** private_data, guint8 * length)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL
      && private_data_specifier != NULL, FALSE);
  __common_desc_checks (descriptor,
      GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER, 4, FALSE);

  data = (guint8 *) descriptor->data + 2;

  *private_data_specifier = GST_READ_UINT32_BE (data);

  if (length && private_data) {
    *length = descriptor->length - 4;

    *private_data = g_memdup (data + 4, *length);
  }
  return TRUE;
}

/* GST_MTS_DESC_DVB_FREQUENCY_LIST (0x62) */
/**
 * gst_mpegts_descriptor_parse_dvb_frequency_list:
 * @descriptor: a %GST_MTS_DESC_DVB_FREQUENCY_LIST #GstMpegtsDescriptor
 * @offset: (out): %FALSE in Hz, %TRUE in kHz
 * @list: (out) (transfer full) (element-type guint32): a list of all frequencies in Hz/kHz
 * depending on %offset
 *
 * Parses out a list of frequencies from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_frequency_list (const GstMpegtsDescriptor
    * descriptor, gboolean * offset, GArray ** list)
{
  guint8 *data, type, len;
  guint32 freq;
  guint i;

  g_return_val_if_fail (descriptor != NULL && offset != NULL &&
      list != NULL, FALSE);
  /* 1 byte coding system, 4 bytes each frequency entry */
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_FREQUENCY_LIST, 5, FALSE);

  data = (guint8 *) descriptor->data + 2;

  type = *data & 0x03;
  data += 1;

  if (type == 1) {
    /* satellite */
    *offset = TRUE;
  } else {
    /* cable, terrestrial */
    *offset = FALSE;
  }

  *list = g_array_new (FALSE, FALSE, sizeof (guint32));

  len = descriptor->length - 1;

  for (i = 0; i < len - 3; i += 4) {
    switch (type) {
      case 1:
        freq = BCD_32 (data) * 10;
        break;
      case 2:
        freq = BCD_32 (data) * 100;
        break;
      case 3:
        freq = GST_READ_UINT32_BE (data) * 10;
        break;
      default:
        break;
    }

    g_array_append_val (*list, freq);
    data += 4;
  }

  return TRUE;
}

/* GST_MTS_DESC_DVB_DATA_BROADCAST (0x64) */
static GstMpegtsDataBroadcastDescriptor *
_gst_mpegts_dvb_data_broadcast_descriptor_copy (GstMpegtsDataBroadcastDescriptor
    * source)
{
  GstMpegtsDataBroadcastDescriptor *copy;

  copy = g_slice_dup (GstMpegtsDataBroadcastDescriptor, source);

  copy->selector_bytes = g_memdup (source->selector_bytes, source->length);
  copy->language_code = g_strdup (source->language_code);
  copy->text = g_strdup (source->text);

  return copy;
}

void
gst_mpegts_dvb_data_broadcast_descriptor_free (GstMpegtsDataBroadcastDescriptor
    * source)
{
  g_free (source->selector_bytes);
  g_free (source->language_code);
  g_free (source->text);
  g_slice_free (GstMpegtsDataBroadcastDescriptor, source);
}

G_DEFINE_BOXED_TYPE (GstMpegtsDataBroadcastDescriptor,
    gst_mpegts_dvb_data_broadcast_descriptor,
    (GBoxedCopyFunc) _gst_mpegts_dvb_data_broadcast_descriptor_copy,
    (GFreeFunc) gst_mpegts_dvb_data_broadcast_descriptor_free);

/**
 * gst_mpegts_descriptor_parse_dvb_data_broadcast:
 * @descriptor: a %GST_MTS_DESC_DVB_DATA_BROADCAST #GstMpegtsDescriptor
 * @res: (out) (transfer full): #GstMpegtsDataBroadcastDescriptor
 *
 * Parses out the data broadcast from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_data_broadcast (const GstMpegtsDescriptor
    * descriptor, GstMpegtsDataBroadcastDescriptor ** desc)
{
  guint8 *data;
  GstMpegtsDataBroadcastDescriptor *res;

  g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_DATA_BROADCAST, 8, FALSE);

  data = (guint8 *) descriptor->data + 2;

  res = g_slice_new0 (GstMpegtsDataBroadcastDescriptor);

  res->data_broadcast_id = GST_READ_UINT16_BE (data);
  data += 2;

  res->component_tag = *data;
  data += 1;

  res->length = *data;
  data += 1;

  res->selector_bytes = g_memdup (data, res->length);
  data += res->length;

  res->language_code = convert_lang_code (data);
  data += 3;

  res->text = get_encoding_and_convert ((const gchar *) data + 1, *data);

  *desc = res;

  return TRUE;
}

/* GST_MTS_DESC_DVB_SCRAMBLING (0x65) */
/**
 * gst_mpegts_descriptor_parse_dvb_scrambling:
 * @descriptor: a %GST_MTS_DESC_DVB_SCRAMBLING #GstMpegtsDescriptor
 * @scrambling_mode: (out): This 8-bit field identifies the selected
 * mode of the scrambling algorithm (#GstMpegtsDVBScramblingModeType).
 * The technical details of the scrambling algorithm are available only
 * to bona-fide users upon signature of a Non Disclosure Agreement (NDA)
 * administered by the DVB Common Scrambling Algorithm Custodian.
 *
 * Parses out the scrambling mode from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_scrambling (const GstMpegtsDescriptor *
    descriptor, GstMpegtsDVBScramblingModeType * scrambling_mode)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL && scrambling_mode != NULL, FALSE);
  __common_desc_checks_exact (descriptor, GST_MTS_DESC_DVB_SCRAMBLING, 1,
      FALSE);

  data = (guint8 *) descriptor->data + 2;

  *scrambling_mode = *data;

  return TRUE;
}

/* GST_MTS_DESC_DVB_DATA_BROADCAST_ID (0x66) */
/**
 * gst_mpegts_descriptor_parse_dvb_data_broadcast_id:
 * @descriptor: a %GST_MTS_DESC_DVB_DATA_BROADCAST_ID #GstMpegtsDescriptor
 * @data_broadcast_id: (out): the data broadcast id
 * @id_selector_bytes: (out) (transfer full): the selector bytes, if present
 * @len: (out): the length of #id_selector_bytes
 *
 * Parses out the data broadcast id from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_data_broadcast_id (const GstMpegtsDescriptor
    * descriptor, guint16 * data_broadcast_id, guint8 ** id_selector_bytes,
    guint8 * len)
{
  guint8 *data;

  g_return_val_if_fail (descriptor != NULL && data_broadcast_id != NULL &&
      id_selector_bytes != NULL, FALSE);
  __common_desc_checks (descriptor, GST_MTS_DESC_DVB_DATA_BROADCAST_ID, 2,
      FALSE);

  data = (guint8 *) descriptor->data + 2;

  *data_broadcast_id = GST_READ_UINT16_BE (data);
  data += 2;

  *len = descriptor->length - 2;

  *id_selector_bytes = g_memdup (data, *len);

  return TRUE;
}

/* GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM (0x7F && 0x04) */
static GstMpegtsT2DeliverySystemDescriptor
    * _gst_mpegts_t2_delivery_system_descriptor_copy
    (GstMpegtsT2DeliverySystemDescriptor * source)
{
  GstMpegtsT2DeliverySystemDescriptor *copy;

  copy = g_slice_dup (GstMpegtsT2DeliverySystemDescriptor, source);
  copy->cells = g_ptr_array_ref (source->cells);

  return copy;
}

void gst_mpegts_t2_delivery_system_descriptor_free
    (GstMpegtsT2DeliverySystemDescriptor * source)
{
  g_ptr_array_unref (source->cells);
  g_slice_free (GstMpegtsT2DeliverySystemDescriptor, source);
}

G_DEFINE_BOXED_TYPE (GstMpegtsT2DeliverySystemDescriptor,
    gst_mpegts_t2_delivery_system_descriptor,
    (GBoxedCopyFunc) _gst_mpegts_t2_delivery_system_descriptor_copy,
    (GFreeFunc) gst_mpegts_t2_delivery_system_descriptor_free);

static void
    _gst_mpegts_t2_delivery_system_cell_extension_free
    (GstMpegtsT2DeliverySystemCellExtension * ext)
{
  g_slice_free (GstMpegtsT2DeliverySystemCellExtension, ext);
}

static void
_gst_mpegts_t2_delivery_system_cell_free (GstMpegtsT2DeliverySystemCell * cell)
{
  g_ptr_array_unref (cell->sub_cells);
  g_array_unref (cell->centre_frequencies);
  g_slice_free (GstMpegtsT2DeliverySystemCell, cell);
}

/**
 * gst_mpegts_descriptor_parse_dvb_t2_delivery_system:
 * @descriptor: a %GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM #GstMpegtsDescriptor
 * @res: (out) (transfer full): #GstMpegtsT2DeliverySystemDescriptor
 *
 * Parses out the DVB-T2 delivery system from the @descriptor.
 *
 * Returns: %TRUE if the parsing happened correctly, else %FALSE.
 */
gboolean
gst_mpegts_descriptor_parse_dvb_t2_delivery_system (const GstMpegtsDescriptor
    * descriptor, GstMpegtsT2DeliverySystemDescriptor ** desc)
{
  guint8 *data;
  guint8 len, freq_len, sub_cell_len;
  guint32 tmp_freq;
  guint8 i;
  GstMpegtsT2DeliverySystemDescriptor *res;

  g_return_val_if_fail (descriptor != NULL && desc != NULL, FALSE);
  __common_desc_ext_checks (descriptor, GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM,
      4, FALSE);

  data = (guint8 *) descriptor->data + 3;

  res = g_slice_new0 (GstMpegtsT2DeliverySystemDescriptor);

  res->plp_id = *data;
  data += 1;

  res->t2_system_id = GST_READ_UINT16_BE (data);
  data += 2;

  if (descriptor->length > 4) {
    // FIXME: siso / miso
    res->siso_miso = (*data >> 6) & 0x03;
    switch ((*data >> 2) & 0x0f) {
      case 0:
        res->bandwidth = 8000000;
        break;
      case 1:
        res->bandwidth = 7000000;
        break;
      case 2:
        res->bandwidth = 6000000;
        break;
      case 3:
        res->bandwidth = 5000000;
        break;
      case 4:
        res->bandwidth = 10000000;
        break;
      case 5:
        res->bandwidth = 1712000;
        break;
      default:
        res->bandwidth = 0;
        break;
    }
    data += 1;

    switch ((*data >> 5) & 0x07) {
      case 0:
        res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_32;
        break;
      case 1:
        res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_16;
        break;
      case 2:
        res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_8;
        break;
      case 3:
        res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_4;
        break;
      case 4:
        res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_128;
        break;
      case 5:
        res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_128;
        break;
      case 6:
        res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_256;
        break;
      default:
        break;
    }

    switch ((*data >> 2) & 0x07) {
      case 0:
        res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_2K;
        break;
      case 1:
        res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_8K;
        break;
      case 2:
        res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_4K;
        break;
      case 3:
        res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_1K;
        break;
      case 4:
        res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_16K;
        break;
      case 5:
        res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_32K;
        break;
      default:
        break;
    }
    res->other_frequency = (*data >> 1) & 0x01;
    res->tfs = (*data) & 0x01;
    data += 1;

    len = descriptor->length - 6;

    res->cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
        _gst_mpegts_t2_delivery_system_cell_free);

    for (i = 0; i < len;) {
      GstMpegtsT2DeliverySystemCell *cell;
      guint8 j, k;

      cell = g_slice_new0 (GstMpegtsT2DeliverySystemCell);
      g_ptr_array_add (res->cells, cell);

      cell->cell_id = GST_READ_UINT16_BE (data);
      data += 2;
      i += 2;

      cell->centre_frequencies = g_array_new (FALSE, FALSE, sizeof (guint32));

      if (res->tfs == TRUE) {
        freq_len = *data;
        data += 1;
        i += 1;

        for (j = 0; j < freq_len;) {
          tmp_freq = GST_READ_UINT32_BE (data) * 10;
          g_array_append_val (cell->centre_frequencies, tmp_freq);
          data += 4;
          j += 4;
          i += 4;
        }
      } else {
        tmp_freq = GST_READ_UINT32_BE (data) * 10;
        g_array_append_val (cell->centre_frequencies, tmp_freq);
        data += 4;
        i += 4;
      }
      sub_cell_len = (*data);
      data += 1;
      i += 1;

      cell->sub_cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
          _gst_mpegts_t2_delivery_system_cell_extension_free);

      for (k = 0; k < sub_cell_len;) {
        GstMpegtsT2DeliverySystemCellExtension *cell_ext;
        cell_ext = g_slice_new0 (GstMpegtsT2DeliverySystemCellExtension);

        g_ptr_array_add (cell->sub_cells, cell_ext);
        cell_ext->cell_id_extension = *data;
        data += 1;

        cell_ext->transposer_frequency = GST_READ_UINT32_BE (data) * 10;
        data += 4;
        i += 5;
        k += 5;
      }
    }
  }

  *desc = res;
  return TRUE;
}
