mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-05 22:12:34 +00:00
oggdemux: perform more (vorbis comment header) tag extractions
In particular, move comment header parsing to gstoggstrem.c. Thanks to Felipe Contreras. Fixes #629349 (partially).
This commit is contained in:
parent
7c4fcf776f
commit
2319c85f46
3 changed files with 132 additions and 56 deletions
|
@ -452,34 +452,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
||||||
if (bytes < 1)
|
if (bytes < 1)
|
||||||
goto empty_packet;
|
goto empty_packet;
|
||||||
|
|
||||||
if (data[0] & 1) {
|
if ((data[0] & 1) || (data[0] & 3 && pad->map.is_ogm_text)) {
|
||||||
/* We don't push header packets for OGM */
|
/* We don't push header packets for OGM */
|
||||||
cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK);
|
|
||||||
goto done;
|
|
||||||
} else if (data[0] & 3 && pad->map.is_ogm_text) {
|
|
||||||
GstTagList *tags;
|
|
||||||
|
|
||||||
/* We don't push comment packets either for text streams,
|
|
||||||
* other streams will handle the comment packets in the
|
|
||||||
* decoder */
|
|
||||||
buf = gst_buffer_new ();
|
|
||||||
|
|
||||||
GST_BUFFER_DATA (buf) = (guint8 *) data;
|
|
||||||
GST_BUFFER_SIZE (buf) = bytes;
|
|
||||||
|
|
||||||
tags = gst_tag_list_from_vorbiscomment_buffer (buf,
|
|
||||||
(const guint8 *) "\003vorbis", 7, NULL);
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
buf = NULL;
|
|
||||||
|
|
||||||
if (tags) {
|
|
||||||
GST_DEBUG_OBJECT (ogg, "tags = %" GST_PTR_FORMAT, tags);
|
|
||||||
gst_element_found_tags_for_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad),
|
|
||||||
tags);
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (ogg, "failed to extract tags from vorbis comment");
|
|
||||||
}
|
|
||||||
|
|
||||||
cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK);
|
cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -497,32 +471,9 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (pad->map.is_vp8) {
|
} else if (pad->map.is_vp8) {
|
||||||
if (packet->bytes >= 7 && memcmp (packet->packet, "OVP80\2 ", 7) == 0) {
|
if ((packet->bytes >= 7 && memcmp (packet->packet, "OVP80\2 ", 7) == 0) ||
|
||||||
GstTagList *tags;
|
packet->b_o_s ||
|
||||||
|
(packet->bytes >= 5 && memcmp (packet->packet, "OVP80", 5) == 0)) {
|
||||||
buf = gst_buffer_new ();
|
|
||||||
|
|
||||||
GST_BUFFER_DATA (buf) = (guint8 *) packet->packet;
|
|
||||||
GST_BUFFER_SIZE (buf) = packet->bytes;
|
|
||||||
|
|
||||||
tags = gst_tag_list_from_vorbiscomment_buffer (buf,
|
|
||||||
(const guint8 *) "OVP80\2 ", 7, NULL);
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
buf = NULL;
|
|
||||||
|
|
||||||
if (tags) {
|
|
||||||
GST_DEBUG_OBJECT (ogg, "tags = %" GST_PTR_FORMAT, tags);
|
|
||||||
gst_element_found_tags_for_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad),
|
|
||||||
tags);
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (ogg,
|
|
||||||
"failed to extract VP8 tags from vorbis comment");
|
|
||||||
}
|
|
||||||
/* We don't push header packets for VP8 */
|
|
||||||
cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK);
|
|
||||||
goto done;
|
|
||||||
} else if (packet->b_o_s || (packet->bytes >= 5
|
|
||||||
&& memcmp (packet->packet, "OVP80", 5) == 0)) {
|
|
||||||
/* We don't push header packets for VP8 */
|
/* We don't push header packets for VP8 */
|
||||||
cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK);
|
cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -1791,6 +1742,10 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
|
||||||
|
|
||||||
gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad));
|
gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad));
|
||||||
pad->added = TRUE;
|
pad->added = TRUE;
|
||||||
|
if (event && pad->map.taglist) {
|
||||||
|
gst_element_found_tags_for_pad (GST_ELEMENT_CAST (ogg),
|
||||||
|
GST_PAD_CAST (pad), pad->map.taglist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* prefer the index bitrate over the ones encoded in the streams */
|
/* prefer the index bitrate over the ones encoded in the streams */
|
||||||
ogg->bitrate = (idx_bitrate ? idx_bitrate : bitrate);
|
ogg->bitrate = (idx_bitrate ? idx_bitrate : bitrate);
|
||||||
|
|
|
@ -596,6 +596,32 @@ granulepos_to_key_granule_vp8 (GstOggStream * pad, gint64 granulepos)
|
||||||
static gboolean
|
static gboolean
|
||||||
is_header_vp8 (GstOggStream * pad, ogg_packet * packet)
|
is_header_vp8 (GstOggStream * pad, ogg_packet * packet)
|
||||||
{
|
{
|
||||||
|
if (packet->bytes >= 7 && memcmp (packet->packet, "OVP80\2 ", 7) == 0) {
|
||||||
|
GstBuffer *buf = NULL;
|
||||||
|
gchar *encoder = NULL;
|
||||||
|
|
||||||
|
buf = gst_buffer_new ();
|
||||||
|
|
||||||
|
GST_BUFFER_DATA (buf) = (guint8 *) packet->packet;
|
||||||
|
GST_BUFFER_SIZE (buf) = packet->bytes;
|
||||||
|
|
||||||
|
pad->taglist = gst_tag_list_from_vorbiscomment_buffer (buf,
|
||||||
|
(const guint8 *) "OVP80\2 ", 7, &encoder);
|
||||||
|
if (!pad->taglist) {
|
||||||
|
GST_ERROR_OBJECT (pad, "couldn't decode comments");
|
||||||
|
pad->taglist = gst_tag_list_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
buf = NULL;
|
||||||
|
if (encoder) {
|
||||||
|
if (encoder[0])
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_ENCODER, encoder, NULL);
|
||||||
|
g_free (encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (packet->bytes >= 5 && packet->packet[0] == 0x4F &&
|
if (packet->bytes >= 5 && packet->packet[0] == 0x4F &&
|
||||||
packet->packet[1] == 0x56 && packet->packet[2] == 0x50 &&
|
packet->packet[1] == 0x56 && packet->packet[2] == 0x50 &&
|
||||||
packet->packet[3] == 0x38 && packet->packet[4] == 0x30)
|
packet->packet[3] == 0x38 && packet->packet[4] == 0x30)
|
||||||
|
@ -611,7 +637,9 @@ setup_vorbis_mapper (GstOggStream * pad, ogg_packet * packet)
|
||||||
guint8 *data = packet->packet;
|
guint8 *data = packet->packet;
|
||||||
guint chans;
|
guint chans;
|
||||||
|
|
||||||
data += 1 + 6 + 4;
|
data += 1 + 6;
|
||||||
|
pad->version = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
chans = GST_READ_UINT8 (data);
|
chans = GST_READ_UINT8 (data);
|
||||||
data += 1;
|
data += 1;
|
||||||
pad->granulerate_n = GST_READ_UINT32_LE (data);
|
pad->granulerate_n = GST_READ_UINT32_LE (data);
|
||||||
|
@ -620,8 +648,26 @@ setup_vorbis_mapper (GstOggStream * pad, ogg_packet * packet)
|
||||||
pad->last_size = 0;
|
pad->last_size = 0;
|
||||||
GST_LOG ("sample rate: %d", pad->granulerate_n);
|
GST_LOG ("sample rate: %d", pad->granulerate_n);
|
||||||
|
|
||||||
data += 8;
|
data += 4;
|
||||||
pad->bitrate = GST_READ_UINT32_LE (data);
|
pad->bitrate_upper = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
|
pad->bitrate_nominal = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
|
pad->bitrate_lower = GST_READ_UINT32_LE (data);
|
||||||
|
|
||||||
|
if (pad->bitrate_nominal > 0 && pad->bitrate_nominal <= 0x7FFFFFFF)
|
||||||
|
pad->bitrate = pad->bitrate_nominal;
|
||||||
|
|
||||||
|
if (pad->bitrate_upper > 0 && pad->bitrate_upper <= 0x7FFFFFFF)
|
||||||
|
if (!pad->bitrate)
|
||||||
|
pad->bitrate = pad->bitrate_upper;
|
||||||
|
|
||||||
|
if (pad->bitrate_lower > 0 && pad->bitrate_lower <= 0x7FFFFFFF)
|
||||||
|
if (!pad->bitrate)
|
||||||
|
pad->bitrate = pad->bitrate_lower;
|
||||||
|
|
||||||
|
pad->taglist = NULL;
|
||||||
|
|
||||||
GST_LOG ("bit rate: %d", pad->bitrate);
|
GST_LOG ("bit rate: %d", pad->bitrate);
|
||||||
|
|
||||||
pad->n_header_packets = 3;
|
pad->n_header_packets = 3;
|
||||||
|
@ -644,6 +690,49 @@ is_header_vorbis (GstOggStream * pad, ogg_packet * packet)
|
||||||
if (packet->bytes > 0 && (packet->packet[0] & 0x01) == 0)
|
if (packet->bytes > 0 && (packet->packet[0] & 0x01) == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (((guint8 *) (packet->packet))[0] == 0x03) {
|
||||||
|
GstBuffer *buf = NULL;
|
||||||
|
gchar *encoder = NULL;
|
||||||
|
buf = gst_buffer_new ();
|
||||||
|
GST_BUFFER_DATA (buf) = (guint8 *) packet->packet;
|
||||||
|
GST_BUFFER_SIZE (buf) = packet->bytes;
|
||||||
|
|
||||||
|
pad->taglist = gst_tag_list_from_vorbiscomment_buffer (buf,
|
||||||
|
(const guint8 *) "\003vorbis", 7, &encoder);
|
||||||
|
|
||||||
|
if (!pad->taglist) {
|
||||||
|
GST_ERROR_OBJECT (pad, "couldn't decode comments");
|
||||||
|
pad->taglist = gst_tag_list_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
buf = NULL;
|
||||||
|
if (encoder) {
|
||||||
|
if (encoder[0])
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_ENCODER, encoder, NULL);
|
||||||
|
g_free (encoder);
|
||||||
|
}
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_ENCODER_VERSION, pad->version, NULL);
|
||||||
|
|
||||||
|
if (pad->bitrate_nominal > 0 && pad->bitrate_nominal <= 0x7FFFFFFF)
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_NOMINAL_BITRATE, (guint) pad->bitrate_nominal, NULL);
|
||||||
|
|
||||||
|
if (pad->bitrate_upper > 0 && pad->bitrate_upper <= 0x7FFFFFFF)
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_MAXIMUM_BITRATE, (guint) pad->bitrate_upper, NULL);
|
||||||
|
|
||||||
|
if (pad->bitrate_lower > 0 && pad->bitrate_lower <= 0x7FFFFFFF)
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_MINIMUM_BITRATE, (guint) pad->bitrate_lower, NULL);
|
||||||
|
|
||||||
|
if (pad->bitrate)
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_BITRATE, (guint) pad->bitrate, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (packet->packet[0] == 5) {
|
if (packet->packet[0] == 5) {
|
||||||
parse_vorbis_setup_packet (pad, packet);
|
parse_vorbis_setup_packet (pad, packet);
|
||||||
}
|
}
|
||||||
|
@ -1204,6 +1293,32 @@ gst_ogg_map_search_index (GstOggStream * pad, gboolean before,
|
||||||
static gboolean
|
static gboolean
|
||||||
is_header_ogm (GstOggStream * pad, ogg_packet * packet)
|
is_header_ogm (GstOggStream * pad, ogg_packet * packet)
|
||||||
{
|
{
|
||||||
|
if (!(packet->packet[0] & 1) && (packet->packet[0] & 3 && pad->is_ogm_text)) {
|
||||||
|
GstBuffer *buf = NULL;
|
||||||
|
gchar *encoder = NULL;
|
||||||
|
|
||||||
|
buf = gst_buffer_new ();
|
||||||
|
GST_BUFFER_DATA (buf) = (guint8 *) packet->packet;
|
||||||
|
GST_BUFFER_SIZE (buf) = packet->bytes;;
|
||||||
|
|
||||||
|
pad->taglist = gst_tag_list_from_vorbiscomment_buffer (buf,
|
||||||
|
(const guint8 *) "\003vorbis", 7, &encoder);
|
||||||
|
|
||||||
|
if (!pad->taglist) {
|
||||||
|
GST_ERROR ("couldn't decode comments");
|
||||||
|
pad->taglist = gst_tag_list_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
buf = NULL;
|
||||||
|
if (encoder) {
|
||||||
|
if (encoder[0])
|
||||||
|
gst_tag_list_add (pad->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
|
GST_TAG_ENCODER, encoder, NULL);
|
||||||
|
g_free (encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (packet->bytes >= 1 && (packet->packet[0] & 0x01))
|
if (packet->bytes >= 1 && (packet->packet[0] & 0x01))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <ogg/ogg.h>
|
#include <ogg/ogg.h>
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/tag/tag.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -79,6 +80,11 @@ struct _GstOggStream
|
||||||
int vorbis_log2_num_modes;
|
int vorbis_log2_num_modes;
|
||||||
int vorbis_mode_sizes[256];
|
int vorbis_mode_sizes[256];
|
||||||
int last_size;
|
int last_size;
|
||||||
|
int version;
|
||||||
|
long bitrate_upper;
|
||||||
|
long bitrate_nominal;
|
||||||
|
long bitrate_lower;
|
||||||
|
GstTagList *taglist;
|
||||||
/* theora stuff */
|
/* theora stuff */
|
||||||
gboolean theora_has_zero_keyoffset;
|
gboolean theora_has_zero_keyoffset;
|
||||||
/* VP8 stuff */
|
/* VP8 stuff */
|
||||||
|
|
Loading…
Reference in a new issue