mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
qtdemux: Post avg./max. bitrate tags for H.264
This reads the average and maximum bitrates from the 'btrt' atom if available, and pushes these as tags, https://bugzilla.gnome.org/show_bug.cgi?id=614927
This commit is contained in:
parent
7cf9967e0b
commit
861311e8f6
2 changed files with 71 additions and 30 deletions
|
@ -5342,45 +5342,85 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
|
|||
const guint8 *avc_data = stsd_data + 0x66;
|
||||
|
||||
/* find avcC */
|
||||
while (len >= 0x8 &&
|
||||
QT_FOURCC (avc_data + 0x4) != FOURCC_avcC &&
|
||||
QT_UINT32 (avc_data) < len) {
|
||||
len -= QT_UINT32 (avc_data);
|
||||
avc_data += QT_UINT32 (avc_data);
|
||||
}
|
||||
|
||||
/* parse, if found */
|
||||
if (len > 0x8 && QT_FOURCC (avc_data + 0x4) == FOURCC_avcC) {
|
||||
GstBuffer *buf;
|
||||
while (len >= 0x8) {
|
||||
gint size;
|
||||
gchar *profile = NULL, *level = NULL;
|
||||
|
||||
if (QT_UINT32 (avc_data) < len)
|
||||
if (QT_UINT32 (avc_data) <= len)
|
||||
size = QT_UINT32 (avc_data) - 0x8;
|
||||
else
|
||||
size = len - 0x8;
|
||||
|
||||
avc_get_profile_and_level_string (avc_data + 0x8, size, &profile,
|
||||
&level);
|
||||
if (profile) {
|
||||
gst_caps_set_simple (stream->caps, "profile", G_TYPE_STRING,
|
||||
profile, NULL);
|
||||
g_free (profile);
|
||||
}
|
||||
if (level) {
|
||||
gst_caps_set_simple (stream->caps, "level", G_TYPE_STRING,
|
||||
level, NULL);
|
||||
g_free (level);
|
||||
if (size < 1)
|
||||
/* No real data, so break out */
|
||||
break;
|
||||
|
||||
switch (QT_FOURCC (avc_data + 0x4)) {
|
||||
case FOURCC_avcC:
|
||||
{
|
||||
/* parse, if found */
|
||||
GstBuffer *buf;
|
||||
gchar *profile = NULL, *level = NULL;
|
||||
|
||||
avc_get_profile_and_level_string (avc_data + 0x8, size,
|
||||
&profile, &level);
|
||||
if (profile) {
|
||||
gst_caps_set_simple (stream->caps, "profile", G_TYPE_STRING,
|
||||
profile, NULL);
|
||||
g_free (profile);
|
||||
}
|
||||
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);
|
||||
memcpy (GST_BUFFER_DATA (buf), avc_data + 0x8, size);
|
||||
gst_caps_set_simple (stream->caps,
|
||||
"codec_data", GST_TYPE_BUFFER, buf, NULL);
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
break;
|
||||
}
|
||||
case FOURCC_btrt:
|
||||
{
|
||||
guint avg_bitrate, max_bitrate;
|
||||
|
||||
/* bufferSizeDB, maxBitrate and avgBitrate - 4 bytes each */
|
||||
if (size < 12)
|
||||
break;
|
||||
|
||||
max_bitrate = QT_UINT32 (avc_data + 0xc);
|
||||
avg_bitrate = QT_UINT32 (avc_data + 0x10);
|
||||
|
||||
if (!max_bitrate && !avg_bitrate)
|
||||
break;
|
||||
|
||||
if (!list)
|
||||
list = gst_tag_list_new ();
|
||||
|
||||
if (max_bitrate > 0 && max_bitrate < G_MAXUINT32) {
|
||||
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
|
||||
GST_TAG_MAXIMUM_BITRATE, max_bitrate, NULL);
|
||||
}
|
||||
if (avg_bitrate > 0 && avg_bitrate < G_MAXUINT32) {
|
||||
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
|
||||
GST_TAG_BITRATE, avg_bitrate, NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (qtdemux, "found avcC codec_data in stsd");
|
||||
|
||||
buf = gst_buffer_new_and_alloc (size);
|
||||
memcpy (GST_BUFFER_DATA (buf), avc_data + 0x8, size);
|
||||
gst_caps_set_simple (stream->caps,
|
||||
"codec_data", GST_TYPE_BUFFER, buf, NULL);
|
||||
gst_buffer_unref (buf);
|
||||
len -= QT_UINT32 (avc_data);
|
||||
avc_data += QT_UINT32 (avc_data);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FOURCC_mjp2:
|
||||
|
|
|
@ -136,6 +136,7 @@ G_BEGIN_DECLS
|
|||
#define FOURCC_drmi GST_MAKE_FOURCC('d','r','m','i')
|
||||
#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1')
|
||||
#define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C')
|
||||
#define FOURCC_btrt GST_MAKE_FOURCC('b','t','r','t')
|
||||
#define FOURCC_VP31 GST_MAKE_FOURCC('V','P','3','1')
|
||||
#define FOURCC_rle_ GST_MAKE_FOURCC('r','l','e',' ')
|
||||
#define FOURCC_MAC6 GST_MAKE_FOURCC('M','A','C','6')
|
||||
|
|
Loading…
Reference in a new issue