From a344cfba2720a447bf354066dec4aaeb3b6c4d05 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Thu, 22 Apr 2010 12:27:35 +0200 Subject: [PATCH] rtpvorbisdepay: also accept in-line configuration Fixes #574416 (vorbis). --- gst/rtp/gstrtpvorbisdepay.c | 70 ++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/gst/rtp/gstrtpvorbisdepay.c b/gst/rtp/gstrtpvorbisdepay.c index acb76305e0..622418ce03 100644 --- a/gst/rtp/gstrtpvorbisdepay.c +++ b/gst/rtp/gstrtpvorbisdepay.c @@ -152,25 +152,20 @@ gst_rtp_vorbis_depay_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } +/* takes ownership of confbuf */ static gboolean gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay, - const gchar * configuration) + GstBuffer * confbuf) { GstBuffer *buf; guint32 num_headers; guint8 *data; - GstBuffer *confbuf; - gsize size; + guint size; guint offset; gint i, j; - /* deserialize base64 to buffer */ - data = g_base64_decode (configuration, &size); - - confbuf = gst_buffer_new (); - GST_BUFFER_DATA (confbuf) = data; - GST_BUFFER_MALLOCDATA (confbuf) = data; - GST_BUFFER_SIZE (confbuf) = size; + data = GST_BUFFER_DATA (confbuf); + size = GST_BUFFER_SIZE (confbuf); GST_DEBUG_OBJECT (rtpvorbisdepay, "config size %" G_GSIZE_FORMAT, size); @@ -242,6 +237,8 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay, "header %d, ident 0x%08x, length %u, left %" G_GSIZE_FORMAT, i, ident, length, size); + /* FIXME check if we already got this ident */ + if (size < length) goto too_small; @@ -308,6 +305,29 @@ too_small: } } +static gboolean +gst_rtp_vorbis_depay_parse_inband_configuration (GstRtpVorbisDepay * + rtpvorbisdepay, guint ident, guint8 * configuration, guint size) +{ + GstBuffer *confbuf; + guint8 *conf; + + if (G_UNLIKELY (size < 4)) + return FALSE; + + /* transform inline to out-of-band and parse that one */ + confbuf = gst_buffer_new_and_alloc (size + 3); + conf = GST_BUFFER_DATA (confbuf); + /* 1 header */ + GST_WRITE_UINT32_BE (conf, 1); + /* write Ident */ + GST_WRITE_UINT24_BE (conf + 4, ident); + /* copy remainder */ + memcpy (conf + 7, configuration + 4, size - 4); + + return gst_rtp_vorbis_depay_parse_configuration (rtpvorbisdepay, confbuf); +} + static gboolean gst_rtp_vorbis_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) { @@ -329,8 +349,18 @@ gst_rtp_vorbis_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) /* read and parse configuration string */ configuration = gst_structure_get_string (structure, "configuration"); if (configuration) { - if (!gst_rtp_vorbis_depay_parse_configuration (rtpvorbisdepay, - configuration)) + GstBuffer *confbuf; + guint8 *data; + gsize size; + + /* deserialize base64 to buffer */ + data = g_base64_decode (configuration, &size); + + confbuf = gst_buffer_new (); + GST_BUFFER_DATA (confbuf) = data; + GST_BUFFER_MALLOCDATA (confbuf) = data; + GST_BUFFER_SIZE (confbuf) = size; + if (!gst_rtp_vorbis_depay_parse_configuration (rtpvorbisdepay, confbuf)) goto invalid_configuration; } else { GST_WARNING_OBJECT (rtpvorbisdepay, "no configuration specified"); @@ -540,6 +570,15 @@ gst_rtp_vorbis_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) if (G_UNLIKELY (length > payload_len)) goto length_short; + /* handle in-band configuration */ + if (G_UNLIKELY (VDT == 1)) { + GST_DEBUG_OBJECT (rtpvorbisdepay, "in-band configuration"); + if (!gst_rtp_vorbis_depay_parse_inband_configuration (rtpvorbisdepay, + ident, payload, payload_len)) + goto invalid_configuration; + goto no_output; + } + /* create buffer for packet */ if (G_UNLIKELY (to_free)) { outbuf = gst_buffer_new (); @@ -601,6 +640,13 @@ length_short: (NULL), ("Packet contains invalid data")); return NULL; } +invalid_configuration: + { + /* fatal, as we otherwise risk carrying on without output */ + GST_ELEMENT_ERROR (rtpvorbisdepay, STREAM, DECODE, + (NULL), ("Packet contains invalid configuration")); + return NULL; + } } static GstStateChangeReturn