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., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, 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) {
101 gst_bit_reader_skip (b, 8);
111 /* Set the Pixel Aspect Ratio in our hdr from a DAR code in the data */
113 set_par_from_dar (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code)
115 /* Pixel_width = DAR_width * display_vertical_size */
116 /* Pixel_height = DAR_height * display_horizontal_size */
118 case 0x02: /* 3:4 DAR = 4:3 pixels */
119 seqhdr->par_w = 4 * seqhdr->height;
120 seqhdr->par_h = 3 * seqhdr->width;
122 case 0x03: /* 9:16 DAR */
123 seqhdr->par_w = 16 * seqhdr->height;
124 seqhdr->par_h = 9 * seqhdr->width;
126 case 0x04: /* 1:2.21 DAR */
127 seqhdr->par_w = 221 * seqhdr->height;
128 seqhdr->par_h = 100 * seqhdr->width;
130 case 0x01: /* Square pixels */
131 seqhdr->par_w = seqhdr->par_h = 1;
134 GST_DEBUG ("unknown/invalid aspect_ratio_information %d", asr_code);
140 set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
142 const gint framerates[][2] = {
143 {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
144 {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
148 if (fps_code && fps_code < 10) {
149 seqhdr->fps_n = framerates[fps_code][0];
150 seqhdr->fps_d = framerates[fps_code][1];
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;
161 gst_mpeg_video_parse_sequence (GstMpegVideoSequenceHdr * seqhdr,
165 guint8 load_intra_flag, load_non_intra_flag;
167 /* Setting the height/width codes */
168 READ_UINT16 (br, seqhdr->width, 12);
169 READ_UINT16 (br, seqhdr->height, 12);
171 READ_UINT8 (br, seqhdr->aspect_ratio_info, 4);
172 set_par_from_dar (seqhdr, seqhdr->aspect_ratio_info);
174 READ_UINT8 (br, seqhdr->frame_rate_code, 4);
175 set_fps_from_code (seqhdr, seqhdr->frame_rate_code);
177 READ_UINT32 (br, seqhdr->bitrate_value, 18);
178 if (seqhdr->bitrate_value == 0x3ffff) {
182 /* Value in header is in units of 400 bps */
183 seqhdr->bitrate *= 400;
186 READ_UINT8 (br, bits, 1);
187 if (bits != MARKER_BIT)
190 /* VBV buffer size */
191 READ_UINT16 (br, seqhdr->vbv_buffer_size_value, 10);
193 /* constrained_parameters_flag */
194 READ_UINT8 (br, seqhdr->constrained_parameters_flag, 1);
196 /* load_intra_quantiser_matrix */
197 READ_UINT8 (br, load_intra_flag, 1);
198 if (load_intra_flag) {
200 for (i = 0; i < 64; i++)
201 READ_UINT8 (br, seqhdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8);
203 memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);
205 /* non intra quantizer matrix */
206 READ_UINT8 (br, load_non_intra_flag, 1);
207 if (load_non_intra_flag) {
209 for (i = 0; i < 64; i++)
210 READ_UINT8 (br, seqhdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]],
213 memset (seqhdr->non_intra_quantizer_matrix, 16, 64);
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);
226 GST_WARNING ("Failed to parse sequence header");
227 /* clear out stuff */
228 memset (seqhdr, 0, sizeof (*seqhdr));
234 scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
240 g_return_val_if_fail (size > 0, -1);
241 g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
244 /* we can't find the pattern with less than 4 bytes */
245 if (G_UNLIKELY (size < 4))
248 data = reader->data + reader->byte + offset;
250 /* set the state to something that does not match */
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;
264 /* TODO: reimplement making 010001 not detected as a sc
265 * Accelerate search for start code
267 * while (i < (size - 4) && data[i] > 1) {
268 * if (data[i + 3] > 1)
273 * state = 0x00000100;
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
290 * Parses the MPEG 1/2 video bitstream contained in @data , and returns the
291 * detect packets as a list of #GstMpegVideoTypeOffsetSize.
293 * Returns: a #GList of #GstMpegVideoTypeOffsetSize
296 gst_mpeg_video_parse (const guint8 * data, gsize size, guint offset)
305 GST_DEBUG_CATEGORY_INIT (mpegvideo_parser_debug, "codecparsers_mpegvideo",
306 0, "Mpegvideo parser library");
311 GST_DEBUG ("Can't parse from offset %d, buffer is to small", offset);
315 gst_byte_reader_init (&br, &data[offset], size);
317 off = scan_for_start_codes (&br, 0, size);
320 GST_DEBUG ("No start code prefix in this buffer");
324 while (off >= 0 && off + 3 < size) {
325 GstMpegVideoTypeOffsetSize *codoffsize;
327 gst_byte_reader_skip (&br, off + 3);
329 codoffsize = g_malloc (sizeof (GstMpegVideoTypeOffsetSize));
330 gst_byte_reader_get_uint8 (&br, &codoffsize->type);
332 codoffsize->offset = gst_byte_reader_get_pos (&br) + offset;
334 rsize = gst_byte_reader_get_remaining (&br);
340 off = scan_for_start_codes (&br, 0, rsize);
342 codoffsize->size = off;
344 ret = g_list_prepend (ret, codoffsize);
345 codoffsize = ret->data;
348 return g_list_reverse (ret);
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
358 * Parses the @seqhdr Mpeg Video Sequence Header structure members from @data
360 * Returns: %TRUE if the seqhdr could be parsed correctly, %FALSE otherwize.
363 gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
364 const guint8 * data, gsize size, guint offset)
368 g_return_val_if_fail (seqhdr != NULL, FALSE);
375 gst_bit_reader_init (&br, &data[offset], size);
377 return gst_mpeg_video_parse_sequence (seqhdr, &br);
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
387 * Parses the @seqext Mpeg Video Sequence Extension structure members from @data
389 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwize.
392 gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext,
393 const guint8 * data, gsize size, guint offset)
397 g_return_val_if_fail (seqext != NULL, FALSE);
402 GST_DEBUG ("not enough bytes to parse the extension");
406 gst_bit_reader_init (&br, &data[offset], size);
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");
414 /* skip profile and level escape bit */
415 gst_bit_reader_skip_unchecked (&br, 1);
417 seqext->profile = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
418 seqext->level = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
421 seqext->progressive = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
424 seqext->chroma_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
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);
430 seqext->bitrate_ext = gst_bit_reader_get_bits_uint16_unchecked (&br, 12);
432 /* skip marker bits */
433 gst_bit_reader_skip_unchecked (&br, 1);
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);
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);
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
453 * Parses the @quant Mpeg Video Quant Matrix Extension structure members from
456 * Returns: %TRUE if the quant matrix extension could be parsed correctly,
460 gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant,
461 const guint8 * data, gsize size, guint offset)
466 g_return_val_if_fail (quant != NULL, FALSE);
471 GST_DEBUG ("not enough bytes to parse the extension");
475 gst_bit_reader_init (&br, &data[offset], size);
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");
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);
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]],
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]],
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++) {
510 quant->chroma_non_intra_quantiser_matrix[mpeg_zigzag_8x8[i]], 8);
517 GST_WARNING ("error parsing \"Quant Matrix Extension\"");
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
528 * Parse the @ext Mpeg Video Picture Extension structure members from @data
530 * Returns: %TRUE if the picture extension could be parsed correctly,
534 gst_mpeg_video_parse_picture_extension (GstMpegVideoPictureExt * ext,
535 const guint8 * data, gsize size, guint offset)
539 g_return_val_if_fail (ext != NULL, FALSE);
546 gst_bit_reader_init (&br, &data[offset], size);
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");
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);
560 /* intra DC precision */
561 READ_UINT8 (&br, ext->intra_dc_precision, 2);
563 /* picture structure */
564 READ_UINT8 (&br, ext->picture_structure, 2);
566 /* top field first */
567 READ_UINT8 (&br, ext->top_field_first, 1);
569 /* frame pred frame dct */
570 READ_UINT8 (&br, ext->frame_pred_frame_dct, 1);
572 /* concealment motion vectors */
573 READ_UINT8 (&br, ext->concealment_motion_vectors, 1);
576 READ_UINT8 (&br, ext->q_scale_type, 1);
578 /* intra vlc format */
579 READ_UINT8 (&br, ext->intra_vlc_format, 1);
582 READ_UINT8 (&br, ext->alternate_scan, 1);
584 /* repeat first field */
585 READ_UINT8 (&br, ext->repeat_first_field, 1);
587 /* chroma_420_type */
588 READ_UINT8 (&br, ext->chroma_420_type, 1);
590 /* progressive_frame */
591 READ_UINT8 (&br, ext->progressive_frame, 1);
593 /* composite display */
594 READ_UINT8 (&br, ext->composite_display, 1);
596 if (ext->composite_display) {
599 READ_UINT8 (&br, ext->v_axis, 1);
602 READ_UINT8 (&br, ext->field_sequence, 3);
605 READ_UINT8 (&br, ext->sub_carrier, 1);
607 /* burst amplitude */
608 READ_UINT8 (&br, ext->burst_amplitude, 7);
610 /* sub_carrier phase */
611 READ_UINT8 (&br, ext->sub_carrier_phase, 8);
617 GST_WARNING ("error parsing \"Picture Coding Extension\"");
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
629 * Parsers the @hdr Mpeg Video Picture Header structure members from @data
631 * Returns: %TRUE if the picture sequence could be parsed correctly, %FALSE
635 gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr * hdr,
636 const guint8 * data, gsize size, guint offset)
640 size = size - offset;
645 gst_bit_reader_init (&br, &data[offset], size);
647 /* temperal sequence number */
648 if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->tsn, 10))
653 if (!gst_bit_reader_get_bits_uint8 (&br, (guint8 *) & hdr->pic_type, 3))
657 if (hdr->pic_type == 0 || hdr->pic_type > 4)
658 goto failed; /* Corrupted picture packet */
661 if (!gst_bit_reader_skip (&br, 16))
664 if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_P
665 || hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
667 READ_UINT8 (&br, hdr->full_pel_forward_vector, 1);
669 READ_UINT8 (&br, hdr->f_code[0][0], 3);
670 hdr->f_code[0][1] = hdr->f_code[0][0];
672 hdr->full_pel_forward_vector = 0;
673 hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
676 if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
677 READ_UINT8 (&br, hdr->full_pel_backward_vector, 1);
679 READ_UINT8 (&br, hdr->f_code[1][0], 3);
680 hdr->f_code[1][1] = hdr->f_code[1][0];
682 hdr->full_pel_backward_vector = 0;
683 hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
690 GST_WARNING ("Failed to parse picture header");
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
702 * Parses the @gop Mpeg Video Group of Picture structure members from @data
704 * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwize.
707 gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, const guint8 * data,
708 gsize size, guint offset)
712 g_return_val_if_fail (gop != NULL, FALSE);
719 gst_bit_reader_init (&br, &data[offset], size);
721 READ_UINT8 (&br, gop->drop_frame_flag, 1);
723 READ_UINT8 (&br, gop->hour, 5);
725 READ_UINT8 (&br, gop->minute, 6);
727 /* skip unused bit */
728 if (!gst_bit_reader_skip (&br, 1))
731 READ_UINT8 (&br, gop->second, 6);
733 READ_UINT8 (&br, gop->frame, 6);
735 READ_UINT8 (&br, gop->closed_gop, 1);
737 READ_UINT8 (&br, gop->broken_link, 1);
742 GST_WARNING ("error parsing \"GOP\"");