udp: use uri parsing code
authorWim Taymans <wim.taymans@collabora.co.uk>
Tue, 9 Mar 2010 16:15:16 +0000 (17:15 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 10 Mar 2010 10:21:19 +0000 (11:21 +0100)
Use the uri parsing helper functions to manage the host and port pairs. This
adds support for IPV6.

gst/udp/gstudpsink.c
gst/udp/gstudpsink.h
gst/udp/gstudpsrc.c
gst/udp/gstudpsrc.h

index 09972f1..bad4300 100644 (file)
@@ -156,72 +156,40 @@ gst_udpsink_class_init (GstUDPSink * klass)
 static void
 gst_udpsink_init (GstUDPSink * udpsink)
 {
-  udpsink->host = g_strdup (UDP_DEFAULT_HOST);
-  udpsink->port = UDP_DEFAULT_PORT;
-  gst_multiudpsink_add (GST_MULTIUDPSINK (udpsink), udpsink->host,
-      udpsink->port);
+  gst_udp_uri_init (&udpsink->uri, UDP_DEFAULT_HOST, UDP_DEFAULT_PORT);
+
+  gst_multiudpsink_add (GST_MULTIUDPSINK (udpsink), udpsink->uri.host,
+      udpsink->uri.port);
 }
 
 static void
 gst_udpsink_finalize (GstUDPSink * udpsink)
 {
-  g_free (udpsink->host);
-  g_free (udpsink->uri);
+  gst_udp_uri_free (&udpsink->uri);
+  g_free (udpsink->uristr);
 
   G_OBJECT_CLASS (parent_class)->finalize ((GObject *) udpsink);
 }
 
-static void
-gst_udpsink_update_uri (GstUDPSink * sink)
-{
-  g_free (sink->uri);
-  sink->uri = g_strdup_printf ("udp://%s:%d", sink->host, sink->port);
-
-  GST_DEBUG_OBJECT (sink, "updated uri to %s", sink->uri);
-}
-
 static gboolean
 gst_udpsink_set_uri (GstUDPSink * sink, const gchar * uri)
 {
-  gchar *protocol;
-  gchar *location;
-  gchar *colptr;
+  gst_multiudpsink_remove (GST_MULTIUDPSINK (sink), sink->uri.host,
+      sink->uri.port);
 
-  protocol = gst_uri_get_protocol (uri);
-  if (strcmp (protocol, "udp") != 0)
-    goto wrong_protocol;
-  g_free (protocol);
+  if (gst_udp_parse_uri (uri, &sink->uri) < 0)
+    goto wrong_uri;
 
-  location = gst_uri_get_location (uri);
-  if (!location)
-    return FALSE;
-  colptr = strstr (location, ":");
-
-  gst_multiudpsink_remove (GST_MULTIUDPSINK (sink), sink->host, sink->port);
-
-  if (colptr != NULL) {
-    g_free (sink->host);
-    sink->host = g_strndup (location, colptr - location);
-    sink->port = atoi (colptr + 1);
-  } else {
-    g_free (sink->host);
-    sink->host = g_strdup (location);
-    sink->port = UDP_DEFAULT_PORT;
-  }
-  g_free (location);
-
-  gst_multiudpsink_add (GST_MULTIUDPSINK (sink), sink->host, sink->port);
-
-  gst_udpsink_update_uri (sink);
+  gst_multiudpsink_add (GST_MULTIUDPSINK (sink), sink->uri.host,
+      sink->uri.port);
 
   return TRUE;
 
   /* ERRORS */
-wrong_protocol:
+wrong_uri:
   {
     GST_ELEMENT_ERROR (sink, RESOURCE, READ, (NULL),
-        ("error parsing uri %s: wrong protocol (%s != udp)", uri, protocol));
-    g_free (protocol);
+        ("error parsing uri %s", uri));
     return FALSE;
   }
 }
@@ -236,15 +204,23 @@ gst_udpsink_set_property (GObject * object, guint prop_id, const GValue * value,
 
   /* remove old host */
   gst_multiudpsink_remove (GST_MULTIUDPSINK (udpsink),
-      udpsink->host, udpsink->port);
+      udpsink->uri.host, udpsink->uri.port);
 
   switch (prop_id) {
     case PROP_HOST:
-      g_free (udpsink->host);
-      udpsink->host = g_value_dup_string (value);
+    {
+      const gchar *host;
+
+      host = g_value_get_string (value);
+
+      if (host)
+        gst_udp_uri_update (&udpsink->uri, host, -1);
+      else
+        gst_udp_uri_update (&udpsink->uri, UDP_DEFAULT_HOST, -1);
       break;
+    }
     case PROP_PORT:
-      udpsink->port = g_value_get_int (value);
+      gst_udp_uri_update (&udpsink->uri, NULL, g_value_get_int (value));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -252,7 +228,7 @@ gst_udpsink_set_property (GObject * object, guint prop_id, const GValue * value,
   }
   /* add new host */
   gst_multiudpsink_add (GST_MULTIUDPSINK (udpsink),
-      udpsink->host, udpsink->port);
+      udpsink->uri.host, udpsink->uri.port);
 }
 
 static void
@@ -265,10 +241,10 @@ gst_udpsink_get_property (GObject * object, guint prop_id, GValue * value,
 
   switch (prop_id) {
     case PROP_HOST:
-      g_value_set_string (value, udpsink->host);
+      g_value_set_string (value, udpsink->uri.host);
       break;
     case PROP_PORT:
-      g_value_set_int (value, udpsink->port);
+      g_value_set_int (value, udpsink->uri.port);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -297,7 +273,10 @@ gst_udpsink_uri_get_uri (GstURIHandler * handler)
 {
   GstUDPSink *sink = GST_UDPSINK (handler);
 
-  return g_strdup (sink->uri);
+  g_free (sink->uristr);
+  sink->uristr = gst_udp_uri_string (&sink->uri);
+
+  return sink->uristr;
 }
 
 static gboolean
index 17f5552..d45045e 100644 (file)
@@ -41,9 +41,8 @@ typedef struct _GstUDPSinkClass GstUDPSinkClass;
 struct _GstUDPSink {
   GstMultiUDPSink parent;
 
-  gchar *uri;
-  gint port;
-  gchar *host;
+  GstUDPUri  uri;
+  gchar *uristr;
 };
 
 struct _GstUDPSinkClass {
index 32f97f9..5e3cedd 100644 (file)
@@ -309,11 +309,11 @@ gst_udpsrc_init (GstUDPSrc * udpsrc, GstUDPSrcClass * g_class)
 {
   WSA_STARTUP (udpsrc);
 
-  udpsrc->port = UDP_DEFAULT_PORT;
+  gst_udp_uri_init (&udpsrc->uri, UDP_DEFAULT_MULTICAST_GROUP,
+      UDP_DEFAULT_PORT);
+
   udpsrc->sockfd = UDP_DEFAULT_SOCKFD;
-  udpsrc->multi_group = g_strdup (UDP_DEFAULT_MULTICAST_GROUP);
   udpsrc->multi_iface = g_strdup (UDP_DEFAULT_MULTICAST_IFACE);
-  udpsrc->uri = g_strdup (UDP_DEFAULT_URI);
   udpsrc->buffer_size = UDP_DEFAULT_BUFFER_SIZE;
   udpsrc->timeout = UDP_DEFAULT_TIMEOUT;
   udpsrc->skip_first_bytes = UDP_DEFAULT_SKIP_FIRST_BYTES;
@@ -340,9 +340,11 @@ gst_udpsrc_finalize (GObject * object)
 
   if (udpsrc->caps)
     gst_caps_unref (udpsrc->caps);
-  g_free (udpsrc->multi_group);
+
   g_free (udpsrc->multi_iface);
-  g_free (udpsrc->uri);
+
+  gst_udp_uri_free (&udpsrc->uri);
+  g_free (udpsrc->uristr);
 
   if (udpsrc->sockfd >= 0 && udpsrc->closefd)
     CLOSE_SOCKET (udpsrc->sockfd);
@@ -600,54 +602,22 @@ skip_error:
   }
 }
 
-/* Call this function when multicastgroup and/or port are updated */
-
-static void
-gst_udpsrc_update_uri (GstUDPSrc * src)
-{
-  g_free (src->uri);
-  src->uri = g_strdup_printf ("udp://%s:%d", src->multi_group, src->port);
-
-  GST_DEBUG_OBJECT (src, "updated uri to %s", src->uri);
-}
-
 static gboolean
 gst_udpsrc_set_uri (GstUDPSrc * src, const gchar * uri)
 {
-  gchar *protocol;
-  gchar *location;
-  gchar *colptr;
+  if (gst_udp_parse_uri (uri, &src->uri) < 0)
+    goto wrong_uri;
 
-  protocol = gst_uri_get_protocol (uri);
-  if (strcmp (protocol, "udp") != 0)
-    goto wrong_protocol;
-  g_free (protocol);
-
-  location = gst_uri_get_location (uri);
-  if (!location)
-    return FALSE;
-  colptr = strrchr (location, ':');
-  if (colptr != NULL) {
-    g_free (src->multi_group);
-    src->multi_group = g_strndup (location, colptr - location);
-    src->port = atoi (colptr + 1);
-  } else {
-    g_free (src->multi_group);
-    src->multi_group = g_strdup (location);
-    src->port = UDP_DEFAULT_PORT;
-  }
-  g_free (location);
-
-  gst_udpsrc_update_uri (src);
+  if (src->uri.port == -1)
+    src->uri.port = UDP_DEFAULT_PORT;
 
   return TRUE;
 
   /* ERRORS */
-wrong_protocol:
+wrong_uri:
   {
     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
-        ("error parsing uri %s: wrong protocol (%s != udp)", uri, protocol));
-    g_free (protocol);
+        ("error parsing uri %s", uri));
     return FALSE;
   }
 }
