mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
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:
parent
49a85930c5
commit
bf586d7966
3 changed files with 60 additions and 2 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue