Blame ext/ogg/dirac_parse.c

Packit 971217
Packit 971217
#include "dirac_parse.h"
Packit 971217
#include <string.h>
Packit 971217
Packit 971217
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
Packit 971217
Packit 971217
typedef struct _Unpack Unpack;
Packit 971217
Packit 971217
struct _Unpack
Packit 971217
{
Packit 971217
  unsigned char *data;
Packit 971217
  int n_bits_left;
Packit 971217
  int index;
Packit 971217
  int guard_bit;
Packit 971217
};
Packit 971217
Packit 971217
static void schro_unpack_init_with_data (Unpack * unpack, unsigned char *data,
Packit 971217
    int n_bytes, unsigned int guard_bit);
Packit 971217
Packit 971217
static unsigned int schro_unpack_decode_bit (Unpack * unpack);
Packit 971217
static unsigned int schro_unpack_decode_uint (Unpack * unpack);
Packit 971217
Packit 971217
Packit 971217
static void schro_video_format_set_std_video_format (DiracSequenceHeader *
Packit 971217
    format, int index);
Packit 971217
static void schro_video_format_set_std_frame_rate (DiracSequenceHeader * format,
Packit 971217
    int index);
Packit 971217
static void schro_video_format_set_std_aspect_ratio (DiracSequenceHeader *
Packit 971217
    format, int index);
Packit 971217
static void schro_video_format_set_std_signal_range (DiracSequenceHeader *
Packit 971217
    format, int index);
Packit 971217
static void schro_video_format_set_std_colour_spec (DiracSequenceHeader *
Packit 971217
    format, int index);
Packit 971217
Packit 971217
Packit 971217
Packit 971217
Packit 971217
int
Packit 971217
gst_dirac_sequence_header_parse (DiracSequenceHeader * header,
Packit 971217
    unsigned char *data, int n_bytes)
Packit 971217
{
Packit 971217
  int bit;
Packit 971217
  int index;
Packit 971217
  Unpack _unpack;
Packit 971217
  Unpack *unpack = &_unpack;
Packit 971217
  int major_version;
Packit 971217
  int minor_version;
Packit 971217
  int profile;
Packit 971217
  int level;
Packit 971217
Packit 971217
  memset (header, 0, sizeof (*header));
Packit 971217
Packit 971217
  schro_unpack_init_with_data (unpack, data, n_bytes, 1);
Packit 971217
Packit 971217
  /* parse parameters */
Packit 971217
  major_version = schro_unpack_decode_uint (unpack);
Packit 971217
  minor_version = schro_unpack_decode_uint (unpack);
Packit 971217
  profile = schro_unpack_decode_uint (unpack);
Packit 971217
  level = schro_unpack_decode_uint (unpack);
Packit 971217
Packit 971217
  /* base video header */
Packit 971217
  index = schro_unpack_decode_uint (unpack);
Packit 971217
  schro_video_format_set_std_video_format (header, index);
Packit 971217
Packit 971217
  header->major_version = major_version;
Packit 971217
  header->minor_version = minor_version;
Packit 971217
  header->profile = profile;
Packit 971217
  header->level = level;
Packit 971217
Packit 971217
  /* source parameters */
Packit 971217
  /* frame dimensions */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    header->width = schro_unpack_decode_uint (unpack);
Packit 971217
    header->height = schro_unpack_decode_uint (unpack);
Packit 971217
  }
Packit 971217
Packit 971217
  /* chroma header */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    header->chroma_format = schro_unpack_decode_uint (unpack);
Packit 971217
  }
Packit 971217
Packit 971217
  /* scan header */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    header->interlaced = schro_unpack_decode_uint (unpack);
Packit 971217
  }
Packit 971217
Packit 971217
  /* frame rate */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    index = schro_unpack_decode_uint (unpack);
Packit 971217
    if (index == 0) {
Packit 971217
      header->frame_rate_numerator = schro_unpack_decode_uint (unpack);
Packit 971217
      header->frame_rate_denominator = schro_unpack_decode_uint (unpack);
Packit 971217
    } else {
Packit 971217
      schro_video_format_set_std_frame_rate (header, index);
Packit 971217
    }
Packit 971217
  }
Packit 971217
Packit 971217
  /* aspect ratio */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    index = schro_unpack_decode_uint (unpack);
