/*
 * gstmpegtssection.c -
 * Copyright (C) 2013 Edward Hervey
 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
 * Copyright (C) 2007 Alessandro Decina
 *               2010 Edward Hervey
 *  Author: Youness Alaoui <youness.alaoui@collabora.co.uk>, Collabora Ltd.
 *  Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
 *  Author: Edward Hervey <bilboed@bilboed.com>, Collabora Ltd.
 *
 * Authors:
 *   Alessandro Decina <alessandro@nnva.org>
 *   Zaheer Abbas Merali <zaheerabbas at merali dot org>
 *   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 <string.h>
#include <stdlib.h>

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

/**
 * SECTION:gstmpegts
 * @title: Mpeg-ts helper library
 * @short_description: Mpeg-ts helper library for plugins and applications
 * @include: gst/mpegts/mpegts.h
 */

/**
 * SECTION:gstmpegtssection
 * @title: Base MPEG-TS sections
 * @short_description: Sections for ITU H.222.0 | ISO/IEC 13818-1 
 * @include: gst/mpegts/mpegts.h
 *
 * For more details, refer to the ITU H.222.0 or ISO/IEC 13818-1 specifications
 * and other specifications mentioned in the documentation.
 */

/*
 * TODO
 *
 * * Check minimum size for section parsing in the various 
 *   gst_mpegts_section_get_<tabld>() methods
 *
 * * Implement parsing code for
 *   * BAT
 *   * CAT
 *   * TSDT
 */

GST_DEBUG_CATEGORY (gst_mpegts_debug);

static GQuark QUARK_PAT;
static GQuark QUARK_CAT;
static GQuark QUARK_BAT;
static GQuark QUARK_PMT;
static GQuark QUARK_NIT;
static GQuark QUARK_SDT;
static GQuark QUARK_EIT;
static GQuark QUARK_TDT;
static GQuark QUARK_TOT;
static GQuark QUARK_SECTION;

static GType _gst_mpegts_section_type = 0;
#define MPEG_TYPE_TS_SECTION (_gst_mpegts_section_type)
GST_DEFINE_MINI_OBJECT_TYPE (GstMpegtsSection, gst_mpegts_section);

static const guint32 crc_tab[256] = {
  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};

/* _calc_crc32 relicensed to LGPL from fluendo ts demuxer */
guint32
_calc_crc32 (const guint8 * data, guint datalen)
{
  gint i;
  guint32 crc = 0xffffffff;

  for (i = 0; i < datalen; i++) {
    crc = (crc << 8) ^ crc_tab[((crc >> 24) ^ *data++) & 0xff];
  }
  return crc;
}

gpointer
__common_section_checks (GstMpegtsSection * section, guint min_size,
    GstMpegtsParseFunc parsefunc, GDestroyNotify destroynotify)
{
  gpointer res;

  /* Check section is big enough */
  if (section->section_length < min_size) {
    GST_WARNING
        ("PID:0x%04x table_id:0x%02x, section too small (Got %d, need at least %d)",
        section->pid, section->table_id, section->section_length, min_size);
    return NULL;
  }

  /* If section has a CRC, check it */
  if (!section->short_section
      && (_calc_crc32 (section->data, section->section_length) != 0)) {
    GST_WARNING ("PID:0x%04x table_id:0x%02x, Bad CRC on section", section->pid,
        section->table_id);
    return NULL;
  }

  /* Finally parse and set the destroy notify */
  res = parsefunc (section);
  if (res == NULL)
    GST_WARNING ("PID:0x%04x table_id:0x%02x, Failed to parse section",
        section->pid, section->table_id);
  else
    section->destroy_parsed = destroynotify;
  return res;
}


/*
 * GENERIC MPEG-TS SECTION
 */
static void
_gst_mpegts_section_free (GstMpegtsSection * section)
{
  GST_DEBUG ("Freeing section type %d", section->section_type);

  if (section->cached_parsed && section->destroy_parsed)
    section->destroy_parsed (section->cached_parsed);

  g_free (section->data);

  g_slice_free (GstMpegtsSection, section);
}

static GstMpegtsSection *
_gst_mpegts_section_copy (GstMpegtsSection * section)
{
  GstMpegtsSection *copy;

  copy = g_slice_new0 (GstMpegtsSection);
  gst_mini_object_init (GST_MINI_OBJECT_CAST (copy), 0, MPEG_TYPE_TS_SECTION,
      (GstMiniObjectCopyFunction) _gst_mpegts_section_copy, NULL,
      (GstMiniObjectFreeFunction) _gst_mpegts_section_free);

  copy->section_type = section->section_type;
  copy->pid = section->pid;
  copy->table_id = section->table_id;
  copy->subtable_extension = section->subtable_extension;
  copy->version_number = section->version_number;
  copy->current_next_indicator = section->current_next_indicator;
  copy->section_number = section->section_number;
  copy->last_section_number = section->last_section_number;
  copy->crc = section->crc;

  copy->data = g_memdup (section->data, section->section_length);
  copy->section_length = section->section_length;
  /* Note: We do not copy the cached parsed item, it will be
   * reconstructed on that copy */
  copy->cached_parsed = NULL;
  copy->offset = section->offset;
  copy->short_section = section->short_section;

  return copy;
}

