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