2 * Copyright (C) <2011> Intel
3 * Copyright (C) <2011> Collabora Ltd.
4 * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 * SECTION:gstmpeg4parser
23 * @short_description: Convenience library for parsing mpeg4 part 2 video
26 * For more details about the structures, you can refer to the
27 * specifications: ISO-IEC-14496-2_2004_MPEG4_VISUAL.pdf
35 #include <gst/base/gstbytereader.h>
38 #include "gstmpeg4parser.h"
39 #include "parserutils.h"
41 #ifndef GST_DISABLE_GST_DEBUG
43 #define GST_CAT_DEFAULT ensure_debug_category()
45 static GstDebugCategory *
46 ensure_debug_category (void)
48 static gsize cat_gonce = 0;
50 if (g_once_init_enter (&cat_gonce)) {
53 cat_done = (gsize) _gst_debug_category_new ("codecparsers_mpeg4", 0,
54 "GstMpeg4 codec parsing library");
56 g_once_init_leave (&cat_gonce, cat_done);
59 return (GstDebugCategory *) cat_gonce;
64 #define ensure_debug_category() /* NOOP */
66 #endif /* GST_DISABLE_GST_DEBUG */
68 #define CHECK_MARKER(br) G_STMT_START { \
70 if (!gst_bit_reader_get_bits_uint8 (br, &marker, 1)) { \
71 GST_WARNING ("failed to read marker bit"); \
73 } else if (!marker) {\
74 GST_WARNING ("Wrong marker bit"); \
79 #define MARKER_UNCHECKED(br) G_STMT_START { \
80 if (!gst_bit_reader_get_bits_uint8_unchecked (br, 1)) { \
81 GST_WARNING ("Wrong marker bit"); \
86 #define CHECK_REMAINING(br, needed) G_STMT_START { \
87 if (gst_bit_reader_get_remaining (br) < needed) \
91 static const guint8 default_intra_quant_mat[64] = {
92 8, 17, 18, 19, 21, 23, 25, 27,
93 17, 18, 19, 21, 23, 25, 27, 28,
94 20, 21, 22, 23, 24, 26, 28, 30,
95 21, 22, 23, 24, 26, 28, 30, 32,
96 22, 23, 24, 26, 28, 30, 32, 35,
97 23, 24, 26, 28, 30, 32, 35, 38,
98 25, 26, 28, 30, 32, 35, 38, 41,
99 27, 28, 30, 32, 35, 38, 41, 45
102 static const guint8 default_non_intra_quant_mat[64] = {
103 16, 17, 18, 19, 20, 21, 22, 23,
104 17, 18, 19, 20, 21, 22, 23, 24,
105 18, 19, 20, 21, 22, 23, 24, 25,
106 19, 20, 21, 22, 23, 24, 26, 27,
107 20, 21, 22, 23, 25, 26, 27, 28,
108 21, 22, 23, 24, 26, 27, 28, 30,
109 22, 23, 24, 26, 27, 28, 30, 31,
110 23, 24, 25, 27, 28, 30, 31, 33,
113 static const guint8 mpeg4_zigzag_8x8[64] = {
114 0, 1, 8, 16, 9, 2, 3, 10,
115 17, 24, 32, 25, 18, 11, 4, 5,
116 12, 19, 26, 33, 40, 48, 41, 34,
117 27, 20, 13, 6, 7, 14, 21, 28,
118 35, 42, 49, 56, 57, 50, 43, 36,
119 29, 22, 15, 23, 30, 37, 44, 51,
120 58, 59, 52, 45, 38, 31, 39, 46,
121 53, 60, 61, 54, 47, 55, 62, 63
124 static const VLCTable mpeg4_dmv_size_vlc_table[] = {
143 mpeg4_util_par_from_info (guint8 aspect_ratio_info, guint8 * par_width,
146 switch (aspect_ratio_info) {
172 parse_quant (GstBitReader * br, guint8 quant_mat[64],
173 const guint8 default_quant_mat[64], guint8 * load_quant_mat)
175 READ_UINT8 (br, *load_quant_mat, 1);
176 if (*load_quant_mat) {
181 for (i = 0; i < 64; i++) {
184 READ_UINT8 (br, val, 8);
188 goto invalid_quant_mat;
189 quant_mat[mpeg4_zigzag_8x8[i]] = quant_mat[mpeg4_zigzag_8x8[i - 1]];
191 quant_mat[mpeg4_zigzag_8x8[i]] = val;
194 memcpy (quant_mat, default_quant_mat, 64);
199 GST_WARNING ("failed parsing quant matrix");
203 GST_WARNING ("the first value should be non zero");
208 parse_signal_type (GstBitReader * br, GstMpeg4VideoSignalType * signal_type)
210 READ_UINT8 (br, signal_type->type, 1);
212 if (signal_type->type) {
214 READ_UINT8 (br, signal_type->format, 3);
215 READ_UINT8 (br, signal_type->range, 1);
216 READ_UINT8 (br, signal_type->color_description, 1);
218 if (signal_type->color_description) {
219 READ_UINT8 (br, signal_type->color_primaries, 8);
220 READ_UINT8 (br, signal_type->transfer_characteristics, 8);
221 READ_UINT8 (br, signal_type->matrix_coefficients, 8);
228 GST_WARNING ("failed parsing \"Video Signal Type\"");
234 parse_sprite_trajectory (GstBitReader * br,
235 GstMpeg4SpriteTrajectory * sprite_traj, guint no_of_sprite_warping_points)
239 for (i = 0; i < no_of_sprite_warping_points; i++) {
241 if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
242 G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
246 READ_UINT16 (br, sprite_traj->vop_ref_points[i], length);
249 if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
250 G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
254 READ_UINT16 (br, sprite_traj->sprite_ref_points[i], length);
261 GST_WARNING ("Could not parse the sprite trajectory");
266 find_psc (GstByteReader * br)
268 guint psc_pos = -1, psc;
270 if (!gst_byte_reader_peek_uint24_be (br, &psc))
273 /* Scan for the picture start code (22 bits - 0x0020) */
274 while ((gst_byte_reader_get_remaining (br) >= 3)) {
275 if (gst_byte_reader_peek_uint24_be (br, &psc) &&
276 ((psc & 0xfffffc) == 0x000080)) {
277 psc_pos = gst_byte_reader_get_pos (br);
280 gst_byte_reader_skip (br, 1);
289 compute_resync_marker_size (const GstMpeg4VideoObjectPlane * vop,
290 guint32 * pattern, guint32 * mask)
294 /* FIXME handle the binary only shape case */
295 switch (vop->coding_type) {
296 case (GST_MPEG4_I_VOP):
299 case (GST_MPEG4_S_VOP):
300 case (GST_MPEG4_P_VOP):
301 off = 15 + vop->fcode_forward;
304 case (GST_MPEG4_B_VOP):
305 off = MAX (15 + MAX (vop->fcode_forward, vop->fcode_backward), 17);
312 if (mask && pattern) {
315 *pattern = 0x00008000;
319 *pattern = 0x00004000;
323 *pattern = 0x00002000;
327 *pattern = 0x00001000;
331 *pattern = 0x00000800;
335 *pattern = 0x00000400;
339 *pattern = 0x00000200;
343 *pattern = 0x00000100;
349 return off++; /* Take the following 1 into account */
353 * gst_mpeg4_next_resync:
354 * @packet: The #GstMpeg4Packet to fill
355 * @vop: The previously parsed #GstMpeg4VideoObjectPlane
356 * @offset: offset from which to start the parsing
357 * @data: The data to parse
358 * @size: The size of the @data to parse
360 * Parses @data and fills @packet with the information of the next resync packet
363 * Returns: a #GstMpeg4ParseResult
365 static GstMpeg4ParseResult
366 gst_mpeg4_next_resync (GstMpeg4Packet * packet,
367 const GstMpeg4VideoObjectPlane * vop, const guint8 * data, gsize size,
368 gboolean first_resync_marker)
370 guint markersize = 0, off1, off2;
371 guint32 mask = 0xff, pattern = 0xff;
374 gst_byte_reader_init (&br, data, size);
376 g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
377 g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
379 markersize = compute_resync_marker_size (vop, &pattern, &mask);
381 if (first_resync_marker) {
384 off1 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern, 0, size);
388 return GST_MPEG4_PARSER_NO_PACKET;
390 GST_DEBUG ("Resync code found at %i", off1);
392 packet->offset = off1;
393 packet->type = GST_MPEG4_RESYNC;
394 packet->marker_size = markersize;
396 off2 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern,
397 off1 + 2, size - off1 - 2);
400 return GST_MPEG4_PARSER_NO_PACKET_END;
402 packet->size = off2 - off1;
404 return GST_MPEG4_PARSER_OK;
408 /********** API **********/
412 * @packet: The #GstMpeg4Packet to fill
413 * @skip_user_data: %TRUE to skip user data packet %FALSE otherwize
414 * @vop: The last parsed #GstMpeg4VideoObjectPlane or %NULL if you do
415 * not need to detect the resync codes.
416 * @offset: offset from which to start the parsing
417 * @data: The data to parse
418 * @size: The size of the @data to parse
420 * Parses @data and fills @packet with the information of the next packet
423 * Returns: a #GstMpeg4ParseResult
426 gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
427 GstMpeg4VideoObjectPlane * vop, const guint8 * data, guint offset,
432 GstMpeg4ParseResult resync_res;
433 static guint first_resync_marker = TRUE;
435 gst_byte_reader_init (&br, data, size);
437 g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
439 if (size - offset <= 4) {
440 GST_DEBUG ("Can't parse, buffer is to small size %" G_GSSIZE_FORMAT
441 " at offset %d", size, offset);
442 return GST_MPEG4_PARSER_ERROR;
447 gst_mpeg4_next_resync (packet, vop, data + offset, size - offset,
448 first_resync_marker);
449 first_resync_marker = FALSE;
451 /* We found a complet slice */
452 if (resync_res == GST_MPEG4_PARSER_OK)
454 else if (resync_res == GST_MPEG4_PARSER_NO_PACKET_END) {
455 /* It doesn't mean there is no standard packet end, look for it */
456 off1 = packet->offset;
458 } else if (resync_res == GST_MPEG4_PARSER_NO_PACKET)
461 first_resync_marker = TRUE;
464 off1 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
465 offset, size - offset);
468 GST_DEBUG ("No start code prefix in this buffer");
469 return GST_MPEG4_PARSER_NO_PACKET;
472 /* Recursively skip user data if needed */
473 if (skip_user_data && data[off1 + 3] == GST_MPEG4_USER_DATA)
474 /* If we are here, we know no resync code has been found the first time, so we
475 * don't look for it this time */
476 return gst_mpeg4_parse (packet, skip_user_data, NULL, data, off1 + 3, size);
478 packet->offset = off1 + 3;
480 packet->type = (GstMpeg4StartCode) (data[off1 + 3]);
483 off2 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
484 off1 + 4, size - off1 - 4);
487 GST_DEBUG ("Packet start %d, No end found", off1 + 4);
489 packet->size = G_MAXUINT;
490 return GST_MPEG4_PARSER_NO_PACKET_END;
493 if (packet->type == GST_MPEG4_RESYNC) {
494 packet->size = (gsize) off2 - off1;
496 packet->size = (gsize) off2 - off1 - 3;
499 GST_DEBUG ("Complete packet of type %x found at: %d, Size: %" G_GSSIZE_FORMAT,
500 packet->type, packet->offset, packet->size);
501 return GST_MPEG4_PARSER_OK;
507 * @packet: The #GstMpeg4Packet to fill
508 * @offset: offset from which to start the parsing
509 * @data: The data to parse
510 * @size: The size of the @data to parse
512 * Parses @data and fills @packet with the information of the next packet
515 * Note that the type of the packet is meaningless in this case.
517 * Returns: a #GstMpeg4ParseResult
520 gst_h263_parse (GstMpeg4Packet * packet,
521 const guint8 * data, guint offset, gsize size)
526 gst_byte_reader_init (&br, data + offset, size - offset);
528 g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
530 if (size - offset < 3) {
531 GST_DEBUG ("Can't parse, buffer is to small size %" G_GSSIZE_FORMAT
532 " at offset %d", size, offset);
533 return GST_MPEG4_PARSER_ERROR;
536 off1 = find_psc (&br);
539 GST_DEBUG ("No start code prefix in this buffer");
540 return GST_MPEG4_PARSER_NO_PACKET;
543 packet->offset = off1 + offset;
546 gst_byte_reader_skip (&br, 3);
547 off2 = find_psc (&br);
550 GST_DEBUG ("Packet start %d, No end found", off1);
552 packet->size = G_MAXUINT;
553 return GST_MPEG4_PARSER_NO_PACKET_END;
556 packet->size = (gsize) off2 - off1;
558 GST_DEBUG ("Complete packet found at: %d, Size: %" G_GSSIZE_FORMAT,
559 packet->offset, packet->size);
561 return GST_MPEG4_PARSER_OK;
565 * gst_mpeg4_parse_visual_object_sequence:
566 * @vos: The #GstMpeg4VisualObjectSequence structure to fill
567 * @data: The data to parse, should contain the visual_object_sequence_start_code
568 * but not the start code prefix
569 * @size: The size of the @data to parse
571 * Parses @data containing the visual object sequence packet, and fills
572 * the @vos structure.
574 * Returns: a #GstMpeg4ParseResult
577 gst_mpeg4_parse_visual_object_sequence (GstMpeg4VisualObjectSequence * vos,
578 const guint8 * data, gsize size)
580 guint8 vos_start_code;
581 GstBitReader br = GST_BIT_READER_INIT (data, size);
583 g_return_val_if_fail (vos != NULL, GST_MPEG4_PARSER_ERROR);
585 READ_UINT8 (&br, vos_start_code, 8);
586 if (vos_start_code != GST_MPEG4_VISUAL_OBJ_SEQ_START)
587 goto wrong_start_code;
589 READ_UINT8 (&br, vos->profile_and_level_indication, 8);
591 switch (vos->profile_and_level_indication) {
593 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
594 vos->level = GST_MPEG4_LEVEL1;
597 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
598 vos->level = GST_MPEG4_LEVEL2;
601 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
602 vos->level = GST_MPEG4_LEVEL3;
605 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
606 vos->level = GST_MPEG4_LEVEL0;
609 vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
610 vos->level = GST_MPEG4_LEVEL0;
613 vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
614 vos->level = GST_MPEG4_LEVEL1;
617 vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
618 vos->level = GST_MPEG4_LEVEL2;
621 vos->profile = GST_MPEG4_PROFILE_CORE;
622 vos->level = GST_MPEG4_LEVEL1;
625 vos->profile = GST_MPEG4_PROFILE_CORE;
626 vos->level = GST_MPEG4_LEVEL2;
629 vos->profile = GST_MPEG4_PROFILE_MAIN;
630 vos->level = GST_MPEG4_LEVEL2;
633 vos->profile = GST_MPEG4_PROFILE_MAIN;
634 vos->level = GST_MPEG4_LEVEL3;
637 vos->profile = GST_MPEG4_PROFILE_MAIN;
638 vos->level = GST_MPEG4_LEVEL4;
641 vos->profile = GST_MPEG4_PROFILE_N_BIT;
642 vos->level = GST_MPEG4_LEVEL2;
645 vos->profile = GST_MPEG4_PROFILE_SCALABLE_TEXTURE;
646 vos->level = GST_MPEG4_LEVEL1;
649 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
650 vos->level = GST_MPEG4_LEVEL1;
653 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
654 vos->level = GST_MPEG4_LEVEL2;
657 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
658 vos->level = GST_MPEG4_LEVEL1;
661 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
662 vos->level = GST_MPEG4_LEVEL2;
665 vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
666 vos->level = GST_MPEG4_LEVEL1;
669 vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
670 vos->level = GST_MPEG4_LEVEL2;
673 vos->profile = GST_MPEG4_PROFILE_HYBRID;
674 vos->level = GST_MPEG4_LEVEL1;
677 vos->profile = GST_MPEG4_PROFILE_HYBRID;
678 vos->level = GST_MPEG4_LEVEL2;
681 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
682 vos->level = GST_MPEG4_LEVEL1;
685 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
686 vos->level = GST_MPEG4_LEVEL2;
689 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
690 vos->level = GST_MPEG4_LEVEL3;
693 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
694 vos->level = GST_MPEG4_LEVEL4;
697 vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
698 vos->level = GST_MPEG4_LEVEL1;
701 vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
702 vos->level = GST_MPEG4_LEVEL2;
705 vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
706 vos->level = GST_MPEG4_LEVEL3;
709 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
710 vos->level = GST_MPEG4_LEVEL1;
713 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
714 vos->level = GST_MPEG4_LEVEL2;
717 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
718 vos->level = GST_MPEG4_LEVEL3;
721 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
722 vos->level = GST_MPEG4_LEVEL4;
725 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
726 vos->level = GST_MPEG4_LEVEL1;
729 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
730 vos->level = GST_MPEG4_LEVEL2;
733 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
734 vos->level = GST_MPEG4_LEVEL3;
737 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
738 vos->level = GST_MPEG4_LEVEL1;
741 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
742 vos->level = GST_MPEG4_LEVEL2;
745 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
746 vos->level = GST_MPEG4_LEVEL3;
749 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
750 vos->level = GST_MPEG4_LEVEL1;
753 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
754 vos->level = GST_MPEG4_LEVEL2;
757 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
758 vos->level = GST_MPEG4_LEVEL3;
761 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
762 vos->level = GST_MPEG4_LEVEL4;
765 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
766 vos->level = GST_MPEG4_LEVEL1;
769 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
770 vos->level = GST_MPEG4_LEVEL2;
773 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
774 vos->level = GST_MPEG4_LEVEL3;
777 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
778 vos->level = GST_MPEG4_LEVEL4;
781 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
782 vos->level = GST_MPEG4_LEVEL0;
785 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
786 vos->level = GST_MPEG4_LEVEL1;
789 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
790 vos->level = GST_MPEG4_LEVEL2;
793 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
794 vos->level = GST_MPEG4_LEVEL3;
797 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
798 vos->level = GST_MPEG4_LEVEL4;
801 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
802 vos->level = GST_MPEG4_LEVEL5;
805 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
806 vos->level = GST_MPEG4_LEVEL3b;
809 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
810 vos->level = GST_MPEG4_LEVEL0;
813 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
814 vos->level = GST_MPEG4_LEVEL1;
817 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
818 vos->level = GST_MPEG4_LEVEL2;
821 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
822 vos->level = GST_MPEG4_LEVEL3;
825 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
826 vos->level = GST_MPEG4_LEVEL4;
829 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
830 vos->level = GST_MPEG4_LEVEL5;
833 vos->profile = GST_MPEG4_PROFILE_RESERVED;
834 vos->level = GST_MPEG4_LEVEL_RESERVED;
838 return GST_MPEG4_PARSER_OK;
841 GST_WARNING ("got buffer with wrong start code");
842 return GST_MPEG4_PARSER_ERROR;
845 GST_WARNING ("failed parsing \"Visual Object\"");
846 return GST_MPEG4_PARSER_ERROR;
850 * gst_mpeg4_parse_visual_object:
851 * @vo: The #GstMpeg4VisualObject structure to fill
852 * @signal_type: The #GstMpeg4VideoSignalType to fill or %NULL
853 * @data: The data to parse, should contain the vo_start_code
854 * but not the start code prefix
855 * @size: The size of the @data to parse
857 * Parses @data containing the visual object packet, and fills
860 * Returns: a #GstMpeg4ParseResult
863 gst_mpeg4_parse_visual_object (GstMpeg4VisualObject * vo,
864 GstMpeg4VideoSignalType * signal_type, const guint8 * data, gsize size)
866 guint8 vo_start_code, type;
867 GstBitReader br = GST_BIT_READER_INIT (data, size);
869 g_return_val_if_fail (vo != NULL, GST_MPEG4_PARSER_ERROR);
871 GST_DEBUG ("Parsing visual object");
873 READ_UINT8 (&br, vo_start_code, 8);
874 if (vo_start_code != GST_MPEG4_VISUAL_OBJ)
875 goto wrong_start_code;
877 /* set default values */
881 READ_UINT8 (&br, vo->is_identifier, 1);
882 if (vo->is_identifier) {
883 READ_UINT8 (&br, vo->verid, 4);
884 READ_UINT8 (&br, vo->priority, 3);
887 READ_UINT8 (&br, type, 4);
890 if ((type == GST_MPEG4_VIDEO_ID ||
891 type == GST_MPEG4_STILL_TEXTURE_ID) && signal_type) {
893 if (!parse_signal_type (&br, signal_type))
896 } else if (signal_type) {
897 signal_type->type = 0;
900 return GST_MPEG4_PARSER_OK;
903 GST_WARNING ("got buffer with wrong start code");
904 return GST_MPEG4_PARSER_ERROR;
907 GST_WARNING ("failed parsing \"Visual Object\"");
908 return GST_MPEG4_PARSER_ERROR;
912 * gst_mpeg4_parse_video_object_layer:
913 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
914 * @vo: The #GstMpeg4VisualObject currently being parsed or %NULL
915 * @data: The data to parse
916 * @size: The size of the @data to parse
918 * Parses @data containing the video object layer packet, and fills
919 * the @vol structure.
921 * Returns: a #GstMpeg4ParseResult
924 gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer * vol,
925 GstMpeg4VisualObject * vo, const guint8 * data, gsize size)
927 guint8 video_object_layer_start_code;
929 /* Used for enums types */
931 GstBitReader br = GST_BIT_READER_INIT (data, size);
933 g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
935 GST_DEBUG ("Parsing video object layer");
937 READ_UINT8 (&br, video_object_layer_start_code, 8);
938 if (!(video_object_layer_start_code >= GST_MPEG4_VIDEO_LAYER_FIRST &&
939 video_object_layer_start_code <= GST_MPEG4_VIDEO_LAYER_LAST))
940 goto wrong_start_code;
942 /* set default values */
944 vol->verid = vo->verid;
945 vol->priority = vo->priority;
948 vol->low_delay = FALSE;
949 vol->chroma_format = 1;
950 vol->vbv_parameters = FALSE;
951 vol->quant_precision = 5;
952 vol->bits_per_pixel = 8;
953 vol->quarter_sample = FALSE;
954 vol->newpred_enable = FALSE;
959 READ_UINT8 (&br, vol->random_accessible_vol, 1);
960 READ_UINT8 (&br, vol->video_object_type_indication, 8);
962 READ_UINT8 (&br, vol->is_object_layer_identifier, 1);
963 if (vol->is_object_layer_identifier) {
964 READ_UINT8 (&br, vol->verid, 4);
965 READ_UINT8 (&br, vol->priority, 3);
968 READ_UINT8 (&br, tmp, 4);
969 vol->aspect_ratio_info = tmp;
970 if (vol->aspect_ratio_info != GST_MPEG4_EXTENDED_PAR) {
971 mpeg4_util_par_from_info (vol->aspect_ratio_info, &vol->par_width,
977 READ_UINT8 (&br, vol->par_width, 8);
979 CHECK_ALLOWED (v, 1, 255);
981 READ_UINT8 (&br, vol->par_height, 8);
983 CHECK_ALLOWED (v, 1, 255);
985 GST_DEBUG ("Pixel aspect ratio %d/%d", vol->par_width, vol->par_width);
987 READ_UINT8 (&br, vol->control_parameters, 1);
988 if (vol->control_parameters) {
989 guint8 chroma_format;
991 READ_UINT8 (&br, chroma_format, 2);
992 vol->chroma_format = chroma_format;
993 READ_UINT8 (&br, vol->low_delay, 1);
995 READ_UINT8 (&br, vol->vbv_parameters, 1);
996 if (vol->vbv_parameters) {
997 CHECK_REMAINING (&br, 79);
999 vol->first_half_bitrate =
1000 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1001 MARKER_UNCHECKED (&br);
1003 vol->latter_half_bitrate =
1004 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1005 MARKER_UNCHECKED (&br);
1008 (vol->first_half_bitrate << 15) | vol->latter_half_bitrate;
1010 vol->first_half_vbv_buffer_size =
1011 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1012 MARKER_UNCHECKED (&br);
1014 vol->latter_half_vbv_buffer_size =
1015 gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
1016 MARKER_UNCHECKED (&br);
1018 vol->vbv_buffer_size = (vol->first_half_vbv_buffer_size << 15) |
1019 vol->latter_half_vbv_buffer_size;
1021 vol->first_half_vbv_occupancy =
1022 gst_bit_reader_get_bits_uint16_unchecked (&br, 11);
1023 MARKER_UNCHECKED (&br);
1025 vol->latter_half_vbv_occupancy =
1026 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1027 MARKER_UNCHECKED (&br);
1031 READ_UINT8 (&br, tmp, 2);
1034 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1035 /* TODO support grayscale shapes, for now we just pass */
1037 /* Something the standard starts to define... */
1038 GST_WARNING ("Grayscale shaped not supported");
1042 if (vol->shape == GST_MPEG4_GRAYSCALE && vol->verid != 0x01)
1043 READ_UINT8 (&br, vol->shape_extension, 4);
1045 CHECK_REMAINING (&br, 19);
1047 MARKER_UNCHECKED (&br);
1048 vol->vop_time_increment_resolution =
1049 gst_bit_reader_get_bits_uint16_unchecked (&br, 16);
1050 if (vol->vop_time_increment_resolution < 1) {
1051 GST_WARNING ("value not in allowed range. value: %d, range %d-%d",
1052 vol->vop_time_increment_resolution, 1, G_MAXUINT16);
1055 vol->vop_time_increment_bits =
1056 g_bit_storage (vol->vop_time_increment_resolution);
1058 MARKER_UNCHECKED (&br);
1059 vol->fixed_vop_rate = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1060 if (vol->fixed_vop_rate)
1061 READ_UINT16 (&br, vol->fixed_vop_time_increment,
1062 vol->vop_time_increment_bits);
1064 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1065 if (vol->shape == GST_MPEG4_RECTANGULAR) {
1066 CHECK_REMAINING (&br, 29);
1068 MARKER_UNCHECKED (&br);
1069 vol->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1070 MARKER_UNCHECKED (&br);
1071 vol->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1072 MARKER_UNCHECKED (&br);
1075 READ_UINT8 (&br, vol->interlaced, 1);
1076 READ_UINT8 (&br, vol->obmc_disable, 1);
1078 if (vol->verid == 0x1) {
1079 READ_UINT8 (&br, tmp, 1);
1080 vol->sprite_enable = tmp;
1082 READ_UINT8 (&br, tmp, 2);
1083 vol->sprite_enable = tmp;
1085 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
1086 vol->sprite_enable == GST_MPEG4_SPRITE_GMG) {
1088 if (vol->sprite_enable == GST_MPEG4_SPRITE_GMG)
1089 CHECK_REMAINING (&br, 9);
1091 CHECK_REMAINING (&br, 65);
1093 vol->sprite_width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1094 MARKER_UNCHECKED (&br);
1096 vol->sprite_height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1097 MARKER_UNCHECKED (&br);
1099 vol->sprite_left_coordinate =
1100 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1101 MARKER_UNCHECKED (&br);
1103 vol->sprite_top_coordinate =
1104 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1105 MARKER_UNCHECKED (&br);
1107 vol->no_of_sprite_warping_points =
1108 gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1109 vol->sprite_warping_accuracy =
1110 gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
1111 vol->sprite_brightness_change =
1112 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1114 if (vol->sprite_enable != GST_MPEG4_SPRITE_GMG)
1115 vol->low_latency_sprite_enable =
1116 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1119 if (vol->shape != GST_MPEG4_RECTANGULAR)
1120 READ_UINT8 (&br, vol->sadct_disable, 1);
1122 READ_UINT8 (&br, vol->not_8_bit, 1);
1123 if (vol->not_8_bit) {
1124 READ_UINT8 (&br, vol->quant_precision, 4);
1125 CHECK_ALLOWED (vol->quant_precision, 3, 9);
1127 READ_UINT8 (&br, vol->bits_per_pixel, 4);
1128 CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
1131 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1132 /* We don't actually support it */
1133 READ_UINT8 (&br, vol->no_gray_quant_update, 1);
1134 READ_UINT8 (&br, vol->composition_method, 1);
1135 READ_UINT8 (&br, vol->linear_composition, 1);
1138 READ_UINT8 (&br, vol->quant_type, 1);
1139 if (vol->quant_type) {
1140 if (!parse_quant (&br, vol->intra_quant_mat, default_intra_quant_mat,
1141 &vol->load_intra_quant_mat))
1144 if (!parse_quant (&br, vol->non_intra_quant_mat,
1145 default_non_intra_quant_mat, &vol->load_non_intra_quant_mat))
1148 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1149 /* Something the standard starts to define... */
1150 GST_WARNING ("Grayscale shaped not supported");
1155 memset (&vol->intra_quant_mat, 0, 64);
1156 memset (&vol->non_intra_quant_mat, 0, 64);
1159 if (vol->verid != 0x1)
1160 READ_UINT8 (&br, vol->quarter_sample, 1);
1162 READ_UINT8 (&br, vol->complexity_estimation_disable, 1);
1163 if (!vol->complexity_estimation_disable)
1164 goto complexity_estimation_error;
1167 READ_UINT8 (&br, vol->resync_marker_disable, 1);
1168 READ_UINT8 (&br, vol->data_partitioned, 1);
1170 if (vol->data_partitioned)
1171 READ_UINT8 (&br, vol->reversible_vlc, 1);
1173 if (vol->verid != 0x01)
1174 READ_UINT8 (&br, vol->newpred_enable, 1);
1176 if (vol->newpred_enable)
1177 /* requested_upstream_message_type and newpred_segment_type */
1180 READ_UINT8 (&br, vol->reduced_resolution_vop_enable, 1);
1182 READ_UINT8 (&br, vol->scalability, 1);
1183 if (vol->scalability) {
1184 SKIP (&br, 26); /* Few not needed props */
1185 READ_UINT8 (&br, vol->enhancement_type, 1);
1188 /* More unused infos */
1189 } else if (vol->verid != 0x01) {
1190 GST_WARNING ("Binary only shapes not fully supported");
1195 return GST_MPEG4_PARSER_OK;
1198 GST_WARNING ("failed parsing \"Video Object Layer\"");
1199 return GST_MPEG4_PARSER_ERROR;
1202 GST_WARNING ("got buffer with wrong start code");
1205 complexity_estimation_error:
1206 GST_WARNING ("don't support complexity estimation");
1211 * gst_mpeg4_parse_group_of_vop:
1212 * @gov: The #GstMpeg4GroupOfVOP structure to fill
1213 * @data: The data to parse
1214 * @size: The size of the @data to parse
1216 * Parses @data containing the group of video object plane packet, and fills
1217 * the @gov structure.
1219 * Returns: a #GstMpeg4ParseResult
1222 gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *
1223 gov, const guint8 * data, gsize size)
1225 guint8 gov_start_code;
1226 GstBitReader br = GST_BIT_READER_INIT (data, size);
1228 g_return_val_if_fail (gov != NULL, GST_MPEG4_PARSER_ERROR);
1230 READ_UINT8 (&br, gov_start_code, 8);
1231 if (gov_start_code != GST_MPEG4_GROUP_OF_VOP)
1232 goto wrong_start_code;
1234 CHECK_REMAINING (&br, 65);
1236 gov->hours = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
1237 gov->minutes = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1239 MARKER_UNCHECKED (&br);
1240 gov->seconds = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1242 gov->closed = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1243 gov->broken_link = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1245 return GST_MPEG4_PARSER_OK;
1248 GST_WARNING ("failed parsing \"Group of Video Object Plane\"");
1249 return GST_MPEG4_PARSER_ERROR;
1252 GST_WARNING ("got buffer with wrong start code");
1257 * gst_mpeg4_parse_video_object_plane:
1258 * @vop: The #GstMpeg4VideoObjectPlane currently being parsed
1259 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
1260 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
1261 * @data: The data to parse
1262 * @size: The size of the @data to parse
1264 * Parses @data containing the video object plane packet, and fills the @vol
1267 * Returns: a #GstMpeg4ParseResult
1270 gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane * vop,
1271 GstMpeg4SpriteTrajectory * sprite_trajectory,
1272 GstMpeg4VideoObjectLayer * vol, const guint8 * data, gsize size)
1274 guint8 vop_start_code, coding_type, modulo_time_base;
1275 GstBitReader br = GST_BIT_READER_INIT (data, size);
1277 g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
1279 if (vol->shape == GST_MPEG4_BINARY_ONLY) {
1280 /* TODO: implement binary only shapes */
1281 GST_WARNING ("Binary only shapes not supported");
1285 READ_UINT8 (&br, vop_start_code, 8);
1286 if (vop_start_code != GST_MPEG4_VIDEO_OBJ_PLANE)
1287 goto wrong_start_code;
1290 /* set default values */
1291 vop->modulo_time_base = 0;
1292 vop->rounding_type = 0;
1293 vop->top_field_first = 1;
1294 vop->alternate_vertical_scan_flag = 0;
1295 vop->fcode_forward = 1;
1296 vop->fcode_backward = 1;
1298 /* Compute macroblock informations */
1299 if (vol->interlaced)
1300 vop->mb_height = (2 * (vol->height + 31) / 32);
1302 vop->mb_height = (vol->height + 15) / 16;
1304 vop->mb_width = (vol->width + 15) / 16;
1305 vop->mb_num = vop->mb_height * vop->mb_width;
1307 READ_UINT8 (&br, coding_type, 2);
1308 vop->coding_type = coding_type;
1310 READ_UINT8 (&br, modulo_time_base, 1);
1311 while (modulo_time_base) {
1312 vop->modulo_time_base++;
1314 READ_UINT8 (&br, modulo_time_base, 1);
1317 CHECK_REMAINING (&br, vol->vop_time_increment_bits + 3);
1319 MARKER_UNCHECKED (&br);
1320 vop->time_increment =
1321 gst_bit_reader_get_bits_uint16_unchecked (&br,
1322 vol->vop_time_increment_bits);
1323 MARKER_UNCHECKED (&br);
1325 vop->coded = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1327 return GST_MPEG4_PARSER_OK;
1329 if (vol->newpred_enable) {
1331 vop->time_increment + 3 < 15 ? vop->time_increment + 3 : 15;
1333 READ_UINT16 (&br, vop->id, nbbits);
1334 READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
1335 if (vop->id_for_prediction_indication) {
1336 /* Would be nice if the standard actually told us... */
1337 READ_UINT16 (&br, vop->id, nbbits);
1342 if (vol->shape != GST_MPEG4_BINARY_ONLY &&
1343 (vop->coding_type == GST_MPEG4_P_VOP ||
1344 (vop->coding_type == GST_MPEG4_S_VOP &&
1345 vol->sprite_enable == GST_MPEG4_SPRITE_GMG)))
1346 READ_UINT8 (&br, vop->rounding_type, 1);
1348 if ((vol->reduced_resolution_vop_enable) &&
1349 (vol->shape == GST_MPEG4_RECTANGULAR ||
1350 (vop->coding_type = GST_MPEG4_P_VOP ||
1351 vop->coding_type == GST_MPEG4_I_VOP)))
1352 READ_UINT8 (&br, vop->reduced_resolution, 1);
1354 if (vol->shape != GST_MPEG4_RECTANGULAR) {
1355 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
1356 vop->coding_type == GST_MPEG4_I_VOP) {
1357 CHECK_REMAINING (&br, 55);
1359 vop->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1360 MARKER_UNCHECKED (&br);
1362 vop->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1363 MARKER_UNCHECKED (&br);
1365 vop->horizontal_mc_spatial_ref =
1366 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1367 MARKER_UNCHECKED (&br);
1369 vop->vertical_mc_spatial_ref =
1370 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1371 MARKER_UNCHECKED (&br);
1373 /* Recompute the Macroblock informations
1374 * accordingly to the new values */
1375 if (vol->interlaced)
1376 vop->mb_height = (2 * (vol->height + 31) / 32);
1378 vop->mb_height = (vol->height + 15) / 16;
1380 vop->mb_width = (vol->width + 15) / 16;
1381 vop->mb_num = vop->mb_height * vop->mb_width;
1384 if ((vol->shape != GST_MPEG4_BINARY_ONLY) &&
1385 vol->scalability && vol->enhancement_type)
1386 READ_UINT8 (&br, vop->background_composition, 1);
1388 READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
1390 READ_UINT8 (&br, vop->constant_alpha, 1);
1391 if (vop->constant_alpha)
1392 READ_UINT8 (&br, vop->constant_alpha_value, 1);
1395 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1396 if (!vol->complexity_estimation_disable) {
1397 GST_WARNING ("Complexity estimation not supported");
1401 READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
1403 if (vol->interlaced) {
1404 READ_UINT8 (&br, vop->top_field_first, 1);
1405 READ_UINT8 (&br, vop->alternate_vertical_scan_flag, 1);
1409 if ((vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
1410 vol->sprite_enable == GST_MPEG4_SPRITE_GMG) &&
1411 vop->coding_type == GST_MPEG4_S_VOP) {
1413 /* only if @sprite_trajectory is not NULL we parse it */
1414 if (sprite_trajectory && vol->no_of_sprite_warping_points)
1415 parse_sprite_trajectory (&br, sprite_trajectory,
1416 vol->no_of_sprite_warping_points);
1418 if (vol->sprite_brightness_change) {
1419 GST_WARNING ("sprite_brightness_change not supported");
1423 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC) {
1424 GST_WARNING ("sprite enable static not supported");
1429 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1430 READ_UINT16 (&br, vop->quant, vol->quant_precision);
1432 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1433 /* TODO implement grayscale support */
1434 GST_WARNING ("Grayscale shapes no supported");
1436 /* TODO implement me */
1440 if (vop->coding_type != GST_MPEG4_I_VOP) {
1441 READ_UINT8 (&br, vop->fcode_forward, 3);
1442 CHECK_ALLOWED (vop->fcode_forward, 1, 7);
1445 if (vop->coding_type == GST_MPEG4_B_VOP) {
1446 READ_UINT8 (&br, vop->fcode_backward, 3);
1447 CHECK_ALLOWED (vop->fcode_backward, 1, 7);
1451 if (!vol->scalability) {
1452 if (vol->shape != GST_MPEG4_RECTANGULAR)
1453 READ_UINT8 (&br, vop->shape_coding_type, 1);
1456 if (vol->enhancement_type) {
1457 READ_UINT8 (&br, vop->load_backward_shape, 1);
1459 if (vop->load_backward_shape) {
1460 GST_WARNING ("Load backward shape not supported");
1464 READ_UINT8 (&br, vop->ref_select_code, 2);
1468 vop->size = gst_bit_reader_get_pos (&br);
1469 /* More things to possibly parse ... */
1471 return GST_MPEG4_PARSER_OK;
1474 GST_WARNING ("failed parsing \"Video Object Plane\"");
1475 return GST_MPEG4_PARSER_ERROR;
1478 GST_WARNING ("got buffer with wrong start code");
1483 * gst_mpeg4_parse_video_plane_with_short_header:
1484 * @shorthdr: The #GstMpeg4VideoPlaneShortHdr to parse
1485 * @data: The data to parse
1486 * @size: The size of the @data to parse
1489 gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
1490 shorthdr, const guint8 * data, gsize size)
1494 GstBitReader br = GST_BIT_READER_INIT (data, size);
1496 g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR);
1498 if (gst_bit_reader_get_remaining (&br) < 48)
1501 if (gst_bit_reader_get_bits_uint32_unchecked (&br, 22) != 0x20)
1504 shorthdr->temporal_reference =
1505 gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
1507 zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1508 if (zero_bits != 0x00)
1511 shorthdr->split_screen_indicator =
1512 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1513 shorthdr->document_camera_indicator =
1514 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1515 shorthdr->full_picture_freeze_release =
1516 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1517 shorthdr->source_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
1519 /* Set parameters/Table 6-25 */
1520 switch (shorthdr->source_format) {
1522 shorthdr->vop_width = 128;
1523 shorthdr->vop_height = 96;
1524 shorthdr->num_macroblocks_in_gob = 8;
1525 shorthdr->num_gobs_in_vop = 6;
1528 shorthdr->vop_width = 176;
1529 shorthdr->vop_height = 144;
1530 shorthdr->num_macroblocks_in_gob = 11;
1531 shorthdr->num_gobs_in_vop = 9;
1534 shorthdr->vop_width = 352;
1535 shorthdr->vop_height = 288;
1536 shorthdr->num_macroblocks_in_gob = 22;
1537 shorthdr->num_gobs_in_vop = 18;
1540 shorthdr->vop_width = 704;
1541 shorthdr->vop_height = 576;
1542 shorthdr->num_macroblocks_in_gob = 88;
1543 shorthdr->num_gobs_in_vop = 18;
1546 shorthdr->vop_width = 1408;
1547 shorthdr->vop_height = 1152;
1548 shorthdr->num_macroblocks_in_gob = 352;
1549 shorthdr->num_gobs_in_vop = 18;
1552 shorthdr->vop_width = 0;
1553 shorthdr->vop_height = 0;
1554 shorthdr->num_macroblocks_in_gob = 0;
1555 shorthdr->num_gobs_in_vop = 0;
1558 shorthdr->picture_coding_type =
1559 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1560 zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
1562 if (zero_bits != 0x00)
1565 shorthdr->vop_quant = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
1566 zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1568 if (zero_bits != 0x00)
1572 READ_UINT8 (&br, shorthdr->pei, 1);
1574 if (shorthdr->pei == 1)
1575 READ_UINT8 (&br, shorthdr->psupp, 8);
1577 } while (shorthdr->pei == 1);
1579 shorthdr->size = gst_bit_reader_get_pos (&br);
1581 return GST_MPEG4_PARSER_OK;
1584 GST_WARNING ("Could not parse the Plane short header");
1586 return GST_MPEG4_PARSER_ERROR;
1590 * gst_mpeg4_parse_video_packet_header:
1591 * @videopackethdr: The #GstMpeg4VideoPacketHdr structure to fill
1592 * @vol: The last parsed #GstMpeg4VideoObjectLayer, will be updated
1593 * with the informations found during the parsing
1594 * @vop: The last parsed #GstMpeg4VideoObjectPlane, will be updated
1595 * with the informations found during the parsing
1596 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
1597 * with the informations found during the parsing
1598 * @data: The data to parse, should be set after the resync marker.
1599 * @size: The size of the data to parse
1601 * Parsers @data containing the video packet header
1602 * and fills the @videopackethdr structure
1605 gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
1606 GstMpeg4VideoObjectLayer * vol, GstMpeg4VideoObjectPlane * vop,
1607 GstMpeg4SpriteTrajectory * sprite_trajectory, const guint8 * data,
1611 GstBitReader br = GST_BIT_READER_INIT (data, size);
1613 g_return_val_if_fail (videopackethdr != NULL, GST_MPEG4_PARSER_ERROR);
1614 g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
1616 markersize = compute_resync_marker_size (vop, NULL, NULL);
1618 CHECK_REMAINING (&br, markersize);
1620 if (gst_bit_reader_get_bits_uint32_unchecked (&br, markersize + 1) != 0x01)
1623 if (vol->shape != GST_MPEG4_RECTANGULAR) {
1624 READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
1625 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
1626 vop->coding_type == GST_MPEG4_I_VOP) {
1628 CHECK_REMAINING (&br, 56);
1630 U_READ_UINT16 (&br, vop->width, 13);
1632 U_READ_UINT16 (&br, vop->height, 13);
1634 U_READ_UINT16 (&br, vop->horizontal_mc_spatial_ref, 13);
1636 U_READ_UINT16 (&br, vop->vertical_mc_spatial_ref, 13);
1639 /* Update macroblock infirmations */
1640 vop->mb_height = (vop->height + 15) / 16;
1641 vop->mb_width = (vop->width + 15) / 16;
1642 vop->mb_num = vop->mb_height * vop->mb_width;
1646 READ_UINT16 (&br, videopackethdr->macroblock_number,
1647 g_bit_storage (vop->mb_num - 1));
1649 if (vol->shape != GST_MPEG4_BINARY_ONLY)
1650 READ_UINT16 (&br, videopackethdr->quant_scale, vol->quant_precision);
1652 if (vol->shape == GST_MPEG4_RECTANGULAR)
1653 READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
1655 if (videopackethdr->header_extension_code) {
1657 guint8 bit = 0, coding_type;
1660 READ_UINT8 (&br, bit, 1);
1664 vol->vop_time_increment_bits = timeincr;
1667 READ_UINT16 (&br, vop->time_increment, timeincr);
1669 READ_UINT8 (&br, coding_type, 2);
1670 vop->coding_type = coding_type;
1672 if (vol->shape != GST_MPEG4_RECTANGULAR) {
1673 READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
1674 if (vop->coding_type != GST_MPEG4_I_VOP)
1675 READ_UINT8 (&br, vop->shape_coding_type, 1);
1678 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1679 READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
1681 if (sprite_trajectory && vol->sprite_enable == GST_MPEG4_SPRITE_GMG &&
1682 vop->coding_type == GST_MPEG4_S_VOP &&
1683 vol->no_of_sprite_warping_points > 0) {
1685 parse_sprite_trajectory (&br, sprite_trajectory,
1686 vol->no_of_sprite_warping_points);
1689 if (vol->reduced_resolution_vop_enable &&
1690 vol->shape == GST_MPEG4_RECTANGULAR &&
1691 (vop->coding_type == GST_MPEG4_P_VOP ||
1692 vop->coding_type == GST_MPEG4_I_VOP))
1693 READ_UINT8 (&br, vop->reduced_resolution, 1);
1695 if (vop->coding_type != GST_MPEG4_I_VOP) {
1696 READ_UINT8 (&br, vop->fcode_forward, 3);
1697 CHECK_ALLOWED (vop->fcode_forward, 1, 7);
1700 if (vop->coding_type == GST_MPEG4_B_VOP) {
1701 READ_UINT8 (&br, vop->fcode_backward, 3);
1702 CHECK_ALLOWED (vop->fcode_backward, 1, 7);
1707 if (vol->newpred_enable) {
1709 vol->vop_time_increment_bits + 3 < 15 ? vop->time_increment + 3 : 15;
1711 READ_UINT16 (&br, vop->id, nbbits);
1712 READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
1713 if (vop->id_for_prediction_indication) {
1714 /* Would be nice if the standard actually told us... */
1715 READ_UINT16 (&br, vop->id, nbbits);
1720 videopackethdr->size = gst_bit_reader_get_pos (&br);
1723 GST_DEBUG ("Failed to parse video packet header");
1725 return GST_MPEG4_PARSER_NO_PACKET;