import ext/codecparsers instead of git submodule
[profile/ivi/gstreamer-vaapi.git] / ext / codecparsers / gst-libs / gst / codecparsers / gstmpegvideoparser.c
1 /* Gstreamer
2  * Copyright (C) <2011> Intel Corporation
3  * Copyright (C) <2011> Collabora Ltd.
4  * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
5  *
6  * From bad/sys/vdpau/mpeg/mpegutil.c:
7  *   Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com>
8  *   Copyright (C) <2009> Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 /**
27  * SECTION:gstmpegvideoparser
28  * @short_description: Convenience library for mpeg1 and 2 video
29  * bitstream parsing.
30  *
31  * <refsect2>
32  * <para>
33  * Provides useful functions for mpeg videos bitstream parsing.
34  * </para>
35  * </refsect2>
36  */
37
38 #ifdef HAVE_CONFIG_H
39 #  include "config.h"
40 #endif
41
42 #include "gstmpegvideoparser.h"
43 #include "parserutils.h"
44
45 #include <string.h>
46 #include <gst/base/gstbitreader.h>
47 #include <gst/base/gstbytereader.h>
48
49 #define MARKER_BIT 0x1
50
51 /* default intra quant matrix, in zig-zag order */
52 static const guint8 default_intra_quantizer_matrix[64] = {
53   8,
54   16, 16,
55   19, 16, 19,
56   22, 22, 22, 22,
57   22, 22, 26, 24, 26,
58   27, 27, 27, 26, 26, 26,
59   26, 27, 27, 27, 29, 29, 29,
60   34, 34, 34, 29, 29, 29, 27, 27,
61   29, 29, 32, 32, 34, 34, 37,
62   38, 37, 35, 35, 34, 35,
63   38, 38, 40, 40, 40,
64   48, 48, 46, 46,
65   56, 56, 58,
66   69, 69,
67   83
68 };
69
70 static const guint8 mpeg_zigzag_8x8[64] = {
71   0, 1, 8, 16, 9, 2, 3, 10,
72   17, 24, 32, 25, 18, 11, 4, 5,
73   12, 19, 26, 33, 40, 48, 41, 34,
74   27, 20, 13, 6, 7, 14, 21, 28,
75   35, 42, 49, 56, 57, 50, 43, 36,
76   29, 22, 15, 23, 30, 37, 44, 51,
77   58, 59, 52, 45, 38, 31, 39, 46,
78   53, 60, 61, 54, 47, 55, 62, 63
79 };
80
81 GST_DEBUG_CATEGORY (mpegvideo_parser_debug);
82 #define GST_CAT_DEFAULT mpegvideo_parser_debug
83
84 static gboolean initialized = FALSE;
85
86 static inline gboolean
87 find_start_code (GstBitReader * b)
88 {
89   guint32 bits;
90
91   /* 0 bits until byte aligned */
92   while (b->bit != 0) {
93     GET_BITS (b, 1, &bits);
94   }
95
96   /* 0 bytes until startcode */
97   while (gst_bit_reader_peek_bits_uint32 (b, &bits, 32)) {
98     if (bits >> 8 == 0x1) {
99       return TRUE;
100     } else if (gst_bit_reader_skip (b, 8) == FALSE)
101       break;
102   }
103
104   return FALSE;
105
106 failed:
107   return FALSE;
108 }
109
110 /* Set the Pixel Aspect Ratio in our hdr from a ASR code in the data */
111 static void
112 set_par_from_asr_mpeg1 (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code)
113 {
114   int ratios[16][2] = {
115     {0, 0},                     /* 0, Invalid */
116     {1, 1},                     /* 1, 1.0 */
117     {10000, 6735},              /* 2, 0.6735 */
118     {64, 45},                   /* 3, 0.7031 16:9 625 line */
119     {10000, 7615},              /* 4, 0.7615 */
120     {10000, 8055},              /* 5, 0.8055 */
121     {32, 27},                   /* 6, 0.8437 */
122     {10000, 8935},              /* 7, 0.8935 */
123     {10000, 9375},              /* 8, 0.9375 */
124     {10000, 9815},              /* 9, 0.9815 */
125     {10000, 10255},             /* 10, 1.0255 */
126     {10000, 10695},             /* 11, 1.0695 */
127     {8, 9},                     /* 12, 1.125 */
128     {10000, 11575},             /* 13, 1.1575 */
129     {10000, 12015},             /* 14, 1.2015 */
130     {0, 0},                     /* 15, invalid */
131   };
132   asr_code &= 0xf;
133
134   seqhdr->par_w = ratios[asr_code][0];
135   seqhdr->par_h = ratios[asr_code][1];
136 }
137
138 static void
139 set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
140 {
141   const gint framerates[][2] = {
142     {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
143     {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
144     {60, 1}, {30, 1}
145   };
146
147   if (fps_code && fps_code < 10) {
148     seqhdr->fps_n = framerates[fps_code][0];
149     seqhdr->fps_d = framerates[fps_code][1];
150   } else {
151     GST_DEBUG ("unknown/invalid frame_rate_code %d", fps_code);
152     /* Force a valid framerate */
153     /* FIXME or should this be kept unknown ?? */
154     seqhdr->fps_n = 30000;
155     seqhdr->fps_d = 1001;
156   }
157 }
158
159 /* @size and @offset are wrt current reader position */
160 static inline guint
161 scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
162 {
163   const guint8 *data;
164   guint i = 0;
165
166   g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
167       -1);
168
169   /* we can't find the pattern with less than 4 bytes */
170   if (G_UNLIKELY (size < 4))
171     return -1;
172
173   data = reader->data + reader->byte + offset;
174
175   while (i <= (size - 4)) {
176     if (data[i + 2] > 1) {
177       i += 3;
178     } else if (data[i + 1]) {
179       i += 2;
180     } else if (data[i] || data[i + 2] != 1) {
181       i++;
182     } else {
183       break;
184     }
185   }
186
187   if (i <= (size - 4))
188     return offset + i;
189
190   /* nothing found */
191   return -1;
192 }
193
194 /****** API *******/
195
196 /**
197  * gst_mpeg_video_parse:
198  * @data: The data to parse
199  * @size: The size of @data
200  * @offset: The offset from which to start parsing
201  *
202  * Parses the MPEG 1/2 video bitstream contained in @data , and returns the
203  * detect packets as a list of #GstMpegVideoTypeOffsetSize.
204  *
205  * Returns: TRUE if a packet start code was found
206  */
207 gboolean
208 gst_mpeg_video_parse (GstMpegVideoPacket * packet,
209     const guint8 * data, gsize size, guint offset)
210 {
211   gint off;
212   GstByteReader br;
213
214   if (!initialized) {
215     GST_DEBUG_CATEGORY_INIT (mpegvideo_parser_debug, "codecparsers_mpegvideo",
216         0, "Mpegvideo parser library");
217     initialized = TRUE;
218   }
219
220   if (size <= offset) {
221     GST_DEBUG ("Can't parse from offset %d, buffer is to small", offset);
222     return FALSE;
223   }
224
225   size -= offset;
226   gst_byte_reader_init (&br, &data[offset], size);
227
228   off = scan_for_start_codes (&br, 0, size);
229
230   if (off < 0) {
231     GST_DEBUG ("No start code prefix in this buffer");
232     return FALSE;
233   }
234
235   if (gst_byte_reader_skip (&br, off + 3) == FALSE)
236     goto failed;
237
238   if (gst_byte_reader_get_uint8 (&br, &packet->type) == FALSE)
239     goto failed;
240
241   packet->data = data;
242   packet->offset = offset + off + 4;
243   packet->size = -1;
244
245   /* try to find end of packet */
246   size -= off + 4;
247   off = scan_for_start_codes (&br, 0, size);
248
249   if (off > 0)
250     packet->size = off;
251
252   return TRUE;
253
254 failed:
255   {
256     GST_WARNING ("Failed to parse");
257     return FALSE;
258   }
259 }
260
261 /**
262  * gst_mpeg_video_parse_sequence_header:
263  * @seqhdr: (out): The #GstMpegVideoSequenceHdr structure to fill
264  * @data: The data from which to parse the sequence header
265  * @size: The size of @data
266  * @offset: The offset in byte from which to start parsing @data
267  *
268  * Parses the @seqhdr Mpeg Video Sequence Header structure members from @data
269  *
270  * Returns: %TRUE if the seqhdr could be parsed correctly, %FALSE otherwize.
271  */
272 gboolean
273 gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
274     const guint8 * data, gsize size, guint offset)
275 {
276   GstBitReader br;
277   guint8 bits;
278   guint8 load_intra_flag, load_non_intra_flag;
279
280   g_return_val_if_fail (seqhdr != NULL, FALSE);
281
282   size -= offset;
283
284   if (size < 4)
285     return FALSE;
286
287   gst_bit_reader_init (&br, &data[offset], size);
288
289   /* Setting the height/width codes */
290   READ_UINT16 (&br, seqhdr->width, 12);
291   READ_UINT16 (&br, seqhdr->height, 12);
292
293   READ_UINT8 (&br, seqhdr->aspect_ratio_info, 4);
294   /* Interpret PAR according to MPEG-1. Needs to be reinterpreted
295    * later, if a sequence_display extension is seen */
296   set_par_from_asr_mpeg1 (seqhdr, seqhdr->aspect_ratio_info);
297
298   READ_UINT8 (&br, seqhdr->frame_rate_code, 4);
299   set_fps_from_code (seqhdr, seqhdr->frame_rate_code);
300
301   READ_UINT32 (&br, seqhdr->bitrate_value, 18);
302   if (seqhdr->bitrate_value == 0x3ffff) {
303     /* VBR stream */
304     seqhdr->bitrate = 0;
305   } else {
306     /* Value in header is in units of 400 bps */
307     seqhdr->bitrate *= 400;
308   }
309
310   READ_UINT8 (&br, bits, 1);
311   if (bits != MARKER_BIT)
312     goto failed;
313
314   /* VBV buffer size */
315   READ_UINT16 (&br, seqhdr->vbv_buffer_size_value, 10);
316
317   /* constrained_parameters_flag */
318   READ_UINT8 (&br, seqhdr->constrained_parameters_flag, 1);
319
320   /* load_intra_quantiser_matrix */
321   READ_UINT8 (&br, load_intra_flag, 1);
322   if (load_intra_flag) {
323     gint i;
324     for (i = 0; i < 64; i++)
325       READ_UINT8 (&br, seqhdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8);
326   } else
327     memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);
328
329   /* non intra quantizer matrix */
330   READ_UINT8 (&br, load_non_intra_flag, 1);
331   if (load_non_intra_flag) {
332     gint i;
333     for (i = 0; i < 64; i++)
334       READ_UINT8 (&br, seqhdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]],
335           8);
336   } else
337     memset (seqhdr->non_intra_quantizer_matrix, 16, 64);
338
339   /* dump some info */
340   GST_LOG ("width x height: %d x %d", seqhdr->width, seqhdr->height);
341   GST_LOG ("fps: %d/%d", seqhdr->fps_n, seqhdr->fps_d);
342   GST_LOG ("par: %d/%d", seqhdr->par_w, seqhdr->par_h);
343   GST_LOG ("bitrate: %d", seqhdr->bitrate);
344
345   return TRUE;
346
347   /* ERRORS */
348 failed:
349   {
350     GST_WARNING ("Failed to parse sequence header");
351     /* clear out stuff */
352     memset (seqhdr, 0, sizeof (*seqhdr));
353     return FALSE;
354   }
355 }
356
357 /**
358  * gst_mpeg_video_parse_sequence_extension:
359  * @seqext: (out): The #GstMpegVideoSequenceExt structure to fill
360  * @data: The data from which to parse the sequence extension
361  * @size: The size of @data
362  * @offset: The offset in byte from which to start parsing @data
363  *
364  * Parses the @seqext Mpeg Video Sequence Extension structure members from @data
365  *
366  * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwize.
367  */
368 gboolean
369 gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext,
370     const guint8 * data, gsize size, guint offset)
371 {
372   GstBitReader br;
373
374   g_return_val_if_fail (seqext != NULL, FALSE);
375
376   size -= offset;
377
378   if (size < 6) {
379     GST_DEBUG ("not enough bytes to parse the extension");
380     return FALSE;
381   }
382
383   gst_bit_reader_init (&br, &data[offset], size);
384
385   if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
386       GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE) {
387     GST_DEBUG ("Not parsing a sequence extension");
388     return FALSE;
389   }
390
391   /* skip profile and level escape bit */
392   gst_bit_reader_skip_unchecked (&br, 1);
393
394   seqext->profile = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
395   seqext->level = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
396
397   /* progressive */
398   seqext->progressive = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
399
400   /* chroma format */
401   seqext->chroma_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
402
403   /* resolution extension */
404   seqext->horiz_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
405   seqext->vert_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
406
407   seqext->bitrate_ext = gst_bit_reader_get_bits_uint16_unchecked (&br, 12);
408
409   /* skip marker bits */
410   gst_bit_reader_skip_unchecked (&br, 1);
411
412   seqext->vbv_buffer_size_extension =
413       gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
414   seqext->low_delay = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
415
416   /* framerate extension */
417   seqext->fps_n_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
418   seqext->fps_d_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
419
420   return TRUE;
421 }
422
423 gboolean
424 gst_mpeg_video_parse_sequence_display_extension (GstMpegVideoSequenceDisplayExt
425     * seqdisplayext, const guint8 * data, gsize size, guint offset)
426 {
427   GstBitReader br;
428
429   g_return_val_if_fail (seqdisplayext != NULL, FALSE);
430   if (offset > size)
431     return FALSE;
432
433   size -= offset;
434   if (size < 5) {
435     GST_DEBUG ("not enough bytes to parse the extension");
436     return FALSE;
437   }
438
439   gst_bit_reader_init (&br, &data[offset], size);
440
441   if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
442       GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY) {
443     GST_DEBUG ("Not parsing a sequence display extension");
444     return FALSE;
445   }
446
447   seqdisplayext->video_format =
448       gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
449   seqdisplayext->colour_description_flag =
450       gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
451
452   if (seqdisplayext->colour_description_flag) {
453     seqdisplayext->colour_primaries =
454         gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
455     seqdisplayext->transfer_characteristics =
456         gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
457     seqdisplayext->matrix_coefficients =
458         gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
459   }
460
461   if (gst_bit_reader_get_remaining (&br) < 29) {
462     GST_DEBUG ("Not enough remaining bytes to parse the extension");
463     return FALSE;
464   }
465
466   seqdisplayext->display_horizontal_size =
467       gst_bit_reader_get_bits_uint16_unchecked (&br, 14);
468   /* skip marker bit */
469   gst_bit_reader_skip_unchecked (&br, 1);
470   seqdisplayext->display_vertical_size =
471       gst_bit_reader_get_bits_uint16_unchecked (&br, 14);
472
473   return TRUE;
474 }
475
476 gboolean
477 gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
478     GstMpegVideoSequenceExt * seqext,
479     GstMpegVideoSequenceDisplayExt * displayext)
480 {
481   guint32 w;
482   guint32 h;
483
484   if (seqext) {
485     seqhdr->fps_n = seqhdr->fps_n * (seqext->fps_n_ext + 1);
486     seqhdr->fps_d = seqhdr->fps_d * (seqext->fps_d_ext + 1);
487     /* Extend width and height to 14 bits by adding the extension bits */
488     seqhdr->width |= (seqext->horiz_size_ext << 12);
489     seqhdr->height |= (seqext->vert_size_ext << 12);
490   }
491
492   w = seqhdr->width;
493   h = seqhdr->height;
494   if (displayext) {
495     /* Use the display size for calculating PAR when display ext present */
496     w = displayext->display_horizontal_size;
497     h = displayext->display_vertical_size;
498   }
499
500   /* Pixel_width = DAR_width * display_vertical_size */
501   /* Pixel_height = DAR_height * display_horizontal_size */
502   switch (seqhdr->aspect_ratio_info) {
503     case 0x01:                 /* Square pixels */
504       seqhdr->par_w = seqhdr->par_h = 1;
505       break;
506     case 0x02:                 /* 3:4 DAR = 4:3 pixels */
507       seqhdr->par_w = 4 * h;
508       seqhdr->par_h = 3 * w;
509       break;
510     case 0x03:                 /* 9:16 DAR */
511       seqhdr->par_w = 16 * h;
512       seqhdr->par_h = 9 * w;
513       break;
514     case 0x04:                 /* 1:2.21 DAR */
515       seqhdr->par_w = 221 * h;
516       seqhdr->par_h = 100 * w;
517       break;
518     default:
519       GST_DEBUG ("unknown/invalid aspect_ratio_information %d",
520           seqhdr->aspect_ratio_info);
521       break;
522   }
523
524   return TRUE;
525 }
526
527 /**
528  * gst_mpeg_video_parse_quant_matrix_extension:
529  * @quant: (out): The #GstMpegVideoQuantMatrixExt structure to fill
530  * @data: The data from which to parse the Quantization Matrix extension
531  * @size: The size of @data
532  * @offset: The offset in byte from which to start the parsing
533  *
534  * Parses the @quant Mpeg Video Quant Matrix Extension structure members from
535  * @data
536  *
537  * Returns: %TRUE if the quant matrix extension could be parsed correctly,
538  * %FALSE otherwize.
539  */
540 gboolean
541 gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant,
542     const guint8 * data, gsize size, guint offset)
543 {
544   guint8 i;
545   GstBitReader br;
546
547   g_return_val_if_fail (quant != NULL, FALSE);
548
549   size -= offset;
550
551   if (size < 1) {
552     GST_DEBUG ("not enough bytes to parse the extension");
553     return FALSE;
554   }
555
556   gst_bit_reader_init (&br, &data[offset], size);
557
558   if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
559       GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX) {
560     GST_DEBUG ("Not parsing a quant matrix extension");
561     return FALSE;
562   }
563
564   READ_UINT8 (&br, quant->load_intra_quantiser_matrix, 1);
565   if (quant->load_intra_quantiser_matrix) {
566     for (i = 0; i < 64; i++) {
567       READ_UINT8 (&br, quant->intra_quantiser_matrix[mpeg_zigzag_8x8[i]], 8);
568     }
569   }
570
571   READ_UINT8 (&br, quant->load_non_intra_quantiser_matrix, 1);
572   if (quant->load_non_intra_quantiser_matrix) {
573     for (i = 0; i < 64; i++) {
574       READ_UINT8 (&br, quant->non_intra_quantiser_matrix[mpeg_zigzag_8x8[i]],
575           8);
576     }
577   }
578
579   READ_UINT8 (&br, quant->load_chroma_intra_quantiser_matrix, 1);
580   if (quant->load_chroma_intra_quantiser_matrix) {
581     for (i = 0; i < 64; i++) {
582       READ_UINT8 (&br, quant->chroma_intra_quantiser_matrix[mpeg_zigzag_8x8[i]],
583           8);
584     }
585   }
586
587   READ_UINT8 (&br, quant->load_chroma_non_intra_quantiser_matrix, 1);
588   if (quant->load_chroma_non_intra_quantiser_matrix) {
589     for (i = 0; i < 64; i++) {
590       READ_UINT8 (&br,
591           quant->chroma_non_intra_quantiser_matrix[mpeg_zigzag_8x8[i]], 8);
592     }
593   }
594
595   return TRUE;
596
597 failed:
598   GST_WARNING ("error parsing \"Quant Matrix Extension\"");
599   return FALSE;
600 }
601
602 /**
603  * gst_mpeg_video_parse_picture_extension:
604  * @ext: (out): The #GstMpegVideoPictureExt structure to fill
605  * @data: The data from which to parse the picture extension
606  * @size: The size of @data
607  * @offset: The offset in byte from which to start the parsing
608  *
609  * Parse the @ext Mpeg Video Picture Extension structure members from @data
610  *
611  * Returns: %TRUE if the picture extension could be parsed correctly,
612  * %FALSE otherwize.
613  */
614 gboolean
615 gst_mpeg_video_parse_picture_extension (GstMpegVideoPictureExt * ext,
616     const guint8 * data, gsize size, guint offset)
617 {
618   GstBitReader br;
619
620   g_return_val_if_fail (ext != NULL, FALSE);
621
622   size -= offset;
623
624   if (size < 4)
625     return FALSE;
626
627   gst_bit_reader_init (&br, &data[offset], size);
628
629   if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
630       GST_MPEG_VIDEO_PACKET_EXT_PICTURE) {
631     GST_DEBUG ("Not parsing a picture extension");
632     return FALSE;
633   }
634
635   /* f_code */
636   READ_UINT8 (&br, ext->f_code[0][0], 4);
637   READ_UINT8 (&br, ext->f_code[0][1], 4);
638   READ_UINT8 (&br, ext->f_code[1][0], 4);
639   READ_UINT8 (&br, ext->f_code[1][1], 4);
640
641   /* intra DC precision */
642   READ_UINT8 (&br, ext->intra_dc_precision, 2);
643
644   /* picture structure */
645   READ_UINT8 (&br, ext->picture_structure, 2);
646
647   /* top field first */
648   READ_UINT8 (&br, ext->top_field_first, 1);
649
650   /* frame pred frame dct */
651   READ_UINT8 (&br, ext->frame_pred_frame_dct, 1);
652
653   /* concealment motion vectors */
654   READ_UINT8 (&br, ext->concealment_motion_vectors, 1);
655
656   /* q scale type */
657   READ_UINT8 (&br, ext->q_scale_type, 1);
658
659   /* intra vlc format */
660   READ_UINT8 (&br, ext->intra_vlc_format, 1);
661
662   /* alternate scan */
663   READ_UINT8 (&br, ext->alternate_scan, 1);
664
665   /* repeat first field */
666   READ_UINT8 (&br, ext->repeat_first_field, 1);
667
668   /* chroma_420_type */
669   READ_UINT8 (&br, ext->chroma_420_type, 1);
670
671   /* progressive_frame */
672   READ_UINT8 (&br, ext->progressive_frame, 1);
673
674   /* composite display */
675   READ_UINT8 (&br, ext->composite_display, 1);
676
677   if (ext->composite_display) {
678
679     /* v axis */
680     READ_UINT8 (&br, ext->v_axis, 1);
681
682     /* field sequence */
683     READ_UINT8 (&br, ext->field_sequence, 3);
684
685     /* sub carrier */
686     READ_UINT8 (&br, ext->sub_carrier, 1);
687
688     /* burst amplitude */
689     READ_UINT8 (&br, ext->burst_amplitude, 7);
690
691     /* sub_carrier phase */
692     READ_UINT8 (&br, ext->sub_carrier_phase, 8);
693   }
694
695   return TRUE;
696
697 failed:
698   GST_WARNING ("error parsing \"Picture Coding Extension\"");
699   return FALSE;
700
701 }
702
703 /**
704  * gst_mpeg_video_parse_picture_header:
705  * @hdr: (out): The #GstMpegVideoPictureHdr structure to fill
706  * @data: The data from which to parse the picture header
707  * @size: The size of @data
708  * @offset: The offset in byte from which to start the parsing
709  *
710  * Parsers the @hdr Mpeg Video Picture Header structure members from @data
711  *
712  * Returns: %TRUE if the picture sequence could be parsed correctly, %FALSE
713  * otherwize.
714  */
715 gboolean
716 gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr * hdr,
717     const guint8 * data, gsize size, guint offset)
718 {
719   GstBitReader br;
720
721   size = size - offset;
722
723   if (size < 4)
724     goto failed;
725
726   gst_bit_reader_init (&br, &data[offset], size);
727
728   /* temperal sequence number */
729   if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->tsn, 10))
730     goto failed;
731
732
733   /* frame type */
734   if (!gst_bit_reader_get_bits_uint8 (&br, (guint8 *) & hdr->pic_type, 3))
735     goto failed;
736
737
738   if (hdr->pic_type == 0 || hdr->pic_type > 4)
739     goto failed;                /* Corrupted picture packet */
740
741   /* skip VBV delay */
742   if (!gst_bit_reader_skip (&br, 16))
743     goto failed;
744
745   if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_P
746       || hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
747
748     READ_UINT8 (&br, hdr->full_pel_forward_vector, 1);
749
750     READ_UINT8 (&br, hdr->f_code[0][0], 3);
751     hdr->f_code[0][1] = hdr->f_code[0][0];
752   } else {
753     hdr->full_pel_forward_vector = 0;
754     hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
755   }
756
757   if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
758     READ_UINT8 (&br, hdr->full_pel_backward_vector, 1);
759
760     READ_UINT8 (&br, hdr->f_code[1][0], 3);
761     hdr->f_code[1][1] = hdr->f_code[1][0];
762   } else {
763     hdr->full_pel_backward_vector = 0;
764     hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
765   }
766
767   return TRUE;
768
769 failed:
770   {
771     GST_WARNING ("Failed to parse picture header");
772     return FALSE;
773   }
774 }
775
776 /**
777  * gst_mpeg_video_parse_gop:
778  * @gop: (out): The #GstMpegVideoGop structure to fill
779  * @data: The data from which to parse the gop
780  * @size: The size of @data
781  * @offset: The offset in byte from which to start the parsing
782  *
783  * Parses the @gop Mpeg Video Group of Picture structure members from @data
784  *
785  * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwize.
786  */
787 gboolean
788 gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, const guint8 * data,
789     gsize size, guint offset)
790 {
791   GstBitReader br;
792
793   g_return_val_if_fail (gop != NULL, FALSE);
794
795   size -= offset;
796
797   if (size < 4)
798     return FALSE;
799
800   gst_bit_reader_init (&br, &data[offset], size);
801
802   READ_UINT8 (&br, gop->drop_frame_flag, 1);
803
804   READ_UINT8 (&br, gop->hour, 5);
805
806   READ_UINT8 (&br, gop->minute, 6);
807
808   /* skip unused bit */
809   if (!gst_bit_reader_skip (&br, 1))
810     return FALSE;
811
812   READ_UINT8 (&br, gop->second, 6);
813
814   READ_UINT8 (&br, gop->frame, 6);
815
816   READ_UINT8 (&br, gop->closed_gop, 1);
817
818   READ_UINT8 (&br, gop->broken_link, 1);
819
820   return TRUE;
821
822 failed:
823   GST_WARNING ("error parsing \"GOP\"");
824   return FALSE;
825 }