summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-04-22 10:28:22 (GMT)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-04-30 11:54:56 (GMT)
commitbe5ffd96fe4289a37a34df289b1f98975acff293 (patch)
tree4908909d6e05e7c1f997551dc0156dc8fa84e31a
parenta344cfba2720a447bf354066dec4aaeb3b6c4d05 (diff)
rtptheoradepay: also accept in-band configuration
Fixes #574416 (theora).
-rw-r--r--gst/rtp/gstrtptheoradepay.c84
1 files changed, 66 insertions, 18 deletions
diff --git a/gst/rtp/gstrtptheoradepay.c b/gst/rtp/gstrtptheoradepay.c
index 226e85f..a1e9749 100644
--- a/gst/rtp/gstrtptheoradepay.c
+++ b/gst/rtp/gstrtptheoradepay.c
@@ -126,20 +126,16 @@ gst_rtp_theora_depay_finalize (GObject * object)
static gboolean
gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay,
- const gchar * configuration)
+ GstBuffer * confbuf)
{
GstBuffer *buf;
guint32 num_headers;
guint8 *data;
- gsize size;
+ guint size;
gint i, j;
- /* deserialize base64 to buffer */
- size = strlen (configuration);
- GST_DEBUG_OBJECT (rtptheoradepay, "base64 config size %" G_GSIZE_FORMAT,
- size);
-
- data = g_base64_decode (configuration, &size);
+ data = GST_BUFFER_DATA (confbuf);
+ size = GST_BUFFER_SIZE (confbuf);
GST_DEBUG_OBJECT (rtptheoradepay, "config size %" G_GSIZE_FORMAT, size);
@@ -209,6 +205,8 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay,
"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;
@@ -267,6 +265,29 @@ too_small:
}
static gboolean
+gst_rtp_theora_depay_parse_inband_configuration (GstRtpTheoraDepay *
+ rtptheoradepay, 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_theora_depay_parse_configuration (rtptheoradepay, confbuf);
+}
+
+static gboolean
gst_rtp_theora_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
{
GstStructure *structure;
@@ -285,25 +306,36 @@ gst_rtp_theora_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
if (delivery_method == NULL)
goto no_delivery_method;
+ /* read and parse configuration string */
+ configuration = gst_structure_get_string (structure, "configuration");
if (!g_ascii_strcasecmp (delivery_method, "inline")) {
- /* configure string is in the caps */
+ GstBuffer *confbuf;
+ guint8 *data;
+ gsize size;
+
+ /* configure string should be in the caps */
+ if (configuration == NULL)
+ goto no_configuration;
+
+ /* 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_theora_depay_parse_configuration (rtptheoradepay, confbuf))
+ goto invalid_configuration;
} else if (!g_ascii_strcasecmp (delivery_method, "in_band")) {
/* headers will (also) be transmitted in the RTP packets */
- goto unsupported_delivery_method;
+ GST_DEBUG_OBJECT (rtptheoradepay, "expecting in_band configuration");
} else if (g_str_has_prefix (delivery_method, "out_band/")) {
/* some other method of header delivery. */
goto unsupported_delivery_method;
} else
goto unsupported_delivery_method;
- /* read and parse configuration string */
- configuration = gst_structure_get_string (structure, "configuration");
- if (configuration == NULL)
- goto no_configuration;
-
- if (!gst_rtp_theora_depay_parse_configuration (rtptheoradepay, configuration))
- goto invalid_configuration;
-
/* set caps on pad and on header */
srccaps = gst_caps_new_simple ("video/x-theora", NULL);
res = gst_pad_set_caps (depayload->srcpad, srccaps);
@@ -515,6 +547,15 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (G_UNLIKELY (length > payload_len))
goto length_short;
+ /* handle in-band configuration */
+ if (G_UNLIKELY (TDT == 1)) {
+ GST_DEBUG_OBJECT (rtptheoradepay, "in-band configuration");
+ if (!gst_rtp_theora_depay_parse_inband_configuration (rtptheoradepay,
+ ident, payload, payload_len))
+ goto invalid_configuration;
+ goto no_output;
+ }
+
/* create buffer for packet */
if (G_UNLIKELY (to_free)) {
outbuf = gst_buffer_new ();
@@ -576,6 +617,13 @@ length_short:
(NULL), ("Packet contains invalid data"));
return NULL;
}
+invalid_configuration:
+ {
+ /* fatal, as we otherwise risk carrying on without output */
+ GST_ELEMENT_ERROR (rtptheoradepay, STREAM, DECODE,
+ (NULL), ("Packet contains invalid configuration"));
+ return NULL;
+ }
}
gboolean