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., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 * SECTION:gstmpeg4parser
23 * @title: GstMpeg4Parser
24 * @short_description: Convenience library for parsing mpeg4 part 2 video
27 * For more details about the structures, you can refer to the
28 * specifications: ISO-IEC-14496-2_2004_MPEG4_VISUAL.pdf
36 #include <gst/base/gstbitreader.h>
37 #include <gst/base/gstbytereader.h>
40 #include "gstmpeg4parser.h"
41 #include "parserutils.h"
43 #ifndef GST_DISABLE_GST_DEBUG
45 #define GST_CAT_DEFAULT ensure_debug_category()
47 static GstDebugCategory *
48 ensure_debug_category (void)
50 static gsize cat_gonce = 0;
52 if (g_once_init_enter (&cat_gonce)) {
55 cat_done = (gsize) _gst_debug_category_new ("codecparsers_mpeg4", 0,
56 "GstMpeg4 codec parsing library");
58 g_once_init_leave (&cat_gonce, cat_done);
61 return (GstDebugCategory *) cat_gonce;
66 #define ensure_debug_category() /* NOOP */
68 #endif /* GST_DISABLE_GST_DEBUG */
70 #define CHECK_MARKER(br) G_STMT_START { \
72 if (!gst_bit_reader_get_bits_uint8 (br, &marker, 1)) { \
73 GST_WARNING ("failed to read marker bit"); \
75 } else if (!marker) {\
76 GST_WARNING ("Wrong marker bit"); \
81 #define MARKER_UNCHECKED(br) G_STMT_START { \
82 if (!gst_bit_reader_get_bits_uint8_unchecked (br, 1)) { \
83 GST_WARNING ("Wrong marker bit"); \
88 #define CHECK_REMAINING(br, needed) G_STMT_START { \
89 if (gst_bit_reader_get_remaining (br) < needed) \
93 static const guint8 default_intra_quant_mat[64] = {
94 8, 17, 18, 19, 21, 23, 25, 27,
95 17, 18, 19, 21, 23, 25, 27, 28,
96 20, 21, 22, 23, 24, 26, 28, 30,
97 21, 22, 23, 24, 26, 28, 30, 32,
98 22, 23, 24, 26, 28, 30, 32, 35,
99 23, 24, 26, 28, 30, 32, 35, 38,
100 25, 26, 28, 30, 32, 35, 38, 41,
101 27, 28, 30, 32, 35, 38, 41, 45
104 static const guint8 default_non_intra_quant_mat[64] = {
105 16, 17, 18, 19, 20, 21, 22, 23,
106 17, 18, 19, 20, 21, 22, 23, 24,
107 18, 19, 20, 21, 22, 23, 24, 25,
108 19, 20, 21, 22, 23, 24, 26, 27,
109 20, 21, 22, 23, 25, 26, 27, 28,
110 21, 22, 23, 24, 26, 27, 28, 30,
111 22, 23, 24, 26, 27, 28, 30, 31,
112 23, 24, 25, 27, 28, 30, 31, 33,
115 static const guint8 mpeg4_zigzag_8x8[64] = {
116 0, 1, 8, 16, 9, 2, 3, 10,
117 17, 24, 32, 25, 18, 11, 4, 5,
118 12, 19, 26, 33, 40, 48, 41, 34,
119 27, 20, 13, 6, 7, 14, 21, 28,
120 35, 42, 49, 56, 57, 50, 43, 36,
121 29, 22, 15, 23, 30, 37, 44, 51,
122 58, 59, 52, 45, 38, 31, 39, 46,
123 53, 60, 61, 54, 47, 55, 62, 63
126 static const VLCTable mpeg4_dmv_size_vlc_table[] = {
145 mpeg4_util_par_from_info (guint8 aspect_ratio_info, guint8 * par_width,
148 switch (aspect_ratio_info) {
174 parse_quant (GstBitReader * br, guint8 quant_mat[64],
175 const guint8 default_quant_mat[64], guint8 * load_quant_mat)
177 READ_UINT8 (br, *load_quant_mat, 1);
178 if (*load_quant_mat) {
183 for (i = 0; i < 64; i++) {
186 READ_UINT8 (br, val, 8);
190 goto invalid_quant_mat;
191 quant_mat[mpeg4_zigzag_8x8[i]] = quant_mat[mpeg4_zigzag_8x8[i - 1]];
193 quant_mat[mpeg4_zigzag_8x8[i]] = val;
196 memcpy (quant_mat, default_quant_mat, 64);
201 GST_WARNING ("failed parsing quant matrix");
205 GST_WARNING ("the first value should be non zero");
210 parse_signal_type (GstBitReader * br, GstMpeg4VideoSignalType * signal_type)
212 READ_UINT8 (br, signal_type->type, 1);
214 if (signal_type->type) {
216 READ_UINT8 (br, signal_type->format, 3);
217 READ_UINT8 (br, signal_type->range, 1);
218 READ_UINT8 (br, signal_type->color_description, 1);
220 if (signal_type->color_description) {
221 READ_UINT8 (br, signal_type->color_primaries, 8);
222 READ_UINT8 (br, signal_type->transfer_characteristics, 8);
223 READ_UINT8 (br, signal_type->matrix_coefficients, 8);
230 GST_WARNING ("failed parsing \"Video Signal Type\"");
236 parse_sprite_trajectory (GstBitReader * br,
237 GstMpeg4SpriteTrajectory * sprite_traj, guint no_of_sprite_warping_points)
241 for (i = 0; i < no_of_sprite_warping_points; i++) {
243 if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
244 G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
248 READ_UINT16 (br, sprite_traj->vop_ref_points[i], length);
251 if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
252 G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
256 READ_UINT16 (br, sprite_traj->sprite_ref_points[i], length);
263 GST_WARNING ("Could not parse the sprite trajectory");
268 find_psc (GstByteReader * br)
270 guint psc_pos = -1, psc;
272 if (!gst_byte_reader_peek_uint24_be (br, &psc))
275 /* Scan for the picture start code (22 bits - 0x0020) */
276 while ((gst_byte_reader_get_remaining (br) >= 3)) {
277 if (gst_byte_reader_peek_uint24_be (br, &psc) &&
278 ((psc & 0xfffffc) == 0x000080)) {
279 psc_pos = gst_byte_reader_get_pos (br);
282 gst_byte_reader_skip_unchecked (br, 1);
291 compute_resync_marker_size (const GstMpeg4VideoObjectPlane * vop,
292 guint32 * pattern, guint32 * mask)
296 /* FIXME handle the binary only shape case */
297 switch (vop->coding_type) {
298 case (GST_MPEG4_I_VOP):
301 case (GST_MPEG4_S_VOP):
302 case (GST_MPEG4_P_VOP):
303 off = 15 + vop->fcode_forward;
306 case (GST_MPEG4_B_VOP):
307 off = MAX (15 + MAX (vop->fcode_forward, vop->fcode_backward), 17);
314 if (mask && pattern) {
317 *pattern = 0x00008000;
321 *pattern = 0x00004000;
325 *pattern = 0x00002000;
329 *pattern = 0x00001000;
333 *pattern = 0x00000800;
337 *pattern = 0x00000400;
341 *pattern = 0x00000200;
345 *pattern = 0x00000100;
351 return off + 1; /* Take the following 1 into account */
355 * gst_mpeg4_next_resync:
356 * @packet: The #GstMpeg4Packet to fill
357 * @vop: The previously parsed #GstMpeg4VideoObjectPlane
358 * @offset: offset from which to start the parsing
359 * @data: The data to parse
360 * @size: The size of the @data to parse
362 * Parses @data and fills @packet with the information of the next resync packet
365 * Returns: a #GstMpeg4ParseResult
367 static GstMpeg4ParseResult
368 gst_mpeg4_next_resync (GstMpeg4Packet * packet,
369 const GstMpeg4VideoObjectPlane * vop, const guint8 * data, gsize size,
370 gboolean first_resync_marker)
372 guint markersize = 0, off1, off2;
373 guint32 mask = 0xff, pattern = 0xff;
376 gst_byte_reader_init (&br, data, size);
378 g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
379 g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
381 markersize = compute_resync_marker_size (vop, &pattern, &mask);
383 if (first_resync_marker) {
386 off1 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern, 0, size);
390 return GST_MPEG4_PARSER_NO_PACKET;
392 GST_DEBUG ("Resync code found at %i", off1);
394 packet->offset = off1;
395 packet->type = GST_MPEG4_RESYNC;
396 packet->marker_size = markersize;
398 off2 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern,
399 off1 + 2, size - off1 - 2);
402 return GST_MPEG4_PARSER_NO_PACKET_END;
404 packet->size = off2 - off1;
406 return GST_MPEG4_PARSER_OK;
410 /********** API **********/
414 * @packet: The #GstMpeg4Packet to fill
415 * @skip_user_data: %TRUE to skip user data packet %FALSE otherwise
416 * @vop: The last parsed #GstMpeg4VideoObjectPlane or %NULL if you do
417 * not need to detect the resync codes.
418 * @offset: offset from which to start the parsing
419 * @data: The data to parse
420 * @size: The size of the @data to parse
422 * Parses @data and fills @packet with the information of the next packet
425 * Returns: a #GstMpeg4ParseResult
428 gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
429 GstMpeg4VideoObjectPlane * vop, const guint8 * data, guint offset,
434 GstMpeg4ParseResult resync_res;
435 static guint first_resync_marker = TRUE;
437 gst_byte_reader_init (&br, data, size);
439 g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
441 if (size - offset <= 4) {
442 GST_DEBUG ("Can't parse, buffer is to small size %" G_GSIZE_FORMAT
443 " at offset %d", size, offset);
444 return GST_MPEG4_PARSER_ERROR;
449 gst_mpeg4_next_resync (packet, vop, data + offset, size - offset,
450 first_resync_marker);
451 first_resync_marker = FALSE;
453 /* We found a complet slice */
454 if (resync_res == GST_MPEG4_PARSER_OK)
456 else if (resync_res == GST_MPEG4_PARSER_NO_PACKET_END) {
457 /* It doesn't mean there is no standard packet end, look for it */
458 off1 = packet->offset;
460 } else if (resync_res == GST_MPEG4_PARSER_NO_PACKET)
463 first_resync_marker = TRUE;
466 off1 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
467 offset, size - offset);
470 GST_DEBUG ("No start code prefix in this buffer");
471 return GST_MPEG4_PARSER_NO_PACKET;
474 /* Recursively skip user data if needed */
475 if (skip_user_data && data[off1 + 3] == GST_MPEG4_USER_DATA)
476 /* If we are here, we know no resync code has been found the first time, so we
477 * don't look for it this time */
478 return gst_mpeg4_parse (packet, skip_user_data, NULL, data, off1 + 3, size);
480 packet->offset = off1 + 3;
482 packet->type = (GstMpeg4StartCode) (data[off1 + 3]);
486 off2 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
487 off1 + 4, size - off1 - 4);
492 GST_DEBUG ("Packet start %d, No end found", off1 + 4);
494 packet->size = G_MAXUINT;
495 return GST_MPEG4_PARSER_NO_PACKET_END;
498 if (packet->type == GST_MPEG4_RESYNC) {
499 packet->size = (gsize) off2 - off1;
501 packet->size = (gsize) off2 - off1 - 3;
504 GST_DEBUG ("Complete packet of type %x found at: %d, Size: %" G_GSIZE_FORMAT,
505 packet->type, packet->offset, packet->size);
506 return GST_MPEG4_PARSER_OK;
512 * @packet: The #GstMpeg4Packet to fill
513 * @offset: offset from which to start the parsing
514 * @data: The data to parse
515 * @size: The size of the @data to parse
517 * Parses @data and fills @packet with the information of the next packet
520 * Note that the type of the packet is meaningless in this case.
522 * Returns: a #GstMpeg4ParseResult
525 gst_h263_parse (GstMpeg4Packet * packet,
526 const guint8 * data, guint offset, gsize size)
531 gst_byte_reader_init (&br, data + offset, size - offset);
533 g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
535 if (size - offset < 3) {
536 GST_DEBUG ("Can't parse, buffer is to small size %" G_GSIZE_FORMAT
537 " at offset %d", size, offset);
538 return GST_MPEG4_PARSER_ERROR;
541 off1 = find_psc (&br);
544 GST_DEBUG ("No start code prefix in this buffer");
545 return GST_MPEG4_PARSER_NO_PACKET;
548 packet->offset = off1 + offset;
551 gst_byte_reader_skip_unchecked (&br, 3);
552 off2 = find_psc (&br);
555 GST_DEBUG ("Packet start %d, No end found", off1);
557 packet->size = G_MAXUINT;
558 return GST_MPEG4_PARSER_NO_PACKET_END;
561 packet->size = (gsize) off2 - off1;
563 GST_DEBUG ("Complete packet found at: %d, Size: %" G_GSIZE_FORMAT,
564 packet->offset, packet->size);
566 return GST_MPEG4_PARSER_OK;
570 * gst_mpeg4_parse_visual_object_sequence:
571 * @vos: The #GstMpeg4VisualObjectSequence structure to fill
572 * @data: The data to parse, should contain the visual_object_sequence_start_code
573 * but not the start code prefix
574 * @size: The size of the @data to parse
576 * Parses @data containing the visual object sequence packet, and fills
577 * the @vos structure.
579 * Returns: a #GstMpeg4ParseResult
582 gst_mpeg4_parse_visual_object_sequence (GstMpeg4VisualObjectSequence * vos,
583 const guint8 * data, gsize size)
585 guint8 vos_start_code;
586 GstBitReader br = GST_BIT_READER_INIT (data, size);
588 g_return_val_if_fail (vos != NULL, GST_MPEG4_PARSER_ERROR);
590 READ_UINT8 (&br, vos_start_code, 8);
591 if (vos_start_code != GST_MPEG4_VISUAL_OBJ_SEQ_START)
592 goto wrong_start_code;
594 READ_UINT8 (&br, vos->profile_and_level_indication, 8);
596 switch (vos->profile_and_level_indication) {
598 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
599 vos->level = GST_MPEG4_LEVEL1;
602 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
603 vos->level = GST_MPEG4_LEVEL2;
606 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
607 vos->level = GST_MPEG4_LEVEL3;
610 vos->profile = GST_MPEG4_PROFILE_SIMPLE;
611 vos->level = GST_MPEG4_LEVEL0;
614 vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
615 vos->level = GST_MPEG4_LEVEL0;
618 vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
619 vos->level = GST_MPEG4_LEVEL1;
622 vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
623 vos->level = GST_MPEG4_LEVEL2;
626 vos->profile = GST_MPEG4_PROFILE_CORE;
627 vos->level = GST_MPEG4_LEVEL1;
630 vos->profile = GST_MPEG4_PROFILE_CORE;
631 vos->level = GST_MPEG4_LEVEL2;
634 vos->profile = GST_MPEG4_PROFILE_MAIN;
635 vos->level = GST_MPEG4_LEVEL2;
638 vos->profile = GST_MPEG4_PROFILE_MAIN;
639 vos->level = GST_MPEG4_LEVEL3;
642 vos->profile = GST_MPEG4_PROFILE_MAIN;
643 vos->level = GST_MPEG4_LEVEL4;
646 vos->profile = GST_MPEG4_PROFILE_N_BIT;
647 vos->level = GST_MPEG4_LEVEL2;
650 vos->profile = GST_MPEG4_PROFILE_SCALABLE_TEXTURE;
651 vos->level = GST_MPEG4_LEVEL1;
654 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
655 vos->level = GST_MPEG4_LEVEL1;
658 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
659 vos->level = GST_MPEG4_LEVEL2;
662 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
663 vos->level = GST_MPEG4_LEVEL1;
666 vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
667 vos->level = GST_MPEG4_LEVEL2;
670 vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
671 vos->level = GST_MPEG4_LEVEL1;
674 vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
675 vos->level = GST_MPEG4_LEVEL2;
678 vos->profile = GST_MPEG4_PROFILE_HYBRID;
679 vos->level = GST_MPEG4_LEVEL1;
682 vos->profile = GST_MPEG4_PROFILE_HYBRID;
683 vos->level = GST_MPEG4_LEVEL2;
686 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
687 vos->level = GST_MPEG4_LEVEL1;
690 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
691 vos->level = GST_MPEG4_LEVEL2;
694 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
695 vos->level = GST_MPEG4_LEVEL3;
698 vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
699 vos->level = GST_MPEG4_LEVEL4;
702 vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
703 vos->level = GST_MPEG4_LEVEL1;
706 vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
707 vos->level = GST_MPEG4_LEVEL2;
710 vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
711 vos->level = GST_MPEG4_LEVEL3;
714 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
715 vos->level = GST_MPEG4_LEVEL1;
718 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
719 vos->level = GST_MPEG4_LEVEL2;
722 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
723 vos->level = GST_MPEG4_LEVEL3;
726 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
727 vos->level = GST_MPEG4_LEVEL4;
730 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
731 vos->level = GST_MPEG4_LEVEL1;
734 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
735 vos->level = GST_MPEG4_LEVEL2;
738 vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
739 vos->level = GST_MPEG4_LEVEL3;
742 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
743 vos->level = GST_MPEG4_LEVEL1;
746 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
747 vos->level = GST_MPEG4_LEVEL2;
750 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
751 vos->level = GST_MPEG4_LEVEL3;
754 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
755 vos->level = GST_MPEG4_LEVEL1;
758 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
759 vos->level = GST_MPEG4_LEVEL2;
762 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
763 vos->level = GST_MPEG4_LEVEL3;
766 vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
767 vos->level = GST_MPEG4_LEVEL4;
770 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
771 vos->level = GST_MPEG4_LEVEL1;
774 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
775 vos->level = GST_MPEG4_LEVEL2;
778 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
779 vos->level = GST_MPEG4_LEVEL3;
782 vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
783 vos->level = GST_MPEG4_LEVEL4;
786 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
787 vos->level = GST_MPEG4_LEVEL0;
790 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
791 vos->level = GST_MPEG4_LEVEL1;
794 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
795 vos->level = GST_MPEG4_LEVEL2;
798 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
799 vos->level = GST_MPEG4_LEVEL3;
802 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
803 vos->level = GST_MPEG4_LEVEL4;
806 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
807 vos->level = GST_MPEG4_LEVEL5;
810 vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
811 vos->level = GST_MPEG4_LEVEL3b;
814 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
815 vos->level = GST_MPEG4_LEVEL0;
818 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
819 vos->level = GST_MPEG4_LEVEL1;
822 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
823 vos->level = GST_MPEG4_LEVEL2;
826 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
827 vos->level = GST_MPEG4_LEVEL3;
830 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
831 vos->level = GST_MPEG4_LEVEL4;
834 vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
835 vos->level = GST_MPEG4_LEVEL5;
838 vos->profile = GST_MPEG4_PROFILE_RESERVED;
839 vos->level = GST_MPEG4_LEVEL_RESERVED;
843 return GST_MPEG4_PARSER_OK;
846 GST_WARNING ("got buffer with wrong start code");
847 return GST_MPEG4_PARSER_ERROR;
850 GST_WARNING ("failed parsing \"Visual Object\"");
851 return GST_MPEG4_PARSER_ERROR;
855 * gst_mpeg4_parse_visual_object:
856 * @vo: The #GstMpeg4VisualObject structure to fill
857 * @signal_type: The #GstMpeg4VideoSignalType to fill or %NULL
858 * @data: The data to parse, should contain the vo_start_code
859 * but not the start code prefix
860 * @size: The size of the @data to parse
862 * Parses @data containing the visual object packet, and fills
865 * Returns: a #GstMpeg4ParseResult
868 gst_mpeg4_parse_visual_object (GstMpeg4VisualObject * vo,
869 GstMpeg4VideoSignalType * signal_type, const guint8 * data, gsize size)
871 guint8 vo_start_code, type;
872 GstBitReader br = GST_BIT_READER_INIT (data, size);
874 g_return_val_if_fail (vo != NULL, GST_MPEG4_PARSER_ERROR);
876 GST_DEBUG ("Parsing visual object");
878 READ_UINT8 (&br, vo_start_code, 8);
879 if (vo_start_code != GST_MPEG4_VISUAL_OBJ)
880 goto wrong_start_code;
882 /* set default values */
886 READ_UINT8 (&br, vo->is_identifier, 1);
887 if (vo->is_identifier) {
888 READ_UINT8 (&br, vo->verid, 4);
889 READ_UINT8 (&br, vo->priority, 3);
892 READ_UINT8 (&br, type, 4);
895 if ((type == GST_MPEG4_VIDEO_ID ||
896 type == GST_MPEG4_STILL_TEXTURE_ID) && signal_type) {
898 if (!parse_signal_type (&br, signal_type))
901 } else if (signal_type) {
902 signal_type->type = 0;
905 return GST_MPEG4_PARSER_OK;
908 GST_WARNING ("got buffer with wrong start code");
909 return GST_MPEG4_PARSER_ERROR;
912 GST_WARNING ("failed parsing \"Visual Object\"");
913 return GST_MPEG4_PARSER_ERROR;
917 * gst_mpeg4_parse_video_object_layer:
918 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
919 * @vo: The #GstMpeg4VisualObject currently being parsed or %NULL
920 * @data: The data to parse
921 * @size: The size of the @data to parse
923 * Parses @data containing the video object layer packet, and fills
924 * the @vol structure.
926 * Returns: a #GstMpeg4ParseResult
929 gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer * vol,
930 GstMpeg4VisualObject * vo, const guint8 * data, gsize size)
932 guint8 video_object_layer_start_code;
934 /* Used for enums types */
936 GstBitReader br = GST_BIT_READER_INIT (data, size);
938 g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
940 GST_DEBUG ("Parsing video object layer");
942 READ_UINT8 (&br, video_object_layer_start_code, 8);
943 if (!(video_object_layer_start_code >= GST_MPEG4_VIDEO_LAYER_FIRST &&
944 video_object_layer_start_code <= GST_MPEG4_VIDEO_LAYER_LAST))
945 goto wrong_start_code;
947 /* set default values */
949 vol->verid = vo->verid;
950 vol->priority = vo->priority;
956 vol->low_delay = FALSE;
957 vol->chroma_format = 1;
958 vol->vbv_parameters = FALSE;
959 vol->quant_precision = 5;
960 vol->bits_per_pixel = 8;
961 vol->quarter_sample = FALSE;
962 vol->newpred_enable = FALSE;
967 READ_UINT8 (&br, vol->random_accessible_vol, 1);
968 READ_UINT8 (&br, vol->video_object_type_indication, 8);
970 READ_UINT8 (&br, vol->is_object_layer_identifier, 1);
971 if (vol->is_object_layer_identifier) {
972 READ_UINT8 (&br, vol->verid, 4);
973 READ_UINT8 (&br, vol->priority, 3);
976 READ_UINT8 (&br, tmp, 4);
977 vol->aspect_ratio_info = tmp;
978 if (vol->aspect_ratio_info != GST_MPEG4_EXTENDED_PAR) {
979 mpeg4_util_par_from_info (vol->aspect_ratio_info, &vol->par_width,
985 READ_UINT8 (&br, vol->par_width, 8);
987 CHECK_ALLOWED (v, 1, 255);
989 READ_UINT8 (&br, vol->par_height, 8);
991 CHECK_ALLOWED (v, 1, 255);
993 GST_DEBUG ("Pixel aspect ratio %d/%d", vol->par_width, vol->par_width);
995 READ_UINT8 (&br, vol->control_parameters, 1);
996 if (vol->control_parameters) {
997 guint8 chroma_format;
999 READ_UINT8 (&br, chroma_format, 2);
1000 vol->chroma_format = chroma_format;
1001 READ_UINT8 (&br, vol->low_delay, 1);
1003 READ_UINT8 (&br, vol->vbv_parameters, 1);
1004 if (vol->vbv_parameters) {
1005 CHECK_REMAINING (&br, 79);
1007 vol->first_half_bitrate =
1008 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1009 MARKER_UNCHECKED (&br);
1011 vol->latter_half_bitrate =
1012 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1013 MARKER_UNCHECKED (&br);
1016 (vol->first_half_bitrate << 15) | vol->latter_half_bitrate;
1018 vol->first_half_vbv_buffer_size =
1019 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1020 MARKER_UNCHECKED (&br);
1022 vol->latter_half_vbv_buffer_size =
1023 gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
1025 vol->vbv_buffer_size = (vol->first_half_vbv_buffer_size << 15) |
1026 vol->latter_half_vbv_buffer_size;
1028 vol->first_half_vbv_occupancy =
1029 gst_bit_reader_get_bits_uint16_unchecked (&br, 11);
1030 MARKER_UNCHECKED (&br);
1032 vol->latter_half_vbv_occupancy =
1033 gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1034 MARKER_UNCHECKED (&br);
1038 READ_UINT8 (&br, tmp, 2);
1041 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1042 /* TODO support grayscale shapes, for now we just pass */
1044 /* Something the standard starts to define... */
1045 GST_WARNING ("Grayscale shaped not supported");
1049 if (vol->shape == GST_MPEG4_GRAYSCALE && vol->verid != 0x01)
1050 READ_UINT8 (&br, vol->shape_extension, 4);
1052 CHECK_REMAINING (&br, 19);
1054 MARKER_UNCHECKED (&br);
1055 vol->vop_time_increment_resolution =
1056 gst_bit_reader_get_bits_uint16_unchecked (&br, 16);
1057 if (vol->vop_time_increment_resolution < 1) {
1058 GST_WARNING ("value not in allowed range. value: %d, range %d-%d",
1059 vol->vop_time_increment_resolution, 1, G_MAXUINT16);
1062 vol->vop_time_increment_bits =
1063 g_bit_storage (vol->vop_time_increment_resolution);
1065 MARKER_UNCHECKED (&br);
1066 vol->fixed_vop_rate = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1067 if (vol->fixed_vop_rate)
1068 READ_UINT16 (&br, vol->fixed_vop_time_increment,
1069 vol->vop_time_increment_bits);
1071 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1072 if (vol->shape == GST_MPEG4_RECTANGULAR) {
1073 CHECK_REMAINING (&br, 29);
1075 MARKER_UNCHECKED (&br);
1076 vol->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1077 MARKER_UNCHECKED (&br);
1078 vol->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1079 MARKER_UNCHECKED (&br);
1082 READ_UINT8 (&br, vol->interlaced, 1);
1083 READ_UINT8 (&br, vol->obmc_disable, 1);
1085 if (vol->verid == 0x1)
1086 READ_UINT8 (&br, tmp, 1);
1088 READ_UINT8 (&br, tmp, 2);
1089 vol->sprite_enable = tmp;
1091 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
1092 vol->sprite_enable == GST_MPEG4_SPRITE_GMG) {
1094 if (vol->sprite_enable == GST_MPEG4_SPRITE_GMG)
1095 CHECK_REMAINING (&br, 9);
1097 CHECK_REMAINING (&br, 65);
1099 vol->sprite_width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1100 MARKER_UNCHECKED (&br);
1102 vol->sprite_height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1103 MARKER_UNCHECKED (&br);
1105 vol->sprite_left_coordinate =
1106 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1107 MARKER_UNCHECKED (&br);
1109 vol->sprite_top_coordinate =
1110 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1111 MARKER_UNCHECKED (&br);
1113 vol->no_of_sprite_warping_points =
1114 gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1115 vol->sprite_warping_accuracy =
1116 gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
1117 vol->sprite_brightness_change =
1118 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1120 if (vol->sprite_enable != GST_MPEG4_SPRITE_GMG)
1121 vol->low_latency_sprite_enable =
1122 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1125 if (vol->verid != 0x1 && vol->shape != GST_MPEG4_RECTANGULAR)
1126 READ_UINT8 (&br, vol->sadct_disable, 1);
1128 READ_UINT8 (&br, vol->not_8_bit, 1);
1129 if (vol->not_8_bit) {
1130 READ_UINT8 (&br, vol->quant_precision, 4);
1131 CHECK_ALLOWED (vol->quant_precision, 3, 9);
1133 READ_UINT8 (&br, vol->bits_per_pixel, 4);
1134 CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
1137 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1138 /* We don't actually support it */
1139 READ_UINT8 (&br, vol->no_gray_quant_update, 1);
1140 READ_UINT8 (&br, vol->composition_method, 1);
1141 READ_UINT8 (&br, vol->linear_composition, 1);
1144 READ_UINT8 (&br, vol->quant_type, 1);
1145 if (vol->quant_type) {
1146 if (!parse_quant (&br, vol->intra_quant_mat, default_intra_quant_mat,
1147 &vol->load_intra_quant_mat))
1150 if (!parse_quant (&br, vol->non_intra_quant_mat,
1151 default_non_intra_quant_mat, &vol->load_non_intra_quant_mat))
1154 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1155 /* Something the standard starts to define... */
1156 GST_WARNING ("Grayscale shaped not supported");
1161 memset (&vol->intra_quant_mat, 0, 64);
1162 memset (&vol->non_intra_quant_mat, 0, 64);
1165 if (vol->verid != 0x1)
1166 READ_UINT8 (&br, vol->quarter_sample, 1);
1168 READ_UINT8 (&br, vol->complexity_estimation_disable, 1);
1169 if (!vol->complexity_estimation_disable) {
1170 guint8 estimation_method;
1171 guint8 estimation_disable;
1173 /* skip unneeded properties */
1174 READ_UINT8 (&br, estimation_method, 2);
1175 if (estimation_method < 2) {
1176 READ_UINT8 (&br, estimation_disable, 1);
1177 if (!estimation_disable)
1179 READ_UINT8 (&br, estimation_disable, 1);
1180 if (!estimation_disable)
1183 READ_UINT8 (&br, estimation_disable, 1);
1184 if (!estimation_disable)
1186 READ_UINT8 (&br, estimation_disable, 1);
1187 if (!estimation_disable)
1191 if (estimation_method == 1) {
1192 READ_UINT8 (&br, estimation_disable, 1);
1193 if (!estimation_disable)
1199 READ_UINT8 (&br, vol->resync_marker_disable, 1);
1200 READ_UINT8 (&br, vol->data_partitioned, 1);
1202 if (vol->data_partitioned)
1203 READ_UINT8 (&br, vol->reversible_vlc, 1);
1205 if (vol->verid != 0x01) {
1206 READ_UINT8 (&br, vol->newpred_enable, 1);
1207 if (vol->newpred_enable)
1208 /* requested_upstream_message_type and newpred_segment_type */
1211 READ_UINT8 (&br, vol->reduced_resolution_vop_enable, 1);
1214 READ_UINT8 (&br, vol->scalability, 1);
1215 if (vol->scalability) {
1216 SKIP (&br, 26); /* Few not needed props */
1217 READ_UINT8 (&br, vol->enhancement_type, 1);
1220 /* More unused infos */
1221 } else if (vol->verid != 0x01) {
1222 GST_WARNING ("Binary only shapes not fully supported");
1227 return GST_MPEG4_PARSER_OK;
1230 GST_WARNING ("failed parsing \"Video Object Layer\"");
1231 return GST_MPEG4_PARSER_ERROR;
1234 GST_WARNING ("got buffer with wrong start code");
1239 * gst_mpeg4_parse_group_of_vop:
1240 * @gov: The #GstMpeg4GroupOfVOP structure to fill
1241 * @data: The data to parse
1242 * @size: The size of the @data to parse
1244 * Parses @data containing the group of video object plane packet, and fills
1245 * the @gov structure.
1247 * Returns: a #GstMpeg4ParseResult
1250 gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *
1251 gov, const guint8 * data, gsize size)
1253 guint8 gov_start_code;
1254 GstBitReader br = GST_BIT_READER_INIT (data, size);
1256 g_return_val_if_fail (gov != NULL, GST_MPEG4_PARSER_ERROR);
1258 READ_UINT8 (&br, gov_start_code, 8);
1259 if (gov_start_code != GST_MPEG4_GROUP_OF_VOP)
1260 goto wrong_start_code;
1262 CHECK_REMAINING (&br, 65);
1264 gov->hours = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
1265 gov->minutes = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1267 MARKER_UNCHECKED (&br);
1268 gov->seconds = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1270 gov->closed = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1271 gov->broken_link = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1273 return GST_MPEG4_PARSER_OK;
1276 GST_WARNING ("failed parsing \"Group of Video Object Plane\"");
1277 return GST_MPEG4_PARSER_ERROR;
1280 GST_WARNING ("got buffer with wrong start code");
1285 * gst_mpeg4_parse_video_object_plane:
1286 * @vop: The #GstMpeg4VideoObjectPlane currently being parsed
1287 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
1288 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
1289 * @data: The data to parse
1290 * @size: The size of the @data to parse
1292 * Parses @data containing the video object plane packet, and fills the @vol
1295 * Returns: a #GstMpeg4ParseResult
1298 gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane * vop,
1299 GstMpeg4SpriteTrajectory * sprite_trajectory,
1300 GstMpeg4VideoObjectLayer * vol, const guint8 * data, gsize size)
1302 guint8 vop_start_code, coding_type, modulo_time_base;
1303 GstBitReader br = GST_BIT_READER_INIT (data, size);
1305 g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
1307 if (vol->shape == GST_MPEG4_BINARY_ONLY) {
1308 /* TODO: implement binary only shapes */
1309 GST_WARNING ("Binary only shapes not supported");
1313 READ_UINT8 (&br, vop_start_code, 8);
1314 if (vop_start_code != GST_MPEG4_VIDEO_OBJ_PLANE)
1315 goto wrong_start_code;
1318 /* set default values */
1319 vop->modulo_time_base = 0;
1320 vop->rounding_type = 0;
1321 vop->top_field_first = 1;
1322 vop->alternate_vertical_scan_flag = 0;
1323 vop->fcode_forward = 1;
1324 vop->fcode_backward = 1;
1326 /* Compute macroblock informations */
1327 if (vol->interlaced)
1328 vop->mb_height = (2 * (vol->height + 31) / 32);
1330 vop->mb_height = (vol->height + 15) / 16;
1332 vop->mb_width = (vol->width + 15) / 16;
1333 vop->mb_num = vop->mb_height * vop->mb_width;
1335 READ_UINT8 (&br, coding_type, 2);
1336 vop->coding_type = coding_type;
1338 READ_UINT8 (&br, modulo_time_base, 1);
1339 while (modulo_time_base) {
1340 vop->modulo_time_base++;
1342 READ_UINT8 (&br, modulo_time_base, 1);
1345 CHECK_REMAINING (&br, vol->vop_time_increment_bits + 3);
1347 MARKER_UNCHECKED (&br);
1348 vop->time_increment =
1349 gst_bit_reader_get_bits_uint16_unchecked (&br,
1350 vol->vop_time_increment_bits);
1351 MARKER_UNCHECKED (&br);
1353 vop->coded = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1355 return GST_MPEG4_PARSER_OK;
1357 if (vol->newpred_enable) {
1359 vop->time_increment + 3 < 15 ? vop->time_increment + 3 : 15;
1361 READ_UINT16 (&br, vop->id, nbbits);
1362 READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
1363 if (vop->id_for_prediction_indication) {
1364 /* Would be nice if the standard actually told us... */
1365 READ_UINT16 (&br, vop->id, nbbits);
1370 if (vol->shape != GST_MPEG4_BINARY_ONLY &&
1371 (vop->coding_type == GST_MPEG4_P_VOP ||
1372 (vop->coding_type == GST_MPEG4_S_VOP &&
1373 vol->sprite_enable == GST_MPEG4_SPRITE_GMG)))
1374 READ_UINT8 (&br, vop->rounding_type, 1);
1376 if ((vol->reduced_resolution_vop_enable) &&
1377 (vol->shape == GST_MPEG4_RECTANGULAR ||
1378 (vop->coding_type = GST_MPEG4_P_VOP ||
1379 vop->coding_type == GST_MPEG4_I_VOP)))
1380 READ_UINT8 (&br, vop->reduced_resolution, 1);
1382 if (vol->shape != GST_MPEG4_RECTANGULAR) {
1383 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
1384 vop->coding_type == GST_MPEG4_I_VOP) {
1385 CHECK_REMAINING (&br, 55);
1387 vop->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1388 MARKER_UNCHECKED (&br);
1390 vop->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1391 MARKER_UNCHECKED (&br);
1393 vop->horizontal_mc_spatial_ref =
1394 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1395 MARKER_UNCHECKED (&br);
1397 vop->vertical_mc_spatial_ref =
1398 gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1399 MARKER_UNCHECKED (&br);
1401 /* Recompute the Macroblock informations
1402 * accordingly to the new values */
1403 if (vol->interlaced)
1404 vop->mb_height = (2 * (vol->height + 31) / 32);
1406 vop->mb_height = (vol->height + 15) / 16;
1408 vop->mb_width = (vol->width + 15) / 16;
1409 vop->mb_num = vop->mb_height * vop->mb_width;
1412 if ((vol->shape != GST_MPEG4_BINARY_ONLY) &&
1413 vol->scalability && vol->enhancement_type)
1414 READ_UINT8 (&br, vop->background_composition, 1);
1416 READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
1418 READ_UINT8 (&br, vop->constant_alpha, 1);
1419 if (vop->constant_alpha)
1420 READ_UINT8 (&br, vop->constant_alpha_value, 1);
1423 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1424 if (!vol->complexity_estimation_disable) {
1425 GST_WARNING ("Complexity estimation not supported");
1429 READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
1431 if (vol->interlaced) {
1432 READ_UINT8 (&br, vop->top_field_first, 1);
1433 READ_UINT8 (&br, vop->alternate_vertical_scan_flag, 1);
1437 if ((vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
1438 vol->sprite_enable == GST_MPEG4_SPRITE_GMG) &&
1439 vop->coding_type == GST_MPEG4_S_VOP) {
1441 /* only if @sprite_trajectory is not NULL we parse it */
1442 if (sprite_trajectory && vol->no_of_sprite_warping_points)
1443 parse_sprite_trajectory (&br, sprite_trajectory,
1444 vol->no_of_sprite_warping_points);
1446 if (vol->sprite_brightness_change) {
1447 GST_WARNING ("sprite_brightness_change not supported");
1451 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC) {
1452 GST_WARNING ("sprite enable static not supported");
1457 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1458 READ_UINT16 (&br, vop->quant, vol->quant_precision);
1460 if (vol->shape == GST_MPEG4_GRAYSCALE) {
1461 /* TODO implement grayscale support */
1462 GST_WARNING ("Grayscale shapes no supported");
1464 /* TODO implement me */
1468 if (vop->coding_type != GST_MPEG4_I_VOP) {
1469 READ_UINT8 (&br, vop->fcode_forward, 3);
1470 CHECK_ALLOWED (vop->fcode_forward, 1, 7);
1473 if (vop->coding_type == GST_MPEG4_B_VOP) {
1474 READ_UINT8 (&br, vop->fcode_backward, 3);
1475 CHECK_ALLOWED (vop->fcode_backward, 1, 7);
1479 if (!vol->scalability) {
1480 if (vol->shape != GST_MPEG4_RECTANGULAR)
1481 READ_UINT8 (&br, vop->shape_coding_type, 1);
1484 if (vol->enhancement_type) {
1485 READ_UINT8 (&br, vop->load_backward_shape, 1);
1487 if (vop->load_backward_shape) {
1488 GST_WARNING ("Load backward shape not supported");
1492 READ_UINT8 (&br, vop->ref_select_code, 2);
1496 vop->size = gst_bit_reader_get_pos (&br);
1497 /* More things to possibly parse ... */
1499 return GST_MPEG4_PARSER_OK;
1502 GST_WARNING ("failed parsing \"Video Object Plane\"");
1503 return GST_MPEG4_PARSER_ERROR;
1506 GST_WARNING ("got buffer with wrong start code");
1511 * gst_mpeg4_parse_video_plane_with_short_header:
1512 * @shorthdr: The #GstMpeg4VideoPlaneShortHdr to parse
1513 * @data: The data to parse
1514 * @size: The size of the @data to parse
1517 gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
1518 shorthdr, const guint8 * data, gsize size)
1522 GstBitReader br = GST_BIT_READER_INIT (data, size);
1524 g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR);
1526 if (gst_bit_reader_get_remaining (&br) < 48)
1529 if (gst_bit_reader_get_bits_uint32_unchecked (&br, 22) != 0x20)
1532 shorthdr->temporal_reference =
1533 gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
1535 zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1536 if (zero_bits != 0x00)
1539 shorthdr->split_screen_indicator =
1540 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1541 shorthdr->document_camera_indicator =
1542 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1543 shorthdr->full_picture_freeze_release =
1544 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1545 shorthdr->source_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
1547 /* Set parameters/Table 6-25 */
1548 switch (shorthdr->source_format) {
1550 shorthdr->vop_width = 128;
1551 shorthdr->vop_height = 96;
1552 shorthdr->num_macroblocks_in_gob = 8;
1553 shorthdr->num_gobs_in_vop = 6;
1556 shorthdr->vop_width = 176;
1557 shorthdr->vop_height = 144;
1558 shorthdr->num_macroblocks_in_gob = 11;
1559 shorthdr->num_gobs_in_vop = 9;
1562 shorthdr->vop_width = 352;
1563 shorthdr->vop_height = 288;
1564 shorthdr->num_macroblocks_in_gob = 22;
1565 shorthdr->num_gobs_in_vop = 18;
1568 shorthdr->vop_width = 704;
1569 shorthdr->vop_height = 576;
1570 shorthdr->num_macroblocks_in_gob = 88;
1571 shorthdr->num_gobs_in_vop = 18;
1574 shorthdr->vop_width = 1408;
1575 shorthdr->vop_height = 1152;
1576 shorthdr->num_macroblocks_in_gob = 352;
1577 shorthdr->num_gobs_in_vop = 18;
1580 shorthdr->vop_width = 0;
1581 shorthdr->vop_height = 0;
1582 shorthdr->num_macroblocks_in_gob = 0;
1583 shorthdr->num_gobs_in_vop = 0;
1586 shorthdr->picture_coding_type =
1587 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1588 zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
1590 if (zero_bits != 0x00)
1593 shorthdr->vop_quant = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
1594 zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1596 if (zero_bits != 0x00)
1600 READ_UINT8 (&br, shorthdr->pei, 1);
1602 if (shorthdr->pei == 1)
1603 READ_UINT8 (&br, shorthdr->psupp, 8);
1605 } while (shorthdr->pei == 1);
1607 shorthdr->size = gst_bit_reader_get_pos (&br);
1609 return GST_MPEG4_PARSER_OK;
1612 GST_WARNING ("Could not parse the Plane short header");
1614 return GST_MPEG4_PARSER_ERROR;
1618 * gst_mpeg4_parse_video_packet_header:
1619 * @videopackethdr: The #GstMpeg4VideoPacketHdr structure to fill
1620 * @vol: The last parsed #GstMpeg4VideoObjectLayer, will be updated
1621 * with the informations found during the parsing
1622 * @vop: The last parsed #GstMpeg4VideoObjectPlane, will be updated
1623 * with the informations found during the parsing
1624 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
1625 * with the informations found during the parsing
1626 * @data: The data to parse, should be set after the resync marker.
1627 * @size: The size of the data to parse
1629 * Parsers @data containing the video packet header
1630 * and fills the @videopackethdr structure
1633 gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
1634 GstMpeg4VideoObjectLayer * vol, GstMpeg4VideoObjectPlane * vop,
1635 GstMpeg4SpriteTrajectory * sprite_trajectory, const guint8 * data,
1639 GstBitReader br = GST_BIT_READER_INIT (data, size);
1641 g_return_val_if_fail (videopackethdr != NULL, GST_MPEG4_PARSER_ERROR);
1642 g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
1644 markersize = compute_resync_marker_size (vop, NULL, NULL);
1646 CHECK_REMAINING (&br, markersize);
1648 if (gst_bit_reader_get_bits_uint32_unchecked (&br, markersize) != 0x01)
1651 if (vol->shape != GST_MPEG4_RECTANGULAR) {
1652 READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
1653 if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
1654 vop->coding_type == GST_MPEG4_I_VOP) {
1656 CHECK_REMAINING (&br, 56);
1658 U_READ_UINT16 (&br, vop->width, 13);
1660 U_READ_UINT16 (&br, vop->height, 13);
1662 U_READ_UINT16 (&br, vop->horizontal_mc_spatial_ref, 13);
1664 U_READ_UINT16 (&br, vop->vertical_mc_spatial_ref, 13);
1667 /* Update macroblock infirmations */
1668 vop->mb_height = (vop->height + 15) / 16;
1669 vop->mb_width = (vop->width + 15) / 16;
1670 vop->mb_num = vop->mb_height * vop->mb_width;
1674 READ_UINT16 (&br, videopackethdr->macroblock_number,
1675 g_bit_storage (vop->mb_num - 1));
1677 if (vol->shape != GST_MPEG4_BINARY_ONLY)
1678 READ_UINT16 (&br, videopackethdr->quant_scale, vol->quant_precision);
1680 if (vol->shape == GST_MPEG4_RECTANGULAR)
1681 READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
1683 if (videopackethdr->header_extension_code) {
1685 guint8 bit = 0, coding_type;
1688 READ_UINT8 (&br, bit, 1);
1692 vol->vop_time_increment_bits = timeincr;
1695 READ_UINT16 (&br, vop->time_increment, timeincr);
1697 READ_UINT8 (&br, coding_type, 2);
1698 vop->coding_type = coding_type;
1700 if (vol->shape != GST_MPEG4_RECTANGULAR) {
1701 READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
1702 if (vop->coding_type != GST_MPEG4_I_VOP)
1703 READ_UINT8 (&br, vop->shape_coding_type, 1);
1706 if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1707 READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
1709 if (sprite_trajectory && vol->sprite_enable == GST_MPEG4_SPRITE_GMG &&
1710 vop->coding_type == GST_MPEG4_S_VOP &&
1711 vol->no_of_sprite_warping_points > 0) {
1713 parse_sprite_trajectory (&br, sprite_trajectory,
1714 vol->no_of_sprite_warping_points);
1717 if (vol->reduced_resolution_vop_enable &&
1718 vol->shape == GST_MPEG4_RECTANGULAR &&
1719 (vop->coding_type == GST_MPEG4_P_VOP ||
1720 vop->coding_type == GST_MPEG4_I_VOP))
1721 READ_UINT8 (&br, vop->reduced_resolution, 1);
1723 if (vop->coding_type != GST_MPEG4_I_VOP) {
1724 READ_UINT8 (&br, vop->fcode_forward, 3);
1725 CHECK_ALLOWED (vop->fcode_forward, 1, 7);
1728 if (vop->coding_type == GST_MPEG4_B_VOP) {
1729 READ_UINT8 (&br, vop->fcode_backward, 3);
1730 CHECK_ALLOWED (vop->fcode_backward, 1, 7);
1735 if (vol->newpred_enable) {
1737 vol->vop_time_increment_bits + 3 < 15 ? vop->time_increment + 3 : 15;
1739 READ_UINT16 (&br, vop->id, nbbits);
1740 READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
1741 if (vop->id_for_prediction_indication) {
1742 /* Would be nice if the standard actually told us... */
1743 READ_UINT16 (&br, vop->id, nbbits);
1748 videopackethdr->size = gst_bit_reader_get_pos (&br);
1751 GST_DEBUG ("Failed to parse video packet header");
1753 return GST_MPEG4_PARSER_NO_PACKET;