diff --git a/docs/libs/gst-plugins-bad-libs-docs.sgml b/docs/libs/gst-plugins-bad-libs-docs.sgml
index 0c9994160e..cf6885b44a 100644
--- a/docs/libs/gst-plugins-bad-libs-docs.sgml
+++ b/docs/libs/gst-plugins-bad-libs-docs.sgml
@@ -30,6 +30,7 @@
+
diff --git a/docs/libs/gst-plugins-bad-libs-sections.txt b/docs/libs/gst-plugins-bad-libs-sections.txt
index 09a395dab4..b949137dfe 100644
--- a/docs/libs/gst-plugins-bad-libs-sections.txt
+++ b/docs/libs/gst-plugins-bad-libs-sections.txt
@@ -117,6 +117,41 @@ gst_mpeg_video_parse_quant_matrix_extension
+
+gstmpeg4parser
+mpeg4parser
+gst/codecparsers/gstmpeg4parser.h
+GstMpeg4StartCode
+GstMpeg4VisualObjectType
+GstMpeg4AspectRatioInfo
+GstMpeg4ParseResult
+GstMpeg4VideoObjectCodingType
+GstMpeg4ChromaFormat
+GstMpeg4VideoObjectLayerShape
+GstMpeg4SpriteEnable
+GstMpeg4Profile
+GstMpeg4Level
+GstMpeg4VisualObjectSequence
+GstMpeg4VisualObject
+GstMpeg4VideoSignalType
+GstMpeg4VideoPlaneShortHdr
+GstMpeg4VideoObjectLayer
+GstMpeg4SpriteTrajectory
+GstMpeg4GroupOfVOP
+GstMpeg4VideoObjectPlane
+GstMpeg4Packet
+GstMpeg4VideoPacketHdr
+gst_mpeg4_parse
+gst_mpeg4_parse_video_object_plane
+gst_mpeg4_parse_group_of_vop
+gst_mpeg4_parse_video_object_layer
+gst_mpeg4_parse_visual_object
+gst_mpeg4_parse_visual_object_sequence
+gst_mpeg4_parse_video_packet_header
+
+
+
+
gstphotography
GST_PHOTOGRAPHY_AUTOFOCUS_DONE
diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am
index f65311dade..2593f85c51 100644
--- a/gst-libs/gst/codecparsers/Makefile.am
+++ b/gst-libs/gst/codecparsers/Makefile.am
@@ -1,7 +1,8 @@
lib_LTLIBRARIES = libgstcodecparsers-@GST_MAJORMINOR@.la
libgstcodecparsers_@GST_MAJORMINOR@_la_SOURCES = \
- gstmpegvideoparser.c gsth264parser.c gstvc1parser.c parserutils.c
+ gstmpegvideoparser.c gsth264parser.c gstvc1parser.c gstmpeg4parser.c \
+ parserutils.c
libgstcodecparsers_@GST_MAJORMINOR@includedir = \
$(includedir)/gstreamer-@GST_MAJORMINOR@/gst/codecparsers
@@ -9,7 +10,7 @@ libgstcodecparsers_@GST_MAJORMINOR@includedir = \
noinst_HEADERS = parserutils.h
libgstcodecparsers_@GST_MAJORMINOR@include_HEADERS = \
- gstmpegvideoparser.h gsth264parser.h gstvc1parser.h
+ gstmpegvideoparser.h gsth264parser.h gstvc1parser.h gstmpeg4parser.h
libgstcodecparsers_@GST_MAJORMINOR@_la_CFLAGS = \
$(GST_PLUGINS_BAD_CFLAGS) \
diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c
new file mode 100644
index 0000000000..6181a5b7e9
--- /dev/null
+++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c
@@ -0,0 +1,1666 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier
+ *
+ * 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:gstmpeg4parser
+ * @short_description: Convenience library for parsing mpeg4 part 2 video
+ * bitstream.
+ *
+ * For more details about the structures, you can refer to the
+ * specifications: ISO-IEC-14496-2_2004_MPEG4_VISUAL.pdf
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+
+
+#include "gstmpeg4parser.h"
+#include "parserutils.h"
+
+#ifndef GST_DISABLE_GST_DEBUG
+
+#define GST_CAT_DEFAULT ensure_debug_category()
+
+static GstDebugCategory *
+ensure_debug_category (void)
+{
+ static gsize cat_gonce = 0;
+
+ if (g_once_init_enter (&cat_gonce)) {
+ gsize cat_done;
+
+ cat_done = (gsize) _gst_debug_category_new ("codecparsers_mpeg4", 0,
+ "GstMpeg4 codec parsing library");
+
+ g_once_init_leave (&cat_gonce, cat_done);
+ }
+
+ return (GstDebugCategory *) cat_gonce;
+}
+
+#else
+
+#define ensure_debug_category() /* NOOP */
+
+#endif /* GST_DISABLE_GST_DEBUG */
+
+#define CHECK_MARKER(br) G_STMT_START { \
+ guint8 marker;\
+ if (!gst_bit_reader_get_bits_uint8 (br, &marker, 1)) { \
+ GST_WARNING ("failed to read marker bit"); \
+ goto failed; \
+ } else if (!marker) {\
+ GST_WARNING ("Wrong marker bit"); \
+ goto failed;\
+ }\
+} G_STMT_END
+
+#define MARKER_UNCHECKED(br) G_STMT_START { \
+ if (!gst_bit_reader_get_bits_uint8_unchecked (br, 1)) { \
+ GST_WARNING ("Wrong marker bit"); \
+ goto failed; \
+ } \
+} G_STMT_END
+
+#define CHECK_REMAINING(br, needed) G_STMT_START { \
+ if (gst_bit_reader_get_remaining (br) < needed) \
+ goto failed; \
+} G_STMT_END
+
+const guint8 default_intra_quant_mat[64] = {
+ 8, 17, 18, 19, 21, 23, 25, 27,
+ 17, 18, 19, 21, 23, 25, 27, 28,
+ 20, 21, 22, 23, 24, 26, 28, 30,
+ 21, 22, 23, 24, 26, 28, 30, 32,
+ 22, 23, 24, 26, 28, 30, 32, 35,
+ 23, 24, 26, 28, 30, 32, 35, 38,
+ 25, 26, 28, 30, 32, 35, 38, 41,
+ 27, 28, 30, 32, 35, 38, 41, 45
+};
+
+const guint8 default_non_intra_quant_mat[64] = {
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 19, 20, 21, 22, 23, 24, 26, 27,
+ 20, 21, 22, 23, 25, 26, 27, 28,
+ 21, 22, 23, 24, 26, 27, 28, 30,
+ 22, 23, 24, 26, 27, 28, 30, 31,
+ 23, 24, 25, 27, 28, 30, 31, 33,
+};
+
+const guint8 mpeg4_zigzag_8x8[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static VLCTable mpeg4_dmv_size_vlc_table[] = {
+ {0x00, 2, 0},
+ {0x02, 3, 1},
+ {0x03, 3, 2},
+ {0x04, 3, 3},
+ {0x05, 3, 4},
+ {0x06, 3, 5},
+ {0x0e, 4, 6},
+ {0x1e, 5, 7},
+ {0x3e, 6, 8},
+ {0x7e, 7, 9},
+ {0xfe, 8, 10},
+ {0x1fe, 9, 11},
+ {0x3fe, 10, 12},
+ {0x7fe, 11, 13},
+ {0xffe, 12, 14}
+};
+
+static void
+mpeg4_util_par_from_info (guint8 aspect_ratio_info, guint8 * par_width,
+ guint8 * par_height)
+{
+ switch (aspect_ratio_info) {
+ case 0x02:
+ *par_width = 12;
+ *par_height = 11;
+ break;
+ case 0x03:
+ *par_width = 10;
+ *par_height = 11;
+ break;
+ case 0x04:
+ *par_width = 16;
+ *par_height = 11;
+ break;
+ case 0x05:
+ *par_width = 40;
+ *par_height = 33;
+ break;
+
+ case 0x01:
+ default:
+ *par_width = 1;
+ *par_height = 1;
+ }
+}
+
+static gboolean
+parse_quant (GstBitReader * br, guint8 quant_mat[64],
+ const guint8 default_quant_mat[64], guint8 * load_quant_mat)
+{
+ READ_UINT8 (br, *load_quant_mat, 1);
+ if (*load_quant_mat) {
+ guint i;
+ guint8 val;
+
+ val = 1;
+ for (i = 0; i < 64; i++) {
+
+ if (val != 0)
+ READ_UINT8 (br, val, 8);
+
+ if (val == 0) {
+ if (i == 0)
+ goto invalid_quant_mat;
+ quant_mat[mpeg4_zigzag_8x8[i]] = quant_mat[mpeg4_zigzag_8x8[i - 1]];
+ } else
+ quant_mat[mpeg4_zigzag_8x8[i]] = val;
+ }
+ } else
+ memcpy (quant_mat, default_quant_mat, 64);
+
+ return TRUE;
+
+failed:
+ GST_WARNING ("failed parsing quant matrix");
+ return FALSE;
+
+invalid_quant_mat:
+ GST_WARNING ("the first value should be non zero");
+ goto failed;
+}
+
+static gboolean
+parse_signal_type (GstBitReader * br, GstMpeg4VideoSignalType * signal_type)
+{
+ READ_UINT8 (br, signal_type->type, 1);
+
+ if (signal_type->type) {
+
+ READ_UINT8 (br, signal_type->format, 3);
+ READ_UINT8 (br, signal_type->range, 1);
+ READ_UINT8 (br, signal_type->color_description, 1);
+
+ if (signal_type->color_description) {
+ READ_UINT8 (br, signal_type->color_primaries, 8);
+ READ_UINT8 (br, signal_type->transfer_characteristics, 8);
+ READ_UINT8 (br, signal_type->matrix_coefficients, 8);
+ }
+ }
+
+ return TRUE;
+
+failed:
+ GST_WARNING ("failed parsing \"Video Signal Type\"");
+
+ return FALSE;
+}
+
+static gboolean
+parse_sprite_trajectory (GstBitReader * br,
+ GstMpeg4SpriteTrajectory * sprite_traj, guint no_of_sprite_warping_points)
+{
+ guint i, length;
+
+ for (i = 0; i < no_of_sprite_warping_points; i++) {
+
+ if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
+ G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
+ goto failed;
+
+ if (length)
+ READ_UINT16 (br, sprite_traj->vop_ref_points[i], length);
+ CHECK_MARKER (br);
+
+ if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
+ G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
+ goto failed;
+
+ if (length)
+ READ_UINT16 (br, sprite_traj->sprite_ref_points[i], length);
+ CHECK_MARKER (br);
+ }
+
+ return TRUE;
+
+failed:
+ GST_WARNING ("Could not parse the sprite trajectory");
+ return FALSE;
+}
+
+static guint
+find_psc (GstByteReader * br)
+{
+ guint psc_pos = -1, psc;
+
+ if (!gst_byte_reader_peek_uint24_be (br, &psc))
+ goto failed;
+
+ /* Scan for the picture start code (22 bits - 0x0020) */
+ while ((gst_byte_reader_get_remaining (br) >= 3)) {
+ if (gst_byte_reader_peek_uint24_be (br, &psc) &&
+ ((psc & 0xffffc0) == 0x000080)) {
+ psc_pos = gst_byte_reader_get_pos (br);
+ break;
+ } else
+ gst_byte_reader_skip (br, 1);
+ }
+
+failed:
+
+ return psc_pos;
+}
+
+static inline guint8
+compute_resync_marker_size (const GstMpeg4VideoObjectPlane * vop)
+{
+ guint8 off;
+ /* FIXME handle the binary only shape case */
+ switch (vop->coding_type) {
+ case (GST_MPEG4_I_VOP):
+ off = 16;
+
+ break;
+ case (GST_MPEG4_S_VOP):
+ case (GST_MPEG4_P_VOP):
+ off = 15 + vop->fcode_forward;
+
+ break;
+ case (GST_MPEG4_B_VOP):
+ off = MAX (15 + MAX (vop->fcode_forward, vop->fcode_backward), 17);
+
+ break;
+ default:
+ return -1;
+ }
+
+ return off++; /* Take the following 1 into account */
+}
+
+/********** API **********/
+
+/**
+ * gst_mpeg4_parse:
+ * @packet: The #GstMpeg4Packet to fill
+ * @skip_user_data: %TRUE to skip user data packet %FALSE otherwize
+ * @offset: offset from which to start the parsing
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data and fills @packet with the information of the next packet
+ * found.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
+ const guint8 * data, guint offset, gsize size)
+{
+ gint off1, off2;
+ GstByteReader br;
+
+ gst_byte_reader_init (&br, data, size);
+
+ g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
+
+ ensure_debug_category ();
+
+ if (size - offset <= 4) {
+ GST_DEBUG ("Can't parse, buffer is to small size %d at offset %d", size,
+ offset);
+ return GST_MPEG4_PARSER_ERROR;
+ }
+
+ off1 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
+ offset, size - offset);
+
+ if (off1 < 0) {
+ GST_DEBUG ("No start code prefix in this buffer");
+ return GST_MPEG4_PARSER_NO_PACKET;
+ }
+
+ /* Recursively skip user data if needed */
+ if (skip_user_data && data[off1 + 3] == GST_MPEG4_USER_DATA)
+ return gst_mpeg4_parse (packet, skip_user_data, data, off1 + 3,
+ size - off1 - 3);
+
+ packet->offset = off1 + 3;
+ packet->data = data;
+ packet->type = (GstMpeg4StartCode) (data[off1 + 3]);
+
+ off2 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
+ off1 + 4, size - off1 - 4);
+
+ if (off2 < 0) {
+ GST_DEBUG ("Packet start %d, No end found", off1 + 4);
+
+ packet->size = G_MAXUINT;
+ return GST_MPEG4_PARSER_NO_PACKET_END;
+ }
+
+ packet->size = (gsize) off2 - off1 - 3;
+
+ GST_DEBUG ("Complete packet of type %x found at: %d, Size: %d",
+ packet->type, packet->offset, packet->size);
+ return GST_MPEG4_PARSER_OK;
+
+}
+
+/**
+ * gst_h263_parse:
+ * @packet: The #GstMpeg4Packet to fill
+ * @offset: offset from which to start the parsing
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data and fills @packet with the information of the next packet
+ * found.
+ *
+ * Note that the type of the packet is meaningless in this case.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_h263_parse (GstMpeg4Packet * packet,
+ const guint8 * data, guint offset, gsize size)
+{
+ gint off1, off2;
+ GstByteReader br;
+
+ gst_byte_reader_init (&br, data, size);
+
+ g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
+
+ ensure_debug_category ();
+
+ if (size - offset < 3) {
+ GST_DEBUG ("Can't parse, buffer is to small size %d at offset %d", size,
+ offset);
+ return GST_MPEG4_PARSER_ERROR;
+ }
+
+ off1 = find_psc (&br);
+
+ if (off1 < 0) {
+ GST_DEBUG ("No start code prefix in this buffer");
+ return GST_MPEG4_PARSER_NO_PACKET;
+ }
+
+ packet->offset = off1;
+ packet->data = data;
+
+ off2 = find_psc (&br);
+
+ if (off2 < 0) {
+ GST_DEBUG ("Packet start %d, No end found", off1);
+
+ packet->size = G_MAXUINT;
+ return GST_MPEG4_PARSER_NO_PACKET_END;
+ }
+
+ packet->size = (gsize) off2 - off1;
+
+ GST_DEBUG ("Complete packet found at: %d, Size: %d",
+ packet->offset, packet->size);
+
+ return GST_MPEG4_PARSER_OK;
+}
+
+/**
+ * gst_mpeg4_parse_visual_object_sequence:
+ * @vos: The #GstMpeg4VisualObjectSequence structure to fill
+ * @data: The data to parse, should contain the visual_object_sequence_start_code
+ * but not the start code prefix
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the visual object sequence packet, and fills
+ * the @vos structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object_sequence (GstMpeg4VisualObjectSequence * vos,
+ const guint8 * data, gsize size)
+{
+ guint8 vos_start_code;
+ GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+ g_return_val_if_fail (vos != NULL, GST_MPEG4_PARSER_ERROR);
+
+ READ_UINT8 (&br, vos_start_code, 8);
+ if (vos_start_code != GST_MPEG4_VISUAL_OBJ_SEQ_START)
+ goto wrong_start_code;
+
+ READ_UINT8 (&br, vos->profile_and_level_indication, 8);
+
+ switch (vos->profile_and_level_indication) {
+ case 0x01:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x02:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x03:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0x08:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL0;
+ break;
+ case 0x10:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL0;
+ break;
+ case 0x11:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x12:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x21:
+ vos->profile = GST_MPEG4_PROFILE_CORE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x22:
+ vos->profile = GST_MPEG4_PROFILE_CORE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x32:
+ vos->profile = GST_MPEG4_PROFILE_MAIN;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x33:
+ vos->profile = GST_MPEG4_PROFILE_MAIN;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0x34:
+ vos->profile = GST_MPEG4_PROFILE_MAIN;
+ vos->level = GST_MPEG4_LEVEL4;
+ break;
+ case 0x42:
+ vos->profile = GST_MPEG4_PROFILE_N_BIT;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x51:
+ vos->profile = GST_MPEG4_PROFILE_SCALABLE_TEXTURE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x61:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x62:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x63:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x64:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x71:
+ vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x72:
+ vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x81:
+ vos->profile = GST_MPEG4_PROFILE_HYBRYD;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x82:
+ vos->profile = GST_MPEG4_PROFILE_HYBRYD;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x91:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0x92:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0x93:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0x94:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL4;
+ break;
+ case 0xa1:
+ vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xa2:
+ vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xa3:
+ vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xb1:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xb2:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xb3:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xb4:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+ vos->level = GST_MPEG4_LEVEL4;
+ break;
+ case 0xc1:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xc2:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xc3:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xd1:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xd2:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xd3:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xe1:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xe2:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xe3:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xe4:
+ vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL4;
+ break;
+ case 0xe5:
+ vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xe6:
+ vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xe7:
+ vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xe8:
+ vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+ vos->level = GST_MPEG4_LEVEL4;
+ break;
+ case 0xf0:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL0;
+ break;
+ case 0xf1:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xf2:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xf3:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xf4:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL4;
+ break;
+ case 0xf5:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL5;
+ break;
+ case 0xf7:
+ vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ vos->level = GST_MPEG4_LEVEL3b;
+ break;
+ case 0xf8:
+ vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL0;
+ break;
+ case 0xf9:
+ vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL1;
+ break;
+ case 0xfa:
+ vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL2;
+ break;
+ case 0xfb:
+ vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL3;
+ break;
+ case 0xfc:
+ vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL4;
+ break;
+ case 0xfd:
+ vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+ vos->level = GST_MPEG4_LEVEL5;
+ break;
+ default:
+ vos->profile = GST_MPEG4_PROFILE_RESERVED;
+ vos->level = GST_MPEG4_LEVEL_RESERVED;
+ break;
+ }
+
+ return GST_MPEG4_PARSER_OK;
+
+wrong_start_code:
+ GST_WARNING ("got buffer with wrong start code");
+ return GST_MPEG4_PARSER_ERROR;
+
+failed:
+ GST_WARNING ("failed parsing \"Visual Object\"");
+ return GST_MPEG4_PARSER_ERROR;
+}
+
+/**
+ * gst_mpeg4_parse_visual_object:
+ * @vo: The #GstMpeg4VisualObject structure to fill
+ * @signal_type: The #GstMpeg4VideoSignalType to fill or %NULL
+ * @data: The data to parse, should contain the vo_start_code
+ * but not the start code prefix
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the visual object packet, and fills
+ * the @vo structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object (GstMpeg4VisualObject * vo,
+ GstMpeg4VideoSignalType * signal_type, const guint8 * data, gsize size)
+{
+ guint8 vo_start_code, type;
+ GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+ g_return_val_if_fail (vo != NULL, GST_MPEG4_PARSER_ERROR);
+
+ GST_DEBUG ("Parsing visual object");
+
+ READ_UINT8 (&br, vo_start_code, 8);
+ if (vo_start_code != GST_MPEG4_VISUAL_OBJ)
+ goto wrong_start_code;
+
+ /* set default values */
+ vo->verid = 0x1;
+ vo->priority = 1;
+
+ READ_UINT8 (&br, vo->is_identifier, 1);
+ if (vo->is_identifier) {
+ READ_UINT8 (&br, vo->verid, 4);
+ READ_UINT8 (&br, vo->priority, 3);
+ }
+
+ READ_UINT8 (&br, type, 4);
+ vo->type = type;
+
+ if ((type == GST_MPEG4_VIDEO_ID ||
+ type == GST_MPEG4_STILL_TEXTURE_ID) && signal_type) {
+
+ if (!parse_signal_type (&br, signal_type))
+ goto failed;
+
+ } else if (signal_type) {
+ signal_type->type = 0;
+ }
+
+ return GST_MPEG4_PARSER_OK;
+
+wrong_start_code:
+ GST_WARNING ("got buffer with wrong start code");
+ return GST_MPEG4_PARSER_ERROR;
+
+failed:
+ GST_WARNING ("failed parsing \"Visual Object\"");
+ return GST_MPEG4_PARSER_ERROR;
+}
+
+/**
+ * gst_mpeg4_parse_video_object_layer:
+ * @vol: The #GstMpeg4VideoObjectLayer structure to fill
+ * @vo: The #GstMpeg4VisualObject currently being parsed or %NULL
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the video object layer packet, and fills
+ * the @vol structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer * vol,
+ GstMpeg4VisualObject * vo, const guint8 * data, gsize size)
+{
+ guint8 video_object_layer_start_code;
+ /* Used for enums types */
+ guint8 tmp;
+ GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+ g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
+
+ GST_DEBUG ("Parsing video object layer");
+
+ READ_UINT8 (&br, video_object_layer_start_code, 8);
+ if (!(video_object_layer_start_code >= GST_MPEG4_VIDEO_LAYER_FIRST &&
+ video_object_layer_start_code <= GST_MPEG4_VIDEO_LAYER_LAST))
+ goto wrong_start_code;
+
+ /* set default values */
+ if (vo) {
+ vol->verid = vo->verid;
+ vol->priority = vo->priority;
+ }
+
+ vol->low_delay = FALSE;
+ vol->chroma_format = 1;
+ vol->vbv_parameters = FALSE;
+ vol->quant_precision = 5;
+ vol->bits_per_pixel = 8;
+ vol->quarter_sample = FALSE;
+ vol->newpred_enable = FALSE;
+ vol->interlaced = 0;
+ vol->width = 0;
+ vol->height = 0;
+
+ READ_UINT8 (&br, vol->random_accessible_vol, 1);
+ READ_UINT8 (&br, vol->video_object_type_indication, 8);
+
+ READ_UINT8 (&br, vol->is_object_layer_identifier, 1);
+ if (vol->is_object_layer_identifier) {
+ READ_UINT8 (&br, vol->verid, 4);
+ READ_UINT8 (&br, vol->priority, 3);
+ }
+
+ READ_UINT8 (&br, tmp, 4);
+ vol->aspect_ratio_info = tmp;
+ if (vol->aspect_ratio_info != GST_MPEG4_EXTENDED_PAR) {
+ mpeg4_util_par_from_info (vol->aspect_ratio_info, &vol->par_width,
+ &vol->par_height);
+
+ } else {
+ READ_UINT8 (&br, vol->par_width, 8);
+ CHECK_ALLOWED (vol->par_width, 1, 255);
+ READ_UINT8 (&br, vol->par_height, 8);
+ CHECK_ALLOWED (vol->par_height, 1, 255);
+ }
+ GST_DEBUG ("Pixel aspect ratio %d/%d", vol->par_width, vol->par_width);
+
+ READ_UINT8 (&br, vol->control_parameters, 1);
+ if (vol->control_parameters) {
+ guint8 chroma_format;
+
+ READ_UINT8 (&br, chroma_format, 2);
+ vol->chroma_format = chroma_format;
+ READ_UINT8 (&br, vol->low_delay, 1);
+
+ READ_UINT8 (&br, vol->vbv_parameters, 1);
+ if (vol->vbv_parameters) {
+ CHECK_REMAINING (&br, 79);
+
+ vol->first_half_bitrate =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+ MARKER_UNCHECKED (&br);
+
+ vol->latter_half_bitrate =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+ MARKER_UNCHECKED (&br);
+
+ vol->bit_rate =
+ (vol->first_half_bitrate << 15) | vol->latter_half_bitrate;
+
+ vol->first_half_vbv_buffer_size =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+ MARKER_UNCHECKED (&br);
+
+ vol->latter_half_vbv_buffer_size =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
+ MARKER_UNCHECKED (&br);
+
+ vol->vbv_buffer_size = (vol->first_half_vbv_buffer_size << 15) |
+ vol->latter_half_vbv_buffer_size;
+
+ vol->first_half_vbv_occupancy =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 11);
+ MARKER_UNCHECKED (&br);
+
+ vol->latter_half_vbv_occupancy =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+ MARKER_UNCHECKED (&br);
+ }
+ }
+
+ READ_UINT8 (&br, tmp, 2);
+ vol->shape = tmp;
+
+ if (vol->shape == GST_MPEG4_GRAYSCALE) {
+ /* TODO support grayscale shapes, for now we just pass */
+
+ /* Something the standard starts to define... */
+ GST_WARNING ("Grayscale shaped not supported");
+ goto failed;
+ }
+
+ if (vol->shape == GST_MPEG4_GRAYSCALE && vol->verid != 0x01)
+ READ_UINT8 (&br, vol->shape_extension, 4);
+
+ CHECK_REMAINING (&br, 19);
+
+ MARKER_UNCHECKED (&br);
+ vol->vop_time_increment_resolution =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 16);
+ CHECK_ALLOWED (vol->vop_time_increment_resolution, 1, G_MAXUINT16);
+ vol->vop_time_increment_bits =
+ g_bit_storage (vol->vop_time_increment_resolution);
+
+ MARKER_UNCHECKED (&br);
+ vol->fixed_vop_rate = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ if (vol->fixed_vop_rate)
+ READ_UINT16 (&br, vol->fixed_vop_time_increment,
+ vol->vop_time_increment_bits);
+
+ if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+ if (vol->shape == GST_MPEG4_RECTANGULAR) {
+ CHECK_REMAINING (&br, 29);
+
+ MARKER_UNCHECKED (&br);
+ vol->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+ vol->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+ }
+
+ READ_UINT8 (&br, vol->interlaced, 1);
+ READ_UINT8 (&br, vol->obmc_disable, 1);
+
+ if (vol->verid == 0x1) {
+ READ_UINT8 (&br, tmp, 1);
+ vol->sprite_enable = tmp;
+ } else
+ READ_UINT8 (&br, tmp, 2);
+ vol->sprite_enable = tmp;
+
+ if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
+ vol->sprite_enable == GST_MPEG4_SPRITE_GMG) {
+
+ if (vol->sprite_enable == GST_MPEG4_SPRITE_GMG)
+ CHECK_REMAINING (&br, 9);
+ else {
+ CHECK_REMAINING (&br, 65);
+
+ vol->sprite_width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+
+ vol->sprite_height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+
+ vol->sprite_left_coordinate =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+
+ vol->sprite_top_coordinate =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+ }
+ vol->no_of_sprite_warping_points =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
+ vol->sprite_warping_accuracy =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+ vol->sprite_brightness_change =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+ if (vol->sprite_enable != GST_MPEG4_SPRITE_GMG)
+ vol->low_latency_sprite_enable =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ }
+
+ if (vol->shape != GST_MPEG4_RECTANGULAR)
+ READ_UINT8 (&br, vol->sadct_disable, 1);
+
+ READ_UINT8 (&br, vol->not_8_bit, 1);
+ if (vol->not_8_bit) {
+ READ_UINT8 (&br, vol->quant_precision, 4);
+ CHECK_ALLOWED (vol->quant_precision, 3, 9);
+
+ READ_UINT8 (&br, vol->bits_per_pixel, 4);
+ CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
+ }
+
+ if (vol->shape == GST_MPEG4_GRAYSCALE) {
+ /* We don't actually support it */
+ READ_UINT8 (&br, vol->no_gray_quant_update, 1);
+ READ_UINT8 (&br, vol->composition_method, 1);
+ READ_UINT8 (&br, vol->linear_composition, 1);
+ }
+
+ READ_UINT8 (&br, vol->quant_type, 1);
+ if (vol->quant_type) {
+ if (!parse_quant (&br, vol->intra_quant_mat, default_intra_quant_mat,
+ &vol->load_intra_quant_mat))
+ goto failed;
+
+ if (!parse_quant (&br, vol->non_intra_quant_mat,
+ default_non_intra_quant_mat, &vol->load_non_intra_quant_mat))
+ goto failed;
+
+ if (vol->shape == GST_MPEG4_GRAYSCALE) {
+ /* Something the standard starts to define... */
+ GST_WARNING ("Grayscale shaped not supported");
+ goto failed;
+ }
+
+ } else {
+ memset (&vol->intra_quant_mat, 0, 64);
+ memset (&vol->non_intra_quant_mat, 0, 64);
+ }
+
+ if (vol->verid != 0x1)
+ READ_UINT8 (&br, vol->quarter_sample, 1);
+
+ READ_UINT8 (&br, vol->complexity_estimation_disable, 1);
+ if (!vol->complexity_estimation_disable)
+ goto complexity_estimation_error;
+
+
+ READ_UINT8 (&br, vol->resync_marker_disable, 1);
+ READ_UINT8 (&br, vol->data_partitioned, 1);
+
+ if (vol->data_partitioned)
+ READ_UINT8 (&br, vol->reversible_vlc, 1);
+
+ if (vol->verid != 0x01)
+ READ_UINT8 (&br, vol->newpred_enable, 1);
+
+ if (vol->newpred_enable)
+ /* requested_upstream_message_type and newpred_segment_type */
+ SKIP (&br, 3);
+
+ READ_UINT8 (&br, vol->reduced_resolution_vop_enable, 1);
+
+ READ_UINT8 (&br, vol->scalability, 1);
+ if (vol->scalability) {
+ SKIP (&br, 26); /* Few not needed props */
+ READ_UINT8 (&br, vol->enhancement_type, 1);
+ }
+
+ /* More unused infos */
+ } else if (vol->verid != 0x01) {
+ GST_WARNING ("Binary only shapes not fully supported");
+ goto failed;
+ }
+ /* ... */
+
+ return GST_MPEG4_PARSER_OK;
+
+failed:
+ GST_WARNING ("failed parsing \"Video Object Layer\"");
+ return GST_MPEG4_PARSER_ERROR;
+
+wrong_start_code:
+ GST_WARNING ("got buffer with wrong start code");
+ goto failed;
+
+complexity_estimation_error:
+ GST_WARNING ("don't support complexity estimation");
+ goto failed;
+}
+
+/**
+ * gst_mpeg4_parse_group_of_vop:
+ * @gov: The #GstMpeg4GroupOfVOP structure to fill
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the group of video object plane packet, and fills
+ * the @gov structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *
+ gov, const guint8 * data, gsize size)
+{
+ guint8 gov_start_code;
+ GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+ g_return_val_if_fail (gov != NULL, GST_MPEG4_PARSER_ERROR);
+
+ READ_UINT8 (&br, gov_start_code, 8);
+ if (gov_start_code != GST_MPEG4_GROUP_OF_VOP)
+ goto wrong_start_code;
+
+ CHECK_REMAINING (&br, 65);
+
+ gov->hours = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
+ gov->minutes = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
+ /* marker bit */
+ MARKER_UNCHECKED (&br);
+ gov->seconds = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
+
+ gov->closed = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ gov->broken_link = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+ return GST_MPEG4_PARSER_OK;
+
+failed:
+ GST_WARNING ("failed parsing \"Group of Video Object Plane\"");
+ return GST_MPEG4_PARSER_ERROR;
+
+wrong_start_code:
+ GST_WARNING ("got buffer with wrong start code");
+ goto failed;
+}
+
+/**
+ * gst_mpeg4_parse_video_object_plane:
+ * @vop: The #GstMpeg4VideoObjectPlane currently being parsed
+ * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
+ * @vol: The #GstMpeg4VideoObjectLayer structure to fill
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the video object plane packet, and fills the @vol
+ * structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane * vop,
+ GstMpeg4SpriteTrajectory * sprite_trajectory,
+ GstMpeg4VideoObjectLayer * vol, const guint8 * data, gsize size)
+{
+ guint8 vop_start_code, coding_type, modulo_time_base;
+ GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+ g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
+
+ if (vol->shape == GST_MPEG4_BINARY_ONLY) {
+ /* TODO: implement binary only shapes */
+ GST_WARNING ("Binary only shapes not supported");
+ goto failed;
+ }
+
+ READ_UINT8 (&br, vop_start_code, 8);
+ if (vop_start_code != GST_MPEG4_VIDEO_OBJ_PLANE)
+ goto wrong_start_code;
+
+
+ /* set default values */
+ vop->modulo_time_base = 0;
+ vop->rounding_type = 0;
+ vop->top_field_first = 1;
+ vop->alternate_vertical_scan_flag = 0;
+ vop->fcode_forward = 1;
+ vop->fcode_backward = 1;
+
+ /* Compute macroblock informations */
+ if (vol->interlaced)
+ vop->mb_height = (2 * (vol->height + 31) / 32);
+ else
+ vop->mb_height = (vol->height + 15) / 16;
+
+ vop->mb_width = (vol->width + 15) / 16;
+ vop->mb_num = vop->mb_height * vop->mb_width;
+
+ READ_UINT8 (&br, coding_type, 2);
+ vop->coding_type = coding_type;
+
+ READ_UINT8 (&br, modulo_time_base, 1);
+ while (modulo_time_base) {
+ vop->modulo_time_base++;
+
+ READ_UINT8 (&br, modulo_time_base, 1);
+ }
+
+ CHECK_REMAINING (&br, vol->vop_time_increment_bits + 3);
+
+ MARKER_UNCHECKED (&br);
+ vop->time_increment =
+ gst_bit_reader_get_bits_uint16_unchecked (&br,
+ vol->vop_time_increment_bits);
+ MARKER_UNCHECKED (&br);
+
+ vop->coded = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ if (!vop->coded)
+ return GST_MPEG4_PARSER_OK;
+
+ if (vol->newpred_enable) {
+ guint16 nbbits =
+ vop->time_increment + 3 < 15 ? vop->time_increment + 3 : 15;
+
+ READ_UINT16 (&br, vop->id, nbbits);
+ READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
+ if (vop->id_for_prediction_indication) {
+ /* Would be nice if the standard actually told us... */
+ READ_UINT16 (&br, vop->id, nbbits);
+ CHECK_MARKER (&br);
+ }
+ }
+
+ if (vol->shape != GST_MPEG4_BINARY_ONLY &&
+ (vop->coding_type == GST_MPEG4_P_VOP ||
+ (vop->coding_type == GST_MPEG4_S_VOP &&
+ vol->sprite_enable == GST_MPEG4_SPRITE_GMG)))
+ READ_UINT8 (&br, vop->rounding_type, 1);
+
+ if ((vol->reduced_resolution_vop_enable) &&
+ (vol->shape == GST_MPEG4_RECTANGULAR ||
+ (vop->coding_type = GST_MPEG4_P_VOP ||
+ vop->coding_type == GST_MPEG4_I_VOP)))
+ READ_UINT8 (&br, vop->reduced_resolution, 1);
+
+ if (vol->shape != GST_MPEG4_RECTANGULAR) {
+ if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
+ vop->coding_type == GST_MPEG4_I_VOP) {
+ CHECK_REMAINING (&br, 55);
+
+ vop->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+
+ vop->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+
+ vop->horizontal_mc_spatial_ref =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+
+ vop->vertical_mc_spatial_ref =
+ gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+ MARKER_UNCHECKED (&br);
+
+ /* Recompute the Macroblock informations
+ * accordingly to the new values */
+ if (vol->interlaced)
+ vop->mb_height = (2 * (vol->height + 31) / 32);
+ else
+ vop->mb_height = (vol->height + 15) / 16;
+
+ vop->mb_width = (vol->width + 15) / 16;
+ vop->mb_num = vop->mb_height * vop->mb_width;
+ }
+
+ if ((vol->shape != GST_MPEG4_BINARY_ONLY) &&
+ vol->scalability && vol->enhancement_type)
+ READ_UINT8 (&br, vop->background_composition, 1);
+
+ READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
+
+ READ_UINT8 (&br, vop->constant_alpha, 1);
+ if (vop->constant_alpha)
+ READ_UINT8 (&br, vop->constant_alpha_value, 1);
+ }
+
+ if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+ if (!vol->complexity_estimation_disable) {
+ GST_WARNING ("Complexity estimation not supported");
+ goto failed;
+ }
+
+ READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
+
+ if (vol->interlaced) {
+ READ_UINT8 (&br, vop->top_field_first, 1);
+ READ_UINT8 (&br, vop->alternate_vertical_scan_flag, 1);
+ }
+ }
+
+ if ((vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
+ vol->sprite_enable == GST_MPEG4_SPRITE_GMG) &&
+ vop->coding_type == GST_MPEG4_S_VOP) {
+
+ /* only if @sprite_trajectory is not NULL we parse it */
+ if (sprite_trajectory && vol->no_of_sprite_warping_points)
+ parse_sprite_trajectory (&br, sprite_trajectory,
+ vol->no_of_sprite_warping_points);
+
+ if (vol->sprite_brightness_change) {
+ GST_WARNING ("sprite_brightness_change not supported");
+ goto failed;
+ }
+
+ if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC) {
+ GST_WARNING ("sprite enable static not supported");
+ goto failed;
+ }
+ }
+
+ if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+ READ_UINT16 (&br, vop->quant, vol->quant_precision);
+
+ if (vol->shape == GST_MPEG4_GRAYSCALE) {
+ /* TODO implement grayscale support */
+ GST_WARNING ("Grayscale shapes no supported");
+
+ /* TODO implement me */
+ goto failed;
+ }
+
+ if (vop->coding_type != GST_MPEG4_I_VOP) {
+ READ_UINT8 (&br, vop->fcode_forward, 3);
+ CHECK_ALLOWED (vop->fcode_forward, 1, 7);
+ }
+
+ if (vop->coding_type == GST_MPEG4_B_VOP) {
+ READ_UINT8 (&br, vop->fcode_backward, 3);
+ CHECK_ALLOWED (vop->fcode_backward, 1, 7);
+ }
+ }
+
+ if (!vol->scalability) {
+ if (vol->shape != GST_MPEG4_RECTANGULAR)
+ READ_UINT8 (&br, vop->shape_coding_type, 1);
+
+ } else {
+ if (vol->enhancement_type) {
+ READ_UINT8 (&br, vop->load_backward_shape, 1);
+
+ if (vop->load_backward_shape) {
+ GST_WARNING ("Load backward shape not supported");
+ goto failed;
+ }
+
+ READ_UINT8 (&br, vop->ref_select_code, 2);
+ }
+ }
+
+ vop->size = gst_bit_reader_get_pos (&br);
+ /* More things to possibly parse ... */
+
+ return GST_MPEG4_PARSER_OK;
+
+failed:
+ GST_WARNING ("failed parsing \"Video Object Plane\"");
+ return GST_MPEG4_PARSER_ERROR;
+
+wrong_start_code:
+ GST_WARNING ("got buffer with wrong start code");
+ goto failed;
+}
+
+/**
+ * gst_mpeg4_parse_video_plane_with_short_header:
+ * @shorthdr: The #GstMpeg4VideoPlaneShortHdr to parse
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
+ shorthdr, const guint8 * data, gsize size)
+{
+ guint8 zero_bits;
+ guint32 gob_resync;
+
+ GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+ g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR);
+
+ if (gst_bit_reader_get_remaining (&br) < 26)
+ goto failed;
+
+ shorthdr->temporal_reference =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
+ CHECK_MARKER (&br);
+ shorthdr->split_screen_indicator =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ shorthdr->document_camera_indicator =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ shorthdr->full_picture_freeze_release =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ shorthdr->source_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
+
+ /* Set parameters/Table 6-25 */
+ switch (shorthdr->source_format) {
+ case 0x01:
+ shorthdr->vop_width = 128;
+ shorthdr->vop_height = 96;
+ shorthdr->num_macroblocks_in_gob = 8;
+ shorthdr->num_gobs_in_vop = 6;
+ case 0x02:
+ shorthdr->vop_width = 176;
+ shorthdr->vop_height = 144;
+ shorthdr->num_macroblocks_in_gob = 11;
+ shorthdr->num_gobs_in_vop = 9;
+ case 0x03:
+ shorthdr->vop_width = 352;
+ shorthdr->vop_height = 288;
+ shorthdr->num_macroblocks_in_gob = 22;
+ shorthdr->num_gobs_in_vop = 18;
+ case 0x04:
+ shorthdr->vop_width = 704;
+ shorthdr->vop_height = 576;
+ shorthdr->num_macroblocks_in_gob = 88;
+ shorthdr->num_gobs_in_vop = 18;
+ case 0x05:
+ shorthdr->vop_width = 1408;
+ shorthdr->vop_height = 1152;
+ shorthdr->num_macroblocks_in_gob = 352;
+ shorthdr->num_gobs_in_vop = 18;
+ default:
+ shorthdr->vop_width = 0;
+ shorthdr->vop_height = 0;
+ shorthdr->num_macroblocks_in_gob = 0;
+ shorthdr->num_gobs_in_vop = 0;
+ }
+
+ shorthdr->picture_coding_type =
+ gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+ zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
+
+ if (zero_bits != 0x00)
+ goto failed;
+
+ shorthdr->vop_quant = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
+ zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+ if (zero_bits != 0x00)
+ goto failed;
+
+ do {
+ READ_UINT8 (&br, shorthdr->pei, 1);
+
+ if (shorthdr->pei == 1)
+ READ_UINT8 (&br, shorthdr->psupp, 8);
+
+ } while (shorthdr->pei == 1);
+
+ if (!gst_bit_reader_peek_bits_uint32 (&br, &gob_resync, 17))
+ goto failed;
+
+ /* gob_layer() */
+
+ /* Setting default values */
+ shorthdr->gob_header_empty = 1;
+ shorthdr->gob_number = 0;
+ shorthdr->gob_frame_id = 0;
+ shorthdr->quant_scale = 0;
+
+ if (gob_resync == 0x01) {
+ shorthdr->gob_header_empty = 0;
+
+ gst_bit_reader_skip_unchecked (&br, 17);
+ READ_UINT8 (&br, shorthdr->gob_number, 5);
+ READ_UINT8 (&br, shorthdr->gob_frame_id, 2);
+ READ_UINT8 (&br, shorthdr->quant_scale, 5);
+ }
+
+ shorthdr->size = gst_bit_reader_get_pos (&br);
+
+ return GST_MPEG4_PARSER_OK;
+
+failed:
+ GST_WARNING ("Could not parse the Plane short header");
+
+ return GST_MPEG4_PARSER_ERROR;
+}
+
+/**
+ * gst_mpeg4_next_resync:
+ * @packet: The #GstMpeg4Packet to fill
+ * @vop: The previously parsed #GstMpeg4VideoObjectPlane
+ * @offset: offset from which to start the parsing
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data and fills @packet with the information of the next resync packet
+ * found.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_next_resync (GstMpeg4Packet * packet,
+ const GstMpeg4VideoObjectPlane * vop, const guint8 * data, gsize size)
+{
+ guint markersize = 0, skip, remaining;
+ GstBitReader br;
+
+ gst_bit_reader_init (&br, data, size);
+
+ g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
+ g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
+
+ /* Skip to the end of the vop header */
+ gst_bit_reader_skip (&br, vop->size);
+
+ /* 5.2.3 Definition of nextbits_bytealigned() function */
+ skip = vop->size % 8;
+ remaining = gst_bit_reader_get_remaining (&br);
+ if (!skip) {
+ if (remaining > 8 && br.data[br.byte + 1] == 0x7f)
+ skip = 8;
+ }
+
+ /* Align to next byte */
+ if (!gst_bit_reader_skip (&br, skip))
+ goto failed;
+
+ markersize = compute_resync_marker_size (vop);
+
+ CHECK_REMAINING (&br, markersize);
+
+ if (gst_bit_reader_peek_bits_uint32_unchecked (&br, markersize) != 0x01)
+ goto failed;
+
+ GST_DEBUG ("Resync code found at %i", br.byte);
+
+ packet->offset = br.byte;
+ packet->type = GST_MPEG4_RESYNC;
+ packet->size = 0;
+ packet->marker_size = markersize;
+
+ return GST_MPEG4_PARSER_OK;
+
+failed:
+ GST_DEBUG ("No resync found in this buffer");
+
+ return GST_MPEG4_PARSER_NO_PACKET;
+}
+
+/**
+ * gst_mpeg4_parse_video_packet_header:
+ * @videopackethdr: The #GstMpeg4VideoPacketHdr structure to fill
+ * @vol: The last parsed #GstMpeg4VideoObjectLayer, will be updated
+ * with the informations found during the parsing
+ * @vop: The last parsed #GstMpeg4VideoObjectPlane, will be updated
+ * with the informations found during the parsing
+ * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
+ * with the informations found during the parsing
+ * @data: The data to parse, should be set after the resync marker.
+ * @size: The size of the data to parse
+ *
+ * Parsers @data containing the video packet header
+ * and fills the @videopackethdr structure
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
+ GstMpeg4VideoObjectLayer * vol, GstMpeg4VideoObjectPlane * vop,
+ GstMpeg4SpriteTrajectory * sprite_trajectory, const guint8 * data,
+ gsize size)
+{
+ guint8 markersize;
+ GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+ g_return_val_if_fail (videopackethdr != NULL, GST_MPEG4_PARSER_ERROR);
+ g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
+
+ markersize = compute_resync_marker_size (vop);
+
+ CHECK_REMAINING (&br, markersize);
+
+ if (gst_bit_reader_get_bits_uint32_unchecked (&br, markersize) != 0x01)
+ goto failed;
+
+ if (vol->shape != GST_MPEG4_RECTANGULAR) {
+ READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
+ if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
+ vop->coding_type == GST_MPEG4_I_VOP) {
+
+ CHECK_REMAINING (&br, 56);
+
+ U_READ_UINT16 (&br, vop->width, 13);
+ CHECK_MARKER (&br);
+ U_READ_UINT16 (&br, vop->height, 13);
+ CHECK_MARKER (&br);
+ U_READ_UINT16 (&br, vop->horizontal_mc_spatial_ref, 13);
+ CHECK_MARKER (&br);
+ U_READ_UINT16 (&br, vop->vertical_mc_spatial_ref, 13);
+ CHECK_MARKER (&br);
+
+ /* Update macroblock infirmations */
+ vop->mb_height = (vop->height + 15) / 16;
+ vop->mb_width = (vop->width + 15) / 16;
+ vop->mb_num = vop->mb_height * vop->mb_width;
+ }
+ }
+
+ READ_UINT16 (&br, videopackethdr->macroblock_number,
+ g_bit_storage (vop->mb_num - 1));
+
+ if (vol->shape != GST_MPEG4_BINARY_ONLY)
+ READ_UINT16 (&br, videopackethdr->quant_scale, vol->quant_precision);
+
+ if (vol->shape == GST_MPEG4_RECTANGULAR)
+ READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
+
+ if (videopackethdr->header_extension_code) {
+ guint timeincr = 0;
+ guint8 bit = 0, coding_type;
+
+ do {
+ READ_UINT8 (&br, bit, 1);
+ timeincr++;
+ } while (bit);
+
+ vol->vop_time_increment_bits = timeincr;
+
+ CHECK_MARKER (&br);
+ READ_UINT16 (&br, vop->time_increment, timeincr);
+ CHECK_MARKER (&br);
+ READ_UINT8 (&br, coding_type, 2);
+ vop->coding_type = coding_type;
+
+ if (vol->shape != GST_MPEG4_RECTANGULAR) {
+ READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
+ if (vop->coding_type != GST_MPEG4_I_VOP)
+ READ_UINT8 (&br, vop->shape_coding_type, 1);
+ }
+
+ if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+ READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
+
+ if (sprite_trajectory && vol->sprite_enable == GST_MPEG4_SPRITE_GMG &&
+ vop->coding_type == GST_MPEG4_S_VOP &&
+ vol->no_of_sprite_warping_points > 0) {
+
+ parse_sprite_trajectory (&br, sprite_trajectory,
+ vol->no_of_sprite_warping_points);
+ }
+
+ if (vol->reduced_resolution_vop_enable &&
+ vol->shape == GST_MPEG4_RECTANGULAR &&
+ (vop->coding_type == GST_MPEG4_P_VOP ||
+ vop->coding_type == GST_MPEG4_I_VOP))
+ READ_UINT8 (&br, vop->reduced_resolution, 1);
+
+ if (vop->coding_type != GST_MPEG4_I_VOP) {
+ READ_UINT8 (&br, vop->fcode_forward, 3);
+ CHECK_ALLOWED (vop->fcode_forward, 1, 7);
+ }
+
+ if (vop->coding_type == GST_MPEG4_B_VOP) {
+ READ_UINT8 (&br, vop->fcode_backward, 3);
+ CHECK_ALLOWED (vop->fcode_backward, 1, 7);
+ }
+ }
+ }
+
+ if (vol->newpred_enable) {
+ guint16 nbbits =
+ vol->vop_time_increment_bits + 3 < 15 ? vop->time_increment + 3 : 15;
+
+ READ_UINT16 (&br, vop->id, nbbits);
+ READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
+ if (vop->id_for_prediction_indication) {
+ /* Would be nice if the standard actually told us... */
+ READ_UINT16 (&br, vop->id, nbbits);
+ CHECK_MARKER (&br);
+ }
+ }
+
+ videopackethdr->size = gst_bit_reader_get_pos (&br);
+
+failed:
+ GST_DEBUG ("Failed to parse video packet header");
+
+ return GST_MPEG4_PARSER_NO_PACKET;
+}
diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.h b/gst-libs/gst/codecparsers/gstmpeg4parser.h
new file mode 100644
index 0000000000..c1fcb1c383
--- /dev/null
+++ b/gst-libs/gst/codecparsers/gstmpeg4parser.h
@@ -0,0 +1,583 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Carl-Anton Ingmarsson
+ *
+ * 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_MPEG4UTIL_H__
+#define __GST_MPEG4UTIL_H__
+
+#include
+#include
+
+typedef struct _GstMpeg4VisualObjectSequence GstMpeg4VisualObjectSequence;
+typedef struct _GstMpeg4VisualObject GstMpeg4VisualObject;
+typedef struct _GstMpeg4VideoObjectLayer GstMpeg4VideoObjectLayer;
+typedef struct _GstMpeg4GroupOfVOP GstMpeg4GroupOfVOP;
+typedef struct _GstMpeg4VideoObjectPlane GstMpeg4VideoObjectPlane;
+typedef struct _GstMpeg4VideoSignalType GstMpeg4VideoSignalType;
+typedef struct _GstMpeg4VideoPlaneShortHdr GstMpeg4VideoPlaneShortHdr;
+typedef struct _GstMpeg4VideoPacketHdr GstMpeg4VideoPacketHdr;
+
+typedef struct _GstMpeg4SpriteTrajectory GstMpeg4SpriteTrajectory;
+
+typedef struct _GstMpeg4Packet GstMpeg4Packet;
+
+/**
+ * GstMpeg4StartCode:
+ *
+ * Defines the different startcodes present in the bitstream as
+ * defined in: Table 6-3 — Start code values
+ */
+typedef enum
+{
+ GST_MPEG4_VIDEO_OBJ_FIRST = 0x00,
+ GST_MPEG4_VIDEO_OBJ_LAST = 0x1f,
+ GST_MPEG4_VIDEO_LAYER_FIRST = 0x20,
+ GST_MPEG4_VIDEO_LAYER_LAST = 0x2f,
+ GST_MPEG4_VISUAL_OBJ_SEQ_START = 0xb0,
+ GST_MPEG4_VISUAL_OBJ_SEQ_END = 0xb1,
+ GST_MPEG4_USER_DATA = 0xb2,
+ GST_MPEG4_GROUP_OF_VOP = 0xb3,
+ GST_MPEG4_VIDEO_SESSION_ERR = 0xb4,
+ GST_MPEG4_VISUAL_OBJ = 0xb5,
+ GST_MPEG4_VIDEO_OBJ_PLANE = 0xb6,
+ GST_MPEG4_FBA = 0xba,
+ GST_MPEG4_FBA_PLAN = 0xbb,
+ GST_MPEG4_MESH = 0xbc,
+ GST_MPEG4_MESH_PLAN = 0xbd,
+ GST_MPEG4_STILL_TEXTURE_OBJ = 0xbe,
+ GST_MPEG4_TEXTURE_SPATIAL = 0xbf,
+ GST_MPEG4_TEXTURE_SNR_LAYER = 0xc0,
+ GST_MPEG4_TEXTURE_TILE = 0xc1,
+ GST_MPEG4_SHAPE_LAYER = 0xc2,
+ GST_MPEG4_STUFFING = 0xc3,
+ GST_MPEG4_SYSTEM_FIRST = 0xc6,
+ GST_MPEG4_SYSTEM_LAST = 0xff,
+ GST_MPEG4_RESYNC = 0xfff
+} GstMpeg4StartCode;
+
+/**
+ * GstMpeg4VisualObjectType:
+ *
+ * Defines the different visual object types as
+ * defined in: Table 6-5 -- Meaning of visual object type
+ */
+typedef enum {
+ GST_MPEG4_VIDEO_ID = 0x01,
+ GST_MPEG4_STILL_TEXTURE_ID = 0x02,
+ GST_MPEG4_STILL_MESH_ID = 0x03,
+ GST_MPEG4_STILL_FBA_ID = 0x04,
+ GST_MPEG4_STILL_3D_MESH_ID = 0x05,
+ /*... reserved */
+
+} GstMpeg4VisualObjectType;
+
+/**
+ * GstMpeg4AspectRatioInfo:
+ * @GST_MPEG4_SQUARE: 1:1 square
+ * @GST_MPEG4_625_TYPE_4_3: 12:11 (625-type for 4:3 picture)
+ * @GST_MPEG4_525_TYPE_4_3: 10:11 (525-type for 4:3 picture)
+ * @GST_MPEG4_625_TYPE_16_9: 16:11 (625-type stretched for 16:9 picture)
+ * @GST_MPEG4_525_TYPE_16_9: 40:33 (525-type stretched for 16:9 picture)
+ * @GST_MPEG4_EXTENDED_PAR: Extended par
+ *
+ * Defines the different pixel aspect ratios as
+ * defined in: Table 6-12 -- Meaning of pixel aspect ratio
+ */
+typedef enum {
+ GST_MPEG4_SQUARE = 0x01,
+ GST_MPEG4_625_TYPE_4_3 = 0x02,
+ GST_MPEG4_525_TYPE_4_3 = 0x03,
+ GST_MPEG4_625_TYPE_16_9 = 0x04,
+ GST_MPEG4_525_TYPE_16_9 = 0x05,
+ GST_MPEG4_EXTENDED_PAR = 0x0f,
+} GstMpeg4AspectRatioInfo;
+
+/**
+ * GstMpeg4ParseResult:
+ * @GST_MPEG4_PARSER_OK: The parsing went well
+ * @GST_MPEG4_PARSER_BROKEN_DATA: The bitstream was broken
+ * @GST_MPEG4_PARSER_NO_PACKET: There was no packet in the buffer
+ * @GST_MPEG4_PARSER_NO_PACKET_END: There was no packet end in the buffer
+ * @GST_MPEG4_PARSER_NO_PACKET_ERROR: An error accured durint the parsing
+ *
+ * Result type of any parsing function.
+ */
+typedef enum {
+ GST_MPEG4_PARSER_OK,
+ GST_MPEG4_PARSER_BROKEN_DATA,
+ GST_MPEG4_PARSER_NO_PACKET,
+ GST_MPEG4_PARSER_NO_PACKET_END,
+ GST_MPEG4_PARSER_ERROR,
+} GstMpeg4ParseResult;
+
+/**
+ * GstMpeg4VideoObjectCodingType:
+ * @GST_MPEG4_I_VOP: intra-coded (I)
+ * @GST_MPEG4_P_VOP: predictive-coded (P)
+ * @GST_MPEG4_B_VOP: bidirectionally-predictive-coded (B)
+ * @GST_MPEG4_S_VOP: sprite (S)
+ *
+ * The vop coding types as defined in:
+ * Table 6-20 -- Meaning of vop_coding_type
+ */
+typedef enum {
+ GST_MPEG4_I_VOP = 0x0,
+ GST_MPEG4_P_VOP = 0x1,
+ GST_MPEG4_B_VOP = 0x2,
+ GST_MPEG4_S_VOP = 0x3
+} GstMpeg4VideoObjectCodingType;
+
+/**
+ * GstMpeg4ChromaFormat
+ *
+ * The chroma format in use as
+ * defined in: Table 6-13 -- Meaning of chroma_format
+ */
+typedef enum {
+ /* Other value are reserved */
+ GST_MPEG4_CHROMA_4_2_0 = 0x01
+} GstMpeg4ChromaFormat;
+
+/**
+ * GstMpeg4VideoObjectLayerShape:
+ *
+ * The different video object layer shapes as defined in:
+ * Table 6-16 — Video Object Layer shape type
+ */
+typedef enum {
+ GST_MPEG4_RECTANGULAR,
+ GST_MPEG4_BINARY,
+ GST_MPEG4_BINARY_ONLY,
+ GST_MPEG4_GRAYSCALE
+} GstMpeg4VideoObjectLayerShape;
+
+/**
+ * GstMpeg4SpriteEnable:
+ *
+ * Indicates the usage of static sprite coding
+ * or global motion compensation (GMC) as defined in:
+ * Table V2 - 2 -- Meaning of sprite_enable codewords
+ */
+typedef enum {
+ GST_MPEG4_SPRITE_UNUSED,
+ GST_MPEG4_SPRITE_STATIC,
+ GST_MPEG4_SPRITE_GMG
+} GstMpeg4SpriteEnable;
+
+/**
+ * GstMpeg4Profile:
+ *
+ * Different defined profiles as defined in:
+ * 9- Profiles and levels
+ *
+ * It is computed using:
+ * Table G.1 — FLC table for profile_and_level_indication
+ */
+typedef enum {
+ GST_MPEG4_PROFILE_CORE,
+ GST_MPEG4_PROFILE_MAIN,
+ GST_MPEG4_PROFILE_N_BIT,
+ GST_MPEG4_PROFILE_SIMPLE,
+ GST_MPEG4_PROFILE_HYBRYD,
+ GST_MPEG4_PROFILE_RESERVED,
+ GST_MPEG4_PROFILE_SIMPLE_FBA,
+ GST_MPEG4_PROFILE_CORE_STUDIO,
+ GST_MPEG4_PROFILE_SIMPLE_STUDIO,
+ GST_MPEG4_PROFILE_CORE_SCALABLE,
+ GST_MPEG4_PROFILE_ADVANCED_CORE,
+ GST_MPEG4_PROFILE_ADVANCED_SIMPLE,
+ GST_MPEG4_PROFILE_SIMPLE_SCALABLE,
+ GST_MPEG4_PROFILE_SCALABLE_TEXTURE,
+ GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION,
+ GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE,
+ GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE,
+ GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE,
+ GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE,
+ GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY
+} GstMpeg4Profile;
+
+/**
+ * GstMpeg4Level:
+ *
+ * Different levels as defined in:
+ * 9- Profiles and levels
+ *
+ * It is computed using:
+ * Table G.1 — FLC table for profile_and_level_indication
+ */
+typedef enum {
+ GST_MPEG4_LEVEL0,
+ GST_MPEG4_LEVEL1,
+ GST_MPEG4_LEVEL2,
+ GST_MPEG4_LEVEL3,
+ GST_MPEG4_LEVEL3b,
+ GST_MPEG4_LEVEL4,
+ GST_MPEG4_LEVEL5,
+ GST_MPEG4_LEVEL_RESERVED
+} GstMpeg4Level;
+
+/**
+ * GstMpeg4VisualObjectSequence:
+ *
+ * The visual object sequence structure as defined in:
+ * 6.2.2 Visual Object Sequence and Visual Object
+ */
+struct _GstMpeg4VisualObjectSequence {
+ guint8 profile_and_level_indication;
+
+ /* Computed according to:
+ * Table G.1 — FLC table for profile_and_level_indication */
+ GstMpeg4Level level;
+ GstMpeg4Profile profile;
+};
+
+/**
+ * The visual object structure as defined in:
+ * 6.2.2 Visual Object Sequence and Visual Object
+ */
+struct _GstMpeg4VisualObject {
+ guint8 is_identifier;
+ /* If is_identifier */
+ guint8 verid;
+ guint8 priority;
+
+ GstMpeg4VisualObjectType type;
+};
+
+/**
+ * GstMpeg4VideoSignalType:
+ *
+ * The video signal type structure as defined in:
+ * 6.2.2 Visual Object Sequence and Visual Object.
+ */
+struct _GstMpeg4VideoSignalType {
+ guint8 type;
+
+ guint8 format;
+ guint8 range;
+ guint8 color_description;
+ guint8 color_primaries;
+ guint8 transfer_characteristics;
+ guint8 matrix_coefficients;
+};
+
+/**
+ * GstMpeg4VideoPlaneShortHdr:
+ *
+ * The video plane short header structure as defined in:
+ * 6.2.5.2 Video Plane with Short Header
+ */
+struct _GstMpeg4VideoPlaneShortHdr {
+ guint8 temporal_reference;
+ guint8 split_screen_indicator;
+ guint8 document_camera_indicator;
+ guint8 full_picture_freeze_release;
+ guint8 source_format;
+ guint8 picture_coding_type;
+ guint8 vop_quant;
+ guint8 pei;
+ guint8 psupp;
+
+ /* Gob layer specific fields */
+ guint8 gob_header_empty;
+ guint8 gob_number;
+ guint8 gob_frame_id;
+ guint8 quant_scale;
+
+ /* Computed
+ * If all the values are set to 0, then it is reserved
+ * Table 6-25 -- Parameters Defined by source_format Field
+ */
+ guint16 vop_width;
+ guint16 vop_height;
+ guint16 num_macroblocks_in_gob;
+ guint8 num_gobs_in_vop;
+
+ /* The size in bits */
+ guint size;
+};
+
+/**
+ * GstMpeg4VideoObjectLayer:
+ *
+ * The video object layer structure as defined in:
+ * 6.2.3 Video Object Layer
+ */
+struct _GstMpeg4VideoObjectLayer {
+ guint8 random_accessible_vol;
+ guint8 video_object_type_indication;
+
+ guint8 is_object_layer_identifier;
+ /* if is_object_layer_identifier */
+ guint8 verid;
+ guint8 priority;
+
+ GstMpeg4AspectRatioInfo aspect_ratio_info;
+ guint8 par_width;
+ guint8 par_height;
+
+ guint8 control_parameters;
+ /* if control_parameters */
+ GstMpeg4ChromaFormat chroma_format;
+ guint8 low_delay;
+ guint8 vbv_parameters;
+ /* if vbv_parameters */
+ guint16 first_half_bitrate;
+ guint16 latter_half_bitrate;
+ guint16 first_half_vbv_buffer_size;
+ guint16 latter_half_vbv_buffer_size;
+ guint16 first_half_vbv_occupancy;
+ guint16 latter_half_vbv_occupancy;
+
+ /* Computed values */
+ guint32 bit_rate;
+ guint32 vbv_buffer_size;
+
+ GstMpeg4VideoObjectLayerShape shape;
+ /* if shape == GST_MPEG4_GRAYSCALE && verid =! 1 */
+ guint8 shape_extension;
+
+ guint16 vop_time_increment_resolution;
+ guint8 vop_time_increment_bits;
+ guint8 fixed_vop_rate;
+ /* if fixed_vop_rate */
+ guint16 fixed_vop_time_increment;
+
+ guint16 width;
+ guint16 height;
+ guint8 interlaced;
+ guint8 obmc_disable;
+
+ GstMpeg4SpriteEnable sprite_enable;
+ /* if vol->sprite_enable == SPRITE_GMG or SPRITE_STATIC*/
+ /* if vol->sprite_enable != GST_MPEG4_SPRITE_GMG */
+ guint16 sprite_width;
+ guint16 sprite_height;
+ guint16 sprite_left_coordinate;
+ guint16 sprite_top_coordinate;
+
+ guint8 no_of_sprite_warping_points;
+ guint8 sprite_warping_accuracy;
+ guint8 sprite_brightness_change;
+ /* if vol->sprite_enable != GST_MPEG4_SPRITE_GMG */
+ guint8 low_latency_sprite_enable;
+
+ /* if shape != GST_MPEG4_RECTANGULAR */
+ guint8 sadct_disable;
+
+ guint8 not_8_bit;
+
+ /* if no_8_bit */
+ guint8 quant_precision;
+ guint8 bits_per_pixel;
+
+ /* if shape == GRAYSCALE */
+ guint8 no_gray_quant_update;
+ guint8 composition_method;
+ guint8 linear_composition;
+
+ guint8 quant_type;
+ /* if quant_type */
+ guint8 load_intra_quant_mat;
+ guint8 intra_quant_mat[64];
+ guint8 load_non_intra_quant_mat;
+ guint8 non_intra_quant_mat[64];
+
+ guint8 quarter_sample;
+ guint8 complexity_estimation_disable;
+ guint8 resync_marker_disable;
+ guint8 data_partitioned;
+ guint8 reversible_vlc;
+ guint8 newpred_enable;
+ guint8 reduced_resolution_vop_enable;
+ guint8 scalability;
+ guint8 enhancement_type;
+
+ GstMpeg4VideoPlaneShortHdr short_hdr;
+};
+
+/**
+ * GstMpeg4SpriteTrajectory:
+ *
+ * The sprite trajectory structure as defined in:
+ * 7.8.4 Sprite reference point decoding and
+ * 6.2.5.4 Sprite coding
+ */
+struct _GstMpeg4SpriteTrajectory {
+ guint16 vop_ref_points[63]; /* Defined as "du" in 6.2.5.4 */
+ guint16 sprite_ref_points[63]; /* Defined as "dv" in 6.2.5.4 */
+};
+
+/**
+ * GstMpeg4GroupOfVOP:
+ *
+ * The group of video object plane structure as defined in:
+ * 6.2.4 Group of Video Object Plane
+ */
+struct _GstMpeg4GroupOfVOP {
+ guint8 hours;
+ guint8 minutes;
+ guint8 seconds;
+
+ guint8 closed;
+ guint8 broken_link;
+};
+
+/**
+ * GstMpeg4VideoObjectPlane:
+ *
+ * The Video object plane structure as defined in:
+ * 6.2.5 Video Object Plane and Video Plane with Short Header
+ */
+struct _GstMpeg4VideoObjectPlane {
+ GstMpeg4VideoObjectCodingType coding_type;
+
+ guint8 modulo_time_base;
+ guint16 time_increment;
+
+ guint8 coded;
+ /* if newpred_enable */
+ guint16 id;
+ guint8 id_for_prediction_indication;
+ guint16 id_for_prediction;
+
+ guint16 width;
+ guint16 height;
+ guint16 horizontal_mc_spatial_ref;
+ guint16 vertical_mc_spatial_ref;
+
+ guint8 rounding_type;
+ /*if vol->shape != GST_MPEG4_RECTANGULAR */
+ guint8 background_composition;
+ guint8 change_conv_ratio_disable;
+ guint8 constant_alpha;
+ guint8 constant_alpha_value;
+ guint8 reduced_resolution;
+
+ guint8 intra_dc_vlc_thr;
+
+
+ guint8 top_field_first;
+ guint8 alternate_vertical_scan_flag;
+
+ guint16 quant;
+
+ guint8 fcode_forward;
+ guint8 fcode_backward;
+
+ guint8 shape_coding_type;
+ guint8 load_backward_shape;
+ guint8 ref_select_code;
+
+ /* Computed macroblock informations */
+ guint16 mb_height;
+ guint16 mb_width;
+ guint mb_num;
+
+ /* The size of the header */
+ guint size;
+};
+
+/**
+ * GstMpeg4VideoPacketHdr:
+ * @size: Size of the header in bit.
+ *
+ * The video packet header structure as defined in:
+ * 6.2.5.2 Video Plane with Short Header
+ */
+struct _GstMpeg4VideoPacketHdr {
+ guint8 header_extension_code;
+ guint16 macroblock_number;
+ guint16 quant_scale;
+ guint size;
+};
+
+/**
+ * GstMpeg4Packet:
+ * @type: the type of the packet that start at @offset
+ * @data: the data of the packet, statring at @offset
+ * @offset: offset of the start of the packet (without the 3 bytes startcode), but
+ * including the #GstMpeg4StartCode byte.
+ * @size: The size in bytes of the packet or %G_MAXUINT if the end wasn't found.
+ * Set to 0 if type == GST_MPEG4_RESYNC.
+ * @marker_size: The size in bit of the resync marker.
+ *
+ * A structure that contains the type of a packet, its offset and its size
+ */
+struct _GstMpeg4Packet
+{
+ const guint8 *data;
+ guint offset;
+ gsize size;
+ guint marker_size;
+
+ GstMpeg4StartCode type;
+};
+
+GstMpeg4ParseResult gst_h263_parse (GstMpeg4Packet * packet,
+ const guint8 * data, guint offset,
+ gsize size);
+
+
+GstMpeg4ParseResult gst_mpeg4_parse (GstMpeg4Packet * packet,
+ gboolean skip_user_data,
+ const guint8 * data, guint offset,
+ gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane *vop,
+ GstMpeg4SpriteTrajectory *sprite_trajectory,
+ GstMpeg4VideoObjectLayer *vol,
+ const guint8 * data,
+ gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *gov,
+ const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer *vol,
+ GstMpeg4VisualObject *vo,
+ const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object (GstMpeg4VisualObject *vo,
+ GstMpeg4VideoSignalType *signal_type,
+ const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object_sequence (GstMpeg4VisualObjectSequence *vos,
+ const guint8 * data, gsize size);
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr * shorthdr,
+ const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_next_resync (GstMpeg4Packet * packet,
+ const GstMpeg4VideoObjectPlane * vop,
+ const guint8 *data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
+ GstMpeg4VideoObjectLayer * vol,
+ GstMpeg4VideoObjectPlane * vop,
+ GstMpeg4SpriteTrajectory * sprite_trajectory,
+ const guint8 * data, gsize size);
+
+#endif /* __GST_MPEG4UTIL_H__ */