X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=gst-plugins-base-subtitles0.10%2Fext%2Fogg%2Fdirac_parse.c;fp=gst-plugins-base-subtitles0.10%2Fext%2Fogg%2Fdirac_parse.c;h=3a3193d9258694c0beb610d2d546a910e209a68d;hb=57ba96e291a055f69dbfd4ae9f1ae2390e36986e;hp=0000000000000000000000000000000000000000;hpb=be2c98fb83895d10ac44af7b9a9c3e00ca54bf49;p=mafwsubrenderer diff --git a/gst-plugins-base-subtitles0.10/ext/ogg/dirac_parse.c b/gst-plugins-base-subtitles0.10/ext/ogg/dirac_parse.c new file mode 100644 index 0000000..3a3193d --- /dev/null +++ b/gst-plugins-base-subtitles0.10/ext/ogg/dirac_parse.c @@ -0,0 +1,498 @@ + +#include "dirac_parse.h" +#include + +#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; +}