summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-03-09 18:07:20 +0100
committerWim Taymans <wim.taymans@collabora.co.uk>2009-03-09 18:07:20 +0100
commit06efeff5d979576a252e5dae57f46d6445b1df12 (patch)
treeae0046b0936142016b85c960e736c77b826a8342
parent8f8e035cd5794658a359d7233fe67f48f5d77b2c (diff)
vorbisdepay: fix some leaks
And leak the codebooks. Use glib base64 decoders. Use subbuffers to avoid a memcpy of the headers.
-rw-r--r--gst/rtp/gstrtpvorbisdepay.c105
1 files changed, 50 insertions, 55 deletions
diff --git a/gst/rtp/gstrtpvorbisdepay.c b/gst/rtp/gstrtpvorbisdepay.c
index e96bc2b5..d1f25765 100644
--- a/gst/rtp/gstrtpvorbisdepay.c
+++ b/gst/rtp/gstrtpvorbisdepay.c
@@ -119,62 +119,41 @@ gst_rtp_vorbis_depay_init (GstRtpVorbisDepay * rtpvorbisdepay,
{
rtpvorbisdepay->adapter = gst_adapter_new ();
}
+
static void
-gst_rtp_vorbis_depay_finalize (GObject * object)
+free_config (GstRtpVorbisConfig * conf)
{
- GstRtpVorbisDepay *rtpvorbisdepay = GST_RTP_VORBIS_DEPAY (object);
+ GList *headers;
- g_object_unref (rtpvorbisdepay->adapter);
+ for (headers = conf->headers; headers; headers = g_list_next (headers)) {
+ GstBuffer *header = GST_BUFFER_CAST (headers->data);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ gst_buffer_unref (header);
+ }
+ g_list_free (conf->headers);
+ g_free (conf);
}
-static const guint8 a2bin[256] = {
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
- 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
- 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
-};
-
-static guint
-decode_base64 (const gchar * in, guint8 * out)
+static void
+free_indents (GstRtpVorbisDepay * rtpvorbisdepay)
{
- guint8 v1, v2;
- guint len = 0;
-
- v1 = a2bin[(gint) * in];
- while (v1 <= 63) {
- /* read 4 bytes, write 3 bytes, invalid base64 are zeroes */
- v2 = a2bin[(gint) * ++in];
- *out++ = (v1 << 2) | ((v2 & 0x3f) >> 4);
- v1 = (v2 > 63 ? 64 : a2bin[(gint) * ++in]);
- *out++ = (v2 << 4) | ((v1 & 0x3f) >> 2);
- v2 = (v1 > 63 ? 64 : a2bin[(gint) * ++in]);
- *out++ = (v1 << 6) | (v2 & 0x3f);
- v1 = (v2 > 63 ? 64 : a2bin[(gint) * ++in]);
- len += 3;
+ GList *walk;
+
+ for (walk = rtpvorbisdepay->configs; walk; walk = g_list_next (walk)) {
+ free_config ((GstRtpVorbisConfig *) walk->data);
}
- /* move to '\0' */
- while (*in != '\0')
- in++;
+ g_list_free (rtpvorbisdepay->configs);
+ rtpvorbisdepay->configs = NULL;
+}
- /* subtract padding */
- while (len > 0 && *--in == '=')
- len--;
+static void
+gst_rtp_vorbis_depay_finalize (GObject * object)
+{
+ GstRtpVorbisDepay *rtpvorbisdepay = GST_RTP_VORBIS_DEPAY (object);
- return len;
+ g_object_unref (rtpvorbisdepay->adapter);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
@@ -184,15 +163,18 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
GstBuffer *buf;
guint32 num_headers;
guint8 *data;
- guint size;
+ GstBuffer *confbuf;
+ gsize size;
+ guint offset;
gint i, j;
/* deserialize base64 to buffer */
- size = strlen (configuration);
- GST_DEBUG_OBJECT (rtpvorbisdepay, "base64 config size %u", size);
+ data = g_base64_decode (configuration, &size);
- data = g_malloc (size);
- size = decode_base64 (configuration, data);
+ confbuf = gst_buffer_new ();
+ GST_BUFFER_DATA (confbuf) = data;
+ GST_BUFFER_MALLOCDATA (confbuf) = data;
+ GST_BUFFER_SIZE (confbuf) = size;
GST_DEBUG_OBJECT (rtpvorbisdepay, "config size %u", size);
@@ -215,6 +197,7 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
num_headers = GST_READ_UINT32_BE (data);
size -= 4;
data += 4;
+ offset = 4;
GST_DEBUG_OBJECT (rtpvorbisdepay, "have %u headers", num_headers);
@@ -257,6 +240,7 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
n_headers = data[5];
size -= 6;
data += 6;
+ offset += 6;
GST_DEBUG_OBJECT (rtpvorbisdepay,
"header %d, ident 0x%08x, length %u, left %u", i, ident, length, size);
@@ -275,10 +259,15 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
if (size < 1)
goto too_small;
b = *data++;
+ offset++;
size--;
h_size = (h_size << 7) | (b & 0x7f);
} while (b & 0x80);
GST_DEBUG_OBJECT (rtpvorbisdepay, "headers %d: size: %u", j, h_size);
+
+ if (length < h_size)
+ goto too_small;
+
h_sizes[j] = h_size;
length -= h_size;
}
@@ -294,20 +283,22 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
guint h_size;
h_size = h_sizes[j];
- if (size < h_size)
+ if (size < h_size) {
+ free_config (conf);
goto too_small;
+ }
GST_DEBUG_OBJECT (rtpvorbisdepay, "reading header %d, size %u", j,
h_size);
- buf = gst_buffer_new_and_alloc (h_size);
- memcpy (GST_BUFFER_DATA (buf), data, h_size);
+ buf = gst_buffer_create_sub (confbuf, offset, h_size);
conf->headers = g_list_append (conf->headers, buf);
- data += h_size;
+ offset += h_size;
size -= h_size;
}
rtpvorbisdepay->configs = g_list_append (rtpvorbisdepay->configs, conf);
}
+ gst_buffer_unref (confbuf);
return TRUE;
@@ -315,6 +306,7 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
too_small:
{
GST_DEBUG_OBJECT (rtpvorbisdepay, "configuration too small");
+ gst_buffer_unref (confbuf);
return FALSE;
}
}
@@ -637,6 +629,9 @@ gst_rtp_vorbis_depay_change_state (GstElement * element,
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ free_indents (rtpvorbisdepay);
+ break;
case GST_STATE_CHANGE_READY_TO_NULL:
break;
default: