/* Gstreamer
 * Copyright (C) <2011> Intel Corporation
 * Copyright (C) <2011> Collabora Ltd.
 * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
 *
 * From bad/sys/vdpau/mpeg/mpegutil.c:
 *   Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com>
 *   Copyright (C) <2009> Carl-Anton Ingmarsson <ca.ingmarsson@gmail.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.
 */

/**
 * SECTION:gstmpegvideoparser
 * @title: GstMpegvideoParser
 * @short_description: Convenience library for mpeg1 and 2 video
 * bitstream parsing.
 *
 * Provides useful functions for mpeg videos bitstream parsing.
 *
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "gstmpegvideoparser.h"
#include "parserutils.h"

#include <string.h>
#include <gst/base/gstbitreader.h>
#include <gst/base/gstbytereader.h>

#define MARKER_BIT 0x1

/* default intra quant matrix, in zig-zag order */
static const guint8 default_intra_quantizer_matrix[64] = {
  8,
  16, 16,
  19, 16, 19,
  22, 22, 22, 22,
  22, 22, 26, 24, 26,
  27, 27, 27, 26, 26, 26,
  26, 27, 27, 27, 29, 29, 29,
  34, 34, 34, 29, 29, 29, 27, 27,
  29, 29, 32, 32, 34, 34, 37,
  38, 37, 35, 35, 34, 35,
  38, 38, 40, 40, 40,
  48, 48, 46, 46,
  56, 56, 58,
  69, 69,
  83
};

static const guint8 mpeg_zigzag_8x8[64] = {
  0, 1, 8, 16, 9, 2, 3, 10,
  17, 24, 32, 25, 18, 11, 4, 5,
  12, 19, 26, 33, 40, 48, 41, 34,
  27, 20, 13, 6, 7, 14, 21, 28,
  35, 42, 49, 56, 57, 50, 43, 36,
  29, 22, 15, 23, 30, 37, 44, 51,
  58, 59, 52, 45, 38, 31, 39, 46,
  53, 60, 61, 54, 47, 55, 62, 63
};

enum
{
  GST_MPEG_VIDEO_MACROBLOCK_ESCAPE = G_MAXUINT,
};

/* Table B-1: Variable length codes for macroblock_address_increment */
static const VLCTable mpeg2_mbaddr_vlc_table[] = {
  {1, 0x01, 1},
  {2, 0x03, 3},
  {3, 0x02, 3},
  {4, 0x03, 4},
  {5, 0x02, 4},
  {6, 0x03, 5},
  {7, 0x02, 5},
  {8, 0x07, 7},
  {9, 0x06, 7},
  {10, 0x0b, 8},
  {11, 0x0a, 8},
  {12, 0x09, 8},
  {13, 0x08, 8},
  {14, 0x07, 8},
  {15, 0x06, 8},
  {16, 0x17, 10},
  {17, 0x16, 10},
  {18, 0x15, 10},
  {19, 0x14, 10},
  {20, 0x13, 10},
  {21, 0x12, 10},
  {22, 0x23, 11},
  {23, 0x22, 11},
  {24, 0x21, 11},
  {25, 0x20, 11},
  {26, 0x1f, 11},
  {27, 0x1e, 11},
  {28, 0x1d, 11},
  {29, 0x1c, 11},
  {30, 0x1b, 11},
  {31, 0x1a, 11},
  {32, 0x19, 11},
  {33, 0x18, 11},
  {GST_MPEG_VIDEO_MACROBLOCK_ESCAPE, 0x08, 11}
};

GST_DEBUG_CATEGORY_STATIC (mpegvideo_parser_debug);
#define GST_CAT_DEFAULT mpegvideo_parser_debug

#define INITIALIZE_DEBUG_CATEGORY \
  GST_DEBUG_CATEGORY_INIT (mpegvideo_parser_debug, "codecparsers_mpegvideo", \
      0, "Mpegvideo parser library");


/* Set the Pixel Aspect Ratio in our hdr from a ASR code in the data */
static void
set_par_from_asr_mpeg1 (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code)
{
  int ratios[16][2] = {
    {0, 0},                     /* 0, Invalid */
    {1, 1},                     /* 1, 1.0 */
    {10000, 6735},              /* 2, 0.6735 */
    {64, 45},                   /* 3, 0.7031 16:9 625 line */
    {10000, 7615},              /* 4, 0.7615 */
    {10000, 8055},              /* 5, 0.8055 */
    {32, 27},                   /* 6, 0.8437 */
    {10000, 8935},              /* 7, 0.8935 */
    {10000, 9375},              /* 8, 0.9375 */
    {10000, 9815},              /* 9, 0.9815 */
    {10000, 10255},             /* 10, 1.0255 */
    {10000, 10695},             /* 11, 1.0695 */
    {8, 9},                     /* 12, 1.125 */
    {10000, 11575},             /* 13, 1.1575 */
    {10000, 12015},             /* 14, 1.2015 */
    {0, 0},                     /* 15, invalid */
  };
  asr_code &= 0xf;

  seqhdr->par_w = ratios[asr_code][0];
  seqhdr->par_h = ratios[asr_code][1];
}

static void
set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
{
  const gint framerates[][2] = {
    {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
    {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
    {60, 1}, {30, 1}
  };

  if (fps_code && fps_code < 10) {
    seqhdr->fps_n = framerates[fps_code][0];
    seqhdr->fps_d = framerates[fps_code][1];
  } else {
    GST_DEBUG ("unknown/invalid frame_rate_code %d", fps_code);
    /* Force a valid framerate */
    /* FIXME or should this be kept unknown ?? */
    seqhdr->fps_n = 30000;
    seqhdr->fps_d = 1001;
  }
}

/* @size and @offset are wrt current reader position */
static inline gint
scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
{
  const guint8 *data;
  guint i = 0;

  g_assert ((guint64) offset + size <= reader->size - reader->byte);

  /* we can't find the pattern with less than 4 bytes */
  if (G_UNLIKELY (size < 4))
    return -1;

  data = reader->data + reader->byte + offset;

  while (i <= (size - 4)) {
    if (data[i + 2] > 1) {
      i += 3;
    } else if (data[i + 1]) {
      i += 2;
    } else if (data[i] || data[i + 2] != 1) {
      i++;
    } else {
      break;
    }
  }

  if (i <= (size - 4))
    return offset + i;

  /* nothing found */
  return -1;
}

/****** API *******/

/**
 * gst_mpeg_video_parse:
 * @packet: a #GstMpegVideoPacket to fill with the data and offset of the
 *     next packet found
 * @data: The data to parse
 * @size: The size of @data
 * @offset: The offset from which to start parsing
 *
 * Parses the MPEG 1/2 video bitstream contained in @data, and returns the
 * offset, and if known also the size, in @packet. This function will scan
 * the data to find the next packet if needed.
 *
 * Returns: TRUE if a packet start code was found, otherwise FALSE.
 */
gboolean
gst_mpeg_video_parse (GstMpegVideoPacket * packet,
    const guint8 * data, gsize size, guint offset)
{
  gint off;
  GstByteReader br;

  INITIALIZE_DEBUG_CATEGORY;

  if (size <= offset) {
    GST_DEBUG ("Can't parse from offset %d, buffer is to small", offset);
    return FALSE;
  }

  size -= offset;
  gst_byte_reader_init (&br, &data[offset], size);

  off = scan_for_start_codes (&br, 0, size);

  if (off < 0) {
    GST_DEBUG ("No start code prefix in this buffer");
    return FALSE;
  }

  if (gst_byte_reader_skip (&br, off + 3) == FALSE)
    goto failed;

  if (gst_byte_reader_get_uint8 (&br, &packet->type) == FALSE)
    goto failed;

  packet->data = data;
  packet->offset = offset + off + 4;
  packet->size = -1;

  /* try to find end of packet */
  size -= off + 4;
  off = scan_for_start_codes (&br, 0, size);

  if (off > 0)
    packet->size = off;

  return TRUE;

failed:
  {
    GST_WARNING ("Failed to parse");
    return FALSE;
  }
}

/**
 * gst_mpeg_video_packet_parse_sequence_header:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @seqhdr: (out): The #GstMpegVideoSequenceHdr structure to fill
 *
 * Parses the @seqhdr MPEG Video Sequence Header structure members
 * from video @packet
 *
 * Returns: %TRUE if the seqhdr could be parsed correctly, %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_sequence_header (const GstMpegVideoPacket * packet,
    GstMpegVideoSequenceHdr * seqhdr)
{
  GstBitReader br;
  guint8 bits;

  g_return_val_if_fail (seqhdr != NULL, FALSE);

  if (packet->size < 8)
    return FALSE;

  INITIALIZE_DEBUG_CATEGORY;

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  /* Setting the height/width codes */
  READ_UINT16 (&br, seqhdr->width, 12);
  READ_UINT16 (&br, seqhdr->height, 12);

  READ_UINT8 (&br, seqhdr->aspect_ratio_info, 4);
  /* Interpret PAR according to MPEG-1. Needs to be reinterpreted
   * later, if a sequence_display extension is seen */
  set_par_from_asr_mpeg1 (seqhdr, seqhdr->aspect_ratio_info);

  READ_UINT8 (&br, seqhdr->frame_rate_code, 4);
  set_fps_from_code (seqhdr, seqhdr->frame_rate_code);

  READ_UINT32 (&br, seqhdr->bitrate_value, 18);
  if (seqhdr->bitrate_value == 0x3ffff) {
    /* VBR stream */
    seqhdr->bitrate = 0;
  } else {
    /* Value in header is in units of 400 bps */
    seqhdr->bitrate = seqhdr->bitrate_value * 400;
  }

  READ_UINT8 (&br, bits, 1);
  if (bits != MARKER_BIT)
    goto failed;

  /* VBV buffer size */
  READ_UINT16 (&br, seqhdr->vbv_buffer_size_value, 10);

  /* constrained_parameters_flag */
  READ_UINT8 (&br, seqhdr->constrained_parameters_flag, 1);

  /* load_intra_quantiser_matrix */
  READ_UINT8 (&br, seqhdr->load_intra_quantiser_matrix, 1);
  if (seqhdr->load_intra_quantiser_matrix) {
    gint i;
    for (i = 0; i < 64; i++)
      READ_UINT8 (&br, seqhdr->intra_quantizer_matrix[i], 8);
  } else
    memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);

  /* non intra quantizer matrix */
  READ_UINT8 (&br, seqhdr->load_non_intra_quantiser_matrix, 1);
  if (seqhdr->load_non_intra_quantiser_matrix) {
    gint i;
    for (i = 0; i < 64; i++)
      READ_UINT8 (&br, seqhdr->non_intra_quantizer_matrix[i], 8);
  } else
    memset (seqhdr->non_intra_quantizer_matrix, 16, 64);

  /* dump some info */
  GST_LOG ("width x height: %d x %d", seqhdr->width, seqhdr->height);
  GST_LOG ("fps: %d/%d", seqhdr->fps_n, seqhdr->fps_d);
  GST_LOG ("par: %d/%d", seqhdr->par_w, seqhdr->par_h);
  GST_LOG ("bitrate: %d", seqhdr->bitrate);

  return TRUE;

  /* ERRORS */
failed:
  {
    GST_WARNING ("Failed to parse sequence header");
    /* clear out stuff */
    memset (seqhdr, 0, sizeof (*seqhdr));
    return FALSE;
  }
}

/**
 * gst_mpeg_video_packet_parse_sequence_extension:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @seqext: (out): The #GstMpegVideoSequenceExt structure to fill
 *
 * Parses the @seqext MPEG Video Sequence Extension structure members
 * from video @packet
 *
 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_sequence_extension (const GstMpegVideoPacket *
    packet, GstMpegVideoSequenceExt * seqext)
{
  GstBitReader br;

  g_return_val_if_fail (seqext != NULL, FALSE);

  if (packet->size < 6) {
    GST_DEBUG ("not enough bytes to parse the extension");
    return FALSE;
  }

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
      GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE) {
    GST_DEBUG ("Not parsing a sequence extension");
    return FALSE;
  }

  /* skip profile and level escape bit */
  seqext->profile_level_escape_bit =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

  seqext->profile = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
  seqext->level = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);

  /* progressive */
  seqext->progressive = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

  /* chroma format */
  seqext->chroma_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);

  /* resolution extension */
  seqext->horiz_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
  seqext->vert_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);

  seqext->bitrate_ext = gst_bit_reader_get_bits_uint16_unchecked (&br, 12);

  /* skip marker bits */
  gst_bit_reader_skip_unchecked (&br, 1);

  seqext->vbv_buffer_size_extension =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
  seqext->low_delay = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

  /* framerate extension */
  seqext->fps_n_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
  seqext->fps_d_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);

  return TRUE;
}

/**
 * gst_mpeg_video_packet_parse_sequence_display_extension:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @seqdisplayext: (out): The #GstMpegVideoSequenceDisplayExt
 *   structure to fill
 *
 * Parses the @seqext MPEG Video Sequence Display Extension structure
 * members from video @packet
 *
 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_sequence_display_extension (const GstMpegVideoPacket
    * packet, GstMpegVideoSequenceDisplayExt * seqdisplayext)
{
  GstBitReader br;

  g_return_val_if_fail (seqdisplayext != NULL, FALSE);

  if (packet->size < 5) {
    GST_DEBUG ("not enough bytes to parse the extension");
    return FALSE;
  }

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
      GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY) {
    GST_DEBUG ("Not parsing a sequence display extension");
    return FALSE;
  }

  seqdisplayext->video_format =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
  seqdisplayext->colour_description_flag =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

  if (seqdisplayext->colour_description_flag) {
    seqdisplayext->colour_primaries =
        gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
    seqdisplayext->transfer_characteristics =
        gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
    seqdisplayext->matrix_coefficients =
        gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
  }

  if (gst_bit_reader_get_remaining (&br) < 29) {
    GST_DEBUG ("Not enough remaining bytes to parse the extension");
    return FALSE;
  }

  seqdisplayext->display_horizontal_size =
      gst_bit_reader_get_bits_uint16_unchecked (&br, 14);
  /* skip marker bit */
  gst_bit_reader_skip_unchecked (&br, 1);
  seqdisplayext->display_vertical_size =
      gst_bit_reader_get_bits_uint16_unchecked (&br, 14);

  return TRUE;
}

/**
 * gst_mpeg_video_packet_parse_sequence_scalable_extension:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @seqscaleext: (out): The #GstMpegVideoSequenceScalableExt structure to fill
 *
 * Parses the @seqscaleext MPEG Video Sequence Scalable Extension structure
 * members from video @packet
 *
 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
    gst_mpeg_video_packet_parse_sequence_scalable_extension
    (const GstMpegVideoPacket * packet,
    GstMpegVideoSequenceScalableExt * seqscaleext) {
  GstBitReader br;

  g_return_val_if_fail (seqscaleext != NULL, FALSE);

  if (packet->size < 2) {
    GST_DEBUG ("not enough bytes to parse the extension");
    return FALSE;
  }

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
      GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE) {
    GST_DEBUG ("Not parsing a sequence scalable extension");
    return FALSE;
  }

  READ_UINT8 (&br, seqscaleext->scalable_mode, 2);
  READ_UINT8 (&br, seqscaleext->layer_id, 4);

  if (seqscaleext->scalable_mode == GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_SPATIAL) {
    READ_UINT16 (&br, seqscaleext->lower_layer_prediction_horizontal_size, 14);

    SKIP (&br, 1);

    READ_UINT16 (&br, seqscaleext->lower_layer_prediction_vertical_size, 14);

    READ_UINT8 (&br, seqscaleext->horizontal_subsampling_factor_m, 5);
    READ_UINT8 (&br, seqscaleext->horizontal_subsampling_factor_n, 5);
    READ_UINT8 (&br, seqscaleext->vertical_subsampling_factor_m, 5);
    READ_UINT8 (&br, seqscaleext->vertical_subsampling_factor_n, 5);
  }

  if (seqscaleext->scalable_mode == GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_TEMPORAL) {
    READ_UINT8 (&br, seqscaleext->picture_mux_enable, 1);
    if (seqscaleext->picture_mux_enable)
      READ_UINT8 (&br, seqscaleext->mux_to_progressive_sequence, 1);
    READ_UINT8 (&br, seqscaleext->picture_mux_order, 3);
    READ_UINT8 (&br, seqscaleext->picture_mux_factor, 3);
  }

  return TRUE;

failed:
  GST_WARNING ("error parsing \"Sequence Scalable Extension\"");
  return FALSE;
}

gboolean
gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
    GstMpegVideoSequenceExt * seqext,
    GstMpegVideoSequenceDisplayExt * displayext)
{
  guint32 w;
  guint32 h;

  if (seqext) {
    seqhdr->fps_n = seqhdr->fps_n * (seqext->fps_n_ext + 1);
    seqhdr->fps_d = seqhdr->fps_d * (seqext->fps_d_ext + 1);
    /* Extend width and height to 14 bits by adding the extension bits */
    seqhdr->width |= (seqext->horiz_size_ext << 12);
    seqhdr->height |= (seqext->vert_size_ext << 12);
    seqhdr->bitrate += (seqext->bitrate_ext << 18) * 400;
  }

  w = seqhdr->width;
  h = seqhdr->height;
  if (displayext) {
    /* Use the display size for calculating PAR when display ext present.
     * But we are handling this like what DVD players are doing. Which means,
     * ignore the display extension values if they are greater than the width/height
     * values provided by seqhdr and calculate the PAR based on the seqhdr values. */
    if (displayext->display_horizontal_size < w)
      w = displayext->display_horizontal_size;
    if (displayext->display_vertical_size < h)
      h = displayext->display_vertical_size;
  }

  /* Pixel_width = DAR_width * display_vertical_size */
  /* Pixel_height = DAR_height * display_horizontal_size */
  switch (seqhdr->aspect_ratio_info) {
    case 0x01:                 /* Square pixels */
      seqhdr->par_w = seqhdr->par_h = 1;
      break;
    case 0x02:                 /* 3:4 DAR = 4:3 pixels */
      seqhdr->par_w = 4 * h;
      seqhdr->par_h = 3 * w;
      break;
    case 0x03:                 /* 9:16 DAR */
      seqhdr->par_w = 16 * h;
      seqhdr->par_h = 9 * w;
      break;
    case 0x04:                 /* 1:2.21 DAR */
      seqhdr->par_w = 221 * h;
      seqhdr->par_h = 100 * w;
      break;
    default:
      GST_DEBUG ("unknown/invalid aspect_ratio_information %d",
          seqhdr->aspect_ratio_info);
      break;
  }

  return TRUE;
}

/**
 * gst_mpeg_video_packet_parse_quant_matrix_extension:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @quant: (out): The #GstMpegVideoQuantMatrixExt structure to fill
 *
 * Parses the @quant MPEG Video Quantization Matrix Extension
 * structure members from video @packet
 *
 * Returns: %TRUE if the quant matrix extension could be parsed correctly,
 * %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_quant_matrix_extension (const GstMpegVideoPacket *
    packet, GstMpegVideoQuantMatrixExt * quant)
{
  guint8 i;
  GstBitReader br;

  g_return_val_if_fail (quant != NULL, FALSE);

  if (packet->size < 1) {
    GST_DEBUG ("not enough bytes to parse the extension");
    return FALSE;
  }

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
      GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX) {
    GST_DEBUG ("Not parsing a quant matrix extension");
    return FALSE;
  }

  READ_UINT8 (&br, quant->load_intra_quantiser_matrix, 1);
  if (quant->load_intra_quantiser_matrix) {
    for (i = 0; i < 64; i++) {
      READ_UINT8 (&br, quant->intra_quantiser_matrix[i], 8);
    }
  }

  READ_UINT8 (&br, quant->load_non_intra_quantiser_matrix, 1);
  if (quant->load_non_intra_quantiser_matrix) {
    for (i = 0; i < 64; i++) {
      READ_UINT8 (&br, quant->non_intra_quantiser_matrix[i], 8);
    }
  }

  READ_UINT8 (&br, quant->load_chroma_intra_quantiser_matrix, 1);
  if (quant->load_chroma_intra_quantiser_matrix) {
    for (i = 0; i < 64; i++) {
      READ_UINT8 (&br, quant->chroma_intra_quantiser_matrix[i], 8);
    }
  }

  READ_UINT8 (&br, quant->load_chroma_non_intra_quantiser_matrix, 1);
  if (quant->load_chroma_non_intra_quantiser_matrix) {
    for (i = 0; i < 64; i++) {
      READ_UINT8 (&br, quant->chroma_non_intra_quantiser_matrix[i], 8);
    }
  }

  return TRUE;

failed:
  GST_WARNING ("error parsing \"Quant Matrix Extension\"");
  return FALSE;
}

/**
 * gst_mpeg_video_packet_parse_picture_extension:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @ext: (out): The #GstMpegVideoPictureExt structure to fill
 *
 * Parse the @ext MPEG Video Picture Extension structure members from
 * video @packet
 *
 * Returns: %TRUE if the picture extension could be parsed correctly,
 * %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_picture_extension (const GstMpegVideoPacket *
    packet, GstMpegVideoPictureExt * ext)
{
  GstBitReader br;

  g_return_val_if_fail (ext != NULL, FALSE);

  if (packet->size < 5)
    return FALSE;

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
      GST_MPEG_VIDEO_PACKET_EXT_PICTURE) {
    GST_DEBUG ("Extension is not a picture extension");
    return FALSE;
  }

  /* f_code */
  READ_UINT8 (&br, ext->f_code[0][0], 4);
  READ_UINT8 (&br, ext->f_code[0][1], 4);
  READ_UINT8 (&br, ext->f_code[1][0], 4);
  READ_UINT8 (&br, ext->f_code[1][1], 4);

  /* intra DC precision */
  READ_UINT8 (&br, ext->intra_dc_precision, 2);

  /* picture structure */
  READ_UINT8 (&br, ext->picture_structure, 2);

  /* top field first */
  READ_UINT8 (&br, ext->top_field_first, 1);

  /* frame pred frame dct */
  READ_UINT8 (&br, ext->frame_pred_frame_dct, 1);

  /* concealment motion vectors */
  READ_UINT8 (&br, ext->concealment_motion_vectors, 1);

  /* q scale type */
  READ_UINT8 (&br, ext->q_scale_type, 1);

  /* intra vlc format */
  READ_UINT8 (&br, ext->intra_vlc_format, 1);

  /* alternate scan */
  READ_UINT8 (&br, ext->alternate_scan, 1);

  /* repeat first field */
  READ_UINT8 (&br, ext->repeat_first_field, 1);

  /* chroma_420_type */
  READ_UINT8 (&br, ext->chroma_420_type, 1);

  /* progressive_frame */
  READ_UINT8 (&br, ext->progressive_frame, 1);

  /* composite display */
  READ_UINT8 (&br, ext->composite_display, 1);

  if (ext->composite_display) {

    /* v axis */
    READ_UINT8 (&br, ext->v_axis, 1);

    /* field sequence */
    READ_UINT8 (&br, ext->field_sequence, 3);

    /* sub carrier */
    READ_UINT8 (&br, ext->sub_carrier, 1);

    /* burst amplitude */
    READ_UINT8 (&br, ext->burst_amplitude, 7);

    /* sub_carrier phase */
    READ_UINT8 (&br, ext->sub_carrier_phase, 8);
  }

  return TRUE;

