Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / gst-libs / gst / codecparsers / gstmpeg4parser.c
1 /* Gstreamer
2  * Copyright (C) <2011> Intel
3  * Copyright (C) <2011> Collabora Ltd.
4  * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
5  *
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.
10  *
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.
15  *
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.
20  */
21 /**
22  * SECTION:gstmpeg4parser
23  * @short_description: Convenience library for parsing mpeg4 part 2 video
24  * bitstream.
25  *
26  * For more details about the structures, you can refer to the
27  * specifications: ISO-IEC-14496-2_2004_MPEG4_VISUAL.pdf
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <string.h>
35 #include <gst/base/gstbytereader.h>
36
37
38 #include "gstmpeg4parser.h"
39 #include "parserutils.h"
40
41 #ifndef GST_DISABLE_GST_DEBUG
42
43 #define GST_CAT_DEFAULT ensure_debug_category()
44
45 static GstDebugCategory *
46 ensure_debug_category (void)
47 {
48   static gsize cat_gonce = 0;
49
50   if (g_once_init_enter (&cat_gonce)) {
51     gsize cat_done;
52
53     cat_done = (gsize) _gst_debug_category_new ("codecparsers_mpeg4", 0,
54         "GstMpeg4 codec parsing library");
55
56     g_once_init_leave (&cat_gonce, cat_done);
57   }
58
59   return (GstDebugCategory *) cat_gonce;
60 }
61
62 #else
63
64 #define ensure_debug_category() /* NOOP */
65
66 #endif /* GST_DISABLE_GST_DEBUG */
67
68 #define CHECK_MARKER(br) G_STMT_START { \
69   guint8 marker;\
70   if (!gst_bit_reader_get_bits_uint8 (br, &marker, 1)) { \
71     GST_WARNING ("failed to read marker bit"); \
72     goto failed; \
73   } else if (!marker) {\
74     GST_WARNING ("Wrong marker bit"); \
75     goto failed;\
76   }\
77 } G_STMT_END
78
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"); \
82     goto failed; \
83   } \
84 } G_STMT_END
85
86 #define CHECK_REMAINING(br, needed) G_STMT_START { \
87   if (gst_bit_reader_get_remaining (br) < needed) \
88     goto failed; \
89 } G_STMT_END
90
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
100 };
101
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,
111 };
112
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
122 };
123
124 static const VLCTable mpeg4_dmv_size_vlc_table[] = {
125   {0x00, 2, 0},
126   {0x02, 3, 1},
127   {0x03, 3, 2},
128   {0x04, 3, 3},
129   {0x05, 3, 4},
130   {0x06, 3, 5},
131   {0x0e, 4, 6},
132   {0x1e, 5, 7},
133   {0x3e, 6, 8},
134   {0x7e, 7, 9},
135   {0xfe, 8, 10},
136   {0x1fe, 9, 11},
137   {0x3fe, 10, 12},
138   {0x7fe, 11, 13},
139   {0xffe, 12, 14}
140 };
141
142 static void
143 mpeg4_util_par_from_info (guint8 aspect_ratio_info, guint8 * par_width,
144     guint8 * par_height)
145 {
146   switch (aspect_ratio_info) {
147     case 0x02:
148       *par_width = 12;
149       *par_height = 11;
150       break;
151     case 0x03:
152       *par_width = 10;
153       *par_height = 11;
154       break;
155     case 0x04:
156       *par_width = 16;
157       *par_height = 11;
158       break;
159     case 0x05:
160       *par_width = 40;
161       *par_height = 33;
162       break;
163
164     case 0x01:
165     default:
166       *par_width = 1;
167       *par_height = 1;
168   }
169 }
170
171 static gboolean
172 parse_quant (GstBitReader * br, guint8 quant_mat[64],
173     const guint8 default_quant_mat[64], guint8 * load_quant_mat)
174 {
175   READ_UINT8 (br, *load_quant_mat, 1);
176   if (*load_quant_mat) {
177     guint i;
178     guint8 val;
179
180     val = 1;
181     for (i = 0; i < 64; i++) {
182
183       if (val != 0)
184         READ_UINT8 (br, val, 8);
185
186       if (val == 0) {
187         if (i == 0)
188           goto invalid_quant_mat;
189         quant_mat[mpeg4_zigzag_8x8[i]] = quant_mat[mpeg4_zigzag_8x8[i - 1]];
190       } else
191         quant_mat[mpeg4_zigzag_8x8[i]] = val;
192     }
193   } else
194     memcpy (quant_mat, default_quant_mat, 64);
195
196   return TRUE;
197
198 failed:
199   GST_WARNING ("failed parsing quant matrix");
200   return FALSE;
201
202 invalid_quant_mat:
203   GST_WARNING ("the first value should be non zero");
204   goto failed;
205 }
206
207 static gboolean
208 parse_signal_type (GstBitReader * br, GstMpeg4VideoSignalType * signal_type)
209 {
210   READ_UINT8 (br, signal_type->type, 1);
211
212   if (signal_type->type) {
213
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);
217
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);
222     }
223   }
224
225   return TRUE;
226
227 failed:
228   GST_WARNING ("failed parsing \"Video Signal Type\"");
229
230   return FALSE;
231 }
232
233 static gboolean
234 parse_sprite_trajectory (GstBitReader * br,
235     GstMpeg4SpriteTrajectory * sprite_traj, guint no_of_sprite_warping_points)
236 {
237   guint i, length;
238
239   for (i = 0; i < no_of_sprite_warping_points; i++) {
240
241     if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
242             G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
243       goto failed;
244
245     if (length)
246       READ_UINT16 (br, sprite_traj->vop_ref_points[i], length);
247     CHECK_MARKER (br);
248
249     if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
250             G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
251       goto failed;
252
253     if (length)
254       READ_UINT16 (br, sprite_traj->sprite_ref_points[i], length);
255     CHECK_MARKER (br);
256   }
257
258   return TRUE;
259
260 failed:
261   GST_WARNING ("Could not parse the sprite trajectory");
262   return FALSE;
263 }
264
265 static guint
266 find_psc (GstByteReader * br)
267 {
268   guint psc_pos = -1, psc;
269
270   if (!gst_byte_reader_peek_uint24_be (br, &psc))
271     goto failed;
272
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);
278       break;
279     } else
280       gst_byte_reader_skip (br, 1);
281   }
282
283 failed:
284
285   return psc_pos;
286 }
287
288 static inline guint8
289 compute_resync_marker_size (const GstMpeg4VideoObjectPlane * vop,
290     guint32 * pattern, guint32 * mask)
291 {
292   guint8 off;
293
294   /* FIXME handle the binary only shape case */
295   switch (vop->coding_type) {
296     case (GST_MPEG4_I_VOP):
297       off = 16;
298       break;
299     case (GST_MPEG4_S_VOP):
300     case (GST_MPEG4_P_VOP):
301       off = 15 + vop->fcode_forward;
302
303       break;
304     case (GST_MPEG4_B_VOP):
305       off = MAX (15 + MAX (vop->fcode_forward, vop->fcode_backward), 17);
306
307       break;
308     default:
309       return -1;
310   }
311
312   if (mask && pattern) {
313     switch (off) {
314       case 16:
315         *pattern = 0x00008000;
316         *mask = 0xffff8000;
317         break;
318       case 17:
319         *pattern = 0x00004000;
320         *mask = 0xffffc000;
321         break;
322       case 18:
323         *pattern = 0x00002000;
324         *mask = 0xffffe000;
325         break;
326       case 19:
327         *pattern = 0x00001000;
328         *mask = 0xfffff000;
329         break;
330       case 20:
331         *pattern = 0x00000800;
332         *mask = 0xfffff800;
333         break;
334       case 21:
335         *pattern = 0x00000400;
336         *mask = 0xfffffc00;
337         break;
338       case 22:
339         *pattern = 0x00000200;
340         *mask = 0xfffffe00;
341         break;
342       case 23:
343         *pattern = 0x00000100;
344         *mask = 0xffffff00;
345         break;
346     }
347   }
348
349   return off++;                 /* Take the following 1 into account */
350 }
351
352 /**
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
359  *
360  * Parses @data and fills @packet with the information of the next resync packet
361  * found.
362  *
363  * Returns: a #GstMpeg4ParseResult
364  */
365 static GstMpeg4ParseResult
366 gst_mpeg4_next_resync (GstMpeg4Packet * packet,
367     const GstMpeg4VideoObjectPlane * vop, const guint8 * data, gsize size,
368     gboolean first_resync_marker)
369 {
370   guint markersize = 0, off1, off2;
371   guint32 mask = 0xff, pattern = 0xff;
372   GstByteReader br;
373
374   gst_byte_reader_init (&br, data, size);
375
376   g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
377   g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
378
379   markersize = compute_resync_marker_size (vop, &pattern, &mask);
380
381   if (first_resync_marker) {
382     off1 = 0;
383   } else {
384     off1 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern, 0, size);
385   }
386
387   if (off1 == -1)
388     return GST_MPEG4_PARSER_NO_PACKET;
389
390   GST_DEBUG ("Resync code found at %i", off1);
391
392   packet->offset = off1;
393   packet->type = GST_MPEG4_RESYNC;
394   packet->marker_size = markersize;
395
396   off2 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern,
397       off1 + 2, size - off1 - 2);
398
399   if (off2 == -1)
400     return GST_MPEG4_PARSER_NO_PACKET_END;
401
402   packet->size = off2 - off1;
403
404   return GST_MPEG4_PARSER_OK;
405 }
406
407
408 /********** API **********/
409
410 /**
411  * gst_mpeg4_parse:
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
419  *
420  * Parses @data and fills @packet with the information of the next packet
421  * found.
422  *
423  * Returns: a #GstMpeg4ParseResult
424  */
425 GstMpeg4ParseResult
426 gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
427     GstMpeg4VideoObjectPlane * vop, const guint8 * data, guint offset,
428     gsize size)
429 {
430   gint off1, off2;
431   GstByteReader br;
432   GstMpeg4ParseResult resync_res;
433   static guint first_resync_marker = TRUE;
434
435   gst_byte_reader_init (&br, data, size);
436
437   g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
438
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;
443   }
444
445   if (vop) {
446     resync_res =
447         gst_mpeg4_next_resync (packet, vop, data + offset, size - offset,
448         first_resync_marker);
449     first_resync_marker = FALSE;
450
451     /*  We found a complet slice */
452     if (resync_res == GST_MPEG4_PARSER_OK)
453       return resync_res;
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;
457       goto find_end;
458     } else if (resync_res == GST_MPEG4_PARSER_NO_PACKET)
459       return resync_res;
460   } else {
461     first_resync_marker = TRUE;
462   }
463
464   off1 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
465       offset, size - offset);
466
467   if (off1 == -1) {
468     GST_DEBUG ("No start code prefix in this buffer");
469     return GST_MPEG4_PARSER_NO_PACKET;
470   }
471
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);
477
478   packet->offset = off1 + 3;
479   packet->data = data;
480   packet->type = (GstMpeg4StartCode) (data[off1 + 3]);
481
482 find_end:
483   off2 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
484       off1 + 4, size - off1 - 4);
485
486   if (off2 == -1) {
487     GST_DEBUG ("Packet start %d, No end found", off1 + 4);
488
489     packet->size = G_MAXUINT;
490     return GST_MPEG4_PARSER_NO_PACKET_END;
491   }
492
493   if (packet->type == GST_MPEG4_RESYNC) {
494     packet->size = (gsize) off2 - off1;
495   } else {
496     packet->size = (gsize) off2 - off1 - 3;
497   }
498
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;
502
503 }
504
505 /**
506  * gst_h263_parse:
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
511  *
512  * Parses @data and fills @packet with the information of the next packet
513  * found.
514  *
515  * Note that the type of the packet is meaningless in this case.
516  *
517  * Returns: a #GstMpeg4ParseResult
518  */
519 GstMpeg4ParseResult
520 gst_h263_parse (GstMpeg4Packet * packet,
521     const guint8 * data, guint offset, gsize size)
522 {
523   gint off1, off2;
524   GstByteReader br;
525
526   gst_byte_reader_init (&br, data + offset, size - offset);
527
528   g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
529
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;
534   }
535
536   off1 = find_psc (&br);
537
538   if (off1 == -1) {
539     GST_DEBUG ("No start code prefix in this buffer");
540     return GST_MPEG4_PARSER_NO_PACKET;
541   }
542
543   packet->offset = off1 + offset;
544   packet->data = data;
545
546   gst_byte_reader_skip (&br, 3);
547   off2 = find_psc (&br);
548
549   if (off2 == -1) {
550     GST_DEBUG ("Packet start %d, No end found", off1);
551
552     packet->size = G_MAXUINT;
553     return GST_MPEG4_PARSER_NO_PACKET_END;
554   }
555
556   packet->size = (gsize) off2 - off1;
557
558   GST_DEBUG ("Complete packet found at: %d, Size: %" G_GSSIZE_FORMAT,
559       packet->offset, packet->size);
560
561   return GST_MPEG4_PARSER_OK;
562 }
563
564 /**
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
570  *
571  * Parses @data containing the visual object sequence packet, and fills
572  * the @vos structure.
573  *
574  * Returns: a #GstMpeg4ParseResult
575  */
576 GstMpeg4ParseResult
577 gst_mpeg4_parse_visual_object_sequence (GstMpeg4VisualObjectSequence * vos,
578     const guint8 * data, gsize size)
579 {
580   guint8 vos_start_code;
581   GstBitReader br = GST_BIT_READER_INIT (data, size);
582
583   g_return_val_if_fail (vos != NULL, GST_MPEG4_PARSER_ERROR);
584
585   READ_UINT8 (&br, vos_start_code, 8);
586   if (vos_start_code != GST_MPEG4_VISUAL_OBJ_SEQ_START)
587     goto wrong_start_code;
588
589   READ_UINT8 (&br, vos->profile_and_level_indication, 8);
590
591   switch (vos->profile_and_level_indication) {
592     case 0x01:
593       vos->profile = GST_MPEG4_PROFILE_SIMPLE;
594       vos->level = GST_MPEG4_LEVEL1;
595       break;
596     case 0x02:
597       vos->profile = GST_MPEG4_PROFILE_SIMPLE;
598       vos->level = GST_MPEG4_LEVEL2;
599       break;
600     case 0x03:
601       vos->profile = GST_MPEG4_PROFILE_SIMPLE;
602       vos->level = GST_MPEG4_LEVEL3;
603       break;
604     case 0x08:
605       vos->profile = GST_MPEG4_PROFILE_SIMPLE;
606       vos->level = GST_MPEG4_LEVEL0;
607       break;
608     case 0x10:
609       vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
610       vos->level = GST_MPEG4_LEVEL0;
611       break;
612     case 0x11:
613       vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
614       vos->level = GST_MPEG4_LEVEL1;
615       break;
616     case 0x12:
617       vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
618       vos->level = GST_MPEG4_LEVEL2;
619       break;
620     case 0x21:
621       vos->profile = GST_MPEG4_PROFILE_CORE;
622       vos->level = GST_MPEG4_LEVEL1;
623       break;
624     case 0x22:
625       vos->profile = GST_MPEG4_PROFILE_CORE;
626       vos->level = GST_MPEG4_LEVEL2;
627       break;
628     case 0x32:
629       vos->profile = GST_MPEG4_PROFILE_MAIN;
630       vos->level = GST_MPEG4_LEVEL2;
631       break;
632     case 0x33:
633       vos->profile = GST_MPEG4_PROFILE_MAIN;
634       vos->level = GST_MPEG4_LEVEL3;
635       break;
636     case 0x34:
637       vos->profile = GST_MPEG4_PROFILE_MAIN;
638       vos->level = GST_MPEG4_LEVEL4;
639       break;
640     case 0x42:
641       vos->profile = GST_MPEG4_PROFILE_N_BIT;
642       vos->level = GST_MPEG4_LEVEL2;
643       break;
644     case 0x51:
645       vos->profile = GST_MPEG4_PROFILE_SCALABLE_TEXTURE;
646       vos->level = GST_MPEG4_LEVEL1;
647       break;
648     case 0x61:
649       vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
650       vos->level = GST_MPEG4_LEVEL1;
651       break;
652     case 0x62:
653       vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
654       vos->level = GST_MPEG4_LEVEL2;
655       break;
656     case 0x63:
657       vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
658       vos->level = GST_MPEG4_LEVEL1;
659       break;
660     case 0x64:
661       vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
662       vos->level = GST_MPEG4_LEVEL2;
663       break;
664     case 0x71:
665       vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
666       vos->level = GST_MPEG4_LEVEL1;
667       break;
668     case 0x72:
669       vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
670       vos->level = GST_MPEG4_LEVEL2;
671       break;
672     case 0x81:
673       vos->profile = GST_MPEG4_PROFILE_HYBRID;
674       vos->level = GST_MPEG4_LEVEL1;
675       break;
676     case 0x82:
677       vos->profile = GST_MPEG4_PROFILE_HYBRID;
678       vos->level = GST_MPEG4_LEVEL2;
679       break;
680     case 0x91:
681       vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
682       vos->level = GST_MPEG4_LEVEL1;
683       break;
684     case 0x92:
685       vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
686       vos->level = GST_MPEG4_LEVEL2;
687       break;
688     case 0x93:
689       vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
690       vos->level = GST_MPEG4_LEVEL3;
691       break;
692     case 0x94:
693       vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
694       vos->level = GST_MPEG4_LEVEL4;
695       break;
696     case 0xa1:
697       vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
698       vos->level = GST_MPEG4_LEVEL1;
699       break;
700     case 0xa2:
701       vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
702       vos->level = GST_MPEG4_LEVEL2;
703       break;
704     case 0xa3:
705       vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
706       vos->level = GST_MPEG4_LEVEL3;
707       break;
708     case 0xb1:
709       vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
710       vos->level = GST_MPEG4_LEVEL1;
711       break;
712     case 0xb2:
713       vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
714       vos->level = GST_MPEG4_LEVEL2;
715       break;
716     case 0xb3:
717       vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
718       vos->level = GST_MPEG4_LEVEL3;
719       break;
720     case 0xb4:
721       vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
722       vos->level = GST_MPEG4_LEVEL4;
723       break;
724     case 0xc1:
725       vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
726       vos->level = GST_MPEG4_LEVEL1;
727       break;
728     case 0xc2:
729       vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
730       vos->level = GST_MPEG4_LEVEL2;
731       break;
732     case 0xc3:
733       vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
734       vos->level = GST_MPEG4_LEVEL3;
735       break;
736     case 0xd1:
737       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
738       vos->level = GST_MPEG4_LEVEL1;
739       break;
740     case 0xd2:
741       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
742       vos->level = GST_MPEG4_LEVEL2;
743       break;
744     case 0xd3:
745       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
746       vos->level = GST_MPEG4_LEVEL3;
747       break;
748     case 0xe1:
749       vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
750       vos->level = GST_MPEG4_LEVEL1;
751       break;
752     case 0xe2:
753       vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
754       vos->level = GST_MPEG4_LEVEL2;
755       break;
756     case 0xe3:
757       vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
758       vos->level = GST_MPEG4_LEVEL3;
759       break;
760     case 0xe4:
761       vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
762       vos->level = GST_MPEG4_LEVEL4;
763       break;
764     case 0xe5:
765       vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
766       vos->level = GST_MPEG4_LEVEL1;
767       break;
768     case 0xe6:
769       vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
770       vos->level = GST_MPEG4_LEVEL2;
771       break;
772     case 0xe7:
773       vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
774       vos->level = GST_MPEG4_LEVEL3;
775       break;
776     case 0xe8:
777       vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
778       vos->level = GST_MPEG4_LEVEL4;
779       break;
780     case 0xf0:
781       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
782       vos->level = GST_MPEG4_LEVEL0;
783       break;
784     case 0xf1:
785       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
786       vos->level = GST_MPEG4_LEVEL1;
787       break;
788     case 0xf2:
789       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
790       vos->level = GST_MPEG4_LEVEL2;
791       break;
792     case 0xf3:
793       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
794       vos->level = GST_MPEG4_LEVEL3;
795       break;
796     case 0xf4:
797       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
798       vos->level = GST_MPEG4_LEVEL4;
799       break;
800     case 0xf5:
801       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
802       vos->level = GST_MPEG4_LEVEL5;
803       break;
804     case 0xf7:
805       vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
806       vos->level = GST_MPEG4_LEVEL3b;
807       break;
808     case 0xf8:
809       vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
810       vos->level = GST_MPEG4_LEVEL0;
811       break;
812     case 0xf9:
813       vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
814       vos->level = GST_MPEG4_LEVEL1;
815       break;
816     case 0xfa:
817       vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
818       vos->level = GST_MPEG4_LEVEL2;
819       break;
820     case 0xfb:
821       vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
822       vos->level = GST_MPEG4_LEVEL3;
823       break;
824     case 0xfc:
825       vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
826       vos->level = GST_MPEG4_LEVEL4;
827       break;
828     case 0xfd:
829       vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
830       vos->level = GST_MPEG4_LEVEL5;
831       break;
832     default:
833       vos->profile = GST_MPEG4_PROFILE_RESERVED;
834       vos->level = GST_MPEG4_LEVEL_RESERVED;
835       break;
836   }
837
838   return GST_MPEG4_PARSER_OK;
839
840 wrong_start_code:
841   GST_WARNING ("got buffer with wrong start code");
842   return GST_MPEG4_PARSER_ERROR;
843
844 failed:
845   GST_WARNING ("failed parsing \"Visual Object\"");
846   return GST_MPEG4_PARSER_ERROR;
847 }
848
849 /**
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
856  *
857  * Parses @data containing the visual object packet, and fills
858  * the @vo structure.
859  *
860  * Returns: a #GstMpeg4ParseResult
861  */
862 GstMpeg4ParseResult
863 gst_mpeg4_parse_visual_object (GstMpeg4VisualObject * vo,
864     GstMpeg4VideoSignalType * signal_type, const guint8 * data, gsize size)
865 {
866   guint8 vo_start_code, type;
867   GstBitReader br = GST_BIT_READER_INIT (data, size);
868
869   g_return_val_if_fail (vo != NULL, GST_MPEG4_PARSER_ERROR);
870
871   GST_DEBUG ("Parsing visual object");
872
873   READ_UINT8 (&br, vo_start_code, 8);
874   if (vo_start_code != GST_MPEG4_VISUAL_OBJ)
875     goto wrong_start_code;
876
877   /* set default values */
878   vo->verid = 0x1;
879   vo->priority = 1;
880
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);
885   }
886
887   READ_UINT8 (&br, type, 4);
888   vo->type = type;
889
890   if ((type == GST_MPEG4_VIDEO_ID ||
891           type == GST_MPEG4_STILL_TEXTURE_ID) && signal_type) {
892
893     if (!parse_signal_type (&br, signal_type))
894       goto failed;
895
896   } else if (signal_type) {
897     signal_type->type = 0;
898   }
899
900   return GST_MPEG4_PARSER_OK;
901
902 wrong_start_code:
903   GST_WARNING ("got buffer with wrong start code");
904   return GST_MPEG4_PARSER_ERROR;
905
906 failed:
907   GST_WARNING ("failed parsing \"Visual Object\"");
908   return GST_MPEG4_PARSER_ERROR;
909 }
910
911 /**
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
917  *
918  * Parses @data containing the video object layer packet, and fills
919  * the @vol structure.
920  *
921  * Returns: a #GstMpeg4ParseResult
922  */
923 GstMpeg4ParseResult
924 gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer * vol,
925     GstMpeg4VisualObject * vo, const guint8 * data, gsize size)
926 {
927   guint8 video_object_layer_start_code;
928
929   /* Used for enums types */
930   guint8 tmp;
931   GstBitReader br = GST_BIT_READER_INIT (data, size);
932
933   g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
934
935   GST_DEBUG ("Parsing video object layer");
936
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;
941
942   /* set default values */
943   if (vo) {
944     vol->verid = vo->verid;
945     vol->priority = vo->priority;
946   }
947
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;
955   vol->interlaced = 0;
956   vol->width = 0;
957   vol->height = 0;
958
959   READ_UINT8 (&br, vol->random_accessible_vol, 1);
960   READ_UINT8 (&br, vol->video_object_type_indication, 8);
961
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);
966   }
967
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,
972         &vol->par_height);
973
974   } else {
975     gint v;
976
977     READ_UINT8 (&br, vol->par_width, 8);
978     v = vol->par_width;
979     CHECK_ALLOWED (v, 1, 255);
980
981     READ_UINT8 (&br, vol->par_height, 8);
982     v = vol->par_height;
983     CHECK_ALLOWED (v, 1, 255);
984   }
985   GST_DEBUG ("Pixel aspect ratio %d/%d", vol->par_width, vol->par_width);
986
987   READ_UINT8 (&br, vol->control_parameters, 1);
988   if (vol->control_parameters) {
989     guint8 chroma_format;
990
991     READ_UINT8 (&br, chroma_format, 2);
992     vol->chroma_format = chroma_format;
993     READ_UINT8 (&br, vol->low_delay, 1);
994
995     READ_UINT8 (&br, vol->vbv_parameters, 1);
996     if (vol->vbv_parameters) {
997       CHECK_REMAINING (&br, 79);
998
999       vol->first_half_bitrate =
1000           gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1001       MARKER_UNCHECKED (&br);
1002
1003       vol->latter_half_bitrate =
1004           gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1005       MARKER_UNCHECKED (&br);
1006
1007       vol->bit_rate =
1008           (vol->first_half_bitrate << 15) | vol->latter_half_bitrate;
1009
1010       vol->first_half_vbv_buffer_size =
1011           gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1012       MARKER_UNCHECKED (&br);
1013
1014       vol->latter_half_vbv_buffer_size =
1015           gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
1016       MARKER_UNCHECKED (&br);
1017
1018       vol->vbv_buffer_size = (vol->first_half_vbv_buffer_size << 15) |
1019           vol->latter_half_vbv_buffer_size;
1020
1021       vol->first_half_vbv_occupancy =
1022           gst_bit_reader_get_bits_uint16_unchecked (&br, 11);
1023       MARKER_UNCHECKED (&br);
1024
1025       vol->latter_half_vbv_occupancy =
1026           gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
1027       MARKER_UNCHECKED (&br);
1028     }
1029   }
1030
1031   READ_UINT8 (&br, tmp, 2);
1032   vol->shape = tmp;
1033
1034   if (vol->shape == GST_MPEG4_GRAYSCALE) {
1035     /* TODO support grayscale shapes, for now we just pass */
1036
1037     /* Something the standard starts to define... */
1038     GST_WARNING ("Grayscale shaped not supported");
1039     goto failed;
1040   }
1041
1042   if (vol->shape == GST_MPEG4_GRAYSCALE && vol->verid != 0x01)
1043     READ_UINT8 (&br, vol->shape_extension, 4);
1044
1045   CHECK_REMAINING (&br, 19);
1046
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);
1053     goto failed;
1054   }
1055   vol->vop_time_increment_bits =
1056       g_bit_storage (vol->vop_time_increment_resolution);
1057
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);
1063
1064   if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1065     if (vol->shape == GST_MPEG4_RECTANGULAR) {
1066       CHECK_REMAINING (&br, 29);
1067
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);
1073     }
1074
1075     READ_UINT8 (&br, vol->interlaced, 1);
1076     READ_UINT8 (&br, vol->obmc_disable, 1);
1077
1078     if (vol->verid == 0x1) {
1079       READ_UINT8 (&br, tmp, 1);
1080       vol->sprite_enable = tmp;
1081     } else
1082       READ_UINT8 (&br, tmp, 2);
1083     vol->sprite_enable = tmp;
1084
1085     if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
1086         vol->sprite_enable == GST_MPEG4_SPRITE_GMG) {
1087
1088       if (vol->sprite_enable == GST_MPEG4_SPRITE_GMG)
1089         CHECK_REMAINING (&br, 9);
1090       else {
1091         CHECK_REMAINING (&br, 65);
1092
1093         vol->sprite_width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1094         MARKER_UNCHECKED (&br);
1095
1096         vol->sprite_height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1097         MARKER_UNCHECKED (&br);
1098
1099         vol->sprite_left_coordinate =
1100             gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1101         MARKER_UNCHECKED (&br);
1102
1103         vol->sprite_top_coordinate =
1104             gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1105         MARKER_UNCHECKED (&br);
1106       }
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);
1113
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);
1117     }
1118
1119     if (vol->shape != GST_MPEG4_RECTANGULAR)
1120       READ_UINT8 (&br, vol->sadct_disable, 1);
1121
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);
1126
1127       READ_UINT8 (&br, vol->bits_per_pixel, 4);
1128       CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
1129     }
1130
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);
1136     }
1137
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))
1142         goto failed;
1143
1144       if (!parse_quant (&br, vol->non_intra_quant_mat,
1145               default_non_intra_quant_mat, &vol->load_non_intra_quant_mat))
1146         goto failed;
1147
1148       if (vol->shape == GST_MPEG4_GRAYSCALE) {
1149         /* Something the standard starts to define... */
1150         GST_WARNING ("Grayscale shaped not supported");
1151         goto failed;
1152       }
1153
1154     } else {
1155       memset (&vol->intra_quant_mat, 0, 64);
1156       memset (&vol->non_intra_quant_mat, 0, 64);
1157     }
1158
1159     if (vol->verid != 0x1)
1160       READ_UINT8 (&br, vol->quarter_sample, 1);
1161
1162     READ_UINT8 (&br, vol->complexity_estimation_disable, 1);
1163     if (!vol->complexity_estimation_disable)
1164       goto complexity_estimation_error;
1165
1166
1167     READ_UINT8 (&br, vol->resync_marker_disable, 1);
1168     READ_UINT8 (&br, vol->data_partitioned, 1);
1169
1170     if (vol->data_partitioned)
1171       READ_UINT8 (&br, vol->reversible_vlc, 1);
1172
1173     if (vol->verid != 0x01)
1174       READ_UINT8 (&br, vol->newpred_enable, 1);
1175
1176     if (vol->newpred_enable)
1177       /* requested_upstream_message_type and newpred_segment_type */
1178       SKIP (&br, 3);
1179
1180     READ_UINT8 (&br, vol->reduced_resolution_vop_enable, 1);
1181
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);
1186     }
1187
1188     /* More unused infos */
1189   } else if (vol->verid != 0x01) {
1190     GST_WARNING ("Binary only shapes not fully supported");
1191     goto failed;
1192   }
1193   /* ... */
1194
1195   return GST_MPEG4_PARSER_OK;
1196
1197 failed:
1198   GST_WARNING ("failed parsing \"Video Object Layer\"");
1199   return GST_MPEG4_PARSER_ERROR;
1200
1201 wrong_start_code:
1202   GST_WARNING ("got buffer with wrong start code");
1203   goto failed;
1204
1205 complexity_estimation_error:
1206   GST_WARNING ("don't support complexity estimation");
1207   goto failed;
1208 }
1209
1210 /**
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
1215  *
1216  * Parses @data containing the group of video object plane packet, and fills
1217  * the @gov structure.
1218  *
1219  * Returns: a #GstMpeg4ParseResult
1220  */
1221 GstMpeg4ParseResult
1222 gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *
1223     gov, const guint8 * data, gsize size)
1224 {
1225   guint8 gov_start_code;
1226   GstBitReader br = GST_BIT_READER_INIT (data, size);
1227
1228   g_return_val_if_fail (gov != NULL, GST_MPEG4_PARSER_ERROR);
1229
1230   READ_UINT8 (&br, gov_start_code, 8);
1231   if (gov_start_code != GST_MPEG4_GROUP_OF_VOP)
1232     goto wrong_start_code;
1233
1234   CHECK_REMAINING (&br, 65);
1235
1236   gov->hours = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
1237   gov->minutes = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1238   /* marker bit */
1239   MARKER_UNCHECKED (&br);
1240   gov->seconds = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
1241
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);
1244
1245   return GST_MPEG4_PARSER_OK;
1246
1247 failed:
1248   GST_WARNING ("failed parsing \"Group of Video Object Plane\"");
1249   return GST_MPEG4_PARSER_ERROR;
1250
1251 wrong_start_code:
1252   GST_WARNING ("got buffer with wrong start code");
1253   goto failed;
1254 }
1255
1256 /**
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
1263  *
1264  * Parses @data containing the video object plane packet, and fills the @vol
1265  * structure.
1266  *
1267  * Returns: a #GstMpeg4ParseResult
1268  */
1269 GstMpeg4ParseResult
1270 gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane * vop,
1271     GstMpeg4SpriteTrajectory * sprite_trajectory,
1272     GstMpeg4VideoObjectLayer * vol, const guint8 * data, gsize size)
1273 {
1274   guint8 vop_start_code, coding_type, modulo_time_base;
1275   GstBitReader br = GST_BIT_READER_INIT (data, size);
1276
1277   g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
1278
1279   if (vol->shape == GST_MPEG4_BINARY_ONLY) {
1280     /* TODO: implement binary only shapes */
1281     GST_WARNING ("Binary only shapes not supported");
1282     goto failed;
1283   }
1284
1285   READ_UINT8 (&br, vop_start_code, 8);
1286   if (vop_start_code != GST_MPEG4_VIDEO_OBJ_PLANE)
1287     goto wrong_start_code;
1288
1289
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;
1297
1298   /*  Compute macroblock informations */
1299   if (vol->interlaced)
1300     vop->mb_height = (2 * (vol->height + 31) / 32);
1301   else
1302     vop->mb_height = (vol->height + 15) / 16;
1303
1304   vop->mb_width = (vol->width + 15) / 16;
1305   vop->mb_num = vop->mb_height * vop->mb_width;
1306
1307   READ_UINT8 (&br, coding_type, 2);
1308   vop->coding_type = coding_type;
1309
1310   READ_UINT8 (&br, modulo_time_base, 1);
1311   while (modulo_time_base) {
1312     vop->modulo_time_base++;
1313
1314     READ_UINT8 (&br, modulo_time_base, 1);
1315   }
1316
1317   CHECK_REMAINING (&br, vol->vop_time_increment_bits + 3);
1318
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);
1324
1325   vop->coded = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1326   if (!vop->coded)
1327     return GST_MPEG4_PARSER_OK;
1328
1329   if (vol->newpred_enable) {
1330     guint16 nbbits =
1331         vop->time_increment + 3 < 15 ? vop->time_increment + 3 : 15;
1332
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);
1338       CHECK_MARKER (&br);
1339     }
1340   }
1341
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);
1347
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);
1353
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);
1358
1359       vop->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1360       MARKER_UNCHECKED (&br);
1361
1362       vop->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1363       MARKER_UNCHECKED (&br);
1364
1365       vop->horizontal_mc_spatial_ref =
1366           gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1367       MARKER_UNCHECKED (&br);
1368
1369       vop->vertical_mc_spatial_ref =
1370           gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
1371       MARKER_UNCHECKED (&br);
1372
1373       /* Recompute the Macroblock informations
1374        * accordingly to the new values */
1375       if (vol->interlaced)
1376         vop->mb_height = (2 * (vol->height + 31) / 32);
1377       else
1378         vop->mb_height = (vol->height + 15) / 16;
1379
1380       vop->mb_width = (vol->width + 15) / 16;
1381       vop->mb_num = vop->mb_height * vop->mb_width;
1382     }
1383
1384     if ((vol->shape != GST_MPEG4_BINARY_ONLY) &&
1385         vol->scalability && vol->enhancement_type)
1386       READ_UINT8 (&br, vop->background_composition, 1);
1387
1388     READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
1389
1390     READ_UINT8 (&br, vop->constant_alpha, 1);
1391     if (vop->constant_alpha)
1392       READ_UINT8 (&br, vop->constant_alpha_value, 1);
1393   }
1394
1395   if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1396     if (!vol->complexity_estimation_disable) {
1397       GST_WARNING ("Complexity estimation not supported");
1398       goto failed;
1399     }
1400
1401     READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
1402
1403     if (vol->interlaced) {
1404       READ_UINT8 (&br, vop->top_field_first, 1);
1405       READ_UINT8 (&br, vop->alternate_vertical_scan_flag, 1);
1406     }
1407   }
1408
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) {
1412
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);
1417
1418     if (vol->sprite_brightness_change) {
1419       GST_WARNING ("sprite_brightness_change not supported");
1420       goto failed;
1421     }
1422
1423     if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC) {
1424       GST_WARNING ("sprite enable static not supported");
1425       goto failed;
1426     }
1427   }
1428
1429   if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1430     READ_UINT16 (&br, vop->quant, vol->quant_precision);
1431
1432     if (vol->shape == GST_MPEG4_GRAYSCALE) {
1433       /* TODO implement grayscale support */
1434       GST_WARNING ("Grayscale shapes no supported");
1435
1436       /* TODO implement me */
1437       goto failed;
1438     }
1439
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);
1443     }
1444
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);
1448     }
1449   }
1450
1451   if (!vol->scalability) {
1452     if (vol->shape != GST_MPEG4_RECTANGULAR)
1453       READ_UINT8 (&br, vop->shape_coding_type, 1);
1454
1455   } else {
1456     if (vol->enhancement_type) {
1457       READ_UINT8 (&br, vop->load_backward_shape, 1);
1458
1459       if (vop->load_backward_shape) {
1460         GST_WARNING ("Load backward shape not supported");
1461         goto failed;
1462       }
1463
1464       READ_UINT8 (&br, vop->ref_select_code, 2);
1465     }
1466   }
1467
1468   vop->size = gst_bit_reader_get_pos (&br);
1469   /* More things to possibly parse ... */
1470
1471   return GST_MPEG4_PARSER_OK;
1472
1473 failed:
1474   GST_WARNING ("failed parsing \"Video Object Plane\"");
1475   return GST_MPEG4_PARSER_ERROR;
1476
1477 wrong_start_code:
1478   GST_WARNING ("got buffer with wrong start code");
1479   goto failed;
1480 }
1481
1482 /**
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
1487  */
1488 GstMpeg4ParseResult
1489 gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
1490     shorthdr, const guint8 * data, gsize size)
1491 {
1492   guint8 zero_bits;
1493
1494   GstBitReader br = GST_BIT_READER_INIT (data, size);
1495
1496   g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR);
1497
1498   if (gst_bit_reader_get_remaining (&br) < 48)
1499     goto failed;
1500
1501   if (gst_bit_reader_get_bits_uint32_unchecked (&br, 22) != 0x20)
1502     goto failed;
1503
1504   shorthdr->temporal_reference =
1505       gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
1506   CHECK_MARKER (&br);
1507   zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
1508   if (zero_bits != 0x00)
1509     goto failed;
1510
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);
1518
1519   /* Set parameters/Table 6-25 */
1520   switch (shorthdr->source_format) {
1521     case 0x01:
1522       shorthdr->vop_width = 128;
1523       shorthdr->vop_height = 96;
1524       shorthdr->num_macroblocks_in_gob = 8;
1525       shorthdr->num_gobs_in_vop = 6;
1526       break;
1527     case 0x02:
1528       shorthdr->vop_width = 176;
1529       shorthdr->vop_height = 144;
1530       shorthdr->num_macroblocks_in_gob = 11;
1531       shorthdr->num_gobs_in_vop = 9;
1532       break;
1533     case 0x03:
1534       shorthdr->vop_width = 352;
1535       shorthdr->vop_height = 288;
1536       shorthdr->num_macroblocks_in_gob = 22;
1537       shorthdr->num_gobs_in_vop = 18;
1538       break;
1539     case 0x04:
1540       shorthdr->vop_width = 704;
1541       shorthdr->vop_height = 576;
1542       shorthdr->num_macroblocks_in_gob = 88;
1543       shorthdr->num_gobs_in_vop = 18;
1544       break;
1545     case 0x05:
1546       shorthdr->vop_width = 1408;
1547       shorthdr->vop_height = 1152;
1548       shorthdr->num_macroblocks_in_gob = 352;
1549       shorthdr->num_gobs_in_vop = 18;
1550       break;
1551     default:
1552       shorthdr->vop_width = 0;
1553       shorthdr->vop_height = 0;
1554       shorthdr->num_macroblocks_in_gob = 0;
1555       shorthdr->num_gobs_in_vop = 0;
1556   }
1557
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);
1561
1562   if (zero_bits != 0x00)
1563     goto failed;
1564
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);
1567
1568   if (zero_bits != 0x00)
1569     goto failed;
1570
1571   do {
1572     READ_UINT8 (&br, shorthdr->pei, 1);
1573
1574     if (shorthdr->pei == 1)
1575       READ_UINT8 (&br, shorthdr->psupp, 8);
1576
1577   } while (shorthdr->pei == 1);
1578
1579   shorthdr->size = gst_bit_reader_get_pos (&br);
1580
1581   return GST_MPEG4_PARSER_OK;
1582
1583 failed:
1584   GST_WARNING ("Could not parse the Plane short header");
1585
1586   return GST_MPEG4_PARSER_ERROR;
1587 }
1588
1589 /**
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
1600  *
1601  * Parsers @data containing the video packet header
1602  * and fills the @videopackethdr structure
1603  */
1604 GstMpeg4ParseResult
1605 gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
1606     GstMpeg4VideoObjectLayer * vol, GstMpeg4VideoObjectPlane * vop,
1607     GstMpeg4SpriteTrajectory * sprite_trajectory, const guint8 * data,
1608     gsize size)
1609 {
1610   guint8 markersize;
1611   GstBitReader br = GST_BIT_READER_INIT (data, size);
1612
1613   g_return_val_if_fail (videopackethdr != NULL, GST_MPEG4_PARSER_ERROR);
1614   g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
1615
1616   markersize = compute_resync_marker_size (vop, NULL, NULL);
1617
1618   CHECK_REMAINING (&br, markersize);
1619
1620   if (gst_bit_reader_get_bits_uint32_unchecked (&br, markersize + 1) != 0x01)
1621     goto failed;
1622
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) {
1627
1628       CHECK_REMAINING (&br, 56);
1629
1630       U_READ_UINT16 (&br, vop->width, 13);
1631       CHECK_MARKER (&br);
1632       U_READ_UINT16 (&br, vop->height, 13);
1633       CHECK_MARKER (&br);
1634       U_READ_UINT16 (&br, vop->horizontal_mc_spatial_ref, 13);
1635       CHECK_MARKER (&br);
1636       U_READ_UINT16 (&br, vop->vertical_mc_spatial_ref, 13);
1637       CHECK_MARKER (&br);
1638
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;
1643     }
1644   }
1645
1646   READ_UINT16 (&br, videopackethdr->macroblock_number,
1647       g_bit_storage (vop->mb_num - 1));
1648
1649   if (vol->shape != GST_MPEG4_BINARY_ONLY)
1650     READ_UINT16 (&br, videopackethdr->quant_scale, vol->quant_precision);
1651
1652   if (vol->shape == GST_MPEG4_RECTANGULAR)
1653     READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
1654
1655   if (videopackethdr->header_extension_code) {
1656     guint timeincr = 0;
1657     guint8 bit = 0, coding_type;
1658
1659     do {
1660       READ_UINT8 (&br, bit, 1);
1661       timeincr++;
1662     } while (bit);
1663
1664     vol->vop_time_increment_bits = timeincr;
1665
1666     CHECK_MARKER (&br);
1667     READ_UINT16 (&br, vop->time_increment, timeincr);
1668     CHECK_MARKER (&br);
1669     READ_UINT8 (&br, coding_type, 2);
1670     vop->coding_type = coding_type;
1671
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);
1676     }
1677
1678     if (vol->shape != GST_MPEG4_BINARY_ONLY) {
1679       READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
1680
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) {
1684
1685         parse_sprite_trajectory (&br, sprite_trajectory,
1686             vol->no_of_sprite_warping_points);
1687       }
1688
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);
1694
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);
1698       }
1699
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);
1703       }
1704     }
1705   }
1706
1707   if (vol->newpred_enable) {
1708     guint16 nbbits =
1709         vol->vop_time_increment_bits + 3 < 15 ? vop->time_increment + 3 : 15;
1710
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);
1716       CHECK_MARKER (&br);
1717     }
1718   }
1719
1720   videopackethdr->size = gst_bit_reader_get_pos (&br);
1721
1722 failed:
1723   GST_DEBUG ("Failed to parse video packet header");
1724
1725   return GST_MPEG4_PARSER_NO_PACKET;
1726 }