diff --git a/gst/udp/gstudpsink.c b/gst/udp/gstudpsink.c index f4b97de2ef..3d2580c3e2 100644 --- a/gst/udp/gstudpsink.c +++ b/gst/udp/gstudpsink.c @@ -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 */ diff --git a/gst/udp/gstudpsink.h b/gst/udp/gstudpsink.h index 4b4cabc55d..fe3a9f873a 100644 --- a/gst/udp/gstudpsink.h +++ b/gst/udp/gstudpsink.h @@ -72,6 +72,7 @@ struct _GstUDPSink { int sock; struct sockaddr_in theiraddr; + struct ip_mreq multi_addr; gint port; Gst_UDP_Control control; diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index ef017ca508..f400b0fb43 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -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: diff --git a/gst/udp/gstudpsrc.h b/gst/udp/gstudpsrc.h index 6fd01cfc5b..3311db7f14 100644 --- a/gst/udp/gstudpsrc.h +++ b/gst/udp/gstudpsrc.h @@ -33,6 +33,9 @@ extern "C" { #include #include #include +#include +#include + #include #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;