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 * @title: GstMpegvideoParser
29 * @short_description: Convenience library for mpeg1 and 2 video
30 * bitstream parsing.
31 *
32 * Provides useful functions for mpeg videos bitstream parsing.
33 *
34 */
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39
40 #include "gstmpegvideoparser.h"
41 #include "parserutils.h"
42
43 #include <string.h>
44 #include <gst/base/gstbitreader.h>
45 #include <gst/base/gstbytereader.h>
46
47 #define MARKER_BIT 0x1
48
49 /* default intra quant matrix, in zig-zag order */
50 static const guint8 default_intra_quantizer_matrix[64] = {
51 8,
52 16, 16,
53 19, 16, 19,
54 22, 22, 22, 22,
55 22, 22, 26, 24, 26,
56 27, 27, 27, 26, 26, 26,
57 26, 27, 27, 27, 29, 29, 29,
58 34, 34, 34, 29, 29, 29, 27, 27,
59 29, 29, 32, 32, 34, 34, 37,
60 38, 37, 35, 35, 34, 35,
61 38, 38, 40, 40, 40,
62 48, 48, 46, 46,
63 56, 56, 58,
64 69, 69,
65 83
66 };
67
68 static const guint8 mpeg_zigzag_8x8[64] = {
69 0, 1, 8, 16, 9, 2, 3, 10,
70 17, 24, 32, 25, 18, 11, 4, 5,
71 12, 19, 26, 33, 40, 48, 41, 34,
72 27, 20, 13, 6, 7, 14, 21, 28,
73 35, 42, 49, 56, 57, 50, 43, 36,
74 29, 22, 15, 23, 30, 37, 44, 51,
75 58, 59, 52, 45, 38, 31, 39, 46,
76 53, 60, 61, 54, 47, 55, 62, 63
77 };
78
79 enum
80 {
81 GST_MPEG_VIDEO_MACROBLOCK_ESCAPE = G_MAXUINT,
82 };
83
84 /* Table B-1: Variable length codes for macroblock_address_increment */
85 static const VLCTable mpeg2_mbaddr_vlc_table[] = {
86 {1, 0x01, 1},
87 {2, 0x03, 3},
88 {3, 0x02, 3},
89 {4, 0x03, 4},
90 {5, 0x02, 4},
91 {6, 0x03, 5},
92 {7, 0x02, 5},
93 {8, 0x07, 7},
94 {9, 0x06, 7},
95 {10, 0x0b, 8},
96 {11, 0x0a, 8},
97 {12, 0x09, 8},
98 {13, 0x08, 8},
99 {14, 0x07, 8},
100 {15, 0x06, 8},
101 {16, 0x17, 10},
102 {17, 0x16, 10},
103 {18, 0x15, 10},
104 {19, 0x14, 10},
105 {20, 0x13, 10},
106 {21, 0x12, 10},
107 {22, 0x23, 11},
108 {23, 0x22, 11},
109 {24, 0x21, 11},
110 {25, 0x20, 11},
111 {26, 0x1f, 11},
112 {27, 0x1e, 11},
113 {28, 0x1d, 11},
114 {29, 0x1c, 11},
115 {30, 0x1b, 11},
116 {31, 0x1a, 11},
117 {32, 0x19, 11},
118 {33, 0x18, 11},
119 {GST_MPEG_VIDEO_MACROBLOCK_ESCAPE, 0x08, 11}
120 };
121
122 GST_DEBUG_CATEGORY_STATIC (mpegvideo_parser_debug);
123 #define GST_CAT_DEFAULT mpegvideo_parser_debug
124
125 #define INITIALIZE_DEBUG_CATEGORY \
126 GST_DEBUG_CATEGORY_INIT (mpegvideo_parser_debug, "codecparsers_mpegvideo", \
127 0, "Mpegvideo parser library");
128
129
130 /* Set the Pixel Aspect Ratio in our hdr from a ASR code in the data */
131 static void
set_par_from_asr_mpeg1(GstMpegVideoSequenceHdr * seqhdr,guint8 asr_code)132 set_par_from_asr_mpeg1 (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code)
133 {
134 int ratios[16][2] = {
135 {0, 0}, /* 0, Invalid */
136 {1, 1}, /* 1, 1.0 */
137 {10000, 6735}, /* 2, 0.6735 */
138 {64, 45}, /* 3, 0.7031 16:9 625 line */
139 {10000, 7615}, /* 4, 0.7615 */
140 {10000, 8055}, /* 5, 0.8055 */
141 {32, 27}, /* 6, 0.8437 */
142 {10000, 8935}, /* 7, 0.8935 */
143 {10000, 9375}, /* 8, 0.9375 */
144 {10000, 9815}, /* 9, 0.9815 */
145 {10000, 10255}, /* 10, 1.0255 */
146 {10000, 10695}, /* 11, 1.0695 */
147 {8, 9}, /* 12, 1.125 */
148 {10000, 11575}, /* 13, 1.1575 */
149 {10000, 12015}, /* 14, 1.2015 */
150 {0, 0}, /* 15, invalid */
151 };
152 asr_code &= 0xf;
153
154 seqhdr->par_w = ratios[asr_code][0];
155 seqhdr->par_h = ratios[asr_code][1];
156 }
157
158 static void
set_fps_from_code(GstMpegVideoSequenceHdr * seqhdr,guint8 fps_code)159 set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
160 {
161 const gint framerates[][2] = {
162 {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
163 {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
164 {60, 1}, {30, 1}
165 };
166
167 if (fps_code && fps_code < 10) {
168 seqhdr->fps_n = framerates[fps_code][0];
169 seqhdr->fps_d = framerates[fps_code][1];
170 } else {
171 GST_DEBUG ("unknown/invalid frame_rate_code %d", fps_code);
172 /* Force a valid framerate */
173 /* FIXME or should this be kept unknown ?? */
174 seqhdr->fps_n = 30000;
175 seqhdr->fps_d = 1001;
176 }
177 }
178
179 /* @size and @offset are wrt current reader position */
180 static inline gint
scan_for_start_codes(const GstByteReader * reader,guint offset,guint size)181 scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
182 {
183 const guint8 *data;
184 guint i = 0;
185
186 g_assert ((guint64) offset + size <= reader->size - reader->byte);
187
188 /* we can't find the pattern with less than 4 bytes */
189 if (G_UNLIKELY (size < 4))
190 return -1;
191
192 data = reader->data + reader->byte + offset;
193
194 while (i <= (size - 4)) {
195 if (data[i + 2] > 1) {
196 i += 3;
197 } else if (data[i + 1]) {
198 i += 2;
199 } else if (data[i] || data[i + 2] != 1) {
200 i++;
201 } else {
202 break;
203 }
204 }
205
206 if (i <= (size - 4))
207 return offset + i;
208
209 /* nothing found */
210 return -1;
211 }
212
213 /****** API *******/
214
215 /**
216 * gst_mpeg_video_parse:
217 * @packet: a #GstMpegVideoPacket to fill with the data and offset of the
218 * next packet found
219 * @data: The data to parse
220 * @size: The size of @data
221 * @offset: The offset from which to start parsing
222 *
223 * Parses the MPEG 1/2 video bitstream contained in @data, and returns the
224 * offset, and if known also the size, in @packet. This function will scan
225 * the data to find the next packet if needed.
226 *
227 * Returns: TRUE if a packet start code was found, otherwise FALSE.
228 */
229 gboolean
gst_mpeg_video_parse(GstMpegVideoPacket * packet,const guint8 * data,gsize size,guint offset)230 gst_mpeg_video_parse (GstMpegVideoPacket * packet,
231 const guint8 * data, gsize size, guint offset)
232 {
233 gint off;
234 GstByteReader br;
235
236 INITIALIZE_DEBUG_CATEGORY;
237
238 if (size <= offset) {
239 GST_DEBUG ("Can't parse from offset %d, buffer is to small", offset);
240 return FALSE;
241 }
242
243 size -= offset;
244 gst_byte_reader_init (&br, &data[offset], size);
245
246 off = scan_for_start_codes (&br, 0, size);
247
248 if (off < 0) {
249 GST_DEBUG ("No start code prefix in this buffer");
250 return FALSE;
251 }
252
253 if (gst_byte_reader_skip (&br, off + 3) == FALSE)
254 goto failed;
255
256 if (gst_byte_reader_get_uint8 (&br, &packet->type) == FALSE)
257 goto failed;
258
259 packet->data = data;
260 packet->offset = offset + off + 4;
261 packet->size = -1;
262
263 /* try to find end of packet */
264 size -= off + 4;
265 off = scan_for_start_codes (&br, 0, size);
266
267 if (off >= 0)
268 packet->size = off;
269
270 return TRUE;
271
272 failed:
273 {
274 GST_WARNING ("Failed to parse");
275 return FALSE;
276 }
277 }
278
279 /**
280 * gst_mpeg_video_packet_parse_sequence_header:
281 * @packet: The #GstMpegVideoPacket that carries the data
282 * @seqhdr: (out): The #GstMpegVideoSequenceHdr structure to fill
283 *
284 * Parses the @seqhdr MPEG Video Sequence Header structure members
285 * from video @packet
286 *
287 * Returns: %TRUE if the seqhdr could be parsed correctly, %FALSE otherwise.
288 *
289 * Since: 1.2
290 */
291 gboolean
gst_mpeg_video_packet_parse_sequence_header(const GstMpegVideoPacket * packet,GstMpegVideoSequenceHdr * seqhdr)292 gst_mpeg_video_packet_parse_sequence_header (const GstMpegVideoPacket * packet,
293 GstMpegVideoSequenceHdr * seqhdr)
294 {
295 GstBitReader br;
296 guint8 bits;
297
298 g_return_val_if_fail (seqhdr != NULL, FALSE);
299
300 if (packet->size < 8)
301 return FALSE;
302
303 INITIALIZE_DEBUG_CATEGORY;
304
305 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
306
307 /* Setting the height/width codes */
308 READ_UINT16 (&br, seqhdr->width, 12);
309 READ_UINT16 (&br, seqhdr->height, 12);
310
311 READ_UINT8 (&br, seqhdr->aspect_ratio_info, 4);
312 /* Interpret PAR according to MPEG-1. Needs to be reinterpreted
313 * later, if a sequence_display extension is seen */
314 set_par_from_asr_mpeg1 (seqhdr, seqhdr->aspect_ratio_info);
315
316 READ_UINT8 (&br, seqhdr->frame_rate_code, 4);
317 set_fps_from_code (seqhdr, seqhdr->frame_rate_code);
318
319 READ_UINT32 (&br, seqhdr->bitrate_value, 18);
320 if (seqhdr->bitrate_value == 0x3ffff) {
321 /* VBR stream */
322 seqhdr->bitrate = 0;
323 } else {
324 /* Value in header is in units of 400 bps */
325 seqhdr->bitrate = seqhdr->bitrate_value * 400;
326 }
327
328 READ_UINT8 (&br, bits, 1);
329 if (bits != MARKER_BIT)
330 goto failed;
331
332 /* VBV buffer size */
333 READ_UINT16 (&br, seqhdr->vbv_buffer_size_value, 10);
334
335 /* constrained_parameters_flag */
336 READ_UINT8 (&br, seqhdr->constrained_parameters_flag, 1);
337
338 /* load_intra_quantiser_matrix */
339 READ_UINT8 (&br, seqhdr->load_intra_quantiser_matrix, 1);
340 if (seqhdr->load_intra_quantiser_matrix) {
341 gint i;
342 for (i = 0; i < 64; i++)
343 READ_UINT8 (&br, seqhdr->intra_quantizer_matrix[i], 8);
344 } else
345 memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);
346
347 /* non intra quantizer matrix */
348 READ_UINT8 (&br, seqhdr->load_non_intra_quantiser_matrix, 1);
349 if (seqhdr->load_non_intra_quantiser_matrix) {
350 gint i;
351 for (i = 0; i < 64; i++)
352 READ_UINT8 (&br, seqhdr->non_intra_quantizer_matrix[i], 8);
353 } else
354 memset (seqhdr->non_intra_quantizer_matrix, 16, 64);
355
356 /* dump some info */
357 GST_LOG ("width x height: %d x %d", seqhdr->width, seqhdr->height);
358 GST_LOG ("fps: %d/%d", seqhdr->fps_n, seqhdr->fps_d);
359 GST_LOG ("par: %d/%d", seqhdr->par_w, seqhdr->par_h);
360 GST_LOG ("bitrate: %d", seqhdr->bitrate);
361
362 return TRUE;
363
364 /* ERRORS */
365 failed:
366 {
367 GST_WARNING ("Failed to parse sequence header");
368 /* clear out stuff */
369 memset (seqhdr, 0, sizeof (*seqhdr));
370 return FALSE;
371 }
372 }
373
374 /**
375 * gst_mpeg_video_packet_parse_sequence_extension:
376 * @packet: The #GstMpegVideoPacket that carries the data
377 * @seqext: (out): The #GstMpegVideoSequenceExt structure to fill
378 *
379 * Parses the @seqext MPEG Video Sequence Extension structure members
380 * from video @packet
381 *
382 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwise.
383 *
384 * Since: 1.2
385 */
386 gboolean
gst_mpeg_video_packet_parse_sequence_extension(const GstMpegVideoPacket * packet,GstMpegVideoSequenceExt * seqext)387 gst_mpeg_video_packet_parse_sequence_extension (const GstMpegVideoPacket *
388 packet, GstMpegVideoSequenceExt * seqext)
389 {
390 GstBitReader br;
391
392 g_return_val_if_fail (seqext != NULL, FALSE);
393
394 if (packet->size < 6) {
395 GST_DEBUG ("not enough bytes to parse the extension");
396 return FALSE;
397 }
398
399 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
400
401 if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
402 GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE) {
403 GST_DEBUG ("Not parsing a sequence extension");
404 return FALSE;
405 }
406
407 /* skip profile and level escape bit */
408 seqext->profile_level_escape_bit =
409 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
410
411 seqext->profile = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
412 seqext->level = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
413
414 /* progressive */
415 seqext->progressive = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
416
417 /* chroma format */
418 seqext->chroma_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
419
420 /* resolution extension */
421 seqext->horiz_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
422 seqext->vert_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
423
424 seqext->bitrate_ext = gst_bit_reader_get_bits_uint16_unchecked (&br, 12);
425
426 /* skip marker bits */
427 gst_bit_reader_skip_unchecked (&br, 1);
428
429 seqext->vbv_buffer_size_extension =
430 gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
431 seqext->low_delay = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
432
433 /* framerate extension */
434 seqext->fps_n_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
435 seqext->fps_d_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
436
437 return TRUE;
438 }
439
440 /**
441 * gst_mpeg_video_packet_parse_sequence_display_extension:
442 * @packet: The #GstMpegVideoPacket that carries the data
443 * @seqdisplayext: (out): The #GstMpegVideoSequenceDisplayExt
444 * structure to fill
445 *
446 * Parses the @seqext MPEG Video Sequence Display Extension structure
447 * members from video @packet
448 *
449 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwise.
450 *
451 * Since: 1.2
452 */
453 gboolean
gst_mpeg_video_packet_parse_sequence_display_extension(const GstMpegVideoPacket * packet,GstMpegVideoSequenceDisplayExt * seqdisplayext)454 gst_mpeg_video_packet_parse_sequence_display_extension (const GstMpegVideoPacket
455 * packet, GstMpegVideoSequenceDisplayExt * seqdisplayext)
456 {
457 GstBitReader br;
458
459 g_return_val_if_fail (seqdisplayext != NULL, FALSE);
460
461 if (packet->size < 5) {
462 GST_DEBUG ("not enough bytes to parse the extension");
463 return FALSE;
464 }
465
466 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
467
468 if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
469 GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY) {
470 GST_DEBUG ("Not parsing a sequence display extension");
471 return FALSE;
472 }
473
474 seqdisplayext->video_format =
475 gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
476 seqdisplayext->colour_description_flag =
477 gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
478
479 if (seqdisplayext->colour_description_flag) {
480 seqdisplayext->colour_primaries =
481 gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
482 seqdisplayext->transfer_characteristics =
483 gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
484 seqdisplayext->matrix_coefficients =
485 gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
486 }
487
488 if (gst_bit_reader_get_remaining (&br) < 29) {
489 GST_DEBUG ("Not enough remaining bytes to parse the extension");
490 return FALSE;
491 }
492
493 seqdisplayext->display_horizontal_size =
494 gst_bit_reader_get_bits_uint16_unchecked (&br, 14);
495 /* skip marker bit */
496 gst_bit_reader_skip_unchecked (&br, 1);
497 seqdisplayext->display_vertical_size =
498 gst_bit_reader_get_bits_uint16_unchecked (&br, 14);
499
500 return TRUE;
501 }
502
503 /**
504 * gst_mpeg_video_packet_parse_sequence_scalable_extension:
505 * @packet: The #GstMpegVideoPacket that carries the data
506 * @seqscaleext: (out): The #GstMpegVideoSequenceScalableExt structure to fill
507 *
508 * Parses the @seqscaleext MPEG Video Sequence Scalable Extension structure
509 * members from video @packet
510 *
511 * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwise.
512 *
513 * Since: 1.2
514 */
515 gboolean
gst_mpeg_video_packet_parse_sequence_scalable_extension(const GstMpegVideoPacket * packet,GstMpegVideoSequenceScalableExt * seqscaleext)516 gst_mpeg_video_packet_parse_sequence_scalable_extension
517 (const GstMpegVideoPacket * packet,
518 GstMpegVideoSequenceScalableExt * seqscaleext) {
519 GstBitReader br;
520
521 g_return_val_if_fail (seqscaleext != NULL, FALSE);
522
523 if (packet->size < 2) {
524 GST_DEBUG ("not enough bytes to parse the extension");
525 return FALSE;
526 }
527
528 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
529
530 if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
531 GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE) {
532 GST_DEBUG ("Not parsing a sequence scalable extension");
533 return FALSE;
534 }
535
536 READ_UINT8 (&br, seqscaleext->scalable_mode, 2);
537 READ_UINT8 (&br, seqscaleext->layer_id, 4);
538
539 if (seqscaleext->scalable_mode == GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_SPATIAL) {
540 READ_UINT16 (&br, seqscaleext->lower_layer_prediction_horizontal_size, 14);
541
542 SKIP (&br, 1);
543
544 READ_UINT16 (&br, seqscaleext->lower_layer_prediction_vertical_size, 14);
545
546 READ_UINT8 (&br, seqscaleext->horizontal_subsampling_factor_m, 5);
547 READ_UINT8 (&br, seqscaleext->horizontal_subsampling_factor_n, 5);
548 READ_UINT8 (&br, seqscaleext->vertical_subsampling_factor_m, 5);
549 READ_UINT8 (&br, seqscaleext->vertical_subsampling_factor_n, 5);
550 }
551
552 if (seqscaleext->scalable_mode == GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_TEMPORAL) {
553 READ_UINT8 (&br, seqscaleext->picture_mux_enable, 1);
554 if (seqscaleext->picture_mux_enable)
555 READ_UINT8 (&br, seqscaleext->mux_to_progressive_sequence, 1);
556 READ_UINT8 (&br, seqscaleext->picture_mux_order, 3);
557 READ_UINT8 (&br, seqscaleext->picture_mux_factor, 3);
558 }
559
560 return TRUE;
561
562 failed:
563 GST_WARNING ("error parsing \"Sequence Scalable Extension\"");
564 return FALSE;
565 }
566
567 gboolean
gst_mpeg_video_finalise_mpeg2_sequence_header(GstMpegVideoSequenceHdr * seqhdr,GstMpegVideoSequenceExt * seqext,GstMpegVideoSequenceDisplayExt * displayext)568 gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
569 GstMpegVideoSequenceExt * seqext,
570 GstMpegVideoSequenceDisplayExt * displayext)
571 {
572 guint32 w;
573 guint32 h;
574
575 if (seqext) {
576 seqhdr->fps_n = seqhdr->fps_n * (seqext->fps_n_ext + 1);
577 seqhdr->fps_d = seqhdr->fps_d * (seqext->fps_d_ext + 1);
578 /* Extend width and height to 14 bits by adding the extension bits */
579 seqhdr->width |= (seqext->horiz_size_ext << 12);
580 seqhdr->height |= (seqext->vert_size_ext << 12);
581 seqhdr->bitrate += (seqext->bitrate_ext << 18) * 400;
582 }
583
584 w = seqhdr->width;
585 h = seqhdr->height;
586 if (displayext) {
587 /* Use the display size for calculating PAR when display ext present.
588 * But we are handling this like what DVD players are doing. Which means,
589 * ignore the display extension values if they are greater than the width/height
590 * values provided by seqhdr and calculate the PAR based on the seqhdr values. */
591 if (displayext->display_horizontal_size < w)
592 w = displayext->display_horizontal_size;
593 if (displayext->display_vertical_size < h)
594 h = displayext->display_vertical_size;
595 }
596
597 /* Pixel_width = DAR_width * display_vertical_size */
598 /* Pixel_height = DAR_height * display_horizontal_size */
599 switch (seqhdr->aspect_ratio_info) {
600 case 0x01: /* Square pixels */
601 seqhdr->par_w = seqhdr->par_h = 1;
602 break;
603 case 0x02: /* 3:4 DAR = 4:3 pixels */
604 seqhdr->par_w = 4 * h;
605 seqhdr->par_h = 3 * w;
606 break;
607 case 0x03: /* 9:16 DAR */
608 seqhdr->par_w = 16 * h;
609 seqhdr->par_h = 9 * w;
610 break;
611 case 0x04: /* 1:2.21 DAR */
612 seqhdr->par_w = 221 * h;
613 seqhdr->par_h = 100 * w;
614 break;
615 default:
616 GST_DEBUG ("unknown/invalid aspect_ratio_information %d",
617 seqhdr->aspect_ratio_info);
618 break;
619 }
620
621 return TRUE;
622 }
623
624 /**
625 * gst_mpeg_video_packet_parse_quant_matrix_extension:
626 * @packet: The #GstMpegVideoPacket that carries the data
627 * @quant: (out): The #GstMpegVideoQuantMatrixExt structure to fill
628 *
629 * Parses the @quant MPEG Video Quantization Matrix Extension
630 * structure members from video @packet
631 *
632 * Returns: %TRUE if the quant matrix extension could be parsed correctly,
633 * %FALSE otherwise.
634 *
635 * Since: 1.2
636 */
637 gboolean
gst_mpeg_video_packet_parse_quant_matrix_extension(const GstMpegVideoPacket * packet,GstMpegVideoQuantMatrixExt * quant)638 gst_mpeg_video_packet_parse_quant_matrix_extension (const GstMpegVideoPacket *
639 packet, GstMpegVideoQuantMatrixExt * quant)
640 {
641 guint8 i;
642 GstBitReader br;
643
644 g_return_val_if_fail (quant != NULL, FALSE);
645
646 if (packet->size < 1) {
647 GST_DEBUG ("not enough bytes to parse the extension");
648 return FALSE;
649 }
650
651 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
652
653 if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
654 GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX) {
655 GST_DEBUG ("Not parsing a quant matrix extension");
656 return FALSE;
657 }
658
659 READ_UINT8 (&br, quant->load_intra_quantiser_matrix, 1);
660 if (quant->load_intra_quantiser_matrix) {
661 for (i = 0; i < 64; i++) {
662 READ_UINT8 (&br, quant->intra_quantiser_matrix[i], 8);
663 }
664 }
665
666 READ_UINT8 (&br, quant->load_non_intra_quantiser_matrix, 1);
667 if (quant->load_non_intra_quantiser_matrix) {
668 for (i = 0; i < 64; i++) {
669 READ_UINT8 (&br, quant->non_intra_quantiser_matrix[i], 8);
670 }
671 }
672
673 READ_UINT8 (&br, quant->load_chroma_intra_quantiser_matrix, 1);
674 if (quant->load_chroma_intra_quantiser_matrix) {
675 for (i = 0; i < 64; i++) {
676 READ_UINT8 (&br, quant->chroma_intra_quantiser_matrix[i], 8);
677 }
678 }
679
680 READ_UINT8 (&br, quant->load_chroma_non_intra_quantiser_matrix, 1);
681 if (quant->load_chroma_non_intra_quantiser_matrix) {
682 for (i = 0; i < 64; i++) {
683 READ_UINT8 (&br, quant->chroma_non_intra_quantiser_matrix[i], 8);
684 }
685 }
686
687 return TRUE;
688
689 failed:
690 GST_WARNING ("error parsing \"Quant Matrix Extension\"");
691 return FALSE;
692 }
693
694 /**
695 * gst_mpeg_video_packet_parse_picture_extension:
696 * @packet: The #GstMpegVideoPacket that carries the data
697 * @ext: (out): The #GstMpegVideoPictureExt structure to fill
698 *
699 * Parse the @ext MPEG Video Picture Extension structure members from
700 * video @packet
701 *
702 * Returns: %TRUE if the picture extension could be parsed correctly,
703 * %FALSE otherwise.
704 *
705 * Since: 1.2
706 */
707 gboolean
gst_mpeg_video_packet_parse_picture_extension(const GstMpegVideoPacket * packet,GstMpegVideoPictureExt * ext)708 gst_mpeg_video_packet_parse_picture_extension (const GstMpegVideoPacket *
709 packet, GstMpegVideoPictureExt * ext)
710 {
711 GstBitReader br;
712
713 g_return_val_if_fail (ext != NULL, FALSE);
714
715 if (packet->size < 5)
716 return FALSE;
717
718 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
719
720 if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
721 GST_MPEG_VIDEO_PACKET_EXT_PICTURE) {
722 GST_DEBUG ("Extension is not a picture extension");
723 return FALSE;
724 }
725
726 /* f_code */
727 READ_UINT8 (&br, ext->f_code[0][0], 4);
728 READ_UINT8 (&br, ext->f_code[0][1], 4);
729 READ_UINT8 (&br, ext->f_code[1][0], 4);
730 READ_UINT8 (&br, ext->f_code[1][1], 4);
731
732 /* intra DC precision */
733 READ_UINT8 (&br, ext->intra_dc_precision, 2);
734
735 /* picture structure */
736 READ_UINT8 (&br, ext->picture_structure, 2);
737
738 /* top field first */
739 READ_UINT8 (&br, ext->top_field_first, 1);
740
741 /* frame pred frame dct */
742 READ_UINT8 (&br, ext->frame_pred_frame_dct, 1);
743
744 /* concealment motion vectors */
745 READ_UINT8 (&br, ext->concealment_motion_vectors, 1);
746
747 /* q scale type */
748 READ_UINT8 (&br, ext->q_scale_type, 1);
749
750 /* intra vlc format */
751 READ_UINT8 (&br, ext->intra_vlc_format, 1);
752
753 /* alternate scan */
754 READ_UINT8 (&br, ext->alternate_scan, 1);
755
756 /* repeat first field */
757 READ_UINT8 (&br, ext->repeat_first_field, 1);
758
759 /* chroma_420_type */
760 READ_UINT8 (&br, ext->chroma_420_type, 1);
761
762 /* progressive_frame */
763 READ_UINT8 (&br, ext->progressive_frame, 1);
764
765 /* composite display */
766 READ_UINT8 (&br, ext->composite_display, 1);
767
768 if (ext->composite_display) {
769
770 /* v axis */
771 READ_UINT8 (&br, ext->v_axis, 1);
772
773 /* field sequence */
774 READ_UINT8 (&br, ext->field_sequence, 3);
775
776 /* sub carrier */
777 READ_UINT8 (&br, ext->sub_carrier, 1);
778
779 /* burst amplitude */
780 READ_UINT8 (&br, ext->burst_amplitude, 7);
781
782 /* sub_carrier phase */
783 READ_UINT8 (&br, ext->sub_carrier_phase, 8);
784 }
785
786 return TRUE;
787
788 failed:
789 GST_WARNING ("error parsing \"Picture Coding Extension\"");
790 return FALSE;
791
792 }
793
794 /**
795 * gst_mpeg_video_packet_parse_picture_header:
796 * @packet: The #GstMpegVideoPacket that carries the data
797 * @pichdr: (out): The #GstMpegVideoPictureHdr structure to fill
798 *
799 * Parsers the @pichdr MPEG Video Picture Header structure members
800 * from video @packet
801 *
802 * Returns: %TRUE if the picture sequence could be parsed correctly, %FALSE
803 * otherwise.
804 *
805 * Since: 1.2
806 */
807 gboolean
gst_mpeg_video_packet_parse_picture_header(const GstMpegVideoPacket * packet,GstMpegVideoPictureHdr * hdr)808 gst_mpeg_video_packet_parse_picture_header (const GstMpegVideoPacket * packet,
809 GstMpegVideoPictureHdr * hdr)
810 {
811 GstBitReader br;
812
813 if (packet->size < 4)
814 goto failed;
815
816 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
817
818 /* temperal sequence number */
819 if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->tsn, 10))
820 goto failed;
821
822
823 /* frame type */
824 if (!gst_bit_reader_get_bits_uint8 (&br, (guint8 *) & hdr->pic_type, 3))
825 goto failed;
826
827
828 if (hdr->pic_type == 0 || hdr->pic_type > 4)
829 goto bad_pic_type; /* Corrupted picture packet */
830
831 /* VBV delay */
832 if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->vbv_delay, 16))
833 goto failed;
834
835 if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_P
836 || hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
837
838 READ_UINT8 (&br, hdr->full_pel_forward_vector, 1);
839
840 READ_UINT8 (&br, hdr->f_code[0][0], 3);
841 hdr->f_code[0][1] = hdr->f_code[0][0];
842 } else {
843 hdr->full_pel_forward_vector = 0;
844 hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
845 }
846
847 if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
848 READ_UINT8 (&br, hdr->full_pel_backward_vector, 1);
849
850 READ_UINT8 (&br, hdr->f_code[1][0], 3);
851 hdr->f_code[1][1] = hdr->f_code[1][0];
852 } else {
853 hdr->full_pel_backward_vector = 0;
854 hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
855 }
856
857 return TRUE;
858
859 bad_pic_type:
860 {
861 GST_WARNING ("Unsupported picture type : %d", hdr->pic_type);
862 return FALSE;
863 }
864
865 failed:
866 {
867 GST_WARNING ("Not enough data to parse picture header");
868 return FALSE;
869 }
870 }
871
872 /**
873 * gst_mpeg_video_packet_parse_gop:
874 * @packet: The #GstMpegVideoPacket that carries the data
875 * @gop: (out): The #GstMpegVideoGop structure to fill
876 *
877 * Parses the @gop MPEG Video Group of Picture structure members from
878 * video @packet
879 *
880 * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwise.
881 *
882 * Since: 1.2
883 */
884 gboolean
gst_mpeg_video_packet_parse_gop(const GstMpegVideoPacket * packet,GstMpegVideoGop * gop)885 gst_mpeg_video_packet_parse_gop (const GstMpegVideoPacket * packet,
886 GstMpegVideoGop * gop)
887 {
888 GstBitReader br;
889
890 g_return_val_if_fail (gop != NULL, FALSE);
891
892 if (packet->size < 4)
893 return FALSE;
894
895 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
896
897 READ_UINT8 (&br, gop->drop_frame_flag, 1);
898
899 READ_UINT8 (&br, gop->hour, 5);
900
901 READ_UINT8 (&br, gop->minute, 6);
902
903 /* skip unused bit */
904 if (!gst_bit_reader_skip (&br, 1))
905 return FALSE;
906
907 READ_UINT8 (&br, gop->second, 6);
908
909 READ_UINT8 (&br, gop->frame, 6);
910
911 READ_UINT8 (&br, gop->closed_gop, 1);
912
913 READ_UINT8 (&br, gop->broken_link, 1);
914
915 return TRUE;
916
917 failed:
918 GST_WARNING ("error parsing \"GOP\"");
919 return FALSE;
920 }
921
922 /**
923 * gst_mpeg_video_packet_parse_slice_header:
924 * @packet: The #GstMpegVideoPacket that carries the data
925 * @slice_hdr: (out): The #GstMpegVideoSliceHdr structure to fill
926 * @seqhdr: The #GstMpegVideoSequenceHdr header
927 * @seqscaleext: The #GstMpegVideoSequenceScalableExt header
928 *
929 * Parses the @GstMpegVideoSliceHdr structure members from @data
930 *
931 * Returns: %TRUE if the slice could be parsed correctly, %FALSE otherwise.
932 *
933 * Since: 1.2
934 */
935 gboolean
gst_mpeg_video_packet_parse_slice_header(const GstMpegVideoPacket * packet,GstMpegVideoSliceHdr * slice_hdr,GstMpegVideoSequenceHdr * seqhdr,GstMpegVideoSequenceScalableExt * seqscaleext)936 gst_mpeg_video_packet_parse_slice_header (const GstMpegVideoPacket * packet,
937 GstMpegVideoSliceHdr * slice_hdr, GstMpegVideoSequenceHdr * seqhdr,
938 GstMpegVideoSequenceScalableExt * seqscaleext)
939 {
940 GstBitReader br;
941 guint height;
942 guint mb_inc;
943 guint8 bits, extra_bits;
944 guint8 vertical_position, vertical_position_extension = 0;
945
946 g_return_val_if_fail (seqhdr != NULL, FALSE);
947
948 if (packet->size < 1)
949 return FALSE;
950
951 gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
952
953 if (packet->type < GST_MPEG_VIDEO_PACKET_SLICE_MIN ||
954 packet->type > GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
955 GST_DEBUG ("Not parsing a slice");
956 return FALSE;
957 }
958 vertical_position = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN;
959
960 height = seqhdr->height;
961 if (height > 2800)
962 READ_UINT8 (&br, vertical_position_extension, 3);
963
964 slice_hdr->vertical_position = packet->type;
965 slice_hdr->vertical_position_ext = vertical_position_extension;
966
967 if (seqscaleext)
968 if (seqscaleext->scalable_mode ==
969 GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_DATA_PARTITIONING)
970 READ_UINT8 (&br, slice_hdr->priority_breakpoint, 7);
971
972 READ_UINT8 (&br, slice_hdr->quantiser_scale_code, 5);
973
974 READ_UINT8 (&br, slice_hdr->slice_ext_flag, 1);
975 if (!slice_hdr->slice_ext_flag)
976 slice_hdr->intra_slice = 0;
977 else {
978 READ_UINT8 (&br, slice_hdr->intra_slice, 1);
979 READ_UINT8 (&br, slice_hdr->slice_picture_id_enable, 1);
980 READ_UINT8 (&br, slice_hdr->slice_picture_id, 6);
981
982 READ_UINT8 (&br, bits, 1);
983 while (bits) {
984 READ_UINT8 (&br, extra_bits, 8);
985 READ_UINT8 (&br, bits, 1);
986 }
987 }
988
989 slice_hdr->header_size = gst_bit_reader_get_pos (&br);
990
991 if (height > 2800)
992 slice_hdr->mb_row = (vertical_position_extension << 7) + vertical_position;
993 else
994 slice_hdr->mb_row = vertical_position;
995
996 slice_hdr->mb_column = -1;
997 do {
998 if (!decode_vlc (&br, &mb_inc, mpeg2_mbaddr_vlc_table,
999 G_N_ELEMENTS (mpeg2_mbaddr_vlc_table))) {
1000 GST_WARNING ("failed to decode first macroblock_address_increment");
1001 goto failed;
1002 }
1003 slice_hdr->mb_column +=
1004 mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc;
1005 } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE);
1006
1007 return TRUE;
1008
1009 failed:
1010 GST_WARNING ("error parsing \"Slice\"");
1011 return FALSE;
1012 }
1013
1014 /**
1015 * gst_mpeg_video_quant_matrix_get_raster_from_zigzag:
1016 * @out_quant: (out): The resulting quantization matrix
1017 * @quant: The source quantization matrix
1018 *
1019 * Converts quantization matrix @quant from zigzag scan order to
1020 * raster scan order and store the resulting factors into @out_quant.
1021 *
1022 * Note: it is an error to pass the same table in both @quant and
1023 * @out_quant arguments.
1024 *
1025 * Since: 1.2
1026 */
1027 void
gst_mpeg_video_quant_matrix_get_raster_from_zigzag(guint8 out_quant[64],const guint8 quant[64])1028 gst_mpeg_video_quant_matrix_get_raster_from_zigzag (guint8 out_quant[64],
1029 const guint8 quant[64])
1030 {
1031 guint i;
1032
1033 g_return_if_fail (out_quant != quant);
1034
1035 for (i = 0; i < 64; i++)
1036 out_quant[mpeg_zigzag_8x8[i]] = quant[i];
1037 }
1038
1039 /**
1040 * gst_mpeg_video_quant_matrix_get_zigzag_from_raster:
1041 * @out_quant: (out): The resulting quantization matrix
1042 * @quant: The source quantization matrix
1043 *
1044 * Converts quantization matrix @quant from raster scan order to
1045 * zigzag scan order and store the resulting factors into @out_quant.
1046 *
1047 * Note: it is an error to pass the same table in both @quant and
1048 * @out_quant arguments.
1049 *
1050 * Since: 1.2
1051 */
1052 void
gst_mpeg_video_quant_matrix_get_zigzag_from_raster(guint8 out_quant[64],const guint8 quant[64])1053 gst_mpeg_video_quant_matrix_get_zigzag_from_raster (guint8 out_quant[64],
1054 const guint8 quant[64])
1055 {
1056 guint i;
1057
1058 g_return_if_fail (out_quant != quant);
1059
1060 for (i = 0; i < 64; i++)
1061 out_quant[i] = quant[mpeg_zigzag_8x8[i]];
1062 }
1063