Congrats everyone! udp plugins are now multicast-enabled
authorZeeshan Ali <zeenix@gmail.com>
Mon, 9 Jun 2003 23:13:40 +0000 (23:13 +0000)
committerZeeshan Ali <zeenix@gmail.com>
Mon, 9 Jun 2003 23:13:40 +0000 (23:13 +0000)
Original commit message from CVS:
Congrats everyone! udp plugins are now multicast-enabled

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

index f4b97de..3d2580c 100644 (file)
@@ -120,7 +120,8 @@ gst_udpsink_class_init (GstUDPSink *klass)
   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HOST,
-    g_param_spec_string ("host", "host", "The host/IP to send the packets to",
+    g_param_spec_string ("host", "host", 
+                        "The host/IP/Multicast group to send the packets to",
                          UDP_DEFAULT_HOST, G_PARAM_READWRITE)); 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT,
     g_param_spec_int ("port", "port", "The port to send the packets to",
@@ -377,15 +378,28 @@ gst_udpsink_init_send (GstUDPSink *sink)
 
   /* if its an IP address */
   if (inet_aton (sink->host, &addr)) {
-    sink->theiraddr.sin_addr = 
-               *((struct in_addr *) g_memdup (&addr, sizeof (addr)));
+    /* check if its a multicast address */
+    if ((ntohl (addr.s_addr) & 0xe0000000) == 0xe0000000) {
+       sink->multi_addr.imr_multiaddr.s_addr = addr.s_addr;
+       sink->multi_addr.imr_interface.s_addr = INADDR_ANY;
+       
+       sink->theiraddr.sin_addr = sink->multi_addr.imr_multiaddr;      
+  
+       /* Joining the multicast group */
+       setsockopt (sink->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &sink->multi_addr, sizeof(sink->multi_addr));
+    }
+    else {
+       sink->theiraddr.sin_addr = 
+               *((struct in_addr *) &addr);    
+    }
   }
  
   /* we dont need to lookup for localhost */
   else if (strcmp (sink->host, UDP_DEFAULT_HOST) == 0 && 
           inet_aton ("127.0.0.1", &addr)) {
        sink->theiraddr.sin_addr = 
-               *((struct in_addr *) g_memdup (&addr, sizeof (addr)));
+               *((struct in_addr *) &addr);
   }
 
   /* if its a hostname */
index 4b4cabc..fe3a9f8 100644 (file)
@@ -72,6 +72,7 @@ struct _GstUDPSink {
 
   int sock;
   struct sockaddr_in theiraddr;
+  struct ip_mreq multi_addr;
 
   gint port;
   Gst_UDP_Control control;
index ef017ca..f400b0f 100644 (file)
@@ -20,7 +20,8 @@
 
 #include "gstudpsrc.h"
 
-#define UDP_DEFAULT_PORT       4951
+#define UDP_DEFAULT_PORT               4951
+#define UDP_DEFAULT_MULTICAST_GROUP    "0.0.0.0"
 
 /* elementfactory information */
 GstElementDetails gst_udpsrc_details = {
@@ -42,7 +43,8 @@ enum {
 enum {
   ARG_0,
   ARG_PORT,
-  ARG_CONTROL
+  ARG_CONTROL,
+  ARG_MULTICAST_GROUP
   /* FILL ME */
 };
 
@@ -119,6 +121,10 @@ gst_udpsrc_class_init (GstUDPSrc *klass)
   g_object_class_install_property (gobject_class, ARG_CONTROL,
     g_param_spec_enum ("control", "control", "The type of control",
                        GST_TYPE_UDPSRC_CONTROL, CONTROL_UDP, G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, ARG_MULTICAST_GROUP,
+    g_param_spec_string ("multicast_group", "multicast_group", 
+                        "The Address of multicast group to join",
+                         UDP_DEFAULT_MULTICAST_GROUP, G_PARAM_READWRITE));
 
   gobject_class->set_property = gst_udpsrc_set_property;
   gobject_class->get_property = gst_udpsrc_get_property;
@@ -150,6 +156,7 @@ gst_udpsrc_init (GstUDPSrc *udpsrc)
   udpsrc->clock = NULL;
   udpsrc->sock = -1;
   udpsrc->control_sock = -1;
+  udpsrc->multi_group = g_strdup (UDP_DEFAULT_MULTICAST_GROUP);
 
   udpsrc->first_buf = TRUE;
 }
@@ -288,6 +295,15 @@ gst_udpsrc_set_property (GObject *object, guint prop_id, const GValue *value, GP
     case ARG_PORT:
         udpsrc->port = g_value_get_int (value);
       break;
+    case ARG_MULTICAST_GROUP:
+      g_free(udpsrc->multi_group);
+      
+      if (g_value_get_string (value) == NULL)
+        udpsrc->multi_group = g_strdup (UDP_DEFAULT_MULTICAST_GROUP);
+      else
+        udpsrc->multi_group = g_strdup (g_value_get_string (value));
+      
+      break;
     case ARG_CONTROL:
         udpsrc->control = g_value_get_enum (value);
       break;
@@ -309,6 +325,9 @@ gst_udpsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSp
     case ARG_PORT:
       g_value_set_int (value, udpsrc->port);
       break;
+    case ARG_MULTICAST_GROUP:
+      g_value_set_string (value, udpsrc->multi_group);
+      break;
     case ARG_CONTROL:
       g_value_set_enum (value, udpsrc->control);
       break;
@@ -338,9 +357,16 @@ gst_udpsrc_init_receive (GstUDPSrc *src)
     return FALSE;
   }
 
+  if (inet_aton (src->multi_group, &(src->multi_addr.imr_multiaddr))) {
+    if (src->multi_addr.imr_multiaddr.s_addr) {
+      src->multi_addr.imr_interface.s_addr = INADDR_ANY;
+      setsockopt (src->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &src->multi_addr, sizeof(src->multi_addr));
+    }
+  }
+
   bc_val = 1;
   setsockopt (src->sock, SOL_SOCKET, SO_BROADCAST, &bc_val, sizeof (bc_val));
-  src->myaddr.sin_port = htons (src->port+1);  /* short, network byte order */
+  src->myaddr.sin_port = htons (src->port+1);
   
   switch (src->control) {
     case CONTROL_TCP:
index 6fd01cf..3311db7 100644 (file)
@@ -33,6 +33,9 @@ extern "C" {
 #include <sys/types.h>
 #include <netdb.h>
 #include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 #include <fcntl.h>
 #include "gstudp.h"
 
@@ -66,7 +69,10 @@ struct _GstUDPSrc {
   int sock;
   int control_sock;
   Gst_UDP_Control control;
+  gchar *multi_group;
+
   struct sockaddr_in myaddr;
+  struct ip_mreq multi_addr;
   GstClock *clock;
 
   gboolean first_buf;