Packit 971217
    if (index == 0) {
Packit 971217
      header->aspect_ratio_numerator = schro_unpack_decode_uint (unpack);
Packit 971217
      header->aspect_ratio_denominator = schro_unpack_decode_uint (unpack);
Packit 971217
    } else {
Packit 971217
      schro_video_format_set_std_aspect_ratio (header, index);
Packit 971217
    }
Packit 971217
  }
Packit 971217
Packit 971217
  /* clean area */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    header->clean_width = schro_unpack_decode_uint (unpack);
Packit 971217
    header->clean_height = schro_unpack_decode_uint (unpack);
Packit 971217
    header->left_offset = schro_unpack_decode_uint (unpack);
Packit 971217
    header->top_offset = schro_unpack_decode_uint (unpack);
Packit 971217
  }
Packit 971217
Packit 971217
  /* signal range */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    index = schro_unpack_decode_uint (unpack);
Packit 971217
    if (index == 0) {
Packit 971217
      header->luma_offset = schro_unpack_decode_uint (unpack);
Packit 971217
      header->luma_excursion = schro_unpack_decode_uint (unpack);
Packit 971217
      header->chroma_offset = schro_unpack_decode_uint (unpack);
Packit 971217
      header->chroma_excursion = schro_unpack_decode_uint (unpack);
Packit 971217
    } else {
Packit 971217
      schro_video_format_set_std_signal_range (header, index);
Packit 971217
    }
Packit 971217
  }
Packit 971217
Packit 971217
  /* colour spec */
Packit 971217
  bit = schro_unpack_decode_bit (unpack);
Packit 971217
  if (bit) {
Packit 971217
    index = schro_unpack_decode_uint (unpack);
Packit 971217
    schro_video_format_set_std_colour_spec (header, index);
Packit 971217
    if (index == 0) {
Packit 971217
      /* colour primaries */
Packit 971217
      bit = schro_unpack_decode_bit (unpack);
Packit 971217
      if (bit) {
Packit 971217
        header->colour_primaries = schro_unpack_decode_uint (unpack);
Packit 971217
      }
Packit 971217
      /* colour matrix */
Packit 971217
      bit = schro_unpack_decode_bit (unpack);
Packit 971217
      if (bit) {
Packit 971217
        header->colour_matrix = schro_unpack_decode_uint (unpack);
Packit 971217
      }
Packit 971217
      /* transfer function */
Packit 971217
      bit = schro_unpack_decode_bit (unpack);
Packit 971217
      if (bit) {
Packit 971217
        header->transfer_function = schro_unpack_decode_uint (unpack);
Packit 971217
      }
Packit 971217
    }
Packit 971217
  }
Packit 971217
Packit 971217
  header->interlaced_coding = schro_unpack_decode_uint (unpack);
Packit 971217
Packit 971217
  return 1;