/**
 * gst_mpegts_section_get_data:
 * @section: a #GstMpegtsSection
 *
 * Gets the original unparsed section data.
 *
 * Returns: (transfer full): The original unparsed section data.
 */
GBytes *
gst_mpegts_section_get_data (GstMpegtsSection * section)
{
  return g_bytes_new (section->data, section->section_length);
}

/**
 * gst_message_parse_mpegts_section:
 * @message: a #GstMessage
 *
 * Returns the #GstMpegtsSection contained in a message.
 *
 * Returns: (transfer full): the contained #GstMpegtsSection, or %NULL.
 */
GstMpegtsSection *
gst_message_parse_mpegts_section (GstMessage * message)
{
  const GstStructure *st;
  GstMpegtsSection *section;

  if (message->type != GST_MESSAGE_ELEMENT)
    return NULL;

  st = gst_message_get_structure (message);
  /* FIXME : Add checks against know section names */
  if (!gst_structure_id_get (st, QUARK_SECTION, GST_TYPE_MPEGTS_SECTION,
          &section, NULL))
    return NULL;

  return section;
}

static GstStructure *
_mpegts_section_get_structure (GstMpegtsSection * section)
{
  GstStructure *st;
  GQuark quark;

  switch (section->section_type) {
    case GST_MPEGTS_SECTION_PAT:
      quark = QUARK_PAT;
      break;
    case GST_MPEGTS_SECTION_PMT:
      quark = QUARK_PMT;
      break;
    case GST_MPEGTS_SECTION_CAT:
      quark = QUARK_CAT;
      break;
    case GST_MPEGTS_SECTION_EIT:
      quark = QUARK_EIT;
      break;
    case GST_MPEGTS_SECTION_BAT:
      quark = QUARK_BAT;
      break;
    case GST_MPEGTS_SECTION_NIT:
      quark = QUARK_NIT;
      break;
    case GST_MPEGTS_SECTION_SDT:
      quark = QUARK_SDT;
      break;
    case GST_MPEGTS_SECTION_TDT:
      quark = QUARK_TDT;
      break;
    case GST_MPEGTS_SECTION_TOT:
      quark = QUARK_TOT;
      break;
    default:
      GST_DEBUG ("Creating structure for unknown GstMpegtsSection");
      quark = QUARK_SECTION;
      break;
  }

  st = gst_structure_new_id (quark, QUARK_SECTION, MPEG_TYPE_TS_SECTION,
      section, NULL);

  return st;
}

/**
 * gst_message_new_mpegts_section:
 * @parent: (transfer none): The creator of the message
 * @section: (transfer none): The #GstMpegtsSection to put in a message
 *
 * Creates a new #GstMessage for a @GstMpegtsSection.
 *
 * Returns: (transfer full): The new #GstMessage to be posted, or %NULL if the
 * section is not valid.
 */
GstMessage *
gst_message_new_mpegts_section (GstObject * parent, GstMpegtsSection * section)
{
  GstMessage *msg;
  GstStructure *st;

  st = _mpegts_section_get_structure (section);

  msg = gst_message_new_element (parent, st);

  return msg;
}

static GstEvent *
_mpegts_section_get_event (GstMpegtsSection * section)
{
  GstStructure *structure;
  GstEvent *event;

  structure = _mpegts_section_get_structure (section);

  event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, structure);

  return event;
}

/**
 * gst_event_parse_mpegts_section:
 * @event: (transfer none): #GstEvent containing a #GstMpegtsSection
 *
 * Extracts the #GstMpegtsSection contained in the @event #GstEvent
 *
 * Returns: (transfer full): The extracted #GstMpegtsSection
 */
GstMpegtsSection *
gst_event_parse_mpegts_section (GstEvent * event)
{
  const GstStructure *structure;
  GstMpegtsSection *section;

  structure = gst_event_get_structure (event);

  if (!gst_structure_id_get (structure, QUARK_SECTION, MPEG_TYPE_TS_SECTION,
          &section, NULL))
    return NULL;

  return section;
}

/**
 * gst_mpegts_section_send_event:
 * @element: (transfer none): The #GstElement to send to section event to
 * @section: (transfer none): The #GstMpegtsSection to put in the event
 *
 * Creates a custom #GstEvent with a @GstMpegtsSection.
 * The #GstEvent is sent to the @element #GstElement.
 *
 * Returns: %TRUE if the event is sent
 */
gboolean
gst_mpegts_section_send_event (GstMpegtsSection * section, GstElement * element)
{
  GstEvent *event;

  g_return_val_if_fail (section != NULL, FALSE);
  g_return_val_if_fail (element != NULL, FALSE);

  event = _mpegts_section_get_event (section);

  if (!gst_element_send_event (element, event)) {
    gst_event_unref (event);
    return FALSE;
  }

  return TRUE;
}

