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
This commit is contained in:
Arun Raghavan 2010-04-18 14:51:35 +05:30 committed by Sebastian Dröge
parent 49a85930c5
commit bf586d7966
3 changed files with 60 additions and 2 deletions

View file

@ -498,7 +498,6 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end)
case MPEG_PACKET_EXT_SEQUENCE: case MPEG_PACKET_EXT_SEQUENCE:
{ {
/* Parse a Sequence Extension */ /* Parse a Sequence Extension */
guint8 profile_level;
gboolean low_delay; gboolean low_delay;
guint8 chroma_format; guint8 chroma_format;
guint8 horiz_size_ext, vert_size_ext; 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 */ /* need at least 10 bytes, minus 4 for the start code 000001b5 */
return FALSE; 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; hdr->progressive = data[1] & 0x08;
chroma_format = (data[1] >> 2) & 0x03; chroma_format = (data[1] >> 2) & 0x03;
horiz_size_ext = ((data[1] << 1) & 0x02) | ((data[2] >> 7) & 0x01); horiz_size_ext = ((data[1] << 1) & 0x02) | ((data[2] >> 7) & 0x01);

View file

@ -78,6 +78,8 @@ struct MPEGSeqHdr
gint fps_n, fps_d; gint fps_n, fps_d;
/* Bitrate */ /* Bitrate */
guint bitrate; guint bitrate;
/* Profile and level */
guint profile, level;
gboolean progressive; gboolean progressive;
}; };

View file

@ -250,6 +250,17 @@ mpegvideoparse_handle_sequence (MpegVideoParse * mpegvideoparse,
if (memcmp (&mpegvideoparse->seq_hdr, &new_hdr, sizeof (MPEGSeqHdr)) != 0) { if (memcmp (&mpegvideoparse->seq_hdr, &new_hdr, sizeof (MPEGSeqHdr)) != 0) {
GstCaps *caps; GstCaps *caps;
GstBuffer *seq_buf; 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 /* Store the entire sequence header + sequence header extension
for output as codec_data */ for output as codec_data */
@ -268,6 +279,51 @@ mpegvideoparse_handle_sequence (MpegVideoParse * mpegvideoparse,
"interlaced", G_TYPE_BOOLEAN, !new_hdr.progressive, "interlaced", G_TYPE_BOOLEAN, !new_hdr.progressive,
"codec_data", GST_TYPE_BUFFER, seq_buf, NULL); "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); GST_DEBUG ("New mpegvideoparse caps: %" GST_PTR_FORMAT, caps);
if (!gst_pad_set_caps (mpegvideoparse->srcpad, caps)) { if (!gst_pad_set_caps (mpegvideoparse->srcpad, caps)) {
gst_caps_unref (caps); gst_caps_unref (caps);