@@ -663,18 +633,18 @@ gst_udpsrc_set_property (GObject * object, guint prop_id, const GValue * value,
       udpsrc->buffer_size = g_value_get_int (value);
       break;
     case PROP_PORT:
-      udpsrc->port = g_value_get_int (value);
-      gst_udpsrc_update_uri (udpsrc);
+      gst_udp_uri_update (&udpsrc->uri, NULL, g_value_get_int (value));
       break;
     case PROP_MULTICAST_GROUP:
-      g_free (udpsrc->multi_group);
+    {
+      const gchar *group;
 
-      if (g_value_get_string (value) == NULL)
-        udpsrc->multi_group = g_strdup (UDP_DEFAULT_MULTICAST_GROUP);
+      if ((group = g_value_get_string (value)))
+        gst_udp_uri_update (&udpsrc->uri, group, -1);
       else
-        udpsrc->multi_group = g_value_dup_string (value);
-      gst_udpsrc_update_uri (udpsrc);
+        gst_udp_uri_update (&udpsrc->uri, UDP_DEFAULT_MULTICAST_GROUP, -1);
       break;
+    }
     case PROP_MULTICAST_IFACE:
       g_free (udpsrc->multi_iface);
 
@@ -742,16 +712,16 @@ gst_udpsrc_get_property (GObject * object, guint prop_id, GValue * value,
       g_value_set_int (value, udpsrc->buffer_size);
       break;
     case PROP_PORT:
-      g_value_set_int (value, udpsrc->port);
+      g_value_set_int (value, udpsrc->uri.port);
       break;
     case PROP_MULTICAST_GROUP:
-      g_value_set_string (value, udpsrc->multi_group);
+      g_value_set_string (value, udpsrc->uri.host);
       break;
     case PROP_MULTICAST_IFACE:
       g_value_set_string (value, udpsrc->multi_iface);
       break;
     case PROP_URI:
-      g_value_set_string (value, udpsrc->uri);
+      g_value_take_string (value, gst_udp_uri_string (&udpsrc->uri));
       break;
     case PROP_CAPS:
       gst_value_set_caps (value, udpsrc->caps);
@@ -800,10 +770,10 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
 
   if (src->sockfd == -1) {
     /* need to allocate a socket */
-    GST_DEBUG_OBJECT (src, "allocating socket for %s:%d", src->multi_group,
-        src->port);
+    GST_DEBUG_OBJECT (src, "allocating socket for %s:%d", src->uri.host,
+        src->uri.port);
     if ((ret =
-            gst_udp_get_addr (src->multi_group, src->port, &src->myaddr)) < 0)
+            gst_udp_get_addr (src->uri.host, src->uri.port, &src->myaddr)) < 0)
       goto getaddrinfo_error;
 
     if ((ret = socket (src->myaddr.ss_family, SOCK_DGRAM, IPPROTO_UDP)) < 0)
@@ -820,7 +790,7 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
                 sizeof (reuse))) < 0)
       goto setsockopt_error;
 
