From bf586d796692d0e2be5b6e601cce8d0c7346695d Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Sun, 18 Apr 2010 14:51:35 +0530 Subject: [PATCH] mpegvideoparse: Export profile and level in caps This exports profile and level in caps for MPEG 2 streams. https://bugzilla.gnome.org/show_bug.cgi?id=616078 --- gst/mpegvideoparse/mpegpacketiser.c | 4 +-- gst/mpegvideoparse/mpegpacketiser.h | 2 ++ gst/mpegvideoparse/mpegvideoparse.c | 56 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/gst/mpegvideoparse/mpegpacketiser.c b/gst/mpegvideoparse/mpegpacketiser.c index 5b4381c9fe..7bb7e9144c 100644 --- a/gst/mpegvideoparse/mpegpacketiser.c +++ b/gst/mpegvideoparse/mpegpacketiser.c @@ -498,7 +498,6 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) case MPEG_PACKET_EXT_SEQUENCE: { /* Parse a Sequence Extension */ - guint8 profile_level; gboolean low_delay; guint8 chroma_format; guint8 horiz_size_ext, vert_size_ext; @@ -508,7 +507,8 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) /* need at least 10 bytes, minus 4 for the start code 000001b5 */ return FALSE; - profile_level = ((data[0] << 4) & 0xf0) | ((data[1]) >> 4); + hdr->profile = data[0] & 0x0f; /* profile (0:2) + escape bit (3) */ + hdr->level = (data[1] >> 4) & 0x0f; hdr->progressive = data[1] & 0x08; chroma_format = (data[1] >> 2) & 0x03; horiz_size_ext = ((data[1] << 1) & 0x02) | ((data[2] >> 7) & 0x01); diff --git a/gst/mpegvideoparse/mpegpacketiser.h b/gst/mpegvideoparse/mpegpacketiser.h index 72f6fd3b8f..88b1ca58a9 100644 --- a/gst/mpegvideoparse/mpegpacketiser.h +++ b/gst/mpegvideoparse/mpegpacketiser.h @@ -78,6 +78,8 @@ struct MPEGSeqHdr gint fps_n, fps_d; /* Bitrate */ guint bitrate; + /* Profile and level */ + guint profile, level; gboolean progressive; }; diff --git a/gst/mpegvideoparse/mpegvideoparse.c b/gst/mpegvideoparse/mpegvideoparse.c index e3a665db6c..d1a0d507f3 100644 --- a/gst/mpegvideoparse/mpegvideoparse.c +++ b/gst/mpegvideoparse/mpegvideoparse.c @@ -250,6 +250,17 @@ mpegvideoparse_handle_sequence (MpegVideoParse * mpegvideoparse, if (memcmp (&mpegvideoparse->seq_hdr, &new_hdr, sizeof (MPEGSeqHdr)) != 0) { GstCaps *caps; GstBuffer *seq_buf; + /* + * Profile indication - 1 => High, 2 => Spatially Scalable, + * 3 => SNR Scalable, 4 => Main, 5 => Simple + * 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1 + */ + const gchar *profiles[] = { "HP", "Spatial", "SNR", "MP", "SP" }; + /* + * Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low, + * except in the case of profile = 0 + */ + const gchar *levels[] = { "HL", "H-14", "ML", "LL" }; /* Store the entire sequence header + sequence header extension for output as codec_data */ @@ -268,6 +279,51 @@ mpegvideoparse_handle_sequence (MpegVideoParse * mpegvideoparse, "interlaced", G_TYPE_BOOLEAN, !new_hdr.progressive, "codec_data", GST_TYPE_BUFFER, seq_buf, NULL); + if (new_hdr.mpeg_version == 2) { + const gchar *profile = NULL, *level = NULL; + + if (new_hdr.profile > 0 && new_hdr.profile < 6) + profile = profiles[new_hdr.profile - 1]; + + if ((new_hdr.level > 3) && (new_hdr.level < 11) && + (new_hdr.level % 2 == 0)) + level = levels[(new_hdr.level >> 1) - 1]; + + if (new_hdr.profile == 8) { + /* Non-hierarchical profile */ + switch (new_hdr.level) { + case 2: + level = levels[0]; + case 5: + level = levels[2]; + profile = "422P"; + break; + case 10: + level = levels[0]; + case 11: + level = levels[1]; + case 13: + level = levels[2]; + case 14: + level = levels[3]; + profile = "MVP"; + break; + default: + break; + } + } + + if (profile) + gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL); + else + GST_DEBUG ("Invalid profile - %u", new_hdr.profile); + + if (level) + gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL); + else + GST_DEBUG ("Invalid level - %u", new_hdr.level); + } + GST_DEBUG ("New mpegvideoparse caps: %" GST_PTR_FORMAT, caps); if (!gst_pad_set_caps (mpegvideoparse->srcpad, caps)) { gst_caps_unref (caps);