From c5c44628fcd4adbcc9d84f12e54f957b3b52a733 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Mon, 3 Sep 2012 09:47:30 -0700 Subject: [PATCH] mpegvideoparse: Handle Sequence Display Extension Change the way the pixel-aspect-ratio is computed by interpreting the sequence header aspect ratio info as MPEG-1 values until a sequence extension or sequence display extension is seen, and then updating the sequence header struct accordingly. Fixes incorrect anamorphic display on some MPEG-2 (DVD) sequences. --- .../gst/codecparsers/gstmpegvideoparser.c | 294 ++++++++++++------ .../gst/codecparsers/gstmpegvideoparser.h | 35 ++- gst/videoparsers/gstmpegvideoparse.c | 68 ++-- gst/videoparsers/gstmpegvideoparse.h | 11 +- 4 files changed, 279 insertions(+), 129 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstmpegvideoparser.c b/gst-libs/gst/codecparsers/gstmpegvideoparser.c index fbe37ef5e9..313339010d 100644 --- a/gst-libs/gst/codecparsers/gstmpegvideoparser.c +++ b/gst-libs/gst/codecparsers/gstmpegvideoparser.c @@ -107,32 +107,32 @@ failed: return FALSE; } -/* Set the Pixel Aspect Ratio in our hdr from a DAR code in the data */ +/* Set the Pixel Aspect Ratio in our hdr from a ASR code in the data */ static void -set_par_from_dar (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code) +set_par_from_asr_mpeg1 (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code) { - /* Pixel_width = DAR_width * display_vertical_size */ - /* Pixel_height = DAR_height * display_horizontal_size */ - switch (asr_code) { - case 0x02: /* 3:4 DAR = 4:3 pixels */ - seqhdr->par_w = 4 * seqhdr->height; - seqhdr->par_h = 3 * seqhdr->width; - break; - case 0x03: /* 9:16 DAR */ - seqhdr->par_w = 16 * seqhdr->height; - seqhdr->par_h = 9 * seqhdr->width; - break; - case 0x04: /* 1:2.21 DAR */ - seqhdr->par_w = 221 * seqhdr->height; - seqhdr->par_h = 100 * seqhdr->width; - break; - case 0x01: /* Square pixels */ - seqhdr->par_w = seqhdr->par_h = 1; - break; - default: - GST_DEBUG ("unknown/invalid aspect_ratio_information %d", asr_code); - break; - } + int ratios[16][2] = { + {0, 0}, /* 0, Invalid */ + {1, 1}, /* 1, 1.0 */ + {10000, 6735}, /* 2, 0.6735 */ + {64, 45}, /* 3, 0.7031 16:9 625 line */ + {10000, 7615}, /* 4, 0.7615 */ + {10000, 8055}, /* 5, 0.8055 */ + {32, 27}, /* 6, 0.8437 */ + {10000, 8935}, /* 7, 0.8935 */ + {10000, 9375}, /* 8, 0.9375 */ + {10000, 9815}, /* 9, 0.9815 */ + {10000, 10255}, /* 10, 1.0255 */ + {10000, 10695}, /* 11, 1.0695 */ + {8, 9}, /* 12, 1.125 */ + {10000, 11575}, /* 13, 1.1575 */ + {10000, 12015}, /* 14, 1.2015 */ + {0, 0}, /* 15, invalid */ + }; + asr_code &= 0xf; + + seqhdr->par_w = ratios[asr_code][0]; + seqhdr->par_h = ratios[asr_code][1]; } static void @@ -156,79 +156,6 @@ set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code) } } -static gboolean -gst_mpeg_video_parse_sequence (GstMpegVideoSequenceHdr * seqhdr, - GstBitReader * br) -{ - guint8 bits; - guint8 load_intra_flag, load_non_intra_flag; - - /* Setting the height/width codes */ - READ_UINT16 (br, seqhdr->width, 12); - READ_UINT16 (br, seqhdr->height, 12); - - READ_UINT8 (br, seqhdr->aspect_ratio_info, 4); - set_par_from_dar (seqhdr, seqhdr->aspect_ratio_info); - - READ_UINT8 (br, seqhdr->frame_rate_code, 4); - set_fps_from_code (seqhdr, seqhdr->frame_rate_code); - - READ_UINT32 (br, seqhdr->bitrate_value, 18); - if (seqhdr->bitrate_value == 0x3ffff) { - /* VBR stream */ - seqhdr->bitrate = 0; - } else { - /* Value in header is in units of 400 bps */ - seqhdr->bitrate *= 400; - } - - READ_UINT8 (br, bits, 1); - if (bits != MARKER_BIT) - goto failed; - - /* VBV buffer size */ - READ_UINT16 (br, seqhdr->vbv_buffer_size_value, 10); - - /* constrained_parameters_flag */ - READ_UINT8 (br, seqhdr->constrained_parameters_flag, 1); - - /* load_intra_quantiser_matrix */ - READ_UINT8 (br, load_intra_flag, 1); - if (load_intra_flag) { - gint i; - for (i = 0; i < 64; i++) - READ_UINT8 (br, seqhdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); - } else - memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); - - /* non intra quantizer matrix */ - READ_UINT8 (br, load_non_intra_flag, 1); - if (load_non_intra_flag) { - gint i; - for (i = 0; i < 64; i++) - READ_UINT8 (br, seqhdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]], - 8); - } else - memset (seqhdr->non_intra_quantizer_matrix, 16, 64); - - /* dump some info */ - GST_LOG ("width x height: %d x %d", seqhdr->width, seqhdr->height); - GST_LOG ("fps: %d/%d", seqhdr->fps_n, seqhdr->fps_d); - GST_LOG ("par: %d/%d", seqhdr->par_w, seqhdr->par_h); - GST_LOG ("bitrate: %d", seqhdr->bitrate); - - return TRUE; - - /* ERRORS */ -failed: - { - GST_WARNING ("Failed to parse sequence header"); - /* clear out stuff */ - memset (seqhdr, 0, sizeof (*seqhdr)); - return FALSE; - } -} - /* @size and @offset are wrt current reader position */ static inline guint scan_for_start_codes (const GstByteReader * reader, guint offset, guint size) @@ -347,6 +274,8 @@ gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr, const guint8 * data, gsize size, guint offset) { GstBitReader br; + guint8 bits; + guint8 load_intra_flag, load_non_intra_flag; g_return_val_if_fail (seqhdr != NULL, FALSE); @@ -357,7 +286,72 @@ gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr, gst_bit_reader_init (&br, &data[offset], size); - return gst_mpeg_video_parse_sequence (seqhdr, &br); + /* Setting the height/width codes */ + READ_UINT16 (&br, seqhdr->width, 12); + READ_UINT16 (&br, seqhdr->height, 12); + + READ_UINT8 (&br, seqhdr->aspect_ratio_info, 4); + /* Interpret PAR according to MPEG-1. Needs to be reinterpreted + * later, if a sequence_display extension is seen */ + set_par_from_asr_mpeg1 (seqhdr, seqhdr->aspect_ratio_info); + + READ_UINT8 (&br, seqhdr->frame_rate_code, 4); + set_fps_from_code (seqhdr, seqhdr->frame_rate_code); + + READ_UINT32 (&br, seqhdr->bitrate_value, 18); + if (seqhdr->bitrate_value == 0x3ffff) { + /* VBR stream */ + seqhdr->bitrate = 0; + } else { + /* Value in header is in units of 400 bps */ + seqhdr->bitrate *= 400; + } + + READ_UINT8 (&br, bits, 1); + if (bits != MARKER_BIT) + goto failed; + + /* VBV buffer size */ + READ_UINT16 (&br, seqhdr->vbv_buffer_size_value, 10); + + /* constrained_parameters_flag */ + READ_UINT8 (&br, seqhdr->constrained_parameters_flag, 1); + + /* load_intra_quantiser_matrix */ + READ_UINT8 (&br, load_intra_flag, 1); + if (load_intra_flag) { + gint i; + for (i = 0; i < 64; i++) + READ_UINT8 (&br, seqhdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); + } else + memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); + + /* non intra quantizer matrix */ + READ_UINT8 (&br, load_non_intra_flag, 1); + if (load_non_intra_flag) { + gint i; + for (i = 0; i < 64; i++) + READ_UINT8 (&br, seqhdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]], + 8); + } else + memset (seqhdr->non_intra_quantizer_matrix, 16, 64); + + /* dump some info */ + GST_LOG ("width x height: %d x %d", seqhdr->width, seqhdr->height); + GST_LOG ("fps: %d/%d", seqhdr->fps_n, seqhdr->fps_d); + GST_LOG ("par: %d/%d", seqhdr->par_w, seqhdr->par_h); + GST_LOG ("bitrate: %d", seqhdr->bitrate); + + return TRUE; + + /* ERRORS */ +failed: + { + GST_WARNING ("Failed to parse sequence header"); + /* clear out stuff */ + memset (seqhdr, 0, sizeof (*seqhdr)); + return FALSE; + } } /** @@ -426,6 +420,110 @@ gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext, return TRUE; } +gboolean +gst_mpeg_video_parse_sequence_display_extension (GstMpegVideoSequenceDisplayExt + * seqdisplayext, const guint8 * data, gsize size, guint offset) +{ + GstBitReader br; + + g_return_val_if_fail (seqdisplayext != NULL, FALSE); + if (offset > size) + return FALSE; + + size -= offset; + if (size < 5) { + GST_DEBUG ("not enough bytes to parse the extension"); + return FALSE; + } + + gst_bit_reader_init (&br, &data[offset], size); + + if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) != + GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY) { + GST_DEBUG ("Not parsing a sequence display extension"); + return FALSE; + } + + seqdisplayext->video_format = + gst_bit_reader_get_bits_uint8_unchecked (&br, 3); + seqdisplayext->colour_description_flag = + gst_bit_reader_get_bits_uint8_unchecked (&br, 1); + + if (seqdisplayext->colour_description_flag) { + seqdisplayext->colour_primaries = + gst_bit_reader_get_bits_uint8_unchecked (&br, 8); + seqdisplayext->transfer_characteristics = + gst_bit_reader_get_bits_uint8_unchecked (&br, 8); + seqdisplayext->matrix_coefficients = + gst_bit_reader_get_bits_uint8_unchecked (&br, 8); + } + + if (gst_bit_reader_get_remaining (&br) < 29) { + GST_DEBUG ("Not enough remaining bytes to parse the extension"); + return FALSE; + } + + seqdisplayext->display_horizontal_size = + gst_bit_reader_get_bits_uint16_unchecked (&br, 14); + /* skip marker bit */ + gst_bit_reader_skip_unchecked (&br, 1); + seqdisplayext->display_vertical_size = + gst_bit_reader_get_bits_uint16_unchecked (&br, 14); + + return TRUE; +} + +gboolean +gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr * seqhdr, + GstMpegVideoSequenceExt * seqext, + GstMpegVideoSequenceDisplayExt * displayext) +{ + guint32 w; + guint32 h; + + if (seqext) { + seqhdr->fps_n = seqhdr->fps_n * (seqext->fps_n_ext + 1); + seqhdr->fps_d = seqhdr->fps_d * (seqext->fps_d_ext + 1); + /* Extend width and height to 14 bits by adding the extension bits */ + seqhdr->width |= (seqext->horiz_size_ext << 12); + seqhdr->height |= (seqext->vert_size_ext << 12); + } + + w = seqhdr->width; + h = seqhdr->height; + if (displayext) { + /* Use the display size for calculating PAR when display ext present */ + w = displayext->display_horizontal_size; + h = displayext->display_vertical_size; + } + + /* Pixel_width = DAR_width * display_vertical_size */ + /* Pixel_height = DAR_height * display_horizontal_size */ + switch (seqhdr->aspect_ratio_info) { + case 0x01: /* Square pixels */ + seqhdr->par_w = seqhdr->par_h = 1; + break; + case 0x02: /* 3:4 DAR = 4:3 pixels */ + seqhdr->par_w = 4 * h; + seqhdr->par_h = 3 * w; + break; + case 0x03: /* 9:16 DAR */ + seqhdr->par_w = 16 * h; + seqhdr->par_h = 9 * w; + break; + case 0x04: /* 1:2.21 DAR */ + seqhdr->par_w = 221 * h; + seqhdr->par_h = 100 * w; + break; + default: + GST_DEBUG ("unknown/invalid aspect_ratio_information %d", + seqhdr->aspect_ratio_info); + break; + } + + return TRUE; +} + /** * gst_mpeg_video_parse_quant_matrix_extension: * @quant: (out): The #GstMpegVideoQuantMatrixExt structure to fill diff --git a/gst-libs/gst/codecparsers/gstmpegvideoparser.h b/gst-libs/gst/codecparsers/gstmpegvideoparser.h index d0a16bcec8..2b13a064c4 100644 --- a/gst-libs/gst/codecparsers/gstmpegvideoparser.h +++ b/gst-libs/gst/codecparsers/gstmpegvideoparser.h @@ -175,6 +175,7 @@ typedef enum { typedef struct _GstMpegVideoSequenceHdr GstMpegVideoSequenceHdr; typedef struct _GstMpegVideoSequenceExt GstMpegVideoSequenceExt; +typedef struct _GstMpegVideoSequenceDisplayExt GstMpegVideoSequenceDisplayExt; typedef struct _GstMpegVideoPictureHdr GstMpegVideoPictureHdr; typedef struct _GstMpegVideoGop GstMpegVideoGop; typedef struct _GstMpegVideoPictureExt GstMpegVideoPictureExt; @@ -218,16 +219,16 @@ struct _GstMpegVideoSequenceHdr /** * GstMpegVideoSequenceExt: - * @profile: mpeg2 decoder profil + * @profile: mpeg2 decoder profile * @level: mpeg2 decoder level - * @progressive: %TRUE if the frames are progressive %FALSE otherwize + * @progressive: %TRUE if the frames are progressive %FALSE otherwise * @chroma_format: indicates the chrominance format * @horiz_size_ext: Horizontal size * @vert_size_ext: Vertical size * @bitrate_ext: The bitrate - * @vbv_buffer_size_extension: Vbv vuffer size + * @vbv_buffer_size_extension: VBV vuffer size * @low_delay: %TRUE if the sequence doesn't contain any B-pictures, %FALSE - * otherwize + * otherwise * @fps_n_ext: Framerate nominator code * @fps_d_ext: Framerate denominator code * @@ -252,6 +253,25 @@ struct _GstMpegVideoSequenceExt }; +/** + * GstMpegVideoSequenceDisplayExt: + * @profile: mpeg2 decoder profil + + */ +struct _GstMpegVideoSequenceDisplayExt +{ + guint8 video_format; + guint8 colour_description_flag; + + /* if colour_description_flag: */ + guint8 colour_primaries; + guint8 transfer_characteristics; + guint8 matrix_coefficients; + + guint16 display_horizontal_size; + guint16 display_vertical_size; +}; + /** * GstMpegVideoQuantMatrixExt: * @load_intra_quantiser_matrix: @@ -384,6 +404,10 @@ gboolean gst_mpeg_video_parse (GstMpegVideoPacket * pack gboolean gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * params, const guint8 * data, gsize size, guint offset); +/* seqext and displayext may be NULL if not received */ +gboolean gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr *hdr, + GstMpegVideoSequenceExt *seqext, GstMpegVideoSequenceDisplayExt *displayext); + gboolean gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr* hdr, const guint8 * data, gsize size, guint offset); @@ -396,6 +420,9 @@ gboolean gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, gboolean gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext, const guint8 * data, gsize size, guint offset); +gboolean gst_mpeg_video_parse_sequence_display_extension (GstMpegVideoSequenceDisplayExt * seqdisplayext, + const guint8 * data, gsize size, guint offset); + gboolean gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant, const guint8 * data, gsize size, guint offset); diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c index c8898af72d..a6be18ef10 100644 --- a/gst/videoparsers/gstmpegvideoparse.c +++ b/gst/videoparsers/gstmpegvideoparse.c @@ -169,7 +169,7 @@ gst_mpegv_parse_class_init (GstMpegvParseClass * klass) static void gst_mpegv_parse_init (GstMpegvParse * parse) { - parse->mpeg_version = 0; + parse->config_flags = FLAG_NONE; } static void @@ -196,6 +196,7 @@ gst_mpegv_parse_reset (GstMpegvParse * mpvparse) gst_buffer_replace (&mpvparse->config, NULL); memset (&mpvparse->sequencehdr, 0, sizeof (mpvparse->sequencehdr)); memset (&mpvparse->sequenceext, 0, sizeof (mpvparse->sequenceext)); + memset (&mpvparse->sequencedispext, 0, sizeof (mpvparse->sequencedispext)); memset (&mpvparse->pichdr, 0, sizeof (mpvparse->pichdr)); } @@ -232,6 +233,7 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, guint8 *data; guint8 *data_with_prefix; GstMapInfo map; + gint i, offset; if (mpvparse->seq_offset < 4) { /* This shouldn't happen, but just in case... */ @@ -256,13 +258,8 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, return TRUE; } - if (gst_mpeg_video_parse_sequence_header (&mpvparse->sequencehdr, data, + if (!gst_mpeg_video_parse_sequence_header (&mpvparse->sequencehdr, data, size - mpvparse->seq_offset, 0)) { - if (mpvparse->fps_num == 0 || mpvparse->fps_den == 0) { - mpvparse->fps_num = mpvparse->sequencehdr.fps_n; - mpvparse->fps_den = mpvparse->sequencehdr.fps_d; - } - } else { GST_DEBUG_OBJECT (mpvparse, "failed to parse config data (size %d) at offset %d", size, mpvparse->seq_offset); @@ -273,23 +270,41 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, GST_LOG_OBJECT (mpvparse, "accepting parsed config size %d", size); /* Set mpeg version, and parse sequence extension */ - if (mpvparse->mpeg_version <= 0) { - gint i, offset; - - mpvparse->mpeg_version = 1; - for (i = 0; i < mpvparse->ext_count; ++i) { - offset = mpvparse->ext_offsets[i]; - mpvparse->mpeg_version = 2; - if (offset < size && - gst_mpeg_video_parse_sequence_extension (&mpvparse->sequenceext, + mpvparse->config_flags = FLAG_NONE; + for (i = 0; i < mpvparse->ext_count; ++i) { + offset = mpvparse->ext_offsets[i]; + mpvparse->config_flags |= FLAG_MPEG2; + if (offset < size) { + if (gst_mpeg_video_parse_sequence_extension (&mpvparse->sequenceext, map.data, size, offset)) { - mpvparse->fps_num = - mpvparse->sequencehdr.fps_n * (mpvparse->sequenceext.fps_n_ext + 1); - mpvparse->fps_den = - mpvparse->sequencehdr.fps_d * (mpvparse->sequenceext.fps_d_ext + 1); + GST_LOG_OBJECT (mpvparse, "Read Sequence Extension"); + mpvparse->config_flags |= FLAG_SEQUENCE_EXT; + } else + if (gst_mpeg_video_parse_sequence_display_extension + (&mpvparse->sequencedispext, map.data, size, offset)) { + GST_LOG_OBJECT (mpvparse, "Read Sequence Display Extension"); + mpvparse->config_flags |= FLAG_SEQUENCE_DISPLAY_EXT; } } } + if (mpvparse->config_flags & FLAG_MPEG2) { + /* Update the sequence header based on extensions */ + GstMpegVideoSequenceExt *seqext = NULL; + GstMpegVideoSequenceDisplayExt *seqdispext = NULL; + + if (mpvparse->config_flags & FLAG_SEQUENCE_EXT) + seqext = &mpvparse->sequenceext; + if (mpvparse->config_flags & FLAG_SEQUENCE_DISPLAY_EXT) + seqdispext = &mpvparse->sequencedispext; + + gst_mpeg_video_finalise_mpeg2_sequence_header (&mpvparse->sequencehdr, + seqext, seqdispext); + } + + if (mpvparse->fps_num == 0 || mpvparse->fps_den == 0) { + mpvparse->fps_num = mpvparse->sequencehdr.fps_n; + mpvparse->fps_den = mpvparse->sequencehdr.fps_d; + } /* parsing ok, so accept it as new config */ if (mpvparse->config != NULL) @@ -627,10 +642,9 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) * config data, so we should at least know about version. * If not, it means it has been requested not to drop data, and * upstream and/or app must know what they are doing ... */ - - if (G_LIKELY (mpvparse->mpeg_version)) - gst_caps_set_simple (caps, - "mpegversion", G_TYPE_INT, mpvparse->mpeg_version, NULL); + gst_caps_set_simple (caps, + "mpegversion", G_TYPE_INT, (mpvparse->config_flags & FLAG_MPEG2) ? 2 : 1, + NULL); gst_caps_set_simple (caps, "systemstream", G_TYPE_BOOLEAN, FALSE, "parsed", G_TYPE_BOOLEAN, TRUE, NULL); @@ -664,7 +678,7 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) GST_TYPE_BUFFER, mpvparse->config, NULL); } - if (mpvparse->mpeg_version == 2) { + if (mpvparse->config_flags & FLAG_SEQUENCE_EXT) { const guint profile_c = mpvparse->sequenceext.profile; const guint level_c = mpvparse->sequenceext.level; const gchar *profile = NULL, *level = NULL; @@ -782,7 +796,9 @@ gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) gchar *codec; /* codec tag */ - codec = g_strdup_printf ("MPEG %d Video", mpvparse->mpeg_version); + codec = + g_strdup_printf ("MPEG %d Video", + (mpvparse->config_flags & FLAG_MPEG2) ? 2 : 1); taglist = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL); g_free (codec); diff --git a/gst/videoparsers/gstmpegvideoparse.h b/gst/videoparsers/gstmpegvideoparse.h index 47ad4ceecc..e00e9c8647 100644 --- a/gst/videoparsers/gstmpegvideoparse.h +++ b/gst/videoparsers/gstmpegvideoparse.h @@ -47,6 +47,14 @@ G_BEGIN_DECLS typedef struct _GstMpegvParse GstMpegvParse; typedef struct _GstMpegvParseClass GstMpegvParseClass; +/* Config/sequence flags. Reset each time config is re-parsed */ +enum { + FLAG_NONE = 0, + FLAG_MPEG2 = 1, + FLAG_SEQUENCE_EXT = 2, + FLAG_SEQUENCE_DISPLAY_EXT = 4 +}; + struct _GstMpegvParse { GstBaseParse element; @@ -62,9 +70,10 @@ struct _GstMpegvParse { GstBuffer *config; guint8 profile; - guint mpeg_version; + guint config_flags; GstMpegVideoSequenceHdr sequencehdr; GstMpegVideoSequenceExt sequenceext; + GstMpegVideoSequenceDisplayExt sequencedispext; GstMpegVideoPictureHdr pichdr; /* properties */