summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2012-09-03 09:47:30 -0700
committerJan Schmidt <thaytan@noraisin.net>2012-09-12 23:05:47 -0700
commitc5c44628fcd4adbcc9d84f12e54f957b3b52a733 (patch)
tree4261c78bf6a5ac61491b8eb037767cb104dc3cf2 /gst
parentad14b96c79f038d5d9c038a5330714ec8528133a (diff)
downloadgstreamer-plugins-bad-c5c44628fcd4adbcc9d84f12e54f957b3b52a733.tar.gz
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.
Diffstat (limited to 'gst')
-rw-r--r--gst/videoparsers/gstmpegvideoparse.c68
-rw-r--r--gst/videoparsers/gstmpegvideoparse.h11
2 files changed, 52 insertions, 27 deletions
diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c
index c8898af72..a6be18ef1 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 47ad4ceec..e00e9c864 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 */