const GValue * value, GParamSpec * pspec);
static void gst_rtsp_server_finalize (GObject * object);
-static GstRTSPClient *default_accept_client (GstRTSPServer * server,
- GIOChannel * channel);
+static GstRTSPClient *default_create_client (GstRTSPServer * server);
+static gboolean default_accept_client (GstRTSPServer * server,
+ GstRTSPClient * client, GIOChannel * channel);
static void
gst_rtsp_server_class_init (GstRTSPServerClass * klass)
GST_TYPE_RTSP_MEDIA_MAPPING,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ klass->create_client = default_create_client;
klass->accept_client = default_accept_client;
GST_DEBUG_CATEGORY_INIT (rtsp_server_debug, "rtspserver", 0, "GstRTSPServer");
static void
gst_rtsp_server_init (GstRTSPServer * server)
{
+ server->lock = g_mutex_new ();
server->address = g_strdup (DEFAULT_ADDRESS);
server->service = g_strdup (DEFAULT_SERVICE);
server->backlog = DEFAULT_BACKLOG;
{
GstRTSPServer *server = GST_RTSP_SERVER (object);
+ g_mutex_free (server->lock);
g_free (server->address);
g_free (server->service);
}
}
-/* default method for creating a new client object in the server to accept and
- * handle a client connection on this server */
+/* add the client to the active list of clients, takes ownership of
+ * the client */
+static void
+manage_client (GstRTSPServer * server, GstRTSPClient * client)
+{
+ gst_rtsp_client_set_server (client, server);
+
+ /* can unref the client now, when the request is finished, it will be
+ * unreffed async. */
+ gst_object_unref (client);
+}
+
static GstRTSPClient *
-default_accept_client (GstRTSPServer * server, GIOChannel * channel)
+default_create_client (GstRTSPServer * server)
{
GstRTSPClient *client;
/* set authentication manager */
gst_rtsp_client_set_auth (client, server->auth);
+ return client;
+}
+
+/* default method for creating a new client object in the server to accept and
+ * handle a client connection on this server */
+static gboolean
+default_accept_client (GstRTSPServer * server, GstRTSPClient * client,
+ GIOChannel * channel)
+{
/* accept connections for that client, this function returns after accepting
* the connection and will run the remainder of the communication with the
* client asyncronously. */
if (!gst_rtsp_client_accept (client, channel))
goto accept_failed;
- return client;
+ return TRUE;
/* ERRORS */
accept_failed:
GST_ERROR_OBJECT (server,
"Could not accept client on server socket %d: %s (%d)",
server->server_sock.fd, g_strerror (errno), errno);
- gst_object_unref (client);
- return NULL;
+ return FALSE;
}
}
gst_rtsp_server_io_func (GIOChannel * channel, GIOCondition condition,
GstRTSPServer * server)
{
+ gboolean result;
GstRTSPClient *client = NULL;
GstRTSPServerClass *klass;
if (condition & G_IO_IN) {
klass = GST_RTSP_SERVER_GET_CLASS (server);
- /* a new client connected, create a client object to handle the client. */
- if (klass->accept_client)
- client = klass->accept_client (server, channel);
+ if (klass->create_client)
+ client = klass->create_client (server);
if (client == NULL)
goto client_failed;
- /* can unref the client now, when the request is finished, it will be
- * unreffed async. */
- gst_object_unref (client);
+ /* a new client connected, create a client object to handle the client. */
+ if (klass->accept_client)
+ result = klass->accept_client (server, client, channel);
+ if (!result)
+ goto accept_failed;
+
+ /* manage the client connection */
+ manage_client (server, client);
} else {
GST_WARNING_OBJECT (server, "received unknown event %08x", condition);
}
GST_ERROR_OBJECT (server, "failed to create a client");
return FALSE;
}
+accept_failed:
+ {
+ GST_ERROR_OBJECT (server, "failed to accept client");
+ gst_object_unref (client);
+ return FALSE;
+ }
}
/**
#include <fcntl.h>
#include <arpa/inet.h>
+#ifndef __GST_RTSP_SERVER_H__
+#define __GST_RTSP_SERVER_H__
+
#include <gst/gst.h>
+G_BEGIN_DECLS
+
+typedef struct _GstRTSPServer GstRTSPServer;
+typedef struct _GstRTSPServerClass GstRTSPServerClass;
+
#include "rtsp-session-pool.h"
#include "rtsp-media-mapping.h"
#include "rtsp-media-factory-uri.h"
#include "rtsp-client.h"
#include "rtsp-auth.h"
-#ifndef __GST_RTSP_SERVER_H__
-#define __GST_RTSP_SERVER_H__
-
-G_BEGIN_DECLS
-
#define GST_TYPE_RTSP_SERVER (gst_rtsp_server_get_type ())
#define GST_IS_RTSP_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_SERVER))
#define GST_IS_RTSP_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_SERVER))
#define GST_RTSP_SERVER_CAST(obj) ((GstRTSPServer*)(obj))
#define GST_RTSP_SERVER_CLASS_CAST(klass) ((GstRTSPServerClass*)(klass))
-typedef struct _GstRTSPServer GstRTSPServer;
-typedef struct _GstRTSPServerClass GstRTSPServerClass;
-
+/**
+ * GstRTSPServer:
+ *
+ * This object listens on a port, creates and manages the clients connected to
+ * it.
+ */
struct _GstRTSPServer {
- GObject parent;
+ GObject parent;
+
+ GMutex *lock;
/* server information */
- gchar *address;
- gchar *service;
- gint backlog;
+ gchar *address;
+ gchar *service;
+ gint backlog;
struct sockaddr_in server_sin;
/* authentication manager */
GstRTSPAuth *auth;
+
+ /* the clients that are connected */
+ GList *clients;
};
/**
* GstRTSPServerClass:
*
- * @accept_client: Create, configure, accept and return a new GstRTSPClient
- * object that handles the new connection on @channel.
+ * @create_client: Create, configure a new GstRTSPClient
+ * object that handles the new connection on @channel.
+ * @accept_client: accept a new GstRTSPClient
*
* The RTSP server class structure
*/
struct _GstRTSPServerClass {
GObjectClass parent_class;
- GstRTSPClient * (*accept_client) (GstRTSPServer *server, GIOChannel *channel);
+ GstRTSPClient * (*create_client) (GstRTSPServer *server);
+ gboolean (*accept_client) (GstRTSPServer *server, GstRTSPClient *client, GIOChannel *channel);
};
GType gst_rtsp_server_get_type (void);