mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
videoparsers: Add dirac parser
This commit is contained in:
parent
fedcf43e29
commit
e9ea237d03
6 changed files with 1090 additions and 2 deletions
|
@ -1,11 +1,15 @@
|
||||||
plugin_LTLIBRARIES = libgsth263parse.la
|
plugin_LTLIBRARIES = libgsth263parse.la
|
||||||
|
|
||||||
libgsth263parse_la_SOURCES = plugin.c \
|
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_CFLAGS = $(GST_CFLAGS)
|
||||||
libgsth263parse_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
libgsth263parse_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
||||||
libgsth263parse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgsth263parse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
libgsth263parse_la_LIBTOOLFLAGS = --tag=disable-static
|
libgsth263parse_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
noinst_HEADERS = gsth263parse.h h263parse.h \
|
noinst_HEADERS = gsth263parse.h h263parse.h \
|
||||||
gsth264parse.h h264parse.h
|
gsth264parse.h h264parse.h \
|
||||||
|
gstdiracparse.h dirac_parse.h
|
||||||
|
|
||||||
|
|
498
gst/videoparsers/dirac_parse.c
Normal file
498
gst/videoparsers/dirac_parse.c
Normal file
|
@ -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;
|
||||||
|
}
|
178
gst/videoparsers/dirac_parse.h
Normal file
178
gst/videoparsers/dirac_parse.h
Normal file
|
@ -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
|
||||||
|
|
352
gst/videoparsers/gstdiracparse.c
Normal file
352
gst/videoparsers/gstdiracparse.c
Normal file
|
@ -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;
|
||||||
|
}
|
52
gst/videoparsers/gstdiracparse.h
Normal file
52
gst/videoparsers/gstdiracparse.h
Normal file
|
@ -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
|
|
@ -1,5 +1,6 @@
|
||||||
/* GStreamer video parsers
|
/* GStreamer video parsers
|
||||||
* Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
|
|
||||||
#include "gsth263parse.h"
|
#include "gsth263parse.h"
|
||||||
#include "gsth264parse.h"
|
#include "gsth264parse.h"
|
||||||
|
#include "gstdiracparse.h"
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_init (GstPlugin * plugin)
|
plugin_init (GstPlugin * plugin)
|
||||||
|
@ -33,6 +35,8 @@ plugin_init (GstPlugin * plugin)
|
||||||
GST_RANK_NONE, GST_TYPE_H263_PARSE);
|
GST_RANK_NONE, GST_TYPE_H263_PARSE);
|
||||||
ret = gst_element_register (plugin, "h264parse",
|
ret = gst_element_register (plugin, "h264parse",
|
||||||
GST_RANK_NONE, GST_TYPE_H264_PARSE);
|
GST_RANK_NONE, GST_TYPE_H264_PARSE);
|
||||||
|
ret = gst_element_register (plugin, "diracparse",
|
||||||
|
GST_RANK_NONE, GST_TYPE_DIRAC_PARSE);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue