2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "gstudpsrc.h"
23 #define UDP_DEFAULT_PORT 4951
25 /* elementfactory information */
26 GstElementDetails gst_udpsrc_details = {
27 "UDP packet receiver",
32 "Wim Taymans <wim.taymans@chello.be>",
36 /* UDPSrc signals and args */
48 static void gst_udpsrc_class_init (GstUDPSrc *klass);
49 static void gst_udpsrc_init (GstUDPSrc *udpsrc);
51 static GstBuffer* gst_udpsrc_get (GstPad *pad);
52 static GstElementStateReturn
53 gst_udpsrc_change_state (GstElement *element);
55 static void gst_udpsrc_set_property (GObject *object, guint prop_id,
56 const GValue *value, GParamSpec *pspec);
57 static void gst_udpsrc_get_property (GObject *object, guint prop_id,
58 GValue *value, GParamSpec *pspec);
60 static GstElementClass *parent_class = NULL;
61 /*static guint gst_udpsrc_signals[LAST_SIGNAL] = { 0 }; */
64 gst_udpsrc_get_type (void)
66 static GType udpsrc_type = 0;
70 static const GTypeInfo udpsrc_info = {
71 sizeof(GstUDPSrcClass),
74 (GClassInitFunc)gst_udpsrc_class_init,
79 (GInstanceInitFunc)gst_udpsrc_init,
82 udpsrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstUDPSrc", &udpsrc_info, 0);
88 gst_udpsrc_class_init (GstUDPSrc *klass)
90 GObjectClass *gobject_class;
91 GstElementClass *gstelement_class;
93 gobject_class = (GObjectClass*) klass;
94 gstelement_class = (GstElementClass*) klass;
96 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
98 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT,
99 g_param_spec_int ("port", "port", "The port to receive the packets from",
100 0, 32768, UDP_DEFAULT_PORT, G_PARAM_READWRITE));
102 gobject_class->set_property = gst_udpsrc_set_property;
103 gobject_class->get_property = gst_udpsrc_get_property;
105 gstelement_class->change_state = gst_udpsrc_change_state;
110 gst_udpsrc_init (GstUDPSrc *udpsrc)
112 /* create the src and src pads */
113 udpsrc->srcpad = gst_pad_new ("src", GST_PAD_SRC);
114 gst_element_add_pad (GST_ELEMENT (udpsrc), udpsrc->srcpad);
115 gst_pad_set_get_function (udpsrc->srcpad, gst_udpsrc_get);
117 udpsrc->port = UDP_DEFAULT_PORT;
121 gst_udpsrc_get (GstPad *pad)
125 struct sockaddr_in tmpaddr;
129 g_return_val_if_fail (pad != NULL, NULL);
130 g_return_val_if_fail (GST_IS_PAD (pad), NULL);
132 udpsrc = GST_UDPSRC (GST_OBJECT_PARENT (pad));
135 FD_SET (udpsrc->control_sock, &read_fds);
136 FD_SET (udpsrc->sock, &read_fds);
138 if (select (udpsrc->control_sock+1, &read_fds, NULL, NULL, NULL) > 0) {
139 if (FD_ISSET (udpsrc->control_sock, &read_fds)) {
140 #ifndef GST_DISABLE_LOADSAVE
144 struct sockaddr addr;
149 buf = g_malloc (1024*10);
151 len = sizeof (struct sockaddr);
152 fdread = accept (udpsrc->control_sock, &addr, &len);
157 ret = read (fdread, buf, 1024*10);
162 doc = xmlParseMemory(buf, ret);
163 caps = gst_caps_load_thyself(doc->xmlRootNode);
165 gst_pad_try_set_caps (udpsrc->srcpad, caps);
171 outbuf = gst_buffer_new ();
172 GST_BUFFER_DATA (outbuf) = g_malloc (24000);
173 GST_BUFFER_SIZE (outbuf) = 24000;
175 numbytes = recvfrom (udpsrc->sock, GST_BUFFER_DATA (outbuf),
176 GST_BUFFER_SIZE (outbuf), 0, (struct sockaddr *)&tmpaddr, &len);
178 if (numbytes != -1) {
179 GST_BUFFER_SIZE (outbuf) = numbytes;
183 gst_buffer_unref (outbuf);
198 gst_udpsrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
202 /* it's not null if we got it, but it might not be ours */
203 g_return_if_fail(GST_IS_UDPSRC(object));
204 udpsrc = GST_UDPSRC(object);
208 udpsrc->port = g_value_get_int (value);
216 gst_udpsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
220 /* it's not null if we got it, but it might not be ours */
221 g_return_if_fail(GST_IS_UDPSRC(object));
222 udpsrc = GST_UDPSRC(object);
226 g_value_set_int (value, udpsrc->port);
229 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
234 /* create a socket for sending to remote machine */
236 gst_udpsrc_init_receive (GstUDPSrc *src)
238 bzero (&src->myaddr, sizeof (src->myaddr));
239 src->myaddr.sin_family = AF_INET; /* host byte order */
240 src->myaddr.sin_port = htons (src->port); /* short, network byte order */
241 src->myaddr.sin_addr.s_addr = INADDR_ANY;
243 if ((src->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
248 if (bind (src->sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) {
253 if ((src->control_sock = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
254 perror("control_socket");
258 if (bind (src->control_sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) {
259 perror("control_bind");
262 if (listen (src->control_sock, 5) == -1) {
266 fcntl (src->control_sock, F_SETFL, O_NONBLOCK);
268 GST_FLAG_SET (src, GST_UDPSRC_OPEN);
274 gst_udpsrc_close (GstUDPSrc *src)
278 GST_FLAG_UNSET (src, GST_UDPSRC_OPEN);
281 static GstElementStateReturn
282 gst_udpsrc_change_state (GstElement *element)
284 g_return_val_if_fail (GST_IS_UDPSRC (element), GST_STATE_FAILURE);
286 if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
287 if (GST_FLAG_IS_SET (element, GST_UDPSRC_OPEN))
288 gst_udpsrc_close (GST_UDPSRC (element));
290 if (!GST_FLAG_IS_SET (element, GST_UDPSRC_OPEN)) {
291 if (!gst_udpsrc_init_receive (GST_UDPSRC (element)))
292 return GST_STATE_FAILURE;
296 if (GST_ELEMENT_CLASS (parent_class)->change_state)
297 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
299 return GST_STATE_SUCCESS;