videoparsers: Add dirac parser
authorDavid Schleef <ds@schleef.org>
Sat, 9 Oct 2010 22:08:39 +0000 (15:08 -0700)
committerDavid Schleef <ds@schleef.org>
Thu, 17 Feb 2011 22:43:35 +0000 (14:43 -0800)
gst/videoparsers/Makefile.am
gst/videoparsers/dirac_parse.c [new file with mode: 0644]
gst/videoparsers/dirac_parse.h [new file with mode: 0644]
gst/videoparsers/gstdiracparse.c [new file with mode: 0644]
gst/videoparsers/gstdiracparse.h [new file with mode: 0644]
gst/videoparsers/plugin.c

index 59b5160..a344117 100644 (file)
@@ -1,11 +1,15 @@
 plugin_LTLIBRARIES = libgsth263parse.la
 
 libgsth263parse_la_SOURCES = plugin.c \
-       h263parse.c gsth263parse.c gsth264parse.c h264parse.c
+       h263parse.c gsth263parse.c \
+       gsth264parse.c h264parse.c \
+       gstdiracparse.c dirac_parse.c
 libgsth263parse_la_CFLAGS = $(GST_CFLAGS)
 libgsth263parse_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
 libgsth263parse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgsth263parse_la_LIBTOOLFLAGS = --tag=disable-static
 
 noinst_HEADERS = gsth263parse.h h263parse.h \
