2 * Copyright (C) <2011> Intel Corporation
3 * Copyright (C) <2011> Collabora Ltd.
4 * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
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>
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.
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.
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.
27 * SECTION:gstmpegvideoparser
28 * @short_description: Convenience library for mpeg1 and 2 video
33 * Provides useful functions for mpeg videos bitstream parsing.
42 #include "gstmpegvideoparser.h"
43 #include "parserutils.h"
46 #include <gst/base/gstbitreader.h>
47 #include <gst/base/gstbytereader.h>
49 #define MARKER_BIT 0x1
51 /* default intra quant matrix, in zig-zag order */
52 static const guint8 default_intra_quantizer_matrix[64] = {
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,
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
81 GST_DEBUG_CATEGORY (mpegvideo_parser_debug);
82 #define GST_CAT_DEFAULT mpegvideo_parser_debug
84 static gboolean initialized = FALSE;
86 static inline gboolean
87 find_start_code (GstBitReader * b)
91 /* 0 bits until byte aligned */
93 GET_BITS (b, 1, &bits);
96 /* 0 bytes until startcode */
97 while (gst_bit_reader_peek_bits_uint32 (b, &bits, 32)) {
98 if (bits >> 8 == 0x1) {
100 } else if (gst_bit_reader_skip (b, 8) == FALSE)
110 /* Set the Pixel Aspect Ratio in our hdr from a ASR code in the data */
112 set_par_from_asr_mpeg1 (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code)
114 int ratios[16][2] = {
115 {0, 0}, /* 0, Invalid */
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 */
134 seqhdr->par_w = ratios[asr_code][0];
135 seqhdr->par_h = ratios[asr_code][1];
139 set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
141 const gint framerates[][2] = {
142 {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
143 {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
147 if (fps_code && fps_code < 10) {
148 seqhdr->fps_n = framerates[fps_code][0];
149 seqhdr->fps_d = framerates[fps_code][1];
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;
159 /* @size and @offset are wrt current reader position */
161 scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
166 g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
169 /* we can't find the pattern with less than 4 bytes */
170 if (G_UNLIKELY (size < 4))
173 data = reader->data + reader->byte + offset;
175 while (i <= (size - 4)) {
176 if (data[i + 2] > 1) {
178 } else if (data[i + 1]) {
180 } else if (data[i] || data[i + 2] != 1) {
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
202 * Parses the MPEG 1/2 video bitstream contained in @data , and returns the
203 * detect packets as a list of #GstMpegVideoTypeOffsetSize.
205 * Returns: TRUE if a packet start code was found
208 gst_mpeg_video_parse (GstMpegVideoPacket * packet,
209 const guint8 * data, gsize size, guint offset)
215 GST_DEBUG_CATEGORY_INIT (mpegvideo_parser_debug, "codecparsers_mpegvideo",
216 0, "Mpegvideo parser library");
220 if (size <= offset) {
221 GST_DEBUG ("Can't parse from offset %d, buffer is to small", offset);
226 gst_byte_reader_init (&br, &data[offset], size);
228 off = scan_for_start_codes (&br, 0, size);
231 GST_DEBUG ("No start code prefix in this buffer");
235 if (gst_byte_reader_skip (&br, off + 3) == FALSE)
238 if (gst_byte_reader_get_uint8 (&br, &packet->type) == FALSE)
242 packet->offset = offset + off + 4;
245 /* try to find end of packet */
247 off = scan_for_start_codes (&br, 0, size);
256 GST_WARNING ("Failed to parse");
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
268 * Parses the @seqhdr Mpeg Video Sequence Header structure members from @data
270 * Returns: %TRUE if the seqhdr could be parsed correctly, %FALSE otherwize.
273 gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
274 const guint8 * data, gsize size, guint offset)
278 guint8 load_intra_flag, load_non_intra_flag;
280 g_return_val_if_fail (seqhdr != NULL, FALSE);
287 gst_bit_reader_init (&br, &data[offset], size);
289 /* Setting the height/width codes */
290 READ_UINT16 (&br, seqhdr->width, 12);
291 READ_UINT16 (&br, seqhdr->height, 12);
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);
298 READ_UINT8 (&br, seqhdr->frame_rate_code, 4);
299 set_fps_from_code (seqhdr, seqhdr->frame_rate_code);
301 READ_UINT32 (&br, seqhdr->bitrate_value, 18);
302 if (seqhdr->bitrate_value == 0x3ffff) {
306 /* Value in header is in units of 400 bps */
307 seqhdr->bitrate *= 400;
310 READ_UINT8 (&br, bits, 1);
311 if (bits != MARKER_BIT)
314 /* VBV buffer size */
315 READ_UINT16 (&br, seqhdr->vbv_buffer_size_value, 10);
317 /* constrained_parameters_flag */
318 READ_UINT8 (&br, seqhdr->constrained_parameters_flag, 1);
320 /* load_intra_quantiser_matrix */
321 READ_UINT8 (&br, load_intra_flag, 1);
322 if (load_intra_flag) {
324 for (i = 0; i < 64; i++)
325 READ_UINT8 (&br, seqhdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8);
327 memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);
329 /* non intra quantizer matrix */
330 READ_UINT8 (&br, load_non_intra_flag, 1);
331 if (load_non_intra_flag) {
333 for (i = 0; i < 64; i++)
334 READ_UINT8 (&br, seqhdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]],
337 memset (seqhdr->non_intra_quantizer_matrix, 16, 64);
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);
350 GST_WARNING ("Failed to parse sequence header");
351 /* clear out stuff */
352 memset (seqhdr, 0, sizeof (*seqhdr));
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
364 * Parses the @seqext Mpeg Video Sequence Extension structure members from @data
366 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwize.
369 gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext,
370 const guint8 * data, gsize size, guint offset)
374 g_return_val_if_fail (seqext != NULL, FALSE);
379 GST_DEBUG ("not enough bytes to parse the extension");
383 gst_bit_reader_init (&br, &data[offset], size);
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");
391 /* skip profile and level escape bit */
392 gst_bit_reader_skip_unchecked (&br, 1);
394 seqext->profile = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
395 seqext->level = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
398 seqext->progressive = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
401 seqext->chroma_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
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);
407 seqext->bitrate_ext = gst_bit_reader_get_bits_uint16_unchecked (&br, 12);
409 /* skip marker bits */
410 gst_bit_reader_skip_unchecked (&br, 1);
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);
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);
424 gst_mpeg_video_parse_sequence_display_extension (GstMpegVideoSequenceDisplayExt
425 * seqdisplayext, const guint8 * data, gsize size, guint offset)
429 g_return_val_if_fail (seqdisplayext != NULL, FALSE);
435 GST_DEBUG ("not enough bytes to parse the extension");
439 gst_bit_reader_init (&br, &data[offset], size);
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");
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);
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);
461 if (gst_bit_reader_get_remaining (&br) < 29) {
462 GST_DEBUG ("Not enough remaining bytes to parse the extension");
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);
477 gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
478 GstMpegVideoSequenceExt * seqext,
479 GstMpegVideoSequenceDisplayExt * displayext)
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);
495 /* Use the display size for calculating PAR when display ext present */
496 w = displayext->display_horizontal_size;
497 h = displayext->display_vertical_size;
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;
506 case 0x02: /* 3:4 DAR = 4:3 pixels */
507 seqhdr->par_w = 4 * h;
508 seqhdr->par_h = 3 * w;
510 case 0x03: /* 9:16 DAR */
511 seqhdr->par_w = 16 * h;
512 seqhdr->par_h = 9 * w;
514 case 0x04: /* 1:2.21 DAR */
515 seqhdr->par_w = 221 * h;
516 seqhdr->par_h = 100 * w;
519 GST_DEBUG ("unknown/invalid aspect_ratio_information %d",
520 seqhdr->aspect_ratio_info);
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
534 * Parses the @quant Mpeg Video Quant Matrix Extension structure members from
537 * Returns: %TRUE if the quant matrix extension could be parsed correctly,
541 gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant,
542 const guint8 * data, gsize size, guint offset)
547 g_return_val_if_fail (quant != NULL, FALSE);
552 GST_DEBUG ("not enough bytes to parse the extension");
556 gst_bit_reader_init (&br, &data[offset], size);
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");
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);
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]],
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]],
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++) {
591 quant->chroma_non_intra_quantiser_matrix[mpeg_zigzag_8x8[i]], 8);
598 GST_WARNING ("error parsing \"Quant Matrix Extension\"");
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
609 * Parse the @ext Mpeg Video Picture Extension structure members from @data
611 * Returns: %TRUE if the picture extension could be parsed correctly,
615 gst_mpeg_video_parse_picture_extension (GstMpegVideoPictureExt * ext,
616 const guint8 * data, gsize size, guint offset)
620 g_return_val_if_fail (ext != NULL, FALSE);
627 gst_bit_reader_init (&br, &data[offset], size);
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");
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);
641 /* intra DC precision */
642 READ_UINT8 (&br, ext->intra_dc_precision, 2);
644 /* picture structure */
645 READ_UINT8 (&br, ext->picture_structure, 2);
647 /* top field first */
648 READ_UINT8 (&br, ext->top_field_first, 1);
650 /* frame pred frame dct */
651 READ_UINT8 (&br, ext->frame_pred_frame_dct, 1);
653 /* concealment motion vectors */
654 READ_UINT8 (&br, ext->concealment_motion_vectors, 1);
657 READ_UINT8 (&br, ext->q_scale_type, 1);
659 /* intra vlc format */
660 READ_UINT8 (&br, ext->intra_vlc_format, 1);
663 READ_UINT8 (&br, ext->alternate_scan, 1);
665 /* repeat first field */
666 READ_UINT8 (&br, ext->repeat_first_field, 1);
668 /* chroma_420_type */
669 READ_UINT8 (&br, ext->chroma_420_type, 1);
671 /* progressive_frame */
672 READ_UINT8 (&br, ext->progressive_frame, 1);
674 /* composite display */
675 READ_UINT8 (&br, ext->composite_display, 1);
677 if (ext->composite_display) {
680 READ_UINT8 (&br, ext->v_axis, 1);
683 READ_UINT8 (&br, ext->field_sequence, 3);
686 READ_UINT8 (&br, ext->sub_carrier, 1);
688 /* burst amplitude */
689 READ_UINT8 (&br, ext->burst_amplitude, 7);
691 /* sub_carrier phase */
692 READ_UINT8 (&br, ext->sub_carrier_phase, 8);
698 GST_WARNING ("error parsing \"Picture Coding Extension\"");
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
710 * Parsers the @hdr Mpeg Video Picture Header structure members from @data
712 * Returns: %TRUE if the picture sequence could be parsed correctly, %FALSE
716 gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr * hdr,
717 const guint8 * data, gsize size, guint offset)
721 size = size - offset;
726 gst_bit_reader_init (&br, &data[offset], size);
728 /* temperal sequence number */
729 if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->tsn, 10))
734 if (!gst_bit_reader_get_bits_uint8 (&br, (guint8 *) & hdr->pic_type, 3))
738 if (hdr->pic_type == 0 || hdr->pic_type > 4)
739 goto failed; /* Corrupted picture packet */
742 if (!gst_bit_reader_skip (&br, 16))
745 if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_P
746 || hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
748 READ_UINT8 (&br, hdr->full_pel_forward_vector, 1);
750 READ_UINT8 (&br, hdr->f_code[0][0], 3);
751 hdr->f_code[0][1] = hdr->f_code[0][0];
753 hdr->full_pel_forward_vector = 0;
754 hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
757 if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
758 READ_UINT8 (&br, hdr->full_pel_backward_vector, 1);
760 READ_UINT8 (&br, hdr->f_code[1][0], 3);
761 hdr->f_code[1][1] = hdr->f_code[1][0];
763 hdr->full_pel_backward_vector = 0;
764 hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
771 GST_WARNING ("Failed to parse picture header");
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
783 * Parses the @gop Mpeg Video Group of Picture structure members from @data
785 * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwize.
788 gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, const guint8 * data,
789 gsize size, guint offset)
793 g_return_val_if_fail (gop != NULL, FALSE);
800 gst_bit_reader_init (&br, &data[offset], size);
802 READ_UINT8 (&br, gop->drop_frame_flag, 1);
804 READ_UINT8 (&br, gop->hour, 5);
806 READ_UINT8 (&br, gop->minute, 6);
808 /* skip unused bit */
809 if (!gst_bit_reader_skip (&br, 1))
812 READ_UINT8 (&br, gop->second, 6);
814 READ_UINT8 (&br, gop->frame, 6);
816 READ_UINT8 (&br, gop->closed_gop, 1);
818 READ_UINT8 (&br, gop->broken_link, 1);
823 GST_WARNING ("error parsing \"GOP\"");