failed:
  GST_WARNING ("error parsing \"Picture Coding Extension\"");
  return FALSE;

}

/**
 * gst_mpeg_video_packet_parse_picture_header:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @pichdr: (out): The #GstMpegVideoPictureHdr structure to fill
 *
 * Parsers the @pichdr MPEG Video Picture Header structure members
 * from video @packet
 *
 * Returns: %TRUE if the picture sequence could be parsed correctly, %FALSE
 * otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_picture_header (const GstMpegVideoPacket * packet,
    GstMpegVideoPictureHdr * hdr)
{
  GstBitReader br;

  if (packet->size < 4)
    goto failed;

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  /* temperal sequence number */
  if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->tsn, 10))
    goto failed;


  /* frame type */
  if (!gst_bit_reader_get_bits_uint8 (&br, (guint8 *) & hdr->pic_type, 3))
    goto failed;


  if (hdr->pic_type == 0 || hdr->pic_type > 4)
    goto bad_pic_type;          /* Corrupted picture packet */

  /* VBV delay */
  if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->vbv_delay, 16))
    goto failed;

  if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_P
      || hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {

    READ_UINT8 (&br, hdr->full_pel_forward_vector, 1);

    READ_UINT8 (&br, hdr->f_code[0][0], 3);
    hdr->f_code[0][1] = hdr->f_code[0][0];
  } else {
    hdr->full_pel_forward_vector = 0;
    hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
  }

  if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
    READ_UINT8 (&br, hdr->full_pel_backward_vector, 1);

    READ_UINT8 (&br, hdr->f_code[1][0], 3);
    hdr->f_code[1][1] = hdr->f_code[1][0];
  } else {
    hdr->full_pel_backward_vector = 0;
    hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
  }

  return TRUE;

bad_pic_type:
  {
    GST_WARNING ("Unsupported picture type : %d", hdr->pic_type);
    return FALSE;
  }

failed:
  {
    GST_WARNING ("Not enough data to parse picture header");
    return FALSE;
  }
}

/**
 * gst_mpeg_video_packet_parse_gop:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @gop: (out): The #GstMpegVideoGop structure to fill
 *
 * Parses the @gop MPEG Video Group of Picture structure members from
 * video @packet
 *
 * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_gop (const GstMpegVideoPacket * packet,
    GstMpegVideoGop * gop)
{
  GstBitReader br;

  g_return_val_if_fail (gop != NULL, FALSE);

  if (packet->size < 4)
    return FALSE;

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  READ_UINT8 (&br, gop->drop_frame_flag, 1);

  READ_UINT8 (&br, gop->hour, 5);

  READ_UINT8 (&br, gop->minute, 6);

  /* skip unused bit */
  if (!gst_bit_reader_skip (&br, 1))
    return FALSE;

  READ_UINT8 (&br, gop->second, 6);

  READ_UINT8 (&br, gop->frame, 6);

  READ_UINT8 (&br, gop->closed_gop, 1);

  READ_UINT8 (&br, gop->broken_link, 1);

  return TRUE;

failed:
  GST_WARNING ("error parsing \"GOP\"");
  return FALSE;
}

