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