-       gsth264parse.h h264parse.h
+       gsth264parse.h h264parse.h \
+       gstdiracparse.h dirac_parse.h
+
diff --git a/gst/videoparsers/dirac_parse.c b/gst/videoparsers/dirac_parse.c
new file mode 100644 (file)
index 0000000..3a3193d
--- /dev/null
@@ -0,0 +1,498 @@
+
+#include "dirac_parse.h"
+#include <string.h>
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+typedef struct _Unpack Unpack;
+
+struct _Unpack
+{
+  unsigned char *data;
+  int n_bits_left;
+  int index;
+  int guard_bit;
+};
+
+static void schro_unpack_init_with_data (Unpack * unpack, unsigned char *data,
+    int n_bytes, unsigned int guard_bit);
+
+static unsigned int schro_unpack_decode_bit (Unpack * unpack);
+static unsigned int schro_unpack_decode_uint (Unpack * unpack);
+
+
+void schro_video_format_set_std_video_format (DiracSequenceHeader * format,
+    int index);
+void schro_video_format_set_std_frame_rate (DiracSequenceHeader * format,
+    int index);
+void schro_video_format_set_std_aspect_ratio (DiracSequenceHeader * format,
+    int index);
+void schro_video_format_set_std_signal_range (DiracSequenceHeader * format,
+    int index);
+void schro_video_format_set_std_colour_spec (DiracSequenceHeader * format,
+    int index);
+
+
+
+
+int
+dirac_sequence_header_parse (DiracSequenceHeader * header,
+    unsigned char *data, int n_bytes)
+{
+  int bit;
+  int index;
+  Unpack _unpack;
+  Unpack *unpack = &_unpack;
+  int major_version;
+  int minor_version;
+  int profile;
+  int level;
+
+  memset (header, 0, sizeof (*header));
+
+  schro_unpack_init_with_data (unpack, data, n_bytes, 1);
+
+  /* parse parameters */
+  major_version = schro_unpack_decode_uint (unpack);
+  minor_version = schro_unpack_decode_uint (unpack);
+  profile = schro_unpack_decode_uint (unpack);
+  level = schro_unpack_decode_uint (unpack);
+
+  /* base video header */
+  index = schro_unpack_decode_uint (unpack);
+  schro_video_format_set_std_video_format (header, index);
+
+  header->major_version = major_version;
+  header->minor_version = minor_version;
+  header->profile = profile;
+  header->level = level;
+
+  /* source parameters */
+  /* frame dimensions */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    header->width = schro_unpack_decode_uint (unpack);
+    header->height = schro_unpack_decode_uint (unpack);
+  }
+
+  /* chroma header */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    header->chroma_format = schro_unpack_decode_uint (unpack);
+  }
+
+  /* scan header */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    header->interlaced = schro_unpack_decode_uint (unpack);
+  }
+
+  /* frame rate */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    index = schro_unpack_decode_uint (unpack);
+    if (index == 0) {
+      header->frame_rate_numerator = schro_unpack_decode_uint (unpack);
+      header->frame_rate_denominator = schro_unpack_decode_uint (unpack);
+    } else {
+      schro_video_format_set_std_frame_rate (header, index);
+    }
+  }
+
+  /* aspect ratio */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    index = schro_unpack_decode_uint (unpack);
+    if (index == 0) {
+      header->aspect_ratio_numerator = schro_unpack_decode_uint (unpack);
+      header->aspect_ratio_denominator = schro_unpack_decode_uint (unpack);
+    } else {
+      schro_video_format_set_std_aspect_ratio (header, index);
+    }
+  }
+
+  /* clean area */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    header->clean_width = schro_unpack_decode_uint (unpack);
+    header->clean_height = schro_unpack_decode_uint (unpack);
+    header->left_offset = schro_unpack_decode_uint (unpack);
+    header->top_offset = schro_unpack_decode_uint (unpack);
+  }
+
+  /* signal range */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    index = schro_unpack_decode_uint (unpack);
+    if (index == 0) {
+      header->luma_offset = schro_unpack_decode_uint (unpack);
+      header->luma_excursion = schro_unpack_decode_uint (unpack);
+      header->chroma_offset = schro_unpack_decode_uint (unpack);
+      header->chroma_excursion = schro_unpack_decode_uint (unpack);
+    } else {
+      schro_video_format_set_std_signal_range (header, index);
+    }
+  }
+
+  /* colour spec */
+  bit = schro_unpack_decode_bit (unpack);
+  if (bit) {
+    index = schro_unpack_decode_uint (unpack);
+    schro_video_format_set_std_colour_spec (header, index);
+    if (index == 0) {
+      /* colour primaries */
+      bit = schro_unpack_decode_bit (unpack);
+      if (bit) {
+        header->colour_primaries = schro_unpack_decode_uint (unpack);
+      }
+      /* colour matrix */
+      bit = schro_unpack_decode_bit (unpack);
+      if (bit) {
+        header->colour_matrix = schro_unpack_decode_uint (unpack);
+      }
+      /* transfer function */
+      bit = schro_unpack_decode_bit (unpack);
+      if (bit) {
+        header->transfer_function = schro_unpack_decode_uint (unpack);
+      }
+    }
+  }
+
+  header->interlaced_coding = schro_unpack_decode_uint (unpack);
+
+  return 1;
+}
+
+/* standard stuff */
+
+static DiracSequenceHeader schro_video_formats[] = {
+  {0, 0, 0, 0,
+        0,                      /* custom */
+        640, 480, SCHRO_CHROMA_420,
+        FALSE, FALSE,
+        24000, 1001, 1, 1,
+        640, 480, 0, 0,
+        0, 255, 128, 255,
+      0, 0, 0},
+  {0, 0, 0, 0,
+        1,                      /* QSIF525 */
+        176, 120, SCHRO_CHROMA_420,
+        FALSE, FALSE,
+        15000, 1001, 10, 11,
+        176, 120, 0, 0,
+        0, 255, 128, 255,
+      1, 1, 0},
+  {0, 0, 0, 0,
+        2,                      /* QCIF */
+        176, 144, SCHRO_CHROMA_420,
+        FALSE, TRUE,
+        25, 2, 12, 11,
+        176, 144, 0, 0,
+        0, 255, 128, 255,
+      2, 1, 0},
+  {0, 0, 0, 0,
+        3,                      /* SIF525 */
+        352, 240, SCHRO_CHROMA_420,
+        FALSE, FALSE,
+        15000, 1001, 10, 11,
+        352, 240, 0, 0,
+        0, 255, 128, 255,
+      1, 1, 0},
+  {0, 0, 0, 0,
+        4,                      /* CIF */
+        352, 288, SCHRO_CHROMA_420,
+        FALSE, TRUE,
+        25, 2, 12, 11,
+        352, 288, 0, 0,
+        0, 255, 128, 255,
+      2, 1, 0},
+  {0, 0, 0, 0,
+        5,                      /* 4SIF525 */
+        704, 480, SCHRO_CHROMA_420,
+        FALSE, FALSE,
+        15000, 1001, 10, 11,
+        704, 480, 0, 0,
+        0, 255, 128, 255,
+      1, 1, 0},
+  {0, 0, 0, 0,
+        6,                      /* 4CIF */
+        704, 576, SCHRO_CHROMA_420,
+        FALSE, TRUE,
+        25, 2, 12, 11,
+        704, 576, 0, 0,
+        0, 255, 128, 255,
+      2, 1, 0},
+  {0, 0, 0, 0,
+        7,                      /* SD480I-60 */
+        720, 480, SCHRO_CHROMA_422,
+        TRUE, FALSE,
+        30000, 1001, 10, 11,
+        704, 480, 8, 0,
+        64, 876, 512, 896,
+      1, 1, 0},
+  {0, 0, 0, 0,
+        8,                      /* SD576I-50 */
+        720, 576, SCHRO_CHROMA_422,
+        TRUE, TRUE,
+        25, 1, 12, 11,
+        704, 576, 8, 0,
+        64, 876, 512, 896,
+      2, 1, 0},
+  {0, 0, 0, 0,
+        9,                      /* HD720P-60 */
+        1280, 720, SCHRO_CHROMA_422,
+        FALSE, TRUE,
+        60000, 1001, 1, 1,
+        1280, 720, 0, 0,
+        64, 876, 512, 896,
+      0, 0, 0},
+  {0, 0, 0, 0,
+        10,                     /* HD720P-50 */
+        1280, 720, SCHRO_CHROMA_422,
+        FALSE, TRUE,
+        50, 1, 1, 1,
+        1280, 720, 0, 0,
+        64, 876, 512, 896,
+      0, 0, 0},
+  {0, 0, 0, 0,
+        11,                     /* HD1080I-60 */
+        1920, 1080, SCHRO_CHROMA_422,
+        TRUE, TRUE,
+        30000, 1001, 1, 1,
+        1920, 1080, 0, 0,
+        64, 876, 512, 896,
+      0, 0, 0},
+  {0, 0, 0, 0,
+        12,                     /* HD1080I-50 */
+        1920, 1080, SCHRO_CHROMA_422,
+        TRUE, TRUE,
+        25, 1, 1, 1,
+        1920, 1080, 0, 0,
+        64, 876, 512, 896,
+      0, 0, 0},
+  {0, 0, 0, 0,
+        13,                     /* HD1080P-60 */
+        1920, 1080, SCHRO_CHROMA_422,
+        FALSE, TRUE,
+        60000, 1001, 1, 1,
+        1920, 1080, 0, 0,
+        64, 876, 512, 896,
+      0, 0, 0},
+  {0, 0, 0, 0,
+        14,                     /* HD1080P-50 */
+        1920, 1080, SCHRO_CHROMA_422,
+        FALSE, TRUE,
+        50, 1, 1, 1,
+        1920, 1080, 0, 0,
+        64, 876, 512, 896,
+      0, 0, 0},
+  {0, 0, 0, 0,
+        15,                     /* DC2K */
+        2048, 1080, SCHRO_CHROMA_444,
+        FALSE, TRUE,
+        24, 1, 1, 1,
+        2048, 1080, 0, 0,
+        256, 3504, 2048, 3584,
+      3, 0, 0},
+  {0, 0, 0, 0,
+        16,                     /* DC4K */
+        4096, 2160, SCHRO_CHROMA_444,
+        FALSE, TRUE,
+        24, 1, 1, 1,
+        2048, 1536, 0, 0,
+        256, 3504, 2048, 3584,
+      3, 0, 0},
+};
+
+void
+schro_video_format_set_std_video_format (DiracSequenceHeader * format,
+    int index)
+{
+
+  if (index < 0 || index >= ARRAY_SIZE (schro_video_formats)) {
+    return;
+  }
+
+  memcpy (format, schro_video_formats + index, sizeof (DiracSequenceHeader));
+}
+
+typedef struct _SchroFrameRate SchroFrameRate;
+struct _SchroFrameRate
+{
+  int numerator;
+  int denominator;
+};
+
+static SchroFrameRate schro_frame_rates[] = {
+  {0, 0},
+  {24000, 1001},
+  {24, 1},
+  {25, 1},
+  {30000, 1001},
+  {30, 1},
+  {50, 1},
+  {60000, 1001},
+  {60, 1},
+  {15000, 1001},
+  {25, 2}
+};
+
+void
+schro_video_format_set_std_frame_rate (DiracSequenceHeader * format, int index)
+{
+  if (index < 1 || index >= ARRAY_SIZE (schro_frame_rates)) {
+    return;
+  }
+
+  format->frame_rate_numerator = schro_frame_rates[index].numerator;
+  format->frame_rate_denominator = schro_frame_rates[index].denominator;
+}
+
+typedef struct _SchroPixelAspectRatio SchroPixelAspectRatio;
+struct _SchroPixelAspectRatio
+{
+  int numerator;
+  int denominator;
+};
+
+static const SchroPixelAspectRatio schro_aspect_ratios[] = {
+  {0, 0},
+  {1, 1},
+  {10, 11},
+  {12, 11},
+  {40, 33},
+  {16, 11},
+  {4, 3}
+};
+
+void
+schro_video_format_set_std_aspect_ratio (DiracSequenceHeader * format,
+    int index)
+{
+  if (index < 1 || index >= ARRAY_SIZE (schro_aspect_ratios)) {
+    return;
+  }
+
+  format->aspect_ratio_numerator = schro_aspect_ratios[index].numerator;
+  format->aspect_ratio_denominator = schro_aspect_ratios[index].denominator;
+
+}
+
+typedef struct _SchroSignalRangeStruct SchroSignalRangeStruct;
+struct _SchroSignalRangeStruct
+{
+  int luma_offset;
+  int luma_excursion;
+  int chroma_offset;
+  int chroma_excursion;
+};
+
+static const SchroSignalRangeStruct schro_signal_ranges[] = {
+  {0, 0, 0, 0},
+  {0, 255, 128, 255},
+  {16, 219, 128, 224},
+  {64, 876, 512, 896},
+  {256, 3504, 2048, 3584}
+};
+
+void
+schro_video_format_set_std_signal_range (DiracSequenceHeader * format, int i)
+{
+  if (i < 1 || i >= ARRAY_SIZE (schro_signal_ranges)) {
+    return;
+  }
+
+  format->luma_offset = schro_signal_ranges[i].luma_offset;
+  format->luma_excursion = schro_signal_ranges[i].luma_excursion;
+  format->chroma_offset = schro_signal_ranges[i].chroma_offset;
+  format->chroma_excursion = schro_signal_ranges[i].chroma_excursion;
+}
+
+typedef struct _SchroColourSpecStruct SchroColourSpecStruct;
+struct _SchroColourSpecStruct
+{
+  int colour_primaries;
+  int colour_matrix;
+  int transfer_function;
+};
+
+static const SchroColourSpecStruct schro_colour_specs[] = {
+  {                             /* Custom */
+        SCHRO_COLOUR_PRIMARY_HDTV,
+        SCHRO_COLOUR_MATRIX_HDTV,
+      SCHRO_TRANSFER_CHAR_TV_GAMMA},
+  {                             /* SDTV 525 */
+        SCHRO_COLOUR_PRIMARY_SDTV_525,
+        SCHRO_COLOUR_MATRIX_SDTV,
+      SCHRO_TRANSFER_CHAR_TV_GAMMA},
+  {                             /* SDTV 625 */
+        SCHRO_COLOUR_PRIMARY_SDTV_625,
+        SCHRO_COLOUR_MATRIX_SDTV,
+      SCHRO_TRANSFER_CHAR_TV_GAMMA},
+  {                             /* HDTV */
+        SCHRO_COLOUR_PRIMARY_HDTV,
+        SCHRO_COLOUR_MATRIX_HDTV,
+      SCHRO_TRANSFER_CHAR_TV_GAMMA},
+  {                             /* Cinema */
+        SCHRO_COLOUR_PRIMARY_CINEMA,
+        SCHRO_COLOUR_MATRIX_HDTV,
+      SCHRO_TRANSFER_CHAR_TV_GAMMA}
+};
+
+void
+schro_video_format_set_std_colour_spec (DiracSequenceHeader * format, int i)
+{
+  if (i < 0 || i >= ARRAY_SIZE (schro_colour_specs)) {
+    return;
+  }
+
+  format->colour_primaries = schro_colour_specs[i].colour_primaries;
+  format->colour_matrix = schro_colour_specs[i].colour_matrix;
+  format->transfer_function = schro_colour_specs[i].transfer_function;
+}
+
+
+/* unpack */
+
+static void
+schro_unpack_init_with_data (Unpack * unpack, unsigned char *data,
+    int n_bytes, unsigned int guard_bit)
+{
+  memset (unpack, 0, sizeof (Unpack));
+
+  unpack->data = data;
+  unpack->n_bits_left = 8 * n_bytes;
+  unpack->guard_bit = guard_bit;
+}
+
+static unsigned int
+schro_unpack_decode_bit (Unpack * unpack)
+{
+  int bit;
+
+  if (unpack->n_bits_left < 1) {
+    return unpack->guard_bit;
+  }
+  bit = (unpack->data[unpack->index >> 3] >> (7 - (unpack->index & 7))) & 1;
+  unpack->index++;
+  unpack->n_bits_left--;
+
+  return bit;
+}
+
+static unsigned int
+schro_unpack_decode_uint (Unpack * unpack)
+{
+  int count;
+  int value;
+
+  count = 0;
+  value = 0;
+  while (!schro_unpack_decode_bit (unpack)) {
+    count++;
+    value <<= 1;
+    value |= schro_unpack_decode_bit (unpack);
+  }
+
+  return (1 << count) - 1 + value;
+}
diff --git a/gst/videoparsers/dirac_parse.h b/gst/videoparsers/dirac_parse.h
new file mode 100644 (file)
index 0000000..9dc4ffe
--- /dev/null
@@ -0,0 +1,178 @@
+
+#ifndef __DIRAC_PARSE_H__
+#define __DIRAC_PARSE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef enum _SchroParseCode {
+  SCHRO_PARSE_CODE_SEQUENCE_HEADER = 0x00,
+  SCHRO_PARSE_CODE_END_OF_SEQUENCE = 0x10,
+  SCHRO_PARSE_CODE_AUXILIARY_DATA = 0x20,
+  SCHRO_PARSE_CODE_PADDING = 0x30,
+
+  SCHRO_PARSE_CODE_INTRA_REF = 0x0c,
+  SCHRO_PARSE_CODE_INTRA_NON_REF = 0x08,
+  SCHRO_PARSE_CODE_INTRA_REF_NOARITH = 0x4c,
+  SCHRO_PARSE_CODE_INTRA_NON_REF_NOARITH = 0x48,
+
+  SCHRO_PARSE_CODE_INTER_REF_1 = 0x0d,
+  SCHRO_PARSE_CODE_INTER_REF_1_NOARITH = 0x4d,
+  SCHRO_PARSE_CODE_INTER_REF_2 = 0x0e,
+  SCHRO_PARSE_CODE_INTER_REF_2_NOARITH = 0x4e,
+
+  SCHRO_PARSE_CODE_INTER_NON_REF_1 = 0x09,
+  SCHRO_PARSE_CODE_INTER_NON_REF_1_NOARITH = 0x49,
+  SCHRO_PARSE_CODE_INTER_NON_REF_2 = 0x0a,
+  SCHRO_PARSE_CODE_INTER_NON_REF_2_NOARITH = 0x4a,
+
+  SCHRO_PARSE_CODE_LD_INTRA_REF = 0xcc,
+  SCHRO_PARSE_CODE_LD_INTRA_NON_REF = 0xc8
+} SchroParseCode;
+
+#define SCHRO_PARSE_CODE_PICTURE(is_ref,n_refs,is_lowdelay,is_noarith) \
+  (8 | ((is_ref)<<2) | (n_refs) | ((is_lowdelay)<<7) | ((is_noarith)<<6))
+
+#define SCHRO_PARSE_CODE_IS_SEQ_HEADER(x) ((x) == SCHRO_PARSE_CODE_SEQUENCE_HEADER)
+#define SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(x) ((x) == SCHRO_PARSE_CODE_END_OF_SEQUENCE)
+#define SCHRO_PARSE_CODE_IS_AUXILIARY_DATA(x) ((x) == SCHRO_PARSE_CODE_AUXILIARY_DATA)
+#define SCHRO_PARSE_CODE_IS_PADDING(x) ((x) == SCHRO_PARSE_CODE_PADDING)
+#define SCHRO_PARSE_CODE_IS_PICTURE(x) ((x) & 0x8)
+#define SCHRO_PARSE_CODE_IS_LOW_DELAY(x) (((x) & 0x88) == 0x88)
+#define SCHRO_PARSE_CODE_IS_CORE_SYNTAX(x) (((x) & 0x88) == 0x08)
+#define SCHRO_PARSE_CODE_USING_AC(x) (((x) & 0x48) == 0x08)
+#define SCHRO_PARSE_CODE_IS_REFERENCE(x) (((x) & 0xc) == 0x0c)
+#define SCHRO_PARSE_CODE_IS_NON_REFERENCE(x) (((x) & 0xc) == 0x08)
+#define SCHRO_PARSE_CODE_NUM_REFS(x) ((x) & 0x3)
+#define SCHRO_PARSE_CODE_IS_INTRA(x) (SCHRO_PARSE_CODE_IS_PICTURE(x) && SCHRO_PARSE_CODE_NUM_REFS(x) == 0)
+#define SCHRO_PARSE_CODE_IS_INTER(x) (SCHRO_PARSE_CODE_IS_PICTURE(x) && SCHRO_PARSE_CODE_NUM_REFS(x) > 0)
+
+#define SCHRO_PARSE_HEADER_SIZE (4+1+4+4)
+
+typedef enum _SchroVideoFormatEnum {
+  SCHRO_VIDEO_FORMAT_CUSTOM = 0,
+  SCHRO_VIDEO_FORMAT_QSIF,
+  SCHRO_VIDEO_FORMAT_QCIF,
+  SCHRO_VIDEO_FORMAT_SIF,
+  SCHRO_VIDEO_FORMAT_CIF,
+  SCHRO_VIDEO_FORMAT_4SIF,
+  SCHRO_VIDEO_FORMAT_4CIF,
+  SCHRO_VIDEO_FORMAT_SD480I_60,
+  SCHRO_VIDEO_FORMAT_SD576I_50,
+  SCHRO_VIDEO_FORMAT_HD720P_60,
+  SCHRO_VIDEO_FORMAT_HD720P_50,
+  SCHRO_VIDEO_FORMAT_HD1080I_60,
+  SCHRO_VIDEO_FORMAT_HD1080I_50,
+  SCHRO_VIDEO_FORMAT_HD1080P_60,
+  SCHRO_VIDEO_FORMAT_HD1080P_50,
+  SCHRO_VIDEO_FORMAT_DC2K_24,
+  SCHRO_VIDEO_FORMAT_DC4K_24
+} SchroVideoFormatEnum;
+
+typedef enum _SchroChromaFormat {
+  SCHRO_CHROMA_444 = 0,
+  SCHRO_CHROMA_422,
+  SCHRO_CHROMA_420
+} SchroChromaFormat;
+
+#define SCHRO_CHROMA_FORMAT_H_SHIFT(format) (((format) == SCHRO_CHROMA_444)?0:1)
+#define SCHRO_CHROMA_FORMAT_V_SHIFT(format) (((format) == SCHRO_CHROMA_420)?1:0)
+
+typedef enum _SchroSignalRange {
+  SCHRO_SIGNAL_RANGE_CUSTOM = 0,
+  SCHRO_SIGNAL_RANGE_8BIT_FULL = 1,
+  SCHRO_SIGNAL_RANGE_8BIT_VIDEO = 2,
+  SCHRO_SIGNAL_RANGE_10BIT_VIDEO = 3,
+  SCHRO_SIGNAL_RANGE_12BIT_VIDEO = 4
+} SchroSignalRange;
+
+typedef enum _SchroColourSpec {
+  SCHRO_COLOUR_SPEC_CUSTOM = 0,
+  SCHRO_COLOUR_SPEC_SDTV_525 = 1,
+  SCHRO_COLOUR_SPEC_SDTV_625 = 2,
+  SCHRO_COLOUR_SPEC_HDTV = 3,
+  SCHRO_COLOUR_SPEC_CINEMA = 4
+} SchroColourSpec;
+
+typedef enum _SchroColourPrimaries {
+  SCHRO_COLOUR_PRIMARY_HDTV = 0,
+  SCHRO_COLOUR_PRIMARY_SDTV_525 = 1,
+  SCHRO_COLOUR_PRIMARY_SDTV_625 = 2,
+  SCHRO_COLOUR_PRIMARY_CINEMA = 3
+} SchroColourPrimaries;
+
+typedef enum _SchroColourMatrix {
+  SCHRO_COLOUR_MATRIX_HDTV = 0,
+  SCHRO_COLOUR_MATRIX_SDTV = 1,
+  SCHRO_COLOUR_MATRIX_REVERSIBLE = 2
+}SchroColourMatrix;
+
+typedef enum _SchroTransferFunction {
+  SCHRO_TRANSFER_CHAR_TV_GAMMA = 0,
+  SCHRO_TRANSFER_CHAR_EXTENDED_GAMUT = 1,
+  SCHRO_TRANSFER_CHAR_LINEAR = 2,
+  SCHRO_TRANSFER_CHAR_DCI_GAMMA = 3
+} SchroTransferFunction;
+
+
+
+typedef struct _DiracSequenceHeader DiracSequenceHeader;
+
+struct _DiracSequenceHeader {
+  int major_version;
+  int minor_version;
+  int profile;
+  int level;
+
+  int index;
+  int width;
+  int height;
+  int chroma_format;
+  
+  int interlaced;
+  int top_field_first;
+  
+  int frame_rate_numerator;
+  int frame_rate_denominator;
+  int aspect_ratio_numerator;
+  int aspect_ratio_denominator;
+    
+  int clean_width;
+  int clean_height;
+  int left_offset;
+  int top_offset;
+    
+  int luma_offset;
+  int luma_excursion;
+  int chroma_offset;
+  int chroma_excursion;
+    
+  int colour_primaries;
+  int colour_matrix;
+  int transfer_function;
+
+  int interlaced_coding;
+
+  int unused0;
+  int unused1;
+  int unused2;
+};  
+
+
+int dirac_sequence_header_parse (DiracSequenceHeader *header,
+    unsigned char *data, int length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/gst/videoparsers/gstdiracparse.c b/gst/videoparsers/gstdiracparse.c
new file mode 100644 (file)
index 0000000..4ddcd3a
--- /dev/null
@@ -0,0 +1,352 @@
+/* GStreamer
+ * Copyright (C) 2010 David Schleef <ds@schleef.org>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/**
+ * SECTION:element-gstdiracparse
+ *
+ * The gstdiracparse element does FIXME stuff.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch -v fakesrc ! gstdiracparse ! FIXME ! fakesink
+ * ]|
+ * FIXME Describe what the pipeline does.
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/base/gstbytereader.h>
+#include <gst/baseparse/gstbaseparse.h>
+#include "gstdiracparse.h"
+
+/* prototypes */
+
+
+static void gst_dirac_parse_set_property (GObject * object,
+    guint property_id, const GValue * value, GParamSpec * pspec);
+static void gst_dirac_parse_get_property (GObject * object,
+    guint property_id, GValue * value, GParamSpec * pspec);
+static void gst_dirac_parse_dispose (GObject * object);
+static void gst_dirac_parse_finalize (GObject * object);
+
+static gboolean gst_dirac_parse_start (GstBaseParse * parse);
+static gboolean gst_dirac_parse_stop (GstBaseParse * parse);
+static gboolean gst_dirac_parse_set_sink_caps (GstBaseParse * parse,
+    GstCaps * caps);
+static gboolean gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_dirac_parse_parse_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame);
+static gboolean gst_dirac_parse_convert (GstBaseParse * parse,
+    GstFormat src_format, gint64 src_value, GstFormat dest_format,
+    gint64 * dest_value);
+static gboolean gst_dirac_parse_event (GstBaseParse * parse, GstEvent * event);
+static gboolean gst_dirac_parse_src_event (GstBaseParse * parse,
+    GstEvent * event);
+static GstFlowReturn gst_dirac_parse_pre_push_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame);
+
+enum
+{
+  PROP_0
+};
+
+/* pad templates */
+
+static GstStaticPadTemplate gst_dirac_parse_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/unknown")
+    );
+
+static GstStaticPadTemplate gst_dirac_parse_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/unknown")
+    );
+
+/* class initialization */
+
+GST_BOILERPLATE (GstDiracParse, gst_dirac_parse, GstBaseParse,
+    GST_TYPE_BASE_PARSE);
+
+static void
+gst_dirac_parse_base_init (gpointer g_class)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_dirac_parse_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_dirac_parse_sink_template));
+
+  gst_element_class_set_details_simple (element_class, "FIXME",
+      "Generic", "FIXME", "David Schleef <ds@schleef.org>");
+}
+
+static void
+gst_dirac_parse_class_init (GstDiracParseClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstBaseParseClass *base_parse_class = GST_BASE_PARSE_CLASS (klass);
+
+  gobject_class->set_property = gst_dirac_parse_set_property;
+  gobject_class->get_property = gst_dirac_parse_get_property;
+  gobject_class->dispose = gst_dirac_parse_dispose;
+  gobject_class->finalize = gst_dirac_parse_finalize;
+  base_parse_class->start = GST_DEBUG_FUNCPTR (gst_dirac_parse_start);
+  base_parse_class->stop = GST_DEBUG_FUNCPTR (gst_dirac_parse_stop);
+  base_parse_class->set_sink_caps =
+      GST_DEBUG_FUNCPTR (gst_dirac_parse_set_sink_caps);
+  base_parse_class->check_valid_frame =
+      GST_DEBUG_FUNCPTR (gst_dirac_parse_check_valid_frame);
+  base_parse_class->parse_frame =
+      GST_DEBUG_FUNCPTR (gst_dirac_parse_parse_frame);
+  base_parse_class->convert = GST_DEBUG_FUNCPTR (gst_dirac_parse_convert);
+  base_parse_class->event = GST_DEBUG_FUNCPTR (gst_dirac_parse_event);
+  base_parse_class->src_event = GST_DEBUG_FUNCPTR (gst_dirac_parse_src_event);
+  base_parse_class->pre_push_frame =
+      GST_DEBUG_FUNCPTR (gst_dirac_parse_pre_push_frame);
+
+}
+
+static void
+gst_dirac_parse_init (GstDiracParse * diracparse,
+    GstDiracParseClass * diracparse_class)
+{
+  gst_base_parse_set_min_frame_size (GST_BASE_PARSE (diracparse), 13);
+
+}
+
+void
+gst_dirac_parse_set_property (GObject * object, guint property_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstDiracParse *diracparse;
+
+  g_return_if_fail (GST_IS_DIRAC_PARSE (object));
+  diracparse = GST_DIRAC_PARSE (object);
+
+  switch (property_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+void
+gst_dirac_parse_get_property (GObject * object, guint property_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstDiracParse *diracparse;
+
+  g_return_if_fail (GST_IS_DIRAC_PARSE (object));
+  diracparse = GST_DIRAC_PARSE (object);
+
+  switch (property_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+void
+gst_dirac_parse_dispose (GObject * object)
+{
+  GstDiracParse *diracparse;
+
+  g_return_if_fail (GST_IS_DIRAC_PARSE (object));
+  diracparse = GST_DIRAC_PARSE (object);
+
+  /* clean up as possible.  may be called multiple times */
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+void
+gst_dirac_parse_finalize (GObject * object)
+{
+  GstDiracParse *diracparse;
+
+  g_return_if_fail (GST_IS_DIRAC_PARSE (object));
+  diracparse = GST_DIRAC_PARSE (object);
+
+  /* clean up object here */
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static gboolean
+gst_dirac_parse_start (GstBaseParse * parse)
+{
+  return TRUE;
+}
+
+static gboolean
+gst_dirac_parse_stop (GstBaseParse * parse)
+{
+  return TRUE;
+}
+
+static gboolean
+gst_dirac_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
+{
+  /* Called when sink caps are set */
+  return TRUE;
+}
+
+static gboolean
+gst_dirac_parse_frame_header (GstDiracParse * diracparse,
+    GstBuffer * buffer, guint * framesize)
+{
+  int next_header;
+
+  next_header = GST_READ_UINT32_BE (GST_BUFFER_DATA (buffer) + 5);
+
+  *framesize = next_header;
+  return TRUE;
+}
+
+static gboolean
+gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+{
+  GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (frame->buffer);
+  GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
+  int off;
+  guint32 next_header;
+  gboolean sync;
+  gboolean drain;
+
+  if (G_UNLIKELY (GST_BUFFER_SIZE (frame->buffer) < 13))
+    return FALSE;
+
+  off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
+      0x42424344, 0, GST_BUFFER_SIZE (frame->buffer));
+
+  if (off < 0) {
+    *skipsize = GST_BUFFER_SIZE (frame->buffer) - 3;
+    return FALSE;
+  }
+
+  GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off);
+
+  if (off > 0) {
+    GST_ERROR ("skipping %d", off);
+    *skipsize = off;
+    return FALSE;
+  }
+
+  if (!gst_dirac_parse_frame_header (diracparse, frame->buffer, framesize)) {
+    GST_ERROR ("bad header");
+    *skipsize = 3;
+    return FALSE;
+  }
+
+  GST_LOG ("framesize %d", *framesize);
+
+  sync = GST_BASE_PARSE_FRAME_SYNC (frame);
+  drain = GST_BASE_PARSE_FRAME_DRAIN (frame);
+
+  if (!sync && !drain) {
+    guint32 next_sync_word;
+
+    next_header = GST_READ_UINT32_BE (GST_BUFFER_DATA (frame->buffer) + 5);
+    GST_LOG ("next header %d", next_header);
+
+    if (!gst_byte_reader_skip (&reader, next_header) ||
+        !gst_byte_reader_get_uint32_be (&reader, &next_sync_word)) {
+      gst_base_parse_set_min_frame_size (parse, next_header + 4);
+      *skipsize = 0;
+      return FALSE;
+    } else {
+      if (next_sync_word != 0x42424344) {
+        *skipsize = 3;
+        return FALSE;
+      } else {
+        gst_base_parse_set_min_frame_size (parse, next_header);
+
+      }
+    }
+  }
+
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
+{
+  //GstDiracParse * diracparse = GST_DIRAC_PARSE (parse);
+
+  /* Called when processing incoming buffers.  Function should parse
+     a checked frame. */
+  /* MUST implement */
+
+  if (GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse)) == NULL) {
+    GstCaps *caps = gst_caps_new_simple ("video/x-dirac", NULL);
+
+    gst_buffer_set_caps (frame->buffer, caps);
+    gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
+    gst_caps_unref (caps);
+
+  }
+
+  gst_base_parse_set_min_frame_size (parse, 13);
+
+  return GST_FLOW_OK;
+}
+
+static gboolean
+gst_dirac_parse_convert (GstBaseParse * parse, GstFormat src_format,
+    gint64 src_value, GstFormat dest_format, gint64 * dest_value)
+{
+  /* Convert between formats */
+
+  return FALSE;
+}
+
+static gboolean
+gst_dirac_parse_event (GstBaseParse * parse, GstEvent * event)
+{
+  /* Sink pad event handler */
+
+  return FALSE;
+}
+
+static gboolean
+gst_dirac_parse_src_event (GstBaseParse * parse, GstEvent * event)
+{
+  /* Src pad event handler */
+
+  return FALSE;
+}
+
+static GstFlowReturn
+gst_dirac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
+{
+
+  return GST_FLOW_OK;
+}
diff --git a/gst/videoparsers/gstdiracparse.h b/gst/videoparsers/gstdiracparse.h
new file mode 100644 (file)
index 0000000..64a1b81
--- /dev/null
@@ -0,0 +1,52 @@
+/* GStreamer
+ * Copyright (C) 2010 REAL_NAME <EMAIL_ADDRESS>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GST_DIRAC_PARSE_H_
+#define _GST_DIRAC_PARSE_H_
+
+#include <gst/gst.h>
+#include <gst/baseparse/gstbaseparse.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_DIRAC_PARSE   (gst_dirac_parse_get_type())
+#define GST_DIRAC_PARSE(obj)   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DIRAC_PARSE,GstDiracParse))
+#define GST_DIRAC_PARSE_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DIRAC_PARSE,GstDiracParseClass))
+#define GST_IS_DIRAC_PARSE(obj)   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DIRAC_PARSE))
+#define GST_IS_DIRAC_PARSE_CLASS(obj)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DIRAC_PARSE))
+
+typedef struct _GstDiracParse GstDiracParse;
+typedef struct _GstDiracParseClass GstDiracParseClass;
+
+struct _GstDiracParse
+{
+  GstBaseParse base_diracparse;
+
+};
+
+struct _GstDiracParseClass
+{
+  GstBaseParseClass base_diracparse_class;
+};
+
+GType gst_dirac_parse_get_type (void);
+
+G_END_DECLS
+
+#endif
index 463e417..cfd8a48 100644 (file)
@@ -1,5 +1,6 @@
 /* GStreamer video parsers
  * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
+ * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,6 +24,7 @@
 
 #include "gsth263parse.h"
 #include "gsth264parse.h"
+#include "gstdiracparse.h"
 
 static gboolean
 plugin_init (GstPlugin * plugin)
@@ -33,6 +35,8 @@ plugin_init (GstPlugin * plugin)
       GST_RANK_NONE, GST_TYPE_H263_PARSE);
   ret = gst_element_register (plugin, "h264parse",
       GST_RANK_NONE, GST_TYPE_H264_PARSE);
+  ret = gst_element_register (plugin, "diracparse",
+      GST_RANK_NONE, GST_TYPE_DIRAC_PARSE);
 
   return ret;
 }