static GstMpegtsPatProgram *
_mpegts_pat_program_copy (GstMpegtsPatProgram * orig)
{
  return g_slice_dup (GstMpegtsPatProgram, orig);
}

static void
_mpegts_pat_program_free (GstMpegtsPatProgram * orig)
{
  g_slice_free (GstMpegtsPatProgram, orig);
}

G_DEFINE_BOXED_TYPE (GstMpegtsPatProgram, gst_mpegts_pat_program,
    (GBoxedCopyFunc) _mpegts_pat_program_copy,
    (GFreeFunc) _mpegts_pat_program_free);

/* Program Association Table */
static gpointer
_parse_pat (GstMpegtsSection * section)
{
  GPtrArray *pat;
  guint16 i, nb_programs;
  GstMpegtsPatProgram *program;
  guint8 *data, *end;

  /* Skip already parsed data */
  data = section->data + 8;

  /* stop at the CRC */
  end = section->data + section->section_length;

  /* Initialize program list */
  nb_programs = (end - 4 - data) / 4;
  pat =
      g_ptr_array_new_full (nb_programs,
      (GDestroyNotify) _mpegts_pat_program_free);

  GST_LOG ("nb_programs %u", nb_programs);

  for (i = 0; i < nb_programs; i++) {
    program = g_slice_new0 (GstMpegtsPatProgram);
    program->program_number = GST_READ_UINT16_BE (data);
    data += 2;

    program->network_or_program_map_PID = GST_READ_UINT16_BE (data) & 0x1FFF;
    data += 2;

    g_ptr_array_index (pat, i) = program;
  }
  pat->len = nb_programs;

  if (data != end - 4) {
    GST_ERROR ("at the end of PAT data != end - 4");
    g_ptr_array_unref (pat);

    return NULL;
  }

  return (gpointer) pat;
}

/**
 * gst_mpegts_section_get_pat:
 * @section: a #GstMpegtsSection of type %GST_MPEGTS_SECTION_PAT
 *
 * Parses a Program Association Table (ITU H.222.0, ISO/IEC 13818-1).
 *
 * Returns the array of #GstMpegtsPatProgram contained in the section.
 *
 * Note: The PAT "transport_id" field corresponds to the "subtable_extension"
 * field of the provided @section.
 *
 * Returns: (transfer container) (element-type GstMpegtsPatProgram): The
 * #GstMpegtsPatProgram contained in the section, or %NULL if an error
 * happened. Release with #g_ptr_array_unref when done.
 */
GPtrArray *
gst_mpegts_section_get_pat (GstMpegtsSection * section)
{
  g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_PAT, NULL);
  g_return_val_if_fail (section->cached_parsed || section->data, NULL);

  if (!section->cached_parsed)
    section->cached_parsed =
        __common_section_checks (section, 12, _parse_pat,
        (GDestroyNotify) g_ptr_array_unref);

  if (section->cached_parsed)
    return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
  return NULL;
}

/**
 * gst_mpegts_pat_new:
 *
 * Allocates a new #GPtrArray for #GstMpegtsPatProgram
 *
 * Returns: (transfer full) (element-type GstMpegtsPatProgram): A newly allocated #GPtrArray
 */
GPtrArray *
gst_mpegts_pat_new (void)
{
  GPtrArray *pat;

  pat = g_ptr_array_new_with_free_func (
      (GDestroyNotify) _mpegts_pat_program_free);

  return pat;
}

/**
 * gst_mpegts_pat_program_new:
 *
 * Allocates a new #GstMpegtsPatProgram.
 *
 * Returns: (transfer full): A newly allocated #GstMpegtsPatProgram
 */
GstMpegtsPatProgram *
gst_mpegts_pat_program_new (void)
{
  GstMpegtsPatProgram *program;

  program = g_slice_new0 (GstMpegtsPatProgram);

  return program;
}

static gboolean
_packetize_pat (GstMpegtsSection * section)
{
  GPtrArray *programs;
  guint8 *data;
  gsize length;
  guint i;

  programs = gst_mpegts_section_get_pat (section);

  if (programs == NULL)
    return FALSE;

  /* 8 byte common section fields
     4 byte CRC */
  length = 12;

  /* 2 byte program number
     2 byte program/network PID */
  length += programs->len * 4;

  _packetize_common_section (section, length);
  data = section->data + 8;

  for (i = 0; i < programs->len; i++) {
    GstMpegtsPatProgram *program;

    program = g_ptr_array_index (programs, i);

    /* program_number       - 16 bit uimsbf */
    GST_WRITE_UINT16_BE (data, program->program_number);
    data += 2;

    /* reserved             - 3  bit
       program/network_PID  - 13 uimsbf */
    GST_WRITE_UINT16_BE (data, program->network_or_program_map_PID | 0xE000);
    data += 2;
  }

  g_ptr_array_unref (programs);

  return TRUE;
}

/**
 * gst_mpegts_section_from_pat:
 * @programs: (transfer full) (element-type GstMpegtsPatProgram): an array of #GstMpegtsPatProgram
 * @ts_id: Transport stream ID of the PAT
 *
 * Creates a PAT #GstMpegtsSection from the @programs array of #GstMpegtsPatPrograms
 *
 * Returns: (transfer full): a #GstMpegtsSection
 */
GstMpegtsSection *
gst_mpegts_section_from_pat (GPtrArray * programs, guint16 ts_id)
{
  GstMpegtsSection *section;

  section = _gst_mpegts_section_init (0x00,
      GST_MTS_TABLE_ID_PROGRAM_ASSOCIATION);

  section->subtable_extension = ts_id;
  section->cached_parsed = (gpointer) programs;
  section->packetizer = _packetize_pat;
  section->destroy_parsed = (GDestroyNotify) g_ptr_array_unref;

  return section;
}

/* Program Map Table */

static GstMpegtsPMTStream *
_gst_mpegts_pmt_stream_copy (GstMpegtsPMTStream * pmt)
{
  GstMpegtsPMTStream *copy;

  copy = g_slice_dup (GstMpegtsPMTStream, pmt);
  copy->descriptors = g_ptr_array_ref (pmt->descriptors);

  return copy;
}

static void
_gst_mpegts_pmt_stream_free (GstMpegtsPMTStream * pmt)
{
  if (pmt->descriptors)
    g_ptr_array_unref (pmt->descriptors);
  g_slice_free (GstMpegtsPMTStream, pmt);
}

G_DEFINE_BOXED_TYPE (GstMpegtsPMTStream, gst_mpegts_pmt_stream,
    (GBoxedCopyFunc) _gst_mpegts_pmt_stream_copy,
    (GFreeFunc) _gst_mpegts_pmt_stream_free);

static GstMpegtsPMT *
_gst_mpegts_pmt_copy (GstMpegtsPMT * pmt)
{
  GstMpegtsPMT *copy;

  copy = g_slice_dup (GstMpegtsPMT, pmt);
  if (pmt->descriptors)
    copy->descriptors = g_ptr_array_ref (pmt->descriptors);
  copy->streams = g_ptr_array_ref (pmt->streams);

  return copy;
}

static void
_gst_mpegts_pmt_free (GstMpegtsPMT * pmt)
{
  if (pmt->descriptors)
    g_ptr_array_unref (pmt->descriptors);
  if (pmt->streams)
    g_ptr_array_unref (pmt->streams);
  g_slice_free (GstMpegtsPMT, pmt);
}

G_DEFINE_BOXED_TYPE (GstMpegtsPMT, gst_mpegts_pmt,
    (GBoxedCopyFunc) _gst_mpegts_pmt_copy, (GFreeFunc) _gst_mpegts_pmt_free);


static gpointer
_parse_pmt (GstMpegtsSection * section)
{
  GstMpegtsPMT *pmt = NULL;
  guint i = 0, allocated_streams = 8;
  guint8 *data, *end;
  guint program_info_length;
  guint stream_info_length;

  pmt = g_slice_new0 (GstMpegtsPMT);

  data = section->data;
  end = data + section->section_length;

  GST_DEBUG ("Parsing %d Program Map Table", section->subtable_extension);

  /* Assign program number from subtable extension,
     and skip already parsed data */
  pmt->program_number = section->subtable_extension;
  data += 8;

  pmt->pcr_pid = GST_READ_UINT16_BE (data) & 0x1FFF;
  data += 2;

  program_info_length = GST_READ_UINT16_BE (data) & 0x0FFF;
  data += 2;

  /* check that the buffer is large enough to contain at least
   * program_info_length bytes + CRC */
  if (program_info_length && (data + program_info_length + 4 > end)) {
    GST_WARNING ("PID %d invalid program info length %d left %d",
        section->pid, program_info_length, (gint) (end - data));
    goto error;
  }
  pmt->descriptors = gst_mpegts_parse_descriptors (data, program_info_length);
  if (pmt->descriptors == NULL)
    goto error;
  data += program_info_length;

  pmt->streams =
      g_ptr_array_new_full (allocated_streams,
      (GDestroyNotify) _gst_mpegts_pmt_stream_free);

  /* parse entries, cycle until there's space for another entry (at least 5
   * bytes) plus the CRC */
  while (data <= end - 4 - 5) {
    GstMpegtsPMTStream *stream = g_slice_new0 (GstMpegtsPMTStream);

    g_ptr_array_add (pmt->streams, stream);

    stream->stream_type = *data++;
    GST_DEBUG ("[%d] Stream type 0x%02x found", i, stream->stream_type);

    stream->pid = GST_READ_UINT16_BE (data) & 0x1FFF;
    data += 2;

    stream_info_length = GST_READ_UINT16_BE (data) & 0x0FFF;
    data += 2;

    if (data + stream_info_length + 4 > end) {
      GST_WARNING ("PID %d invalid stream info length %d left %d", section->pid,
          stream_info_length, (gint) (end - data));
      goto error;
    }

    stream->descriptors =
        gst_mpegts_parse_descriptors (data, stream_info_length);
    if (stream->descriptors == NULL)
      goto error;
    data += stream_info_length;

    i += 1;
  }

  /* Section length was longer than the actual content of the PMT */
  if (data < end - 4)
    goto error;

  /* Ensure we did not read after the end of our array */
  g_assert (data == end - 4);

  return (gpointer) pmt;

error:
  if (pmt)
    _gst_mpegts_pmt_free (pmt);

  return NULL;
}