Packit 971217
}
Packit 971217
Packit 971217
/* standard stuff */
Packit 971217
Packit 971217
static const DiracSequenceHeader schro_video_formats[] = {
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        0,                      /* custom */
Packit 971217
        640, 480, SCHRO_CHROMA_420,
Packit 971217
        FALSE, FALSE,
Packit 971217
        24000, 1001, 1, 1,
Packit 971217
        640, 480, 0, 0,
Packit 971217
        0, 255, 128, 255,
Packit 971217
      0, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        1,                      /* QSIF525 */
Packit 971217
        176, 120, SCHRO_CHROMA_420,
Packit 971217
        FALSE, FALSE,
Packit 971217
        15000, 1001, 10, 11,
Packit 971217
        176, 120, 0, 0,
Packit 971217
        0, 255, 128, 255,
Packit 971217
      1, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        2,                      /* QCIF */
Packit 971217
        176, 144, SCHRO_CHROMA_420,
Packit 971217
        FALSE, TRUE,
Packit 971217
        25, 2, 12, 11,
Packit 971217
        176, 144, 0, 0,
Packit 971217
        0, 255, 128, 255,
Packit 971217
      2, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        3,                      /* SIF525 */
Packit 971217
        352, 240, SCHRO_CHROMA_420,
Packit 971217
        FALSE, FALSE,
Packit 971217
        15000, 1001, 10, 11,
Packit 971217
        352, 240, 0, 0,
Packit 971217
        0, 255, 128, 255,
Packit 971217
      1, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        4,                      /* CIF */
Packit 971217
        352, 288, SCHRO_CHROMA_420,
Packit 971217
        FALSE, TRUE,
Packit 971217
        25, 2, 12, 11,
Packit 971217
        352, 288, 0, 0,
Packit 971217
        0, 255, 128, 255,
Packit 971217
      2, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        5,                      /* 4SIF525 */
Packit 971217
        704, 480, SCHRO_CHROMA_420,
Packit 971217
        FALSE, FALSE,
Packit 971217
        15000, 1001, 10, 11,
Packit 971217
        704, 480, 0, 0,
Packit 971217
        0, 255, 128, 255,
Packit 971217
      1, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        6,                      /* 4CIF */
Packit 971217
        704, 576, SCHRO_CHROMA_420,
Packit 971217
        FALSE, TRUE,
Packit 971217
        25, 2, 12, 11,
Packit 971217
        704, 576, 0, 0,
Packit 971217
        0, 255, 128, 255,
Packit 971217
      2, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        7,                      /* SD480I-60 */
Packit 971217
        720, 480, SCHRO_CHROMA_422,
Packit 971217
        TRUE, FALSE,
Packit 971217
        30000, 1001, 10, 11,
Packit 971217
        704, 480, 8, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      1, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        8,                      /* SD576I-50 */
Packit 971217
        720, 576, SCHRO_CHROMA_422,
Packit 971217
        TRUE, TRUE,
Packit 971217
        25, 1, 12, 11,
Packit 971217
        704, 576, 8, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      2, 1, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        9,                      /* HD720P-60 */
Packit 971217
        1280, 720, SCHRO_CHROMA_422,
Packit 971217
        FALSE, TRUE,
Packit 971217
        60000, 1001, 1, 1,
Packit 971217
        1280, 720, 0, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      0, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        10,                     /* HD720P-50 */
Packit 971217
        1280, 720, SCHRO_CHROMA_422,
Packit 971217
        FALSE, TRUE,
Packit 971217
        50, 1, 1, 1,
Packit 971217
        1280, 720, 0, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      0, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        11,                     /* HD1080I-60 */
Packit 971217
        1920, 1080, SCHRO_CHROMA_422,
Packit 971217
        TRUE, TRUE,
Packit 971217
        30000, 1001, 1, 1,
Packit 971217
        1920, 1080, 0, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      0, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        12,                     /* HD1080I-50 */
Packit 971217
        1920, 1080, SCHRO_CHROMA_422,
Packit 971217
        TRUE, TRUE,
Packit 971217
        25, 1, 1, 1,
Packit 971217
        1920, 1080, 0, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      0, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        13,                     /* HD1080P-60 */
Packit 971217
        1920, 1080, SCHRO_CHROMA_422,
Packit 971217
        FALSE, TRUE,
Packit 971217
        60000, 1001, 1, 1,
Packit 971217
        1920, 1080, 0, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      0, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        14,                     /* HD1080P-50 */
Packit 971217
        1920, 1080, SCHRO_CHROMA_422,
Packit 971217
        FALSE, TRUE,
Packit 971217
        50, 1, 1, 1,
Packit 971217
        1920, 1080, 0, 0,
Packit 971217
        64, 876, 512, 896,
Packit 971217
      0, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        15,                     /* DC2K */
Packit 971217
        2048, 1080, SCHRO_CHROMA_444,
Packit 971217
        FALSE, TRUE,
Packit 971217
        24, 1, 1, 1,
Packit 971217
        2048, 1080, 0, 0,
Packit 971217
        256, 3504, 2048, 3584,
Packit 971217
      3, 0, 0},
Packit 971217
  {0, 0, 0, 0,
Packit 971217
        16,                     /* DC4K */
Packit 971217
        4096, 2160, SCHRO_CHROMA_444,
Packit 971217
        FALSE, TRUE,
Packit 971217
        24, 1, 1, 1,
Packit 971217
        2048, 1536, 0, 0,
Packit 971217
        256, 3504, 2048, 3584,
Packit 971217
      3, 0, 0},
Packit 971217
};
Packit 971217
Packit 971217
static void
Packit 971217
schro_video_format_set_std_video_format (DiracSequenceHeader * format,
Packit 971217
    int index)
