summaryrefslogtreecommitdiffstats
path: root/gst/rtsp
diff options
context:
space:
mode:
authorjp.liu <jp_liu@astrocom.cn>2007-02-14 15:24:50 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-02-14 15:24:50 +0000
commit6021b924655550c1b8f185920452c64665a04cf4 (patch)
tree94c821f582bcdb215654333a15db4d086d3d5044 /gst/rtsp
parentd08a7da76b99ebe6c67ba3a76aaaa346298f0b09 (diff)
gst/rtsp/sdpmessage.*: Fix memory management of SDP messages. Fixes #407793.
Original commit message from CVS: * gst/rtsp/sdpmessage.c: (sdp_origin_init), (sdp_connection_init), (sdp_bandwidth_init), (sdp_time_init), (sdp_zone_init), (sdp_key_init), (sdp_attribute_init), (sdp_message_init), (sdp_message_uninit), (sdp_message_free), (sdp_media_init), (sdp_media_uninit), (sdp_media_free), (sdp_message_add_media), (sdp_parse_line): * gst/rtsp/sdpmessage.h: Based on patch by: jp.liu <jp_liu at astrocom dot cn> Fix memory management of SDP messages. Fixes #407793.
Diffstat (limited to 'gst/rtsp')
-rw-r--r--gst/rtsp/sdpmessage.c234
-rw-r--r--gst/rtsp/sdpmessage.h10
2 files changed, 204 insertions, 40 deletions
diff --git a/gst/rtsp/sdpmessage.c b/gst/rtsp/sdpmessage.c
index 1277bdc1..1adc6d77 100644
--- a/gst/rtsp/sdpmessage.c
+++ b/gst/rtsp/sdpmessage.c
@@ -57,11 +57,15 @@ G_STMT_START { \
} G_STMT_END
#define REPLACE_STRING(field,val) FREE_STRING(field);field=g_strdup (val);
-#define INIT_ARRAY(field,type) \
-G_STMT_START { \
- if (field) \
- g_array_set_size (field,0); \
- else \
+#define INIT_ARRAY(field,type,init_func) \
+G_STMT_START { \
+ if (field) { \
+ gint i; \
+ for(i=0; i<field->len; i++) \
+ init_func (&g_array_index(field, type, i)); \
+ g_array_set_size (field,0); \
+ } \
+ else \
field = g_array_new (FALSE, TRUE, sizeof(type)); \
} G_STMT_END
@@ -95,8 +99,71 @@ RTSPResult sdp_message_add_##method (SDPMessage *msg, type val) { \
return RTSP_OK; \
}
+static void
+sdp_origin_init (SDPOrigin * origin)
+{
+ FREE_STRING (origin->username);
+ FREE_STRING (origin->sess_id);
+ FREE_STRING (origin->sess_version);
+ FREE_STRING (origin->nettype);
+ FREE_STRING (origin->addrtype);
+ FREE_STRING (origin->addr);
+}
+
+static void
+sdp_connection_init (SDPConnection * connection)
+{
+ FREE_STRING (connection->nettype);
+ FREE_STRING (connection->addrtype);
+ FREE_STRING (connection->address);
+ connection->ttl = 0;
+ connection->addr_number = 0;
+}
+
+static void
+sdp_bandwidth_init (SDPBandwidth * bandwidth)
+{
+ FREE_STRING (bandwidth->bwtype);
+ bandwidth->bandwidth = 0;
+}
+
+static void
+sdp_time_init (SDPTime * time)
+{
+ FREE_STRING (time->start);
+ FREE_STRING (time->stop);
+ time->n_repeat = 0;
+}
+
+static void
+sdp_zone_init (SDPZone * zone)
+{
+ FREE_STRING (zone->time);
+ FREE_STRING (zone->typed_time);
+}
+
+static void
+sdp_key_init (SDPKey * key)
+{
+ FREE_STRING (key->type);
+ FREE_STRING (key->data);
+}
+static void
+sdp_attribute_init (SDPAttribute * attr)
+{
+ FREE_STRING (attr->key);
+ FREE_STRING (attr->value);
+}
+/**
+ * sdp_message_new:
+ * @msg: pointer to new #SDPMessage
+ *
+ * Allocate a new SDPMessage and store the result in @msg.
+ *
+ * Returns: a #RTSPResult.
+ */
RTSPResult
sdp_message_new (SDPMessage ** msg)
{
@@ -111,44 +178,56 @@ sdp_message_new (SDPMessage ** msg)
return sdp_message_init (newmsg);
}
+/**
+ * sdp_message_init:
+ * @msg: an #SDPMessage
+ *
+ * Initialize @msg so that its contents are as if it was freshly allocated
+ * with sdp_message_new(). This function is mostly used to initialize a message
+ * allocated on the stack. sdp_message_uninit() undoes this operation.
+ *
+ * Returns: a #RTSPResult.
+ */
RTSPResult
sdp_message_init (SDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
FREE_STRING (msg->version);
- FREE_STRING (msg->origin.username);
- FREE_STRING (msg->origin.sess_id);
- FREE_STRING (msg->origin.sess_version);
- FREE_STRING (msg->origin.nettype);
- FREE_STRING (msg->origin.addrtype);
- FREE_STRING (msg->origin.addr);
+ sdp_origin_init (&msg->origin);
FREE_STRING (msg->session_name);
FREE_STRING (msg->information);
FREE_STRING (msg->uri);
- INIT_ARRAY (msg->emails, gchar *);
- INIT_ARRAY (msg->phones, gchar *);
- FREE_STRING (msg->connection.nettype);
- FREE_STRING (msg->connection.addrtype);
- FREE_STRING (msg->connection.address);
- msg->connection.ttl = 0;
- msg->connection.addr_number = 0;
- INIT_ARRAY (msg->bandwidths, SDPBandwidth);
- INIT_ARRAY (msg->times, SDPTime);
- INIT_ARRAY (msg->zones, SDPZone);
- FREE_STRING (msg->key.type);
- FREE_STRING (msg->key.data);
- INIT_ARRAY (msg->attributes, SDPAttribute);
- INIT_ARRAY (msg->medias, SDPMedia);
+ INIT_ARRAY (msg->emails, gchar *, g_free);
+ INIT_ARRAY (msg->phones, gchar *, g_free);
+ sdp_connection_init (&msg->connection);
+ INIT_ARRAY (msg->bandwidths, SDPBandwidth, sdp_bandwidth_init);
+ INIT_ARRAY (msg->times, SDPTime, sdp_time_init);
+ INIT_ARRAY (msg->zones, SDPZone, sdp_zone_init);
+ sdp_key_init (&msg->key);
+ INIT_ARRAY (msg->attributes, SDPAttribute, sdp_attribute_init);
+ INIT_ARRAY (msg->medias, SDPMedia, sdp_media_uninit);
return RTSP_OK;
}
+/**
+ * sdp_message_uninit:
+ * @msg: an #SDPMessage
+ *
+ * Free all resources allocated in @msg. @msg should not be used anymore after
+ * this function. This function should be used when @msg was allocated on the
+ * stack and initialized with sdp_message_init().
+ *
+ * Returns: a #RTSPResult.
+ */
RTSPResult
-sdp_message_clean (SDPMessage * msg)
+sdp_message_uninit (SDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
+ sdp_message_init (msg);
+
FREE_ARRAY (msg->emails);
FREE_ARRAY (msg->phones);
FREE_ARRAY (msg->bandwidths);
@@ -160,19 +239,35 @@ sdp_message_clean (SDPMessage * msg)
return RTSP_OK;
}
+/**
+ * sdp_message_free:
+ * @msg: an #SDPMessage
+ *
+ * Free all resources allocated by @msg. @msg should not be used anymore after
+ * this function. This function should be used when @msg was dynamically
+ * allocated with sdp_message_new().
+ *
+ * Returns: a #RTSPResult.
+ */
RTSPResult
sdp_message_free (SDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
- sdp_message_clean (msg);
-
+ sdp_message_uninit (msg);
g_free (msg);
return RTSP_OK;
}
-
+/**
+ * sdp_media_new:
+ * @media: pointer to new #SDPMedia
+ *
+ * Allocate a new SDPMedia and store the result in @media.
+ *
+ * Returns: a #RTSPResult.
+ */
RTSPResult
sdp_media_new (SDPMedia ** media)
{
@@ -187,6 +282,16 @@ sdp_media_new (SDPMedia ** media)
return sdp_media_init (newmedia);
}
+/**
+ * sdp_media_init:
+ * @media: a #SDPMedia
+ *
+ * Initialize @media so that its contents are as if it was freshly allocated
+ * with sdp_media_new(). This function is mostly used to initialize a media
+ * allocated on the stack. sdp_media_uninit() undoes this operation.
+ *
+ * Returns: a #RTSPResult.
+ */
RTSPResult
sdp_media_init (SDPMedia * media)
{
@@ -196,13 +301,57 @@ sdp_media_init (SDPMedia * media)
media->port = 0;
media->num_ports = 0;
FREE_STRING (media->proto);
- INIT_ARRAY (media->fmts, gchar *);
+ INIT_ARRAY (media->fmts, gchar *, g_free);
FREE_STRING (media->information);
- INIT_ARRAY (media->connections, SDPConnection);
- INIT_ARRAY (media->bandwidths, SDPBandwidth);
- FREE_STRING (media->key.type);
- FREE_STRING (media->key.data);
- INIT_ARRAY (media->attributes, SDPAttribute);
+ INIT_ARRAY (media->connections, SDPConnection, sdp_connection_init);
+ INIT_ARRAY (media->bandwidths, SDPBandwidth, sdp_bandwidth_init);
+ sdp_key_init (&media->key);
+ INIT_ARRAY (media->attributes, SDPAttribute, sdp_attribute_init);
+
+ return RTSP_OK;
+}
+
+/**
+ * sdp_media_uninit:
+ * @media: an #SDPMedia
+ *
+ * Free all resources allocated in @media. @media should not be used anymore after
+ * this function. This function should be used when @media was allocated on the
+ * stack and initialized with sdp_media_init().
+ *
+ * Returns: a #RTSPResult.
+ */
+RTSPResult
+sdp_media_uninit (SDPMedia * media)
+{
+ g_return_val_if_fail (media != NULL, RTSP_EINVAL);
+
+ sdp_media_init (media);
+ FREE_ARRAY (media->fmts);
+ FREE_ARRAY (media->connections);
+ FREE_ARRAY (media->bandwidths);
+ FREE_ARRAY (media->attributes);
+
+ return RTSP_OK;
+}
+
+/**
+ * sdp_media_free:
+ * @media: an #SDPMedia
+ *
+ * Free all resources allocated by @media. @media should not be used anymore after
+ * this function. This function should be used when @media was dynamically
+ * allocated with sdp_media_new().
+ *
+ * Returns: a #RTSPResult.
+ */
+RTSPResult
+sdp_media_free (SDPMedia * media)
+{
+ g_return_val_if_fail (media != NULL, RTSP_EINVAL);
+
+ sdp_media_uninit (media);
+ g_free (media);
return RTSP_OK;
}
@@ -359,6 +508,18 @@ sdp_message_add_attribute (SDPMessage * msg, gchar * key, gchar * value)
DEFINE_ARRAY_LEN (medias);
DEFINE_ARRAY_P_GETTER (media, medias, SDPMedia);
+
+/**
+ * sdp_message_add_media:
+ * @msg: an #SDPMessage
+ * @media: an #SDPMedia to add
+ *
+ * Adds @media to the array of medias in @msg. This function takes ownership of
+ * the contents of @media so that @media will have to be reinitialized with
+ * gst_media_init() before it can be used again.
+ *
+ * Returns: an #RTSPResult.
+ */
RTSPResult
sdp_message_add_media (SDPMessage * msg, SDPMedia * media)
{
@@ -370,6 +531,7 @@ sdp_message_add_media (SDPMessage * msg, SDPMedia * media)
nmedia = &g_array_index (msg->medias, SDPMedia, len);
memcpy (nmedia, media, sizeof (SDPMedia));
+ memset (media, 0, sizeof (SDPMedia));
return RTSP_OK;
}
@@ -584,8 +746,6 @@ sdp_parse_line (SDPContext * c, gchar type, gchar * buffer)
gchar *slash;
SDPMedia nmedia;
- nmedia.media = NULL;
-
c->state = SDP_MEDIA;
sdp_media_init (&nmedia);
diff --git a/gst/rtsp/sdpmessage.h b/gst/rtsp/sdpmessage.h
index 97014bcd..93bf0809 100644
--- a/gst/rtsp/sdpmessage.h
+++ b/gst/rtsp/sdpmessage.h
@@ -130,7 +130,7 @@ typedef struct {
/* Session descriptions */
RTSPResult sdp_message_new (SDPMessage **msg);
RTSPResult sdp_message_init (SDPMessage *msg);
-RTSPResult sdp_message_clean (SDPMessage *msg);
+RTSPResult sdp_message_uninit (SDPMessage *msg);
RTSPResult sdp_message_free (SDPMessage *msg);
RTSPResult sdp_message_parse_buffer (guint8 *data, guint size, SDPMessage *msg);
@@ -182,14 +182,18 @@ RTSPResult sdp_message_dump (SDPMessage *msg);
/* Media descriptions */
RTSPResult sdp_media_new (SDPMedia **media);
RTSPResult sdp_media_init (SDPMedia *media);
-RTSPResult sdp_media_clean (SDPMedia *media);
+RTSPResult sdp_media_uninit (SDPMedia *media);
RTSPResult sdp_media_free (SDPMedia *media);
+RTSPResult sdp_media_add_bandwidth (SDPMedia * media, gchar * bwtype, gint bandwidth);
+
+RTSPResult sdp_media_add_attribute (SDPMedia *media, gchar * key, gchar * value);
SDPAttribute * sdp_media_get_attribute (SDPMedia *media, guint idx);
gchar* sdp_media_get_attribute_val (SDPMedia *media, gchar *key);
gchar* sdp_media_get_attribute_val_n (SDPMedia *media, gchar *key, guint nth);
-gchar* sdp_media_get_format (SDPMedia *media, guint idx);
+RTSPResult sdp_media_add_format (SDPMedia * media, gchar * format);
+gchar* sdp_media_get_format (SDPMedia *media, guint idx);
G_END_DECLS