/**
 * gst_mpegts_section_get_pmt:
 * @section: a #GstMpegtsSection of type %GST_MPEGTS_SECTION_PMT
 *
 * Returns the #GstMpegtsPMT contained in the @section.
 *
 * Returns: The #GstMpegtsPMT contained in the section, or %NULL if an error
 * happened.
 */
const GstMpegtsPMT *
gst_mpegts_section_get_pmt (GstMpegtsSection * section)
{
  g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_PMT, NULL);
  g_return_val_if_fail (section->cached_parsed || section->data, NULL);

  if (!section->cached_parsed)
    section->cached_parsed =
        __common_section_checks (section, 16, _parse_pmt,
        (GDestroyNotify) _gst_mpegts_pmt_free);

  return (const GstMpegtsPMT *) section->cached_parsed;
}

/**
 * gst_mpegts_pmt_new:
 *
 * Allocates and initializes a new #GstMpegtsPMT.
 *
 * Returns: (transfer full): #GstMpegtsPMT
 */
GstMpegtsPMT *
gst_mpegts_pmt_new (void)
{
  GstMpegtsPMT *pmt;

  pmt = g_slice_new0 (GstMpegtsPMT);

  pmt->descriptors = g_ptr_array_new_with_free_func ((GDestroyNotify)
      gst_mpegts_descriptor_free);
  pmt->streams = g_ptr_array_new_with_free_func ((GDestroyNotify)
      _gst_mpegts_pmt_stream_free);

  return pmt;
}

/**
 * gst_mpegts_pmt_stream_new:
 *
 * Allocates and initializes a new #GstMpegtsPMTStream.
 *
 * Returns: (transfer full): #GstMpegtsPMTStream
 */
GstMpegtsPMTStream *
gst_mpegts_pmt_stream_new (void)
{
  GstMpegtsPMTStream *stream;

  stream = g_slice_new0 (GstMpegtsPMTStream);

  stream->descriptors = g_ptr_array_new_with_free_func ((GDestroyNotify)
      gst_mpegts_descriptor_free);

  return stream;
}

static gboolean
_packetize_pmt (GstMpegtsSection * section)
{
  const GstMpegtsPMT *pmt;
  GstMpegtsPMTStream *stream;
  GstMpegtsDescriptor *descriptor;
  gsize length, pgm_info_length, stream_length;
  guint8 *data;
  guint i, j;

  pmt = gst_mpegts_section_get_pmt (section);

  if (pmt == NULL)
    return FALSE;

  /* 8 byte common section fields
     2 byte PCR pid
     2 byte program info length
     4 byte CRC */
  length = 16;

  /* Find length of program info */
  pgm_info_length = 0;
  if (pmt->descriptors) {
    for (i = 0; i < pmt->descriptors->len; i++) {
      descriptor = g_ptr_array_index (pmt->descriptors, i);
      pgm_info_length += descriptor->length + 2;
    }
  }

  /* Find length of PMT streams */
  stream_length = 0;
  if (pmt->streams) {
    for (i = 0; i < pmt->streams->len; i++) {
      stream = g_ptr_array_index (pmt->streams, i);

      /* 1 byte stream type
         2 byte PID
         2 byte ES info length */
      stream_length += 5;

      if (stream->descriptors) {
        for (j = 0; j < stream->descriptors->len; j++) {
          descriptor = g_ptr_array_index (stream->descriptors, j);
          stream_length += descriptor->length + 2;
        }
      }
    }
  }

  length += pgm_info_length + stream_length;

  _packetize_common_section (section, length);
  data = section->data + 8;

  /* reserved                         - 3  bit
     PCR_PID                          - 13 uimsbf */
  GST_WRITE_UINT16_BE (data, pmt->pcr_pid | 0xE000);
  data += 2;

  /* reserved                         - 4  bit
     program_info_length              - 12 uimsbf */
  GST_WRITE_UINT16_BE (data, pgm_info_length | 0xF000);
  data += 2;

  _packetize_descriptor_array (pmt->descriptors, &data);

  if (pmt->streams) {
    guint8 *pos;

    for (i = 0; i < pmt->streams->len; i++) {
      stream = g_ptr_array_index (pmt->streams, i);
      /* stream_type                  - 8  bit uimsbf */
      *data++ = stream->stream_type;

      /* reserved                     - 3  bit
         elementary_PID               - 13 bit uimsbf */
      GST_WRITE_UINT16_BE (data, stream->pid | 0xE000);
      data += 2;

      /* reserved                     - 4  bit
         ES_info_length               - 12 bit uimsbf */
      pos = data;
      data += 2;
      _packetize_descriptor_array (stream->descriptors, &data);

      /* Go back and update descriptor length */
      GST_WRITE_UINT16_BE (pos, (data - pos - 2) | 0xF000);
    }
  }

  return TRUE;
}