-    GST_DEBUG_OBJECT (src, "binding on port %d", src->port);
+    GST_DEBUG_OBJECT (src, "binding on port %d", src->uri.port);
 
     len = gst_udp_get_sockaddr_length (&src->myaddr);
     if ((ret = bind (src->sock.fd, (struct sockaddr *) &src->myaddr, len)) < 0)
@@ -891,7 +861,7 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
 #endif
 
   if (src->auto_multicast && gst_udp_is_multicast (&src->myaddr)) {
-    GST_DEBUG_OBJECT (src, "joining multicast group %s", src->multi_group);
+    GST_DEBUG_OBJECT (src, "joining multicast group %s", src->uri.host);
     ret = gst_udp_join_group (src->sock.fd, &src->myaddr, src->multi_iface);
     if (ret < 0)
       goto membership;
@@ -901,8 +871,8 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
    * follows ss_family on both */
   port = g_ntohs (((struct sockaddr_in *) &src->myaddr)->sin_port);
   GST_DEBUG_OBJECT (src, "bound, on port %d", port);
-  if (port != src->port) {
-    src->port = port;
+  if (port != src->uri.port) {
+    src->uri.port = port;
     GST_DEBUG_OBJECT (src, "notifying port %d", port);
     g_object_notify (G_OBJECT (src), "port");
   }
@@ -1003,7 +973,7 @@ gst_udpsrc_stop (GstBaseSrc * bsrc)
 
   if (src->sock.fd >= 0) {
     if (src->auto_multicast && gst_udp_is_multicast (&src->myaddr)) {
-      GST_DEBUG_OBJECT (src, "leaving multicast group %s", src->multi_group);
+      GST_DEBUG_OBJECT (src, "leaving multicast group %s", src->uri.host);
       gst_udp_leave_group (src->sock.fd, &src->myaddr);
     }
     CLOSE_IF_REQUESTED (src);
@@ -1038,7 +1008,10 @@ gst_udpsrc_uri_get_uri (GstURIHandler * handler)
 {
   GstUDPSrc *src = GST_UDPSRC (handler);
 
-  return src->uri;
+  g_free (src->uristr);
+  src->uristr = gst_udp_uri_string (&src->uri);
+
+  return src->uristr;
 }
 
 static gboolean
index aec167e..ea6a0bf 100644 (file)
@@ -53,9 +53,7 @@ struct _GstUDPSrc {
   GstPushSrc parent;
 
   /* properties */
-  gchar     *uri;
-  int        port;
-  gchar     *multi_group;
+  GstUDPUri  uri;
   gchar     *multi_iface;
   gint       ttl;
   GstCaps   *caps;
@@ -70,8 +68,11 @@ struct _GstUDPSrc {
   GstPollFD  sock;
   GstPoll   *fdset;
   gboolean   externalfd;
+  gboolean   is_ipv6;
 
   struct   sockaddr_storage myaddr;
+
+  gchar     *uristr;
 };
 
 struct _GstUDPSrcClass {