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