/**
 * gst_mpegts_section_from_pmt:
 * @pmt: (transfer full): a #GstMpegtsPMT to create a #GstMpegtsSection from
 * @pid: The PID that the #GstMpegtsPMT belongs to
 *
 * Creates a #GstMpegtsSection from @pmt that is bound to @pid
 *
 * Returns: (transfer full): #GstMpegtsSection
 */
GstMpegtsSection *
gst_mpegts_section_from_pmt (GstMpegtsPMT * pmt, guint16 pid)
{
  GstMpegtsSection *section;

  g_return_val_if_fail (pmt != NULL, NULL);

  section = _gst_mpegts_section_init (pid, GST_MTS_TABLE_ID_TS_PROGRAM_MAP);

  section->subtable_extension = pmt->program_number;
  section->cached_parsed = (gpointer) pmt;
  section->packetizer = _packetize_pmt;
  section->destroy_parsed = (GDestroyNotify) _gst_mpegts_pmt_free;

  return section;
}

/* Conditional Access Table */
static gpointer
_parse_cat (GstMpegtsSection * section)
{
  guint8 *data;
  guint desc_len;

  /* Skip parts already parsed */
  data = section->data + 8;

  /* descriptors */
  desc_len = section->section_length - 4 - 8;
  return (gpointer) gst_mpegts_parse_descriptors (data, desc_len);
}

/**
 * gst_mpegts_section_get_cat:
 * @section: a #GstMpegtsSection of type %GST_MPEGTS_SECTION_CAT
 *
 * Returns the array of #GstMpegtsDescriptor contained in the Conditional
 * Access Table.
 *
 * Returns: (transfer container) (element-type GstMpegtsDescriptor): The
 * #GstMpegtsDescriptor contained in the section, or %NULL if an error
 * happened. Release with #g_array_unref when done.
 */
GPtrArray *
gst_mpegts_section_get_cat (GstMpegtsSection * section)
{
  g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_CAT, NULL);
  g_return_val_if_fail (section->cached_parsed || section->data, NULL);

  if (!section->cached_parsed)
    section->cached_parsed =
        __common_section_checks (section, 12, _parse_cat,
        (GDestroyNotify) g_ptr_array_unref);

  if (section->cached_parsed)
    return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
  return NULL;
}

/* Transport Stream Description Table (TSDT) */
/**
 * gst_mpegts_section_get_tsdt:
 * @section: a #GstMpegtsSection of type %GST_MPEGTS_SECTION_TSDT
 *
 * Returns the array of #GstMpegtsDescriptor contained in the section
 *
 * Returns: (transfer container) (element-type GstMpegtsDescriptor): The
 * #GstMpegtsDescriptor contained in the section, or %NULL if an error
 * happened. Release with #g_array_unref when done.
 */
GPtrArray *
gst_mpegts_section_get_tsdt (GstMpegtsSection * section)
{
  g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_TSDT, NULL);
  g_return_val_if_fail (section->cached_parsed || section->data, NULL);

  if (section->cached_parsed)
    return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);

  /* FIXME : parse TSDT */
  return NULL;
}


/**
 * gst_mpegts_initialize:
 *
 * Initializes the MPEG-TS helper library. Must be called before any
 * usage.
 */
void
gst_mpegts_initialize (void)
{
  if (_gst_mpegts_section_type)
    return;

  GST_DEBUG_CATEGORY_INIT (gst_mpegts_debug, "mpegts", 0,
      "MPEG-TS helper library");

  /* FIXME : Temporary hack to initialize section gtype */
  _gst_mpegts_section_type = gst_mpegts_section_get_type ();

  QUARK_PAT = g_quark_from_string ("pat");
  QUARK_CAT = g_quark_from_string ("cat");
  QUARK_PMT = g_quark_from_string ("pmt");
  QUARK_NIT = g_quark_from_string ("nit");
  QUARK_BAT = g_quark_from_string ("bat");
  QUARK_SDT = g_quark_from_string ("sdt");
  QUARK_EIT = g_quark_from_string ("eit");
  QUARK_TDT = g_quark_from_string ("tdt");
  QUARK_TOT = g_quark_from_string ("tot");
  QUARK_SECTION = g_quark_from_string ("section");

  __initialize_descriptors ();
}

/* FIXME : Later on we might need to use more than just the table_id
 * to figure out which type of section this is. */
