From: Zeeshan A. K. <za...@us...> - 2002-11-16 18:55:56
|
CVS Root: /cvsroot/gstreamer Module: gst-plugins Changes by: zak147 Date: Sat Nov 16 2002 10:55:56 PST Log message: (1) Caps nego are now dynamic, the Application developer now have choices: udp, tcp & none. (2) Broadcast flag set to true on all the udp sockets. Modified files: gst/udp : gstudpsink.c gstudpsink.h gstudpsrc.c gstudpsrc.h Links: http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/udp/gstudpsink.c.diff?r1=1.9&r2=1.10 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/udp/gstudpsink.h.diff?r1=1.3&r2=1.4 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/udp/gstudpsrc.c.diff?r1=1.9&r2=1.10 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/udp/gstudpsrc.h.diff?r1=1.3&r2=1.4 ====Begin Diffs==== Index: gstudpsink.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/gst/udp/gstudpsink.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- gstudpsink.c 8 Nov 2002 01:29:11 -0000 1.9 +++ gstudpsink.c 16 Nov 2002 18:55:43 -0000 1.10 @@ -22,6 +22,7 @@ #define UDP_DEFAULT_HOST "localhost" #define UDP_DEFAULT_PORT 4951 +#define UDP_DEFAULT_CONTROL 1 /* elementfactory information */ GstElementDetails gst_udpsink_details = { @@ -45,9 +46,26 @@ ARG_0, ARG_HOST, ARG_PORT, + ARG_CONTROL /* FILL ME */ }; +#define GST_TYPE_UDPSINK_CONTROL (gst_udpsink_control_get_type()) +static GType +gst_udpsink_control_get_type(void) { + static GType udpsink_control_type = 0; + static GEnumValue udpsink_control[] = { + {CONTROL_NONE, "1", "none"}, + {CONTROL_UDP, "2", "udp"}, + {CONTROL_TCP, "3", "tcp"}, + {CONTROL_ZERO, NULL, NULL}, + }; + if (!udpsink_control_type) { + udpsink_control_type = g_enum_register_static("GstUDPSinkControl", udpsink_control); + } + return udpsink_control_type; +} + static void gst_udpsink_class_init (GstUDPSink *klass); static void gst_udpsink_init (GstUDPSink *udpsink); @@ -104,6 +122,9 @@ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT, g_param_spec_int ("port", "port", "The port to send the packets to", 0, 32768, UDP_DEFAULT_PORT, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_CONTROL, + g_param_spec_enum ("control", "control", "The type of control", + GST_TYPE_UDPSINK_CONTROL, CONTROL_UDP, G_PARAM_READWRITE)); gobject_class->set_property = gst_udpsink_set_property; gobject_class->get_property = gst_udpsink_get_property; @@ -120,47 +141,82 @@ struct hostent *serverhost; int fd; FILE *f; + guint bc_val; #ifndef GST_DISABLE_LOADSAVE xmlDocPtr doc; -#endif + xmlChar *buf; + int buf_size; udpsink = GST_UDPSINK (gst_pad_get_parent (pad)); - - fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (fd < 0) { - perror("socket"); - return GST_PAD_CONNECT_REFUSED; - } + memset(&serv_addr, 0, sizeof(serv_addr)); + /* its a name rather than an ipnum */ serverhost = gethostbyname(udpsink->host); if (serverhost == (struct hostent *)0) { - perror("gethostbyname"); - return GST_PAD_CONNECT_REFUSED; + perror("gethostbyname"); + return GST_PAD_CONNECT_REFUSED; } + memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length); serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(udpsink->port); - - if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) { - g_printerr ("udpsink: connect to %s port %d failed: %s\n", - udpsink->host, udpsink->port, g_strerror(errno)); - return GST_PAD_CONNECT_REFUSED; - } - f = fdopen (dup (fd), "wb"); - -#ifndef GST_DISABLE_LOADSAVE + serv_addr.sin_port = htons(udpsink->port+1); + doc = xmlNewDoc ("1.0"); doc->xmlRootNode = xmlNewDocNode (doc, NULL, "NewCaps", NULL); gst_caps_save_thyself (caps, doc->xmlRootNode); - xmlDocDump(f, doc); -#endif - fclose (f); - close (fd); + switch (udpsink->control) { + case CONTROL_UDP: + if ((fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + perror("socket"); + return GST_PAD_CONNECT_REFUSED; + } + + /* We can only do broadcast in udp */ + bc_val = 1; + setsockopt (fd,SOL_SOCKET, SO_BROADCAST, &bc_val, sizeof (bc_val)); + + xmlDocDumpMemory(doc, &buf, &buf_size); + + if (sendto (fd, buf, buf_size, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) + { + perror("sending"); + return GST_PAD_CONNECT_REFUSED; + } + + close (fd); + break; + case CONTROL_TCP: + if ((fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { + perror("socket"); + return GST_PAD_CONNECT_REFUSED; + } + + if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) { + g_printerr ("udpsink: connect to %s port %d failed: %s\n", + udpsink->host, udpsink->port, g_strerror(errno)); + return GST_PAD_CONNECT_REFUSED; + } + + f = fdopen (dup (fd), "wb"); + xmlDocDump(f, doc); + fclose (f); + close (fd); + + break; + case CONTROL_NONE: + return GST_PAD_CONNECT_OK; + break; + default: + return GST_PAD_CONNECT_REFUSED; + break; + } +#endif + return GST_PAD_CONNECT_OK; } @@ -185,6 +241,7 @@ udpsink->host = g_strdup (UDP_DEFAULT_HOST); udpsink->port = UDP_DEFAULT_PORT; + udpsink->control = CONTROL_UDP; udpsink->clock = NULL; @@ -240,6 +297,9 @@ case ARG_PORT: udpsink->port = g_value_get_int (value); break; + case ARG_CONTROL: + udpsink->control = g_value_get_enum (value); + break; default: break; } @@ -261,6 +321,9 @@ case ARG_PORT: g_value_set_int (value, udpsink->port); break; + case ARG_CONTROL: + g_value_set_enum (value, udpsink->control); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -273,6 +336,7 @@ gst_udpsink_init_send (GstUDPSink *sink) { struct hostent *he; + guint bc_val; bzero (&sink->theiraddr, sizeof (sink->theiraddr)); sink->theiraddr.sin_family = AF_INET; /* host byte order */ @@ -284,10 +348,13 @@ sink->theiraddr.sin_addr = *((struct in_addr *) he->h_addr); if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { - perror("socket"); - return FALSE; + perror("socket"); + return FALSE; } + bc_val = 1; + setsockopt (sink->sock, SOL_SOCKET, SO_BROADCAST, &bc_val, sizeof (bc_val)); + GST_FLAG_SET (sink, GST_UDPSINK_OPEN); return TRUE; Index: gstudpsink.h =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/gst/udp/gstudpsink.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- gstudpsink.h 8 Nov 2002 01:29:11 -0000 1.3 +++ gstudpsink.h 16 Nov 2002 18:55:43 -0000 1.4 @@ -41,6 +41,7 @@ #include <sys/socket.h> #include <sys/wait.h> #include <fcntl.h> +#include "gstudp.h" #define GST_TYPE_UDPSINK \ (gst_udpsink_get_type()) @@ -72,6 +73,7 @@ struct sockaddr_in theiraddr; gint port; + Gst_UDP_Control control; gchar *host; GstClock *clock; Index: gstudpsrc.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/gst/udp/gstudpsrc.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- gstudpsrc.c 8 Nov 2002 01:56:49 -0000 1.9 +++ gstudpsrc.c 16 Nov 2002 18:55:43 -0000 1.10 @@ -42,9 +42,26 @@ enum { ARG_0, ARG_PORT, + ARG_CONTROL /* FILL ME */ }; +#define GST_TYPE_UDPSRC_CONTROL (gst_udpsrc_control_get_type()) +static GType +gst_udpsrc_control_get_type(void) { + static GType udpsrc_control_type = 0; + static GEnumValue udpsrc_control[] = { + {CONTROL_NONE, "1", "none"}, + {CONTROL_UDP, "2", "udp"}, + {CONTROL_TCP, "3", "tcp"}, + {CONTROL_ZERO, NULL, NULL}, + }; + if (!udpsrc_control_type) { + udpsrc_control_type = g_enum_register_static("GstUDPSrcControl", udpsrc_control); + } + return udpsrc_control_type; +} + static void gst_udpsrc_class_init (GstUDPSrc *klass); static void gst_udpsrc_init (GstUDPSrc *udpsrc); @@ -98,6 +115,9 @@ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT, g_param_spec_int ("port", "port", "The port to receive the packets from", 0, 32768, UDP_DEFAULT_PORT, G_PARAM_READWRITE)); + 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)); gobject_class->set_property = gst_udpsrc_set_property; gobject_class->get_property = gst_udpsrc_get_property; @@ -115,6 +135,7 @@ gst_pad_set_get_function (udpsrc->srcpad, gst_udpsrc_get); udpsrc->port = UDP_DEFAULT_PORT; + udpsrc->control = CONTROL_UDP; } static GstBuffer* @@ -126,6 +147,7 @@ socklen_t len; gint numbytes; fd_set read_fds; + guint max_sock; g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (GST_IS_PAD (pad), NULL); @@ -133,10 +155,18 @@ udpsrc = GST_UDPSRC (GST_OBJECT_PARENT (pad)); FD_ZERO (&read_fds); - FD_SET (udpsrc->control_sock, &read_fds); FD_SET (udpsrc->sock, &read_fds); + + if (udpsrc->control != CONTROL_NONE) { + FD_SET (udpsrc->control_sock, &read_fds); + max_sock = udpsrc->control_sock; + } - if (select (udpsrc->control_sock+1, &read_fds, NULL, NULL, NULL) > 0) { + else { + max_sock = udpsrc->sock; + } + + if (select (max_sock+1, &read_fds, NULL, NULL, NULL) > 0) { if (FD_ISSET (udpsrc->control_sock, &read_fds)) { #ifndef GST_DISABLE_LOADSAVE guchar *buf; @@ -148,16 +178,29 @@ buf = g_malloc (1024*10); - len = sizeof (struct sockaddr); - fdread = accept (udpsrc->control_sock, &addr, &len); - if (fdread < 0) { - perror ("accept"); - } + switch (udpsrc->control) { + case CONTROL_TCP: + len = sizeof (struct sockaddr); + fdread = accept (udpsrc->control_sock, &addr, &len); + if (fdread < 0) { + perror ("accept"); + } - ret = read (fdread, buf, 1024*10); - if (ret < 0) { - perror ("read"); + ret = read (fdread, buf, 1024*10); + break; + case CONTROL_UDP: + ret = recvfrom (udpsrc->control_sock, buf, 1024*10, 0, (struct sockaddr *)&tmpaddr, &len); + if (ret < 0) { + perror ("recvfrom"); + } + break; + case CONTROL_NONE: + default: + g_free (buf); + return NULL; + break; } + buf[ret] = '\0'; doc = xmlParseMemory(buf, ret); caps = gst_caps_load_thyself(doc->xmlRootNode); @@ -165,6 +208,7 @@ gst_pad_try_set_caps (udpsrc->srcpad, caps); #endif + g_free (buf); outbuf = NULL; } else { @@ -207,6 +251,9 @@ case ARG_PORT: udpsrc->port = g_value_get_int (value); break; + case ARG_CONTROL: + udpsrc->control = g_value_get_enum (value); + break; default: break; } @@ -225,6 +272,9 @@ case ARG_PORT: g_value_set_int (value, udpsrc->port); break; + case ARG_CONTROL: + g_value_set_enum (value, udpsrc->control); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -235,6 +285,7 @@ static gboolean gst_udpsrc_init_receive (GstUDPSrc *src) { + guint bc_val; bzero (&src->myaddr, sizeof (src->myaddr)); src->myaddr.sin_family = AF_INET; /* host byte order */ src->myaddr.sin_port = htons (src->port); /* short, network byte order */ @@ -245,25 +296,58 @@ return FALSE; } - if (bind (src->sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) { + if (bind (src->sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) { perror("bind"); return FALSE; } - if ((src->control_sock = socket (AF_INET, SOCK_STREAM, 0)) == -1) { - perror("control_socket"); - return FALSE; - } + 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 */ + + switch (src->control) { + case CONTROL_TCP: + if ((src->control_sock = socket (AF_INET, SOCK_STREAM, 0)) == -1) { + perror("control_socket"); + return FALSE; + } - if (bind (src->control_sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) { - perror("control_bind"); - return FALSE; - } - if (listen (src->control_sock, 5) == -1) { - perror("listen"); - return FALSE; + if (bind (src->control_sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) { + perror("control_bind"); + return FALSE; + } + + if (listen (src->control_sock, 5) == -1) { + perror("listen"); + return FALSE; + } + + fcntl (src->control_sock, F_SETFL, O_NONBLOCK); + + break; + case CONTROL_UDP: + if ((src->control_sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { + perror("socket"); + return FALSE; + } + + if (bind (src->control_sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) + { + perror("control_bind"); + return FALSE; + } + /* We can only do broadcast in udp */ + bc_val = 1; + setsockopt (src->control_sock, SOL_SOCKET, SO_BROADCAST, &bc_val, sizeof (bc_val)); + break; + case CONTROL_NONE: + GST_FLAG_SET (src, GST_UDPSRC_OPEN); + return TRUE; + break; + default: + return FALSE; + break; } - fcntl (src->control_sock, F_SETFL, O_NONBLOCK); GST_FLAG_SET (src, GST_UDPSRC_OPEN); @@ -274,6 +358,7 @@ gst_udpsrc_close (GstUDPSrc *src) { close (src->sock); + close (src->control_sock); GST_FLAG_UNSET (src, GST_UDPSRC_OPEN); } Index: gstudpsrc.h =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/gst/udp/gstudpsrc.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- gstudpsrc.h 8 Nov 2002 01:56:49 -0000 1.3 +++ gstudpsrc.h 16 Nov 2002 18:55:43 -0000 1.4 @@ -34,6 +34,7 @@ #include <netdb.h> #include <sys/socket.h> #include <fcntl.h> +#include "gstudp.h" #define GST_TYPE_UDPSRC \ (gst_udpsrc_get_type()) @@ -64,6 +65,7 @@ int port; int sock; int control_sock; + Gst_UDP_Control control; struct sockaddr_in myaddr; }; |