Packit 971217
{
Packit 971217
Packit 971217
  if (index < 0 || index >= ARRAY_SIZE (schro_video_formats)) {
Packit 971217
    return;
Packit 971217
  }
Packit 971217
Packit 971217
  memcpy (format, schro_video_formats + index, sizeof (DiracSequenceHeader));
Packit 971217
}
Packit 971217
Packit 971217
typedef struct _SchroFrameRate SchroFrameRate;
Packit 971217
struct _SchroFrameRate
Packit 971217
{
Packit 971217
  int numerator;
Packit 971217
  int denominator;
Packit 971217
};
Packit 971217
Packit 971217
static const SchroFrameRate schro_frame_rates[] = {
Packit 971217
  {0, 0},
Packit 971217
  {24000, 1001},
Packit 971217
  {24, 1},
Packit 971217
  {25, 1},
Packit 971217
  {30000, 1001},
Packit 971217
  {30, 1},
Packit 971217
  {50, 1},
Packit 971217
  {60000, 1001},
Packit 971217
  {60, 1},
Packit 971217
  {15000, 1001},
Packit 971217
  {25, 2}
Packit 971217
};
Packit 971217
Packit 971217
static void
Packit 971217
schro_video_format_set_std_frame_rate (DiracSequenceHeader * format, int index)
Packit 971217
{
Packit 971217
  if (index < 1 || index >= ARRAY_SIZE (schro_frame_rates)) {
Packit 971217
    return;
Packit 971217
  }
Packit 971217
Packit 971217
  format->frame_rate_numerator = schro_frame_rates[index].numerator;
Packit 971217
  format->frame_rate_denominator = schro_frame_rates[index].denominator;
Packit 971217
}
Packit 971217
Packit 971217
typedef struct _SchroPixelAspectRatio SchroPixelAspectRatio;
Packit 971217
struct _SchroPixelAspectRatio
Packit 971217
{
Packit 971217
  int numerator;
Packit 971217
  int denominator;
Packit 971217
};
Packit 971217
Packit 971217
static const SchroPixelAspectRatio schro_aspect_ratios[] = {
Packit 971217
  {0, 0},
Packit 971217
  {1, 1},
Packit 971217
  {10, 11},
Packit 971217
  {12, 11},
Packit 971217
  {40, 33},
Packit 971217
  {16, 11},
Packit 971217
  {4, 3}
Packit 971217
};
Packit 971217
Packit 971217
static void
Packit 971217
schro_video_format_set_std_aspect_ratio (DiracSequenceHeader * format,
Packit 971217
    int index)