static GstMpegtsSectionType
_identify_section (guint16 pid, guint8 table_id)
{
  switch (table_id) {
    case GST_MTS_TABLE_ID_PROGRAM_ASSOCIATION:
      if (pid == 0x00)
        return GST_MPEGTS_SECTION_PAT;
      break;
    case GST_MTS_TABLE_ID_CONDITIONAL_ACCESS:
      if (pid == 0x01)
        return GST_MPEGTS_SECTION_CAT;
      break;
    case GST_MTS_TABLE_ID_TS_PROGRAM_MAP:
      return GST_MPEGTS_SECTION_PMT;
    case GST_MTS_TABLE_ID_BOUQUET_ASSOCIATION:
      if (pid == 0x0011)
        return GST_MPEGTS_SECTION_BAT;
      break;
    case GST_MTS_TABLE_ID_NETWORK_INFORMATION_ACTUAL_NETWORK:
    case GST_MTS_TABLE_ID_NETWORK_INFORMATION_OTHER_NETWORK:
      if (pid == 0x0010)
        return GST_MPEGTS_SECTION_NIT;
      break;
    case GST_MTS_TABLE_ID_SERVICE_DESCRIPTION_ACTUAL_TS:
    case GST_MTS_TABLE_ID_SERVICE_DESCRIPTION_OTHER_TS:
      if (pid == 0x0011)
        return GST_MPEGTS_SECTION_SDT;
      break;
    case GST_MTS_TABLE_ID_TIME_DATE:
      if (pid == 0x0014)
        return GST_MPEGTS_SECTION_TDT;
      break;
    case GST_MTS_TABLE_ID_TIME_OFFSET:
      if (pid == 0x0014)
        return GST_MPEGTS_SECTION_TOT;
      break;
    case GST_MTS_TABLE_ID_ATSC_TERRESTRIAL_VIRTUAL_CHANNEL:
      if (pid == 0x1ffb)
        return GST_MPEGTS_SECTION_ATSC_TVCT;
      break;
    case GST_MTS_TABLE_ID_ATSC_CABLE_VIRTUAL_CHANNEL:
      if (pid == 0x1ffb)
        return GST_MPEGTS_SECTION_ATSC_CVCT;
      break;
    case GST_MTS_TABLE_ID_ATSC_MASTER_GUIDE:
      if (pid == 0x1ffb)
        return GST_MPEGTS_SECTION_ATSC_MGT;
      break;
    case GST_MTS_TABLE_ID_ATSC_EVENT_INFORMATION:
      /* FIXME check pids reported on the MGT to confirm expectations */
      return GST_MPEGTS_SECTION_ATSC_EIT;
    case GST_MTS_TABLE_ID_ATSC_CHANNEL_OR_EVENT_EXTENDED_TEXT:
      /* FIXME check pids reported on the MGT to confirm expectations */
      return GST_MPEGTS_SECTION_ATSC_ETT;
      /* FIXME : FILL */
    case GST_MTS_TABLE_ID_ATSC_SYSTEM_TIME:
      if (pid == 0x1ffb)
        return GST_MPEGTS_SECTION_ATSC_STT;
      break;
    default:
      /* Handle ranges */
      if (table_id >= GST_MTS_TABLE_ID_EVENT_INFORMATION_ACTUAL_TS_PRESENT &&
          table_id <= GST_MTS_TABLE_ID_EVENT_INFORMATION_OTHER_TS_SCHEDULE_N) {
        if (pid == 0x0012)
          return GST_MPEGTS_SECTION_EIT;
      }
      return GST_MPEGTS_SECTION_UNKNOWN;
  }
  return GST_MPEGTS_SECTION_UNKNOWN;

}

GstMpegtsSection *
_gst_mpegts_section_init (guint16 pid, guint8 table_id)
{
  GstMpegtsSection *section;

  section = g_slice_new0 (GstMpegtsSection);
  gst_mini_object_init (GST_MINI_OBJECT_CAST (section), 0, MPEG_TYPE_TS_SECTION,
      (GstMiniObjectCopyFunction) _gst_mpegts_section_copy, NULL,
      (GstMiniObjectFreeFunction) _gst_mpegts_section_free);

  section->pid = pid;
  section->table_id = table_id;
  section->current_next_indicator = TRUE;
  section->section_type = _identify_section (pid, table_id);

  return section;
}

void
_packetize_common_section (GstMpegtsSection * section, gsize length)
{
  guint8 *data;

  section->section_length = length;
  data = section->data = g_malloc (length);

  /* table_id                         - 8 bit uimsbf */
  *data++ = section->table_id;

  /* section_syntax_indicator         - 1  bit
     reserved                         - 3  bit
     section_length                   - 12 bit uimsbf */
  switch (section->section_type) {
    case GST_MPEGTS_SECTION_PAT:
    case GST_MPEGTS_SECTION_PMT:
    case GST_MPEGTS_SECTION_CAT:
    case GST_MPEGTS_SECTION_TSDT:
      /* Tables from ISO/IEC 13818-1 has a '0' bit
       * after the section_syntax_indicator */
      GST_WRITE_UINT16_BE (data, (section->section_length - 3) | 0x3000);
      break;
    default:
      GST_WRITE_UINT16_BE (data, (section->section_length - 3) | 0x7000);
  }

  /* short sections do not contain any further fields */
  if (section->short_section)
    return;

  /* Set section_syntax_indicator bit since we do not have a short section */
  *data |= 0x80;
  data += 2;

  /* subtable_extension               - 16 bit uimsbf */
  GST_WRITE_UINT16_BE (data, section->subtable_extension);
  data += 2;

  /* reserved                         - 2  bit
     version_number                   - 5  bit uimsbf
     current_next_indicator           - 1  bit */
  *data++ = 0xC0 |
      ((section->version_number & 0x1F) << 1) |
      (section->current_next_indicator & 0x01);

  /* section_number                   - 8  bit uimsbf */
  *data++ = section->section_number;
  /* last_section_number              - 8  bit uimsbf */
  *data++ = section->last_section_number;
}