/**
 * gst_mpeg_video_packet_parse_slice_header:
 * @packet: The #GstMpegVideoPacket that carries the data
 * @slice_hdr: (out): The #GstMpegVideoSliceHdr structure to fill
 * @seqhdr: The #GstMpegVideoSequenceHdr header
 * @seqscaleext: The #GstMpegVideoSequenceScalableExt header
 *
 * Parses the @GstMpegVideoSliceHdr  structure members from @data
 *
 * Returns: %TRUE if the slice could be parsed correctly, %FALSE otherwise.
 *
 * Since: 1.2
 */
gboolean
gst_mpeg_video_packet_parse_slice_header (const GstMpegVideoPacket * packet,
    GstMpegVideoSliceHdr * slice_hdr, GstMpegVideoSequenceHdr * seqhdr,
    GstMpegVideoSequenceScalableExt * seqscaleext)
{
  GstBitReader br;
  guint height;
  guint mb_inc;
  guint8 bits, extra_bits;
  guint8 vertical_position, vertical_position_extension = 0;

  g_return_val_if_fail (seqhdr != NULL, FALSE);

  if (packet->size < 1)
    return FALSE;

  gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);

  if (packet->type < GST_MPEG_VIDEO_PACKET_SLICE_MIN ||
      packet->type > GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
    GST_DEBUG ("Not parsing a slice");
    return FALSE;
  }
  vertical_position = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN;

  height = seqhdr->height;
  if (height > 2800)
    READ_UINT8 (&br, vertical_position_extension, 3);

  slice_hdr->vertical_position = packet->type;
  slice_hdr->vertical_position_ext = vertical_position_extension;

  if (seqscaleext)
    if (seqscaleext->scalable_mode ==
        GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_DATA_PARTITIONING)
      READ_UINT8 (&br, slice_hdr->priority_breakpoint, 7);

  READ_UINT8 (&br, slice_hdr->quantiser_scale_code, 5);

  READ_UINT8 (&br, slice_hdr->slice_ext_flag, 1);
  if (!slice_hdr->slice_ext_flag)
    slice_hdr->intra_slice = 0;
  else {
    READ_UINT8 (&br, slice_hdr->intra_slice, 1);
    READ_UINT8 (&br, slice_hdr->slice_picture_id_enable, 1);
    READ_UINT8 (&br, slice_hdr->slice_picture_id, 6);

    READ_UINT8 (&br, bits, 1);
    while (bits) {
      READ_UINT8 (&br, extra_bits, 8);
      READ_UINT8 (&br, bits, 1);
    }
  }

  slice_hdr->header_size = gst_bit_reader_get_pos (&br);

  if (height > 2800)
    slice_hdr->mb_row = (vertical_position_extension << 7) + vertical_position;
  else
    slice_hdr->mb_row = vertical_position;

  slice_hdr->mb_column = -1;
  do {
    if (!decode_vlc (&br, &mb_inc, mpeg2_mbaddr_vlc_table,
            G_N_ELEMENTS (mpeg2_mbaddr_vlc_table))) {
      GST_WARNING ("failed to decode first macroblock_address_increment");
      goto failed;
    }
    slice_hdr->mb_column +=
        mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc;
  } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE);

  return TRUE;

failed:
  GST_WARNING ("error parsing \"Slice\"");
  return FALSE;
}

/**
 * gst_mpeg_video_quant_matrix_get_raster_from_zigzag:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from zigzag scan order to
 * raster scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.2
 */
void
gst_mpeg_video_quant_matrix_get_raster_from_zigzag (guint8 out_quant[64],
    const guint8 quant[64])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 64; i++)
    out_quant[mpeg_zigzag_8x8[i]] = quant[i];
}

/**
 * gst_mpeg_video_quant_matrix_get_zigzag_from_raster:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from raster scan order to
 * zigzag scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.2
 */
void
gst_mpeg_video_quant_matrix_get_zigzag_from_raster (guint8 out_quant[64],
    const guint8 quant[64])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 64; i++)
    out_quant[i] = quant[mpeg_zigzag_8x8[i]];
}
