Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / 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., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, 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 {
101       gst_bit_reader_skip (b, 8);
102     }
103   }
104
105   return FALSE;
106
107 failed:
108   return FALSE;
109 }
110
111 /* Set the Pixel Aspect Ratio in our hdr from a DAR code in the data */
112 static void
113 set_par_from_dar (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code)
114 {
115   /* Pixel_width = DAR_width * display_vertical_size */
116   /* Pixel_height = DAR_height * display_horizontal_size */
117   switch (asr_code) {
118     case 0x02:                 /* 3:4 DAR = 4:3 pixels */
119       seqhdr->par_w = 4 * seqhdr->height;
120       seqhdr->par_h = 3 * seqhdr->width;
121       break;
122     case 0x03:                 /* 9:16 DAR */
123       seqhdr->par_w = 16 * seqhdr->height;
124       seqhdr->par_h = 9 * seqhdr->width;
125       break;
126     case 0x04:                 /* 1:2.21 DAR */
127       seqhdr->par_w = 221 * seqhdr->height;
128       seqhdr->par_h = 100 * seqhdr->width;
129       break;
130     case 0x01:                 /* Square pixels */
131       seqhdr->par_w = seqhdr->par_h = 1;
132       break;
133     default:
134       GST_DEBUG ("unknown/invalid aspect_ratio_information %d", asr_code);
135       break;
136   }
137 }
138
139 static void
140 set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
141 {
142   const gint framerates[][2] = {
143     {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
144     {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
145     {60, 1}, {30, 1}
146   };
147
148   if (fps_code && fps_code < 10) {
149     seqhdr->fps_n = framerates[fps_code][0];
150     seqhdr->fps_d = framerates[fps_code][1];
151   } else {
152     GST_DEBUG ("unknown/invalid frame_rate_code %d", fps_code);
153     /* Force a valid framerate */
154     /* FIXME or should this be kept unknown ?? */
155     seqhdr->fps_n = 30000;
156     seqhdr->fps_d = 1001;
157   }
158 }
159
160 static gboolean
161 gst_mpeg_video_parse_sequence (GstMpegVideoSequenceHdr * seqhdr,
162     GstBitReader * br)
163 {
164   guint8 bits;
165   guint8 load_intra_flag, load_non_intra_flag;
166
167   /* Setting the height/width codes */
168   READ_UINT16 (br, seqhdr->width, 12);
169   READ_UINT16 (br, seqhdr->height, 12);
170
171   READ_UINT8 (br, seqhdr->aspect_ratio_info, 4);
172   set_par_from_dar (seqhdr, seqhdr->aspect_ratio_info);
173
174   READ_UINT8 (br, seqhdr->frame_rate_code, 4);
175   set_fps_from_code (seqhdr, seqhdr->frame_rate_code);
176
177   READ_UINT32 (br, seqhdr->bitrate_value, 18);
178   if (seqhdr->bitrate_value == 0x3ffff) {
179     /* VBR stream */
180     seqhdr->bitrate = 0;
181   } else {
182     /* Value in header is in units of 400 bps */
183     seqhdr->bitrate *= 400;
184   }
185
186   READ_UINT8 (br, bits, 1);
187   if (bits != MARKER_BIT)
188     goto failed;
189
190   /* VBV buffer size */
191   READ_UINT16 (br, seqhdr->vbv_buffer_size_value, 10);
192
193   /* constrained_parameters_flag */
194   READ_UINT8 (br, seqhdr->constrained_parameters_flag, 1);
195
196   /* load_intra_quantiser_matrix */
197   READ_UINT8 (br, load_intra_flag, 1);
198   if (load_intra_flag) {
199     gint i;
200     for (i = 0; i < 64; i++)
201       READ_UINT8 (br, seqhdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8);
202   } else
203     memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);
204
205   /* non intra quantizer matrix */
206   READ_UINT8 (br, load_non_intra_flag, 1);
207   if (load_non_intra_flag) {
208     gint i;
209     for (i = 0; i < 64; i++)
210       READ_UINT8 (br, seqhdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]],
211           8);
212   } else
213     memset (seqhdr->non_intra_quantizer_matrix, 16, 64);
214
215   /* dump some info */
216   GST_LOG ("width x height: %d x %d", seqhdr->width, seqhdr->height);
217   GST_LOG ("fps: %d/%d", seqhdr->fps_n, seqhdr->fps_d);
218   GST_LOG ("par: %d/%d", seqhdr->par_w, seqhdr->par_h);
219   GST_LOG ("bitrate: %d", seqhdr->bitrate);
220
221   return TRUE;
222
223   /* ERRORS */
224 failed:
225   {
226     GST_WARNING ("Failed to parse sequence header");
227     /* clear out stuff */
228     memset (seqhdr, 0, sizeof (*seqhdr));
229     return FALSE;
230   }
231 }
232
233 static inline guint
234 scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
235 {
236   const guint8 *data;
237   guint32 state;
238   guint i;
239
240   g_return_val_if_fail (size > 0, -1);
241   g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
242       -1);
243
244   /* we can't find the pattern with less than 4 bytes */
245   if (G_UNLIKELY (size < 4))
246     return -1;
247
248   data = reader->data + reader->byte + offset;
249
250   /* set the state to something that does not match */
251   state = 0xffffffff;
252
253   /* now find data */
254   for (i = 0; i < size; i++) {
255     /* throw away one byte and move in the next byte */
256     state = ((state << 8) | data[i]);
257     if (G_UNLIKELY ((state & 0xffffff00) == 0x00000100)) {
258       /* we have a match but we need to have skipped at
259        * least 4 bytes to fill the state. */
260       if (G_LIKELY (i >= 3))
261         return offset + i - 3;
262     }
263
264     /* TODO: reimplement making 010001 not detected as a sc
265      * Accelerate search for start code
266      * if (data[i] > 1) {
267      * while (i < (size - 4) && data[i] > 1) {
268      *   if (data[i + 3] > 1)
269      *     i += 4;
270      *   else
271      *     i += 1;
272      * }
273      * state = 0x00000100;
274      *}
275      */
276   }
277
278   /* nothing found */
279   return -1;
280 }
281
282 /****** API *******/
283
284 /**
285  * gst_mpeg_video_parse:
286  * @data: The data to parse
287  * @size: The size of @data
288  * @offset: The offset from which to start parsing
289  *
290  * Parses the MPEG 1/2 video bitstream contained in @data , and returns the
291  * detect packets as a list of #GstMpegVideoTypeOffsetSize.
292  *
293  * Returns: a #GList of #GstMpegVideoTypeOffsetSize
294  */
295 GList *
296 gst_mpeg_video_parse (const guint8 * data, gsize size, guint offset)
297 {
298   gint off, rsize;
299   GstByteReader br;
300   GList *ret = NULL;
301
302   size -= offset;
303
304   if (!initialized) {
305     GST_DEBUG_CATEGORY_INIT (mpegvideo_parser_debug, "codecparsers_mpegvideo",
306         0, "Mpegvideo parser library");
307     initialized = TRUE;
308   }
309
310   if (size <= 0) {
311     GST_DEBUG ("Can't parse from offset %d, buffer is to small", offset);
312     return NULL;
313   }
314
315   gst_byte_reader_init (&br, &data[offset], size);
316
317   off = scan_for_start_codes (&br, 0, size);
318
319   if (off < 0) {
320     GST_DEBUG ("No start code prefix in this buffer");
321     return NULL;
322   }
323
324   while (off >= 0 && off + 3 < size) {
325     GstMpegVideoTypeOffsetSize *codoffsize;
326
327     gst_byte_reader_skip (&br, off + 3);
328
329     codoffsize = g_malloc (sizeof (GstMpegVideoTypeOffsetSize));
330     gst_byte_reader_get_uint8 (&br, &codoffsize->type);
331
332     codoffsize->offset = gst_byte_reader_get_pos (&br) + offset;
333
334     rsize = gst_byte_reader_get_remaining (&br);
335     if (rsize <= 0) {
336       g_free (codoffsize);
337       break;
338     }
339
340     off = scan_for_start_codes (&br, 0, rsize);
341
342     codoffsize->size = off;
343
344     ret = g_list_prepend (ret, codoffsize);
345     codoffsize = ret->data;
346   }
347
348   return g_list_reverse (ret);
349 }
350
351 /**
352  * gst_mpeg_video_parse_sequence_header:
353  * @seqhdr: (out): The #GstMpegVideoSequenceHdr structure to fill
354  * @data: The data from which to parse the sequence header
355  * @size: The size of @data
356  * @offset: The offset in byte from which to start parsing @data
357  *
358  * Parses the @seqhdr Mpeg Video Sequence Header structure members from @data
359  *
360  * Returns: %TRUE if the seqhdr could be parsed correctly, %FALSE otherwize.
361  */
362 gboolean
363 gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
364     const guint8 * data, gsize size, guint offset)
365 {
366   GstBitReader br;
367
368   g_return_val_if_fail (seqhdr != NULL, FALSE);
369
370   size -= offset;
371
372   if (size < 4)
373     return FALSE;
374
375   gst_bit_reader_init (&br, &data[offset], size);
376
377   return gst_mpeg_video_parse_sequence (seqhdr, &br);
378 }
379
380 /**
381  * gst_mpeg_video_parse_sequence_extension:
382  * @seqext: (out): The #GstMpegVideoSequenceExt structure to fill
383  * @data: The data from which to parse the sequence extension
384  * @size: The size of @data
385  * @offset: The offset in byte from which to start parsing @data
386  *
387  * Parses the @seqext Mpeg Video Sequence Extension structure members from @data
388  *
389  * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwize.
390  */
391 gboolean
392 gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext,
393     const guint8 * data, gsize size, guint offset)
394 {
395   GstBitReader br;
396
397   g_return_val_if_fail (seqext != NULL, FALSE);
398
399   size -= offset;
400
401   if (size < 6) {
402     GST_DEBUG ("not enough bytes to parse the extension");
403     return FALSE;
404   }
405
406   gst_bit_reader_init (&br, &data[offset], size);
407
408   if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
409       GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE) {
410     GST_DEBUG ("Not parsing a sequence extension");
411     return FALSE;
412   }
413
414   /* skip profile and level escape bit */
415   gst_bit_reader_skip_unchecked (&br, 1);
416
417   seqext->profile = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
418   seqext->level = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
419
420   /* progressive */
421   seqext->progressive = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
422
423   /* chroma format */
424   seqext->chroma_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
425
426   /* resolution extension */
427   seqext->horiz_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
428   seqext->vert_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
429
430   seqext->bitrate_ext = gst_bit_reader_get_bits_uint16_unchecked (&br, 12);
431
432   /* skip marker bits */
433   gst_bit_reader_skip_unchecked (&br, 1);
434
435   seqext->vbv_buffer_size_extension =
436       gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
437   seqext->low_delay = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
438
439   /* framerate extension */
440   seqext->fps_n_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
441   seqext->fps_d_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
442
443   return TRUE;
444 }
445
446 /**
447  * gst_mpeg_video_parse_quant_matrix_extension:
448  * @quant: (out): The #GstMpegVideoQuantMatrixExt structure to fill
449  * @data: The data from which to parse the Quantization Matrix extension
450  * @size: The size of @data
451  * @offset: The offset in byte from which to start the parsing
452  *
453  * Parses the @quant Mpeg Video Quant Matrix Extension structure members from
454  * @data
455  *
456  * Returns: %TRUE if the quant matrix extension could be parsed correctly,
457  * %FALSE otherwize.
458  */
459 gboolean
460 gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant,
461     const guint8 * data, gsize size, guint offset)
462 {
463   guint8 i;
464   GstBitReader br;
465
466   g_return_val_if_fail (quant != NULL, FALSE);
467
468   size -= offset;
469
470   if (size < 1) {
471     GST_DEBUG ("not enough bytes to parse the extension");
472     return FALSE;
473   }
474
475   gst_bit_reader_init (&br, &data[offset], size);
476
477   if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
478       GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX) {
479     GST_DEBUG ("Not parsing a quant matrix extension");
480     return FALSE;
481   }
482
483   READ_UINT8 (&br, quant->load_intra_quantiser_matrix, 1);
484   if (quant->load_intra_quantiser_matrix) {
485     for (i = 0; i < 64; i++) {
486       READ_UINT8 (&br, quant->intra_quantiser_matrix[mpeg_zigzag_8x8[i]], 8);
487     }
488   }
489
490   READ_UINT8 (&br, quant->load_non_intra_quantiser_matrix, 1);
491   if (quant->load_non_intra_quantiser_matrix) {
492     for (i = 0; i < 64; i++) {
493       READ_UINT8 (&br, quant->non_intra_quantiser_matrix[mpeg_zigzag_8x8[i]],
494           8);
495     }
496   }
497
498   READ_UINT8 (&br, quant->load_chroma_intra_quantiser_matrix, 1);
499   if (quant->load_chroma_intra_quantiser_matrix) {
500     for (i = 0; i < 64; i++) {
501       READ_UINT8 (&br, quant->chroma_intra_quantiser_matrix[mpeg_zigzag_8x8[i]],
502           8);
503     }
504   }
505
506   READ_UINT8 (&br, quant->load_chroma_non_intra_quantiser_matrix, 1);
507   if (quant->load_chroma_non_intra_quantiser_matrix) {
508     for (i = 0; i < 64; i++) {
509       READ_UINT8 (&br,
510           quant->chroma_non_intra_quantiser_matrix[mpeg_zigzag_8x8[i]], 8);
511     }
512   }
513
514   return TRUE;
515
516 failed:
517   GST_WARNING ("error parsing \"Quant Matrix Extension\"");
518   return FALSE;
519 }
520
521 /**
522  * gst_mpeg_video_parse_picture_extension:
523  * @ext: (out): The #GstMpegVideoPictureExt structure to fill
524  * @data: The data from which to parse the picture extension
525  * @size: The size of @data
526  * @offset: The offset in byte from which to start the parsing
527  *
528  * Parse the @ext Mpeg Video Picture Extension structure members from @data
529  *
530  * Returns: %TRUE if the picture extension could be parsed correctly,
531  * %FALSE otherwize.
532  */
533 gboolean
534 gst_mpeg_video_parse_picture_extension (GstMpegVideoPictureExt * ext,
535     const guint8 * data, gsize size, guint offset)
536 {
537   GstBitReader br;
538
539   g_return_val_if_fail (ext != NULL, FALSE);
540
541   size -= offset;
542
543   if (size < 4)
544     return FALSE;
545
546   gst_bit_reader_init (&br, &data[offset], size);
547
548   if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
549       GST_MPEG_VIDEO_PACKET_EXT_PICTURE) {
550     GST_DEBUG ("Not parsing a picture extension");
551     return FALSE;
552   }
553
554   /* f_code */
555   READ_UINT8 (&br, ext->f_code[0][0], 4);
556   READ_UINT8 (&br, ext->f_code[0][1], 4);
557   READ_UINT8 (&br, ext->f_code[1][0], 4);
558   READ_UINT8 (&br, ext->f_code[1][1], 4);
559
560   /* intra DC precision */
561   READ_UINT8 (&br, ext->intra_dc_precision, 2);
562
563   /* picture structure */
564   READ_UINT8 (&br, ext->picture_structure, 2);
565
566   /* top field first */
567   READ_UINT8 (&br, ext->top_field_first, 1);
568
569   /* frame pred frame dct */
570   READ_UINT8 (&br, ext->frame_pred_frame_dct, 1);
571
572   /* concealment motion vectors */
573   READ_UINT8 (&br, ext->concealment_motion_vectors, 1);
574
575   /* q scale type */
576   READ_UINT8 (&br, ext->q_scale_type, 1);
577
578   /* intra vlc format */
579   READ_UINT8 (&br, ext->intra_vlc_format, 1);
580
581   /* alternate scan */
582   READ_UINT8 (&br, ext->alternate_scan, 1);
583
584   /* repeat first field */
585   READ_UINT8 (&br, ext->repeat_first_field, 1);
586
587   /* chroma_420_type */
588   READ_UINT8 (&br, ext->chroma_420_type, 1);
589
590   /* progressive_frame */
591   READ_UINT8 (&br, ext->progressive_frame, 1);
592
593   /* composite display */
594   READ_UINT8 (&br, ext->composite_display, 1);
595
596   if (ext->composite_display) {
597
598     /* v axis */
599     READ_UINT8 (&br, ext->v_axis, 1);
600
601     /* field sequence */
602     READ_UINT8 (&br, ext->field_sequence, 3);
603
604     /* sub carrier */
605     READ_UINT8 (&br, ext->sub_carrier, 1);
606
607     /* burst amplitude */
608     READ_UINT8 (&br, ext->burst_amplitude, 7);
609
610     /* sub_carrier phase */
611     READ_UINT8 (&br, ext->sub_carrier_phase, 8);
612   }
613
614   return TRUE;
615
616 failed:
617   GST_WARNING ("error parsing \"Picture Coding Extension\"");
618   return FALSE;
619
620 }
621
622 /**
623  * gst_mpeg_video_parse_picture_header:
624  * @hdr: (out): The #GstMpegVideoPictureHdr structure to fill
625  * @data: The data from which to parse the picture header
626  * @size: The size of @data
627  * @offset: The offset in byte from which to start the parsing
628  *
629  * Parsers the @hdr Mpeg Video Picture Header structure members from @data
630  *
631  * Returns: %TRUE if the picture sequence could be parsed correctly, %FALSE
632  * otherwize.
633  */
634 gboolean
635 gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr * hdr,
636     const guint8 * data, gsize size, guint offset)
637 {
638   GstBitReader br;
639
640   size = size - offset;
641
642   if (size < 4)
643     goto failed;
644
645   gst_bit_reader_init (&br, &data[offset], size);
646
647   /* temperal sequence number */
648   if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->tsn, 10))
649     goto failed;
650
651
652   /* frame type */
653   if (!gst_bit_reader_get_bits_uint8 (&br, (guint8 *) & hdr->pic_type, 3))
654     goto failed;
655
656
657   if (hdr->pic_type == 0 || hdr->pic_type > 4)
658     goto failed;                /* Corrupted picture packet */
659
660   /* skip VBV delay */
661   if (!gst_bit_reader_skip (&br, 16))
662     goto failed;
663
664   if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_P
665       || hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
666
667     READ_UINT8 (&br, hdr->full_pel_forward_vector, 1);
668
669     READ_UINT8 (&br, hdr->f_code[0][0], 3);
670     hdr->f_code[0][1] = hdr->f_code[0][0];
671   } else {
672     hdr->full_pel_forward_vector = 0;
673     hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
674   }
675
676   if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
677     READ_UINT8 (&br, hdr->full_pel_backward_vector, 1);
678
679     READ_UINT8 (&br, hdr->f_code[1][0], 3);
680     hdr->f_code[1][1] = hdr->f_code[1][0];
681   } else {
682     hdr->full_pel_backward_vector = 0;
683     hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
684   }
685
686   return TRUE;
687
688 failed:
689   {
690     GST_WARNING ("Failed to parse picture header");
691     return FALSE;
692   }
693 }
694
695 /**
696  * gst_mpeg_video_parse_gop:
697  * @gop: (out): The #GstMpegVideoGop structure to fill
698  * @data: The data from which to parse the gop
699  * @size: The size of @data
700  * @offset: The offset in byte from which to start the parsing
701  *
702  * Parses the @gop Mpeg Video Group of Picture structure members from @data
703  *
704  * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwize.
705  */
706 gboolean
707 gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, const guint8 * data,
708     gsize size, guint offset)
709 {
710   GstBitReader br;
711
712   g_return_val_if_fail (gop != NULL, FALSE);
713
714   size -= offset;
715
716   if (size < 4)
717     return FALSE;
718
719   gst_bit_reader_init (&br, &data[offset], size);
720
721   READ_UINT8 (&br, gop->drop_frame_flag, 1);
722
723   READ_UINT8 (&br, gop->hour, 5);
724
725   READ_UINT8 (&br, gop->minute, 6);
726
727   /* skip unused bit */
728   if (!gst_bit_reader_skip (&br, 1))
729     return FALSE;
730
731   READ_UINT8 (&br, gop->second, 6);
732
733   READ_UINT8 (&br, gop->frame, 6);
734
735   READ_UINT8 (&br, gop->closed_gop, 1);
736
737   READ_UINT8 (&br, gop->broken_link, 1);
738
739   return TRUE;
740
741 failed:
742   GST_WARNING ("error parsing \"GOP\"");
743   return FALSE;
744 }