/**
 * gst_mpegts_section_new:
 * @pid: the PID to which this section belongs
 * @data: (transfer full): a pointer to the beginning of the section (i.e. the first byte
 * should contain the table_id field).
 * @data_size: size of the @data argument.
 *
 * Creates a new #GstMpegtsSection from the provided @data.
 *
 * Note: Ensuring @data is big enough to contain the full section is the
 * responsibility of the caller. If it is not big enough, %NULL will be
 * returned.
 *
 * Note: it is the responsibility of the caller to ensure @data does point
 * to the beginning of the section.
 *
 * Returns: (transfer full): A new #GstMpegtsSection if the data was valid,
 * else %NULL
 */
GstMpegtsSection *
gst_mpegts_section_new (guint16 pid, guint8 * data, gsize data_size)
{
  GstMpegtsSection *res = NULL;
  guint8 tmp;
  guint8 table_id;
  guint16 section_length = 0;

  /* The smallest section ever is 3 bytes */
  if (G_UNLIKELY (data_size < 3))
    goto short_packet;

  /* Check for length */
  section_length = GST_READ_UINT16_BE (data + 1) & 0x0FFF;
  if (G_UNLIKELY (data_size < section_length + 3))
    goto short_packet;

  GST_LOG ("data_size:%" G_GSIZE_FORMAT " section_length:%u",
      data_size, section_length);

  /* Table id is in first byte */
  table_id = *data;

  res = _gst_mpegts_section_init (pid, table_id);

  res->data = data;
  /* table_id (already parsed)       : 8  bit */
  data++;
  /* section_syntax_indicator        : 1  bit
   * other_fields (reserved)         : 3  bit*/
  res->short_section = (*data & 0x80) == 0x00;
  /* section_length (already parsed) : 12 bit */
  res->section_length = section_length + 3;
  if (!res->short_section) {
    /* A long packet needs to be at least 11 bytes long
     * _ 3 for the bytes above
     * _ 5 for the bytes below
     * _ 4 for the CRC */
    if (G_UNLIKELY (data_size < 11))
      goto bad_long_packet;

    /* CRC is after section_length (-4 for the size of the CRC) */
    res->crc = GST_READ_UINT32_BE (res->data + res->section_length - 4);
    /* Skip to after section_length */
    data += 2;
    /* subtable extension            : 16 bit */
    res->subtable_extension = GST_READ_UINT16_BE (data);
    data += 2;
    /* reserved                      : 2  bit
     * version_number                : 5  bit
     * current_next_indicator        : 1  bit */
    tmp = *data++;
    res->version_number = tmp >> 1 & 0x1f;
    res->current_next_indicator = tmp & 0x01;
    /* section_number                : 8  bit */
    res->section_number = *data++;
    /* last_section_number                : 8  bit */
    res->last_section_number = *data;
  }

  return res;

short_packet:
  {
    GST_WARNING
        ("PID 0x%04x section extends past provided data (got:%" G_GSIZE_FORMAT
        ", need:%d)", pid, data_size, section_length + 3);
    g_free (data);
    return NULL;
  }
bad_long_packet:
  {
    GST_WARNING ("PID 0x%04x long section is too short (%" G_GSIZE_FORMAT
        " bytes, need at least 11)", pid, data_size);
    gst_mpegts_section_unref (res);
    return NULL;
  }
}

/**
 * gst_mpegts_section_packetize:
 * @section: (transfer none): the #GstMpegtsSection that holds the data
 * @output_size: (out): #gsize to hold the size of the data
 *
 * If the data in @section has already been packetized, the data pointer is returned
 * immediately. Otherwise, the data field is allocated and populated.
 *
 * Returns: (transfer none): pointer to section data, or %NULL on fail
 */
guint8 *
gst_mpegts_section_packetize (GstMpegtsSection * section, gsize * output_size)
{
  guint8 *crc;
  g_return_val_if_fail (section != NULL, NULL);
  g_return_val_if_fail (output_size != NULL, NULL);
  g_return_val_if_fail (section->packetizer != NULL, NULL);

  /* Section data has already been packetized */
  if (section->data) {
    *output_size = section->section_length;
    return section->data;
  }

  if (!section->packetizer (section))
    return NULL;

  if (!section->short_section) {
    /* Update the CRC in the last 4 bytes of the section */
    crc = section->data + section->section_length - 4;
    GST_WRITE_UINT32_BE (crc, _calc_crc32 (section->data, crc - section->data));
  }

  *output_size = section->section_length;

  return section->data;
}
