2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
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., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
23 #include "rtsp-server.h"
24 #include "rtsp-client.h"
26 #define GST_RTSP_SERVER_GET_PRIVATE(obj) \
27 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_SERVER, GstRTSPServerPrivate))
29 #define GST_RTSP_SERVER_GET_LOCK(server) (&(GST_RTSP_SERVER_CAST(server)->priv->lock))
30 #define GST_RTSP_SERVER_LOCK(server) (g_mutex_lock(GST_RTSP_SERVER_GET_LOCK(server)))
31 #define GST_RTSP_SERVER_UNLOCK(server) (g_mutex_unlock(GST_RTSP_SERVER_GET_LOCK(server)))
33 struct _GstRTSPServerPrivate
35 GMutex lock; /* protects everything in this struct */
37 /* server information */
45 /* sessions on this server */
46 GstRTSPSessionPool *session_pool;
48 /* mount points for this server */
49 GstRTSPMountPoints *mount_points;
51 /* authentication manager */
54 /* the clients that are connected */
56 GQueue loops; /* the main loops used in the threads */
59 #define DEFAULT_ADDRESS "0.0.0.0"
60 #define DEFAULT_BOUND_PORT -1
61 /* #define DEFAULT_ADDRESS "::0" */
62 #define DEFAULT_SERVICE "8554"
63 #define DEFAULT_BACKLOG 5
64 #define DEFAULT_MAX_THREADS 0
66 /* Define to use the SO_LINGER option so that the server sockets can be resused
67 * sooner. Disabled for now because it is not very well implemented by various
68 * OSes and it causes clients to fail to read the TEARDOWN response. */
87 SIGNAL_CLIENT_CONNECTED,
91 G_DEFINE_TYPE (GstRTSPServer, gst_rtsp_server, G_TYPE_OBJECT);
93 GST_DEBUG_CATEGORY_STATIC (rtsp_server_debug);
94 #define GST_CAT_DEFAULT rtsp_server_debug
96 typedef struct _ClientContext ClientContext;
97 typedef struct _Loop Loop;
99 static guint gst_rtsp_server_signals[SIGNAL_LAST] = { 0 };
101 static void gst_rtsp_server_get_property (GObject * object, guint propid,
102 GValue * value, GParamSpec * pspec);
103 static void gst_rtsp_server_set_property (GObject * object, guint propid,
104 const GValue * value, GParamSpec * pspec);
105 static void gst_rtsp_server_finalize (GObject * object);
107 static gpointer do_loop (Loop * loop);
108 static GstRTSPClient *default_create_client (GstRTSPServer * server);
109 static gboolean default_accept_client (GstRTSPServer * server,
110 GstRTSPClient * client, GSocket * socket, GError ** error);
113 gst_rtsp_server_class_init (GstRTSPServerClass * klass)
115 GObjectClass *gobject_class;
117 g_type_class_add_private (klass, sizeof (GstRTSPServerPrivate));
119 gobject_class = G_OBJECT_CLASS (klass);
121 gobject_class->get_property = gst_rtsp_server_get_property;
122 gobject_class->set_property = gst_rtsp_server_set_property;
123 gobject_class->finalize = gst_rtsp_server_finalize;
126 * GstRTSPServer::address:
128 * The address of the server. This is the address where the server will
131 g_object_class_install_property (gobject_class, PROP_ADDRESS,
132 g_param_spec_string ("address", "Address",
133 "The address the server uses to listen on", DEFAULT_ADDRESS,
134 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
136 * GstRTSPServer::service:
138 * The service of the server. This is either a string with the service name or
139 * a port number (as a string) the server will listen on.
141 g_object_class_install_property (gobject_class, PROP_SERVICE,
142 g_param_spec_string ("service", "Service",
143 "The service or port number the server uses to listen on",
144 DEFAULT_SERVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146 * GstRTSPServer::bound-port:
148 * The actual port the server is listening on. Can be used to retrieve the
149 * port number when the server is started on port 0, which means bind to a
150 * random port. Set to -1 if the server has not been bound yet.
152 g_object_class_install_property (gobject_class, PROP_BOUND_PORT,
153 g_param_spec_int ("bound-port", "Bound port",
154 "The port number the server is listening on",
155 -1, G_MAXUINT16, DEFAULT_BOUND_PORT,
156 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
158 * GstRTSPServer::backlog:
160 * The backlog argument defines the maximum length to which the queue of
161 * pending connections for the server may grow. If a connection request arrives
162 * when the queue is full, the client may receive an error with an indication of
163 * ECONNREFUSED or, if the underlying protocol supports retransmission, the
164 * request may be ignored so that a later reattempt at connection succeeds.
166 g_object_class_install_property (gobject_class, PROP_BACKLOG,
167 g_param_spec_int ("backlog", "Backlog",
168 "The maximum length to which the queue "
169 "of pending connections may grow", 0, G_MAXINT, DEFAULT_BACKLOG,
170 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
172 * GstRTSPServer::session-pool:
174 * The session pool of the server. By default each server has a separate
175 * session pool but sessions can be shared between servers by setting the same
176 * session pool on multiple servers.
178 g_object_class_install_property (gobject_class, PROP_SESSION_POOL,
179 g_param_spec_object ("session-pool", "Session Pool",
180 "The session pool to use for client session",
181 GST_TYPE_RTSP_SESSION_POOL,
182 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
184 * GstRTSPServer::mount-points:
186 * The mount points to use for this server. By default the server has no
187 * mount points and thus cannot map urls to media streams.
189 g_object_class_install_property (gobject_class, PROP_MOUNT_POINTS,
190 g_param_spec_object ("mount-points", "Mount Points",
191 "The mount points to use for client session",
192 GST_TYPE_RTSP_MOUNT_POINTS,
193 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
195 * GstRTSPServer::max-threads:
197 * The maximum amount of threads to use for client connections. A value of
198 * 0 means to use only the mainloop, -1 means an unlimited amount of
201 g_object_class_install_property (gobject_class, PROP_MAX_THREADS,
202 g_param_spec_int ("max-threads", "Max Threads",
203 "The maximum amount of threads to use for client connections "
204 "(0 = only mainloop, -1 = unlimited)", -1, G_MAXINT,
205 DEFAULT_MAX_THREADS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
207 gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED] =
208 g_signal_new ("client-connected", G_TYPE_FROM_CLASS (gobject_class),
209 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPServerClass, client_connected),
210 NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
211 gst_rtsp_client_get_type ());
213 klass->create_client = default_create_client;
214 klass->accept_client = default_accept_client;
216 klass->pool = g_thread_pool_new ((GFunc) do_loop, klass, -1, FALSE, NULL);
218 GST_DEBUG_CATEGORY_INIT (rtsp_server_debug, "rtspserver", 0, "GstRTSPServer");
222 gst_rtsp_server_init (GstRTSPServer * server)
224 GstRTSPServerPrivate *priv = GST_RTSP_SERVER_GET_PRIVATE (server);
228 g_mutex_init (&priv->lock);
229 priv->address = g_strdup (DEFAULT_ADDRESS);
230 priv->service = g_strdup (DEFAULT_SERVICE);
232 priv->backlog = DEFAULT_BACKLOG;
233 priv->session_pool = gst_rtsp_session_pool_new ();
234 priv->mount_points = gst_rtsp_mount_points_new ();
235 priv->max_threads = DEFAULT_MAX_THREADS;
236 g_queue_init (&priv->loops);
240 gst_rtsp_server_finalize (GObject * object)
242 GstRTSPServer *server = GST_RTSP_SERVER (object);
243 GstRTSPServerPrivate *priv = server->priv;
245 GST_DEBUG_OBJECT (server, "finalize server");
247 g_free (priv->address);
248 g_free (priv->service);
251 g_object_unref (priv->socket);
253 g_object_unref (priv->session_pool);
254 g_object_unref (priv->mount_points);
257 g_object_unref (priv->auth);
259 g_mutex_clear (&priv->lock);
261 G_OBJECT_CLASS (gst_rtsp_server_parent_class)->finalize (object);
265 * gst_rtsp_server_new:
267 * Create a new #GstRTSPServer instance.
270 gst_rtsp_server_new (void)
272 GstRTSPServer *result;
274 result = g_object_new (GST_TYPE_RTSP_SERVER, NULL);
280 * gst_rtsp_server_set_address:
281 * @server: a #GstRTSPServer
282 * @address: the address
284 * Configure @server to accept connections on the given address.
286 * This function must be called before the server is bound.
289 gst_rtsp_server_set_address (GstRTSPServer * server, const gchar * address)
291 GstRTSPServerPrivate *priv;
293 g_return_if_fail (GST_IS_RTSP_SERVER (server));
294 g_return_if_fail (address != NULL);
298 GST_RTSP_SERVER_LOCK (server);
299 g_free (priv->address);
300 priv->address = g_strdup (address);
301 GST_RTSP_SERVER_UNLOCK (server);
305 * gst_rtsp_server_get_address:
306 * @server: a #GstRTSPServer
308 * Get the address on which the server will accept connections.
310 * Returns: the server address. g_free() after usage.
313 gst_rtsp_server_get_address (GstRTSPServer * server)
315 GstRTSPServerPrivate *priv;
318 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
322 GST_RTSP_SERVER_LOCK (server);
323 result = g_strdup (priv->address);
324 GST_RTSP_SERVER_UNLOCK (server);
330 * gst_rtsp_server_get_bound_port:
331 * @server: a #GstRTSPServer
333 * Get the port number where the server was bound to.
335 * Returns: the port number
338 gst_rtsp_server_get_bound_port (GstRTSPServer * server)
340 GstRTSPServerPrivate *priv;
341 GSocketAddress *address;
344 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), result);
348 GST_RTSP_SERVER_LOCK (server);
349 if (priv->socket == NULL)
352 address = g_socket_get_local_address (priv->socket, NULL);
353 result = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
354 g_object_unref (address);
357 GST_RTSP_SERVER_UNLOCK (server);
363 * gst_rtsp_server_set_service:
364 * @server: a #GstRTSPServer
365 * @service: the service
367 * Configure @server to accept connections on the given service.
368 * @service should be a string containing the service name (see services(5)) or
369 * a string containing a port number between 1 and 65535.
371 * This function must be called before the server is bound.
374 gst_rtsp_server_set_service (GstRTSPServer * server, const gchar * service)
376 GstRTSPServerPrivate *priv;
378 g_return_if_fail (GST_IS_RTSP_SERVER (server));
379 g_return_if_fail (service != NULL);
383 GST_RTSP_SERVER_LOCK (server);
384 g_free (priv->service);
385 priv->service = g_strdup (service);
386 GST_RTSP_SERVER_UNLOCK (server);
390 * gst_rtsp_server_get_service:
391 * @server: a #GstRTSPServer
393 * Get the service on which the server will accept connections.
395 * Returns: the service. use g_free() after usage.
398 gst_rtsp_server_get_service (GstRTSPServer * server)
400 GstRTSPServerPrivate *priv;
403 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
407 GST_RTSP_SERVER_LOCK (server);
408 result = g_strdup (priv->service);
409 GST_RTSP_SERVER_UNLOCK (server);
415 * gst_rtsp_server_set_backlog:
416 * @server: a #GstRTSPServer
417 * @backlog: the backlog
419 * configure the maximum amount of requests that may be queued for the
422 * This function must be called before the server is bound.
425 gst_rtsp_server_set_backlog (GstRTSPServer * server, gint backlog)
427 GstRTSPServerPrivate *priv;
429 g_return_if_fail (GST_IS_RTSP_SERVER (server));
433 GST_RTSP_SERVER_LOCK (server);
434 priv->backlog = backlog;
435 GST_RTSP_SERVER_UNLOCK (server);
439 * gst_rtsp_server_get_backlog:
440 * @server: a #GstRTSPServer
442 * The maximum amount of queued requests for the server.
444 * Returns: the server backlog.
447 gst_rtsp_server_get_backlog (GstRTSPServer * server)
449 GstRTSPServerPrivate *priv;
452 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
456 GST_RTSP_SERVER_LOCK (server);
457 result = priv->backlog;
458 GST_RTSP_SERVER_UNLOCK (server);
464 * gst_rtsp_server_set_session_pool:
465 * @server: a #GstRTSPServer
466 * @pool: a #GstRTSPSessionPool
468 * configure @pool to be used as the session pool of @server.
471 gst_rtsp_server_set_session_pool (GstRTSPServer * server,
472 GstRTSPSessionPool * pool)
474 GstRTSPServerPrivate *priv;
475 GstRTSPSessionPool *old;
477 g_return_if_fail (GST_IS_RTSP_SERVER (server));
484 GST_RTSP_SERVER_LOCK (server);
485 old = priv->session_pool;
486 priv->session_pool = pool;
487 GST_RTSP_SERVER_UNLOCK (server);
490 g_object_unref (old);
494 * gst_rtsp_server_get_session_pool:
495 * @server: a #GstRTSPServer
497 * Get the #GstRTSPSessionPool used as the session pool of @server.
499 * Returns: (transfer full): the #GstRTSPSessionPool used for sessions. g_object_unref() after
503 gst_rtsp_server_get_session_pool (GstRTSPServer * server)
505 GstRTSPServerPrivate *priv;
506 GstRTSPSessionPool *result;
508 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
512 GST_RTSP_SERVER_LOCK (server);
513 if ((result = priv->session_pool))
514 g_object_ref (result);
515 GST_RTSP_SERVER_UNLOCK (server);
521 * gst_rtsp_server_set_mount_points:
522 * @server: a #GstRTSPServer
523 * @mounts: a #GstRTSPMountPoints
525 * configure @mounts to be used as the mount points of @server.
528 gst_rtsp_server_set_mount_points (GstRTSPServer * server,
529 GstRTSPMountPoints * mounts)
531 GstRTSPServerPrivate *priv;
532 GstRTSPMountPoints *old;
534 g_return_if_fail (GST_IS_RTSP_SERVER (server));
539 g_object_ref (mounts);
541 GST_RTSP_SERVER_LOCK (server);
542 old = priv->mount_points;
543 priv->mount_points = mounts;
544 GST_RTSP_SERVER_UNLOCK (server);
547 g_object_unref (old);
552 * gst_rtsp_server_get_mount_points:
553 * @server: a #GstRTSPServer
555 * Get the #GstRTSPMountPoints used as the mount points of @server.
557 * Returns: (transfer full): the #GstRTSPMountPoints of @server. g_object_unref() after
561 gst_rtsp_server_get_mount_points (GstRTSPServer * server)
563 GstRTSPServerPrivate *priv;
564 GstRTSPMountPoints *result;
566 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
570 GST_RTSP_SERVER_LOCK (server);
571 if ((result = priv->mount_points))
572 g_object_ref (result);
573 GST_RTSP_SERVER_UNLOCK (server);
579 * gst_rtsp_server_set_auth:
580 * @server: a #GstRTSPServer
581 * @auth: a #GstRTSPAuth
583 * configure @auth to be used as the authentication manager of @server.
586 gst_rtsp_server_set_auth (GstRTSPServer * server, GstRTSPAuth * auth)
588 GstRTSPServerPrivate *priv;
591 g_return_if_fail (GST_IS_RTSP_SERVER (server));
598 GST_RTSP_SERVER_LOCK (server);
601 GST_RTSP_SERVER_UNLOCK (server);
604 g_object_unref (old);
609 * gst_rtsp_server_get_auth:
610 * @server: a #GstRTSPServer
612 * Get the #GstRTSPAuth used as the authentication manager of @server.
614 * Returns: (transfer full): the #GstRTSPAuth of @server. g_object_unref() after
618 gst_rtsp_server_get_auth (GstRTSPServer * server)
620 GstRTSPServerPrivate *priv;
623 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
627 GST_RTSP_SERVER_LOCK (server);
628 if ((result = priv->auth))
629 g_object_ref (result);
630 GST_RTSP_SERVER_UNLOCK (server);
636 * gst_rtsp_server_set_max_threads:
637 * @server: a #GstRTSPServer
638 * @max_threads: maximum threads
640 * Set the maximum threads used by the server to handle client requests.
641 * A value of 0 will use the server mainloop, a value of -1 will use an
642 * unlimited number of threads.
645 gst_rtsp_server_set_max_threads (GstRTSPServer * server, gint max_threads)
647 GstRTSPServerPrivate *priv;
649 g_return_if_fail (GST_IS_RTSP_SERVER (server));
653 GST_RTSP_SERVER_LOCK (server);
654 priv->max_threads = max_threads;
655 GST_RTSP_SERVER_UNLOCK (server);
659 * gst_rtsp_server_get_max_threads:
660 * @server: a #GstRTSPServer
662 * Get the maximum number of threads used for client connections.
663 * See gst_rtsp_server_set_max_threads().
665 * Returns: the maximum number of threads.
668 gst_rtsp_server_get_max_threads (GstRTSPServer * server)
670 GstRTSPServerPrivate *priv;
673 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
677 GST_RTSP_SERVER_LOCK (server);
678 res = priv->max_threads;
679 GST_RTSP_SERVER_UNLOCK (server);
686 gst_rtsp_server_get_property (GObject * object, guint propid,
687 GValue * value, GParamSpec * pspec)
689 GstRTSPServer *server = GST_RTSP_SERVER (object);
693 g_value_take_string (value, gst_rtsp_server_get_address (server));
696 g_value_take_string (value, gst_rtsp_server_get_service (server));
698 case PROP_BOUND_PORT:
699 g_value_set_int (value, gst_rtsp_server_get_bound_port (server));
702 g_value_set_int (value, gst_rtsp_server_get_backlog (server));
704 case PROP_SESSION_POOL:
705 g_value_take_object (value, gst_rtsp_server_get_session_pool (server));
707 case PROP_MOUNT_POINTS:
708 g_value_take_object (value, gst_rtsp_server_get_mount_points (server));
710 case PROP_MAX_THREADS:
711 g_value_set_int (value, gst_rtsp_server_get_max_threads (server));
714 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
719 gst_rtsp_server_set_property (GObject * object, guint propid,
720 const GValue * value, GParamSpec * pspec)
722 GstRTSPServer *server = GST_RTSP_SERVER (object);
726 gst_rtsp_server_set_address (server, g_value_get_string (value));
729 gst_rtsp_server_set_service (server, g_value_get_string (value));
732 gst_rtsp_server_set_backlog (server, g_value_get_int (value));
734 case PROP_SESSION_POOL:
735 gst_rtsp_server_set_session_pool (server, g_value_get_object (value));
737 case PROP_MOUNT_POINTS:
738 gst_rtsp_server_set_mount_points (server, g_value_get_object (value));
740 case PROP_MAX_THREADS:
741 gst_rtsp_server_set_max_threads (server, g_value_get_int (value));
744 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
749 * gst_rtsp_server_create_socket:
750 * @server: a #GstRTSPServer
751 * @cancellable: a #GCancellable
754 * Create a #GSocket for @server. The socket will listen on the
755 * configured service.
757 * Returns: (transfer full): the #GSocket for @server or NULL when an error occured.
760 gst_rtsp_server_create_socket (GstRTSPServer * server,
761 GCancellable * cancellable, GError ** error)
763 GstRTSPServerPrivate *priv;
764 GSocketConnectable *conn;
765 GSocketAddressEnumerator *enumerator;
766 GSocket *socket = NULL;
768 struct linger linger;
770 GError *sock_error = NULL;
771 GError *bind_error = NULL;
774 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
778 GST_RTSP_SERVER_LOCK (server);
779 GST_DEBUG_OBJECT (server, "getting address info of %s/%s", priv->address,
782 /* resolve the server IP address */
783 port = atoi (priv->service);
784 if (port != 0 || !strcmp (priv->service, "0"))
785 conn = g_network_address_new (priv->address, port);
787 conn = g_network_service_new (priv->service, "tcp", priv->address);
789 enumerator = g_socket_connectable_enumerate (conn);
790 g_object_unref (conn);
792 /* create server socket, we loop through all the addresses until we manage to
793 * create a socket and bind. */
795 GSocketAddress *sockaddr;
798 g_socket_address_enumerator_next (enumerator, cancellable, error);
801 GST_DEBUG_OBJECT (server, "no more addresses %s",
802 *error ? (*error)->message : "");
804 GST_DEBUG_OBJECT (server, "failed to retrieve next address %s",
809 /* only keep the first error */
810 socket = g_socket_new (g_socket_address_get_family (sockaddr),
811 G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP,
812 sock_error ? NULL : &sock_error);
814 if (socket == NULL) {
815 GST_DEBUG_OBJECT (server, "failed to make socket (%s), try next",
816 sock_error->message);
817 g_object_unref (sockaddr);
821 if (g_socket_bind (socket, sockaddr, TRUE, bind_error ? NULL : &bind_error)) {
822 g_object_unref (sockaddr);
826 GST_DEBUG_OBJECT (server, "failed to bind socket (%s), try next",
827 bind_error->message);
828 g_object_unref (sockaddr);
829 g_object_unref (socket);
832 g_object_unref (enumerator);
837 g_clear_error (&sock_error);
838 g_clear_error (&bind_error);
840 GST_DEBUG_OBJECT (server, "opened sending server socket");
842 /* keep connection alive; avoids SIGPIPE during write */
843 g_socket_set_keepalive (socket, TRUE);
847 /* make sure socket is reset 5 seconds after close. This ensure that we can
848 * reuse the socket quickly while still having a chance to send data to the
852 if (setsockopt (sockfd, SOL_SOCKET, SO_LINGER,
853 (void *) &linger, sizeof (linger)) < 0)
858 /* set the server socket to nonblocking */
859 g_socket_set_blocking (socket, FALSE);
861 /* set listen backlog */
862 g_socket_set_listen_backlog (socket, priv->backlog);
864 if (!g_socket_listen (socket, error))
867 GST_DEBUG_OBJECT (server, "listening on server socket %p with queue of %d",
868 socket, priv->backlog);
870 GST_RTSP_SERVER_UNLOCK (server);
877 GST_ERROR_OBJECT (server, "failed to create socket");
884 GST_ERROR_OBJECT (server, "failed to no linger socket: %s",
892 GST_ERROR_OBJECT (server, "failed to listen on socket: %s",
899 g_object_unref (socket);
903 g_propagate_error (error, sock_error);
905 g_error_free (sock_error);
908 if ((error == NULL) || (*error == NULL))
909 g_propagate_error (error, bind_error);
911 g_error_free (bind_error);
913 GST_RTSP_SERVER_UNLOCK (server);
922 GstRTSPServer *server;
924 GMainContext *mainctx;
927 /* must be called with the lock held */
929 loop_unref (Loop * loop)
931 GstRTSPServer *server = loop->server;
932 GstRTSPServerPrivate *priv = server->priv;
936 if (loop->refcnt <= 0) {
937 g_queue_remove (&priv->loops, loop);
938 g_main_loop_quit (loop->mainloop);
942 struct _ClientContext
944 GstRTSPServer *server;
946 GstRTSPClient *client;
950 free_client_context (ClientContext * ctx)
952 GST_RTSP_SERVER_LOCK (ctx->server);
954 loop_unref (ctx->loop);
955 GST_RTSP_SERVER_UNLOCK (ctx->server);
957 g_object_unref (ctx->client);
958 g_slice_free (ClientContext, ctx);
960 return G_SOURCE_REMOVE;
964 do_loop (Loop * loop)
966 GST_INFO ("enter mainloop");
967 g_main_loop_run (loop->mainloop);
968 GST_INFO ("exit mainloop");
970 g_main_context_unref (loop->mainctx);
971 g_main_loop_unref (loop->mainloop);
972 g_object_unref (loop->server);
973 g_slice_free (Loop, loop);
978 /* Must be called with lock held */
981 gst_rtsp_server_get_main_loop (GstRTSPServer * server)
983 GstRTSPServerPrivate *priv = server->priv;
986 if (priv->max_threads > 0 &&
987 g_queue_get_length (&priv->loops) >= priv->max_threads) {
988 loop = g_queue_pop_head (&priv->loops);
991 GstRTSPServerClass *klass = GST_RTSP_SERVER_GET_CLASS (server);
993 loop = g_slice_new0 (Loop);
995 loop->server = g_object_ref (server);
996 loop->mainctx = g_main_context_new ();
997 loop->mainloop = g_main_loop_new (loop->mainctx, FALSE);
999 g_thread_pool_push (klass->pool, loop, NULL);
1002 g_queue_push_tail (&priv->loops, loop);
1008 unmanage_client (GstRTSPClient * client, ClientContext * ctx)
1010 GstRTSPServer *server = ctx->server;
1011 GstRTSPServerPrivate *priv = server->priv;
1013 GST_DEBUG_OBJECT (server, "unmanage client %p", client);
1015 g_object_ref (server);
1017 GST_RTSP_SERVER_LOCK (server);
1018 priv->clients = g_list_remove (priv->clients, ctx);
1019 GST_RTSP_SERVER_UNLOCK (server);
1024 src = g_idle_source_new ();
1025 g_source_set_callback (src, (GSourceFunc) free_client_context, ctx, NULL);
1026 g_source_attach (src, ctx->loop->mainctx);
1027 g_source_unref (src);
1029 free_client_context (ctx);
1032 g_object_unref (server);
1035 /* add the client context to the active list of clients, takes ownership
1038 manage_client (GstRTSPServer * server, GstRTSPClient * client)
1041 GstRTSPServerPrivate *priv = server->priv;
1042 GMainContext *mainctx;
1044 GST_DEBUG_OBJECT (server, "manage client %p", client);
1046 ctx = g_slice_new0 (ClientContext);
1047 ctx->server = server;
1048 ctx->client = client;
1050 GST_RTSP_SERVER_LOCK (server);
1051 if (priv->max_threads == 0) {
1054 /* find the context to add the watch */
1055 if ((source = g_main_current_source ()))
1056 mainctx = g_source_get_context (source);
1060 ctx->loop = gst_rtsp_server_get_main_loop (server);
1061 mainctx = ctx->loop->mainctx;
1064 g_signal_connect (client, "closed", (GCallback) unmanage_client, ctx);
1065 priv->clients = g_list_prepend (priv->clients, ctx);
1067 gst_rtsp_client_attach (client, mainctx);
1069 GST_RTSP_SERVER_UNLOCK (server);
1072 static GstRTSPClient *
1073 default_create_client (GstRTSPServer * server)
1075 GstRTSPClient *client;
1076 GstRTSPServerPrivate *priv = server->priv;
1078 /* a new client connected, create a session to handle the client. */
1079 client = gst_rtsp_client_new ();
1081 /* set the session pool that this client should use */
1082 GST_RTSP_SERVER_LOCK (server);
1083 gst_rtsp_client_set_session_pool (client, priv->session_pool);
1084 /* set the mount points that this client should use */
1085 gst_rtsp_client_set_mount_points (client, priv->mount_points);
1086 /* set authentication manager */
1087 gst_rtsp_client_set_auth (client, priv->auth);
1088 GST_RTSP_SERVER_UNLOCK (server);
1093 /* default method for creating a new client object in the server to accept and
1094 * handle a client connection on this server */
1096 default_accept_client (GstRTSPServer * server, GstRTSPClient * client,
1097 GSocket * socket, GError ** error)
1099 /* accept connections for that client, this function returns after accepting
1100 * the connection and will run the remainder of the communication with the
1101 * client asyncronously. */
1102 if (!gst_rtsp_client_accept (client, socket, NULL, error))
1110 GST_ERROR_OBJECT (server,
1111 "Could not accept client on server : %s", (*error)->message);
1117 * gst_rtsp_server_transfer_connection:
1118 * @server: a #GstRTSPServer
1119 * @socket: a network socket
1120 * @ip: the IP address of the remote client
1121 * @port: the port used by the other end
1122 * @initial_buffer: any initial data that was already read from the socket
1124 * Take an existing network socket and use it for an RTSP connection. This
1125 * is used when transferring a socket from an HTTP server which should be used
1126 * as an RTSP over HTTP tunnel. The @initial_buffer contains any remaining data
1127 * that the HTTP server read from the socket while parsing the HTTP header.
1129 * Returns: TRUE if all was ok, FALSE if an error occured.
1132 gst_rtsp_server_transfer_connection (GstRTSPServer * server, GSocket * socket,
1133 const gchar * ip, gint port, const gchar * initial_buffer)
1135 GstRTSPClient *client = NULL;
1136 GstRTSPServerClass *klass;
1137 GError *error = NULL;
1139 klass = GST_RTSP_SERVER_GET_CLASS (server);
1141 if (klass->create_client)
1142 client = klass->create_client (server);
1146 /* a new client connected, create a client object to handle the client. */
1147 if (!gst_rtsp_client_use_socket (client, socket, ip,
1148 port, initial_buffer, &error)) {
1149 goto transfer_failed;
1152 /* manage the client connection */
1153 manage_client (server, client);
1155 g_signal_emit (server, gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED], 0,
1163 GST_ERROR_OBJECT (server, "failed to create a client");
1168 GST_ERROR_OBJECT (server, "failed to accept client: %s", error->message);
1169 g_error_free (error);
1170 g_object_unref (client);
1176 * gst_rtsp_server_io_func:
1177 * @socket: a #GSocket
1178 * @condition: the condition on @source
1179 * @server: a #GstRTSPServer
1181 * A default #GSocketSourceFunc that creates a new #GstRTSPClient to accept and handle a
1182 * new connection on @socket or @server.
1184 * Returns: TRUE if the source could be connected, FALSE if an error occured.
1187 gst_rtsp_server_io_func (GSocket * socket, GIOCondition condition,
1188 GstRTSPServer * server)
1190 gboolean result = TRUE;
1191 GstRTSPClient *client = NULL;
1192 GstRTSPServerClass *klass;
1193 GError *error = NULL;
1195 if (condition & G_IO_IN) {
1196 klass = GST_RTSP_SERVER_GET_CLASS (server);
1198 if (klass->create_client)
1199 client = klass->create_client (server);
1203 /* a new client connected, create a client object to handle the client. */
1204 if (klass->accept_client)
1205 result = klass->accept_client (server, client, socket, &error);
1209 /* manage the client connection */
1210 manage_client (server, client);
1212 g_signal_emit (server, gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED], 0,
1215 GST_WARNING_OBJECT (server, "received unknown event %08x", condition);
1222 GST_ERROR_OBJECT (server, "failed to create a client");
1227 GST_ERROR_OBJECT (server, "failed to accept client: %s", error->message);
1228 g_error_free (error);
1229 g_object_unref (client);
1235 watch_destroyed (GstRTSPServer * server)
1237 GstRTSPServerPrivate *priv = server->priv;
1239 GST_DEBUG_OBJECT (server, "source destroyed");
1241 g_object_unref (priv->socket);
1242 priv->socket = NULL;
1243 g_object_unref (server);
1247 * gst_rtsp_server_create_source:
1248 * @server: a #GstRTSPServer
1249 * @cancellable: a #GCancellable or %NULL.
1252 * Create a #GSource for @server. The new source will have a default
1253 * #GSocketSourceFunc of gst_rtsp_server_io_func().
1255 * @cancellable if not NULL can be used to cancel the source, which will cause
1256 * the source to trigger, reporting the current condition (which is likely 0
1257 * unless cancellation happened at the same time as a condition change). You can
1258 * check for this in the callback using g_cancellable_is_cancelled().
1260 * Returns: the #GSource for @server or NULL when an error occured. Free with
1264 gst_rtsp_server_create_source (GstRTSPServer * server,
1265 GCancellable * cancellable, GError ** error)
1267 GstRTSPServerPrivate *priv;
1268 GSocket *socket, *old;
1271 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
1273 priv = server->priv;
1275 socket = gst_rtsp_server_create_socket (server, NULL, error);
1279 GST_RTSP_SERVER_LOCK (server);
1281 priv->socket = g_object_ref (socket);
1282 GST_RTSP_SERVER_UNLOCK (server);
1285 g_object_unref (old);
1287 /* create a watch for reads (new connections) and possible errors */
1288 source = g_socket_create_source (socket, G_IO_IN |
1289 G_IO_ERR | G_IO_HUP | G_IO_NVAL, cancellable);
1290 g_object_unref (socket);
1292 /* configure the callback */
1293 g_source_set_callback (source,
1294 (GSourceFunc) gst_rtsp_server_io_func, g_object_ref (server),
1295 (GDestroyNotify) watch_destroyed);
1301 GST_ERROR_OBJECT (server, "failed to create socket");
1307 * gst_rtsp_server_attach:
1308 * @server: a #GstRTSPServer
1309 * @context: (allow-none): a #GMainContext
1311 * Attaches @server to @context. When the mainloop for @context is run, the
1312 * server will be dispatched. When @context is NULL, the default context will be
1315 * This function should be called when the server properties and urls are fully
1316 * configured and the server is ready to start.
1318 * Returns: the ID (greater than 0) for the source within the GMainContext.
1321 gst_rtsp_server_attach (GstRTSPServer * server, GMainContext * context)
1325 GError *error = NULL;
1327 g_return_val_if_fail (GST_IS_RTSP_SERVER (server), 0);
1329 source = gst_rtsp_server_create_source (server, NULL, &error);
1333 res = g_source_attach (source, context);
1334 g_source_unref (source);
1341 GST_ERROR_OBJECT (server, "failed to create watch: %s", error->message);
1342 g_error_free (error);