Packit 971217
{
Packit 971217
  if (index < 1 || index >= ARRAY_SIZE (schro_aspect_ratios)) {
Packit 971217
    return;
Packit 971217
  }
Packit 971217
Packit 971217
  format->aspect_ratio_numerator = schro_aspect_ratios[index].numerator;
Packit 971217
  format->aspect_ratio_denominator = schro_aspect_ratios[index].denominator;
Packit 971217
Packit 971217
}
Packit 971217
Packit 971217
typedef struct _SchroSignalRangeStruct SchroSignalRangeStruct;
Packit 971217
struct _SchroSignalRangeStruct
Packit 971217
{
Packit 971217
  int luma_offset;
Packit 971217
  int luma_excursion;
Packit 971217
  int chroma_offset;
Packit 971217
  int chroma_excursion;
Packit 971217
};
Packit 971217
Packit 971217
static const SchroSignalRangeStruct schro_signal_ranges[] = {
Packit 971217
  {0, 0, 0, 0},
Packit 971217
  {0, 255, 128, 255},
Packit 971217
  {16, 219, 128, 224},
Packit 971217
  {64, 876, 512, 896},
Packit 971217
  {256, 3504, 2048, 3584}
Packit 971217
};
Packit 971217
Packit 971217
static void
Packit 971217
schro_video_format_set_std_signal_range (DiracSequenceHeader * format, int i)
Packit 971217
{
Packit 971217
  if (i < 1 || i >= ARRAY_SIZE (schro_signal_ranges)) {
Packit 971217
    return;
Packit 971217
  }
Packit 971217
Packit 971217
  format->luma_offset = schro_signal_ranges[i].luma_offset;
Packit 971217
  format->luma_excursion = schro_signal_ranges[i].luma_excursion;
Packit 971217
  format->chroma_offset = schro_signal_ranges[i].chroma_offset;
Packit 971217
  format->chroma_excursion = schro_signal_ranges[i].chroma_excursion;
Packit 971217
}
Packit 971217
Packit 971217
typedef struct _SchroColourSpecStruct SchroColourSpecStruct;
Packit 971217
struct _SchroColourSpecStruct
Packit 971217
{
Packit 971217
  int colour_primaries;
Packit 971217
  int colour_matrix;
Packit 971217
  int transfer_function;
Packit 971217
};
Packit 971217
Packit 971217
static const SchroColourSpecStruct schro_colour_specs[] = {
Packit 971217
  {                             /* Custom */
Packit 971217
        SCHRO_COLOUR_PRIMARY_HDTV,
Packit 971217
        SCHRO_COLOUR_MATRIX_HDTV,
Packit 971217
      SCHRO_TRANSFER_CHAR_TV_GAMMA},
Packit 971217
  {                             /* SDTV 525 */
Packit 971217
        SCHRO_COLOUR_PRIMARY_SDTV_525,
Packit 971217
        SCHRO_COLOUR_MATRIX_SDTV,
Packit 971217
      SCHRO_TRANSFER_CHAR_TV_GAMMA},
Packit 971217
  {                             /* SDTV 625 */
Packit 971217
        SCHRO_COLOUR_PRIMARY_SDTV_625,
Packit 971217
        SCHRO_COLOUR_MATRIX_SDTV,
Packit 971217
      SCHRO_TRANSFER_CHAR_TV_GAMMA},
Packit 971217
  {                             /* HDTV */
Packit 971217
        SCHRO_COLOUR_PRIMARY_HDTV,
Packit 971217
        SCHRO_COLOUR_MATRIX_HDTV,
Packit 971217
      SCHRO_TRANSFER_CHAR_TV_GAMMA},
Packit 971217
  {                             /* Cinema */
Packit 971217
        SCHRO_COLOUR_PRIMARY_CINEMA,
Packit 971217
        SCHRO_COLOUR_MATRIX_HDTV,
Packit 971217
      SCHRO_TRANSFER_CHAR_TV_GAMMA}
Packit 971217
};
Packit 971217
Packit 971217
static void
Packit 971217
schro_video_format_set_std_colour_spec (DiracSequenceHeader * format, int i)
Packit 971217
{
Packit 971217
  if (i < 0 || i >= ARRAY_SIZE (schro_colour_specs)) {
Packit 971217
    return;
Packit 971217
  }
Packit 971217
Packit 971217
  format->colour_primaries = schro_colour_specs[i].colour_primaries;
Packit 971217
  format->colour_matrix = schro_colour_specs[i].colour_matrix;
Packit 971217
  format->transfer_function = schro_colour_specs[i].transfer_function;
Packit 971217
}
Packit 971217
Packit 971217
Packit 971217
/* unpack */
Packit 971217
Packit 971217
static void
Packit 971217
schro_unpack_init_with_data (Unpack * unpack, unsigned char *data,
Packit 971217
    int n_bytes, unsigned int guard_bit)
Packit 971217
{
Packit 971217
  memset (unpack, 0, sizeof (Unpack));
Packit 971217
Packit 971217
  unpack->data = data;
Packit 971217
  unpack->n_bits_left = 8 * n_bytes;
Packit 971217
  unpack->guard_bit = guard_bit;
Packit 971217
}
Packit 971217
Packit 971217
static unsigned int
Packit 971217
schro_unpack_decode_bit (Unpack * unpack)
Packit 971217
{
Packit 971217
  int bit;
Packit 971217
Packit 971217
  if (unpack->n_bits_left < 1) {
Packit 971217
    return unpack->guard_bit;
Packit 971217
  }
Packit 971217
  bit = (unpack->data[unpack->index >> 3] >> (7 - (unpack->index & 7))) & 1;
Packit 971217
  unpack->index++;
Packit 971217
  unpack->n_bits_left--;
Packit 971217
Packit 971217
  return bit;
Packit 971217
}
Packit 971217
Packit 971217
static unsigned int
Packit 971217
schro_unpack_decode_uint (Unpack * unpack)
Packit 971217
{
Packit 971217
  int count;
Packit 971217
  int value;
Packit 971217
Packit 971217
  count = 0;
Packit 971217
  value = 0;
Packit 971217
  while (!schro_unpack_decode_bit (unpack)) {
Packit 971217
    count++;
Packit 971217
    value <<= 1;
Packit 971217
    value |= schro_unpack_decode_bit (unpack);
Packit 971217
  }
Packit 971217
Packit 971217
  return (1 << count) - 1 + value;
Packit 971217
}