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
+
--- /dev/null
+
+#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;
+}
--- /dev/null
+
+#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
+
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
/* 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
#include "gsth263parse.h"
#include "gsth264parse.h"
+#include "gstdiracparse.h"
static gboolean
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;
}