From: <sl...@ke...> - 2010-04-02 16:52:33
|
Module: gst-plugins-good Branch: master Commit: d6dcd70b4c6daa7254b4c1248d04ec5a2fbea794 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=d6dcd70b4c6daa7254b4c1248d04ec5a2fbea794 Author: Arun Raghavan <for...@ge...> Date: Thu Apr 1 18:35:09 2010 +0530 qtdemux: Export h.264 level in caps This exports the h.264 level in the stream caps (as a string) which can be used to match a decoder, or as metadata. https://bugzilla.gnome.org/show_bug.cgi?id=614651 --- gst/qtdemux/qtdemux.c | 38 +++++++++++++++++++++++++++++++++++++- 1 files changed, 37 insertions(+), 1 deletions(-) diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index f8cf452..76db5bf 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -49,6 +49,7 @@ #include "gst/gst-i18n-plugin.h" +#include <glib/gprintf.h> #include <gst/tag/tag.h> #include "qtatomparser.h" @@ -5065,6 +5066,30 @@ avc_profile_idc_to_string (gint profile_idc, gint constraint_set_flags) return g_strdup (profile); } +static gchar * +avc_level_idc_to_string (gint level_idc, gint constraint_set_flags) +{ + const gchar *level = NULL; + gchar buf[4]; + gint csf3; + + csf3 = (constraint_set_flags & 0x10) >> 4; + + if (level_idc == 11 && csf3) + level = "1b"; + else { + /* Level is (level_idc / 10) */ + if (level_idc % 10 == 0) + g_sprintf (buf, "%d", level_idc / 10); + else + g_sprintf (buf, "%d.%d", level_idc / 10, level_idc % 10); + + level = buf; + } + + return g_strdup (level); +} + /* parse the traks. * With each track we associate a new QtDemuxStream that contains all the info * about the trak. @@ -5308,7 +5333,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) if (len > 0x8 && QT_FOURCC (avc_data + 0x4) == FOURCC_avcC) { GstBuffer *buf; gint size; - gchar *profile; + gchar *profile, *level; if (QT_UINT32 (avc_data) < len) size = QT_UINT32 (avc_data) - 0x8; @@ -5327,6 +5352,17 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) } } + if (size >= 4) { + /* Fourth byte is the level indication */ + level = avc_level_idc_to_string (QT_UINT8 (avc_data + 0xB), + QT_UINT8 (avc_data + 0xA)); + if (level) { + gst_caps_set_simple (stream->caps, "level", G_TYPE_STRING, + level, NULL); + g_free (level); + } + } + GST_DEBUG_OBJECT (qtdemux, "found avcC codec_data in stsd"); buf = gst_buffer_new_and_alloc (size); |