• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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