mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
Make more properties configurable in the server.
Expose the GIOChannel and GSource better to allow for more customisations.
This commit is contained in:
parent
8d2ace0026
commit
491b20bedd
2 changed files with 274 additions and 34 deletions
|
@ -22,12 +22,16 @@
|
|||
#include "rtsp-server.h"
|
||||
#include "rtsp-client.h"
|
||||
|
||||
#define TCP_BACKLOG 5
|
||||
#define DEFAULT_BACKLOG 5
|
||||
#define DEFAULT_PORT 1554
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
PROP_PORT
|
||||
PROP_0,
|
||||
PROP_BACKLOG,
|
||||
PROP_PORT,
|
||||
PROP_POOL,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstRTSPServer, gst_rtsp_server, G_TYPE_OBJECT);
|
||||
|
@ -47,16 +51,45 @@ gst_rtsp_server_class_init (GstRTSPServerClass * klass)
|
|||
gobject_class->get_property = gst_rtsp_server_get_property;
|
||||
gobject_class->set_property = gst_rtsp_server_set_property;
|
||||
|
||||
/**
|
||||
* GstRTSPServer::backlog
|
||||
*
|
||||
* The backlog argument defines the maximum length to which the queue of
|
||||
* pending connections for the server may grow. If a connection request arrives
|
||||
* when the queue is full, the client may receive an error with an indication of
|
||||
* ECONNREFUSED or, if the underlying protocol supports retransmission, the
|
||||
* request may be ignored so that a later reattempt at connection succeeds.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_BACKLOG,
|
||||
g_param_spec_int ("backlog", "Backlog", "The maximum length to which the queue "
|
||||
"of pending connections may grow",
|
||||
0, G_MAXINT, DEFAULT_BACKLOG, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
/**
|
||||
* GstRTSPServer::port
|
||||
*
|
||||
* The session port of the server. This is the port where the server will
|
||||
* listen on.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_PORT,
|
||||
g_param_spec_int ("port", "Port", "The port the server uses",
|
||||
1, 65535, DEFAULT_PORT,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_param_spec_int ("port", "Port", "The port the server uses to listen on",
|
||||
1, 65535, DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
/**
|
||||
* GstRTSPServer::pool
|
||||
*
|
||||
* The session pool of the server. By default each server has a separate
|
||||
* session pool but sessions can be shared between servers by setting the same
|
||||
* session pool on multiple servers.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_POOL,
|
||||
g_param_spec_object ("pool", "Pool", "The session pool to use for client session",
|
||||
GST_TYPE_RTSP_SESSION_POOL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_server_init (GstRTSPServer * server)
|
||||
{
|
||||
server->server_port = DEFAULT_PORT;
|
||||
server->backlog = DEFAULT_BACKLOG;
|
||||
server->pool = gst_rtsp_session_pool_new ();
|
||||
}
|
||||
|
||||
|
@ -75,6 +108,117 @@ gst_rtsp_server_new (void)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_set_port:
|
||||
* @server: a #GstRTSPServer
|
||||
* @port: the port
|
||||
*
|
||||
* Configure @server to accept connections on the given port.
|
||||
* @port should be a port number between 1 and 65535.
|
||||
*
|
||||
* This function must be called before the server is bound.
|
||||
*/
|
||||
void
|
||||
gst_rtsp_server_set_port (GstRTSPServer *server, gint port)
|
||||
{
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
g_return_if_fail (port >= 1 && port <= 65535);
|
||||
|
||||
server->server_port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_get_port:
|
||||
* @server: a #GstRTSPServer
|
||||
*
|
||||
* Get the port number on which the server will accept connections.
|
||||
*
|
||||
* Returns: the server port.
|
||||
*/
|
||||
gint
|
||||
gst_rtsp_server_get_port (GstRTSPServer *server)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
|
||||
|
||||
return server->server_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_set_backlog:
|
||||
* @server: a #GstRTSPServer
|
||||
* @backlog: the backlog
|
||||
*
|
||||
* configure the maximum amount of requests that may be queued for the
|
||||
* server.
|
||||
*
|
||||
* This function must be called before the server is bound.
|
||||
*/
|
||||
void
|
||||
gst_rtsp_server_set_backlog (GstRTSPServer *server, gint backlog)
|
||||
{
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
|
||||
server->backlog = backlog;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_get_backlog:
|
||||
* @server: a #GstRTSPServer
|
||||
*
|
||||
* The maximum amount of queued requests for the server.
|
||||
*
|
||||
* Returns: the server backlog.
|
||||
*/
|
||||
gint
|
||||
gst_rtsp_server_get_backlog (GstRTSPServer *server)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
|
||||
|
||||
return server->backlog;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_set_session_pool:
|
||||
* @server: a #GstRTSPServer
|
||||
* @pool: a #GstRTSPSessionPool
|
||||
*
|
||||
* configure @pool to be used as the session pool of @server.
|
||||
*/
|
||||
void
|
||||
gst_rtsp_server_set_session_pool (GstRTSPServer *server, GstRTSPSessionPool *pool)
|
||||
{
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
|
||||
if (server->pool)
|
||||
g_object_unref (server->pool);
|
||||
if (pool)
|
||||
pool = g_object_ref (pool);
|
||||
server->pool = pool;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_get_session_pool:
|
||||
* @server: a #GstRTSPServer
|
||||
*
|
||||
* Get the #GstRTSPSessionPool used as the session pool of @server.
|
||||
*
|
||||
* Returns: the #GstRTSPSessionPool used for sessions. g_object_unref() after
|
||||
* usage.
|
||||
*/
|
||||
GstRTSPSessionPool *
|
||||
gst_rtsp_server_get_session_pool (GstRTSPServer *server)
|
||||
{
|
||||
GstRTSPSessionPool *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
if ((result = server->pool))
|
||||
g_object_ref (result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_server_get_property (GObject *object, guint propid,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
|
@ -83,7 +227,13 @@ gst_rtsp_server_get_property (GObject *object, guint propid,
|
|||
|
||||
switch (propid) {
|
||||
case PROP_PORT:
|
||||
g_value_set_int (value, server->server_port);
|
||||
g_value_set_int (value, gst_rtsp_server_get_port (server));
|
||||
break;
|
||||
case PROP_BACKLOG:
|
||||
g_value_set_int (value, gst_rtsp_server_get_backlog (server));
|
||||
break;
|
||||
case PROP_POOL:
|
||||
g_value_take_object (value, gst_rtsp_server_get_session_pool (server));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||
|
@ -98,13 +248,20 @@ gst_rtsp_server_set_property (GObject *object, guint propid,
|
|||
|
||||
switch (propid) {
|
||||
case PROP_PORT:
|
||||
server->server_port = g_value_get_int (value);
|
||||
gst_rtsp_server_set_port (server, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_BACKLOG:
|
||||
gst_rtsp_server_set_backlog (server, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_POOL:
|
||||
gst_rtsp_server_set_session_pool (server, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare a server socket for @server and make it listen on the configured port */
|
||||
static gboolean
|
||||
gst_rtsp_server_sink_init_send (GstRTSPServer * server)
|
||||
{
|
||||
|
@ -146,8 +303,8 @@ gst_rtsp_server_sink_init_send (GstRTSPServer * server)
|
|||
fcntl (server->server_sock.fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
GST_DEBUG_OBJECT (server, "listening on server socket %d with queue of %d",
|
||||
server->server_sock.fd, TCP_BACKLOG);
|
||||
if (listen (server->server_sock.fd, TCP_BACKLOG) == -1)
|
||||
server->server_sock.fd, server->backlog);
|
||||
if (listen (server->server_sock.fd, server->backlog) == -1)
|
||||
goto listen_failed;
|
||||
|
||||
GST_DEBUG_OBJECT (server,
|
||||
|
@ -200,13 +357,22 @@ bind_failed:
|
|||
}
|
||||
}
|
||||
|
||||
/* called when an event is available on our server socket */
|
||||
static gboolean
|
||||
server_dispatch (GIOChannel *source, GIOCondition condition, GstRTSPServer *server)
|
||||
/**
|
||||
* gst_rtsp_server_io_func:
|
||||
* @channel: a #GIOChannel
|
||||
* @condition: the condition on @source
|
||||
*
|
||||
* A default #GIOFunc that creates a new #GstRTSPClient to accept and handle a
|
||||
* new connection on @channel or @server.
|
||||
*
|
||||
* Returns: TRUE if the source could be connected, FALSE if an error occured.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_server_io_func (GIOChannel *channel, GIOCondition condition, GstRTSPServer *server)
|
||||
{
|
||||
if (condition & G_IO_IN) {
|
||||
GstRTSPClient *client;
|
||||
GstRTSPClient *client;
|
||||
|
||||
if (condition & G_IO_IN) {
|
||||
/* a new client connected, create a session to handle the client. */
|
||||
client = gst_rtsp_client_new ();
|
||||
|
||||
|
@ -216,7 +382,7 @@ server_dispatch (GIOChannel *source, GIOCondition condition, GstRTSPServer *serv
|
|||
/* 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, source))
|
||||
if (!gst_rtsp_client_accept (client, channel))
|
||||
goto accept_failed;
|
||||
|
||||
/* can unref the client now, when the request is finished, it will be
|
||||
|
@ -233,10 +399,75 @@ accept_failed:
|
|||
{
|
||||
g_error ("Could not accept client on server socket %d: %s (%d)",
|
||||
server->server_sock.fd, g_strerror (errno), errno);
|
||||
gst_object_unref (client);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_get_io_channel:
|
||||
* @server: a #GstRTSPServer
|
||||
*
|
||||
* Create a #GIOChannel for @server.
|
||||
*
|
||||
* Returns: the GIOChannel for @server or NULL when an error occured.
|
||||
*/
|
||||
GIOChannel *
|
||||
gst_rtsp_server_get_io_channel (GstRTSPServer *server)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
if (server->io_channel == NULL) {
|
||||
if (!gst_rtsp_server_sink_init_send (server))
|
||||
goto init_failed;
|
||||
|
||||
/* create IO channel for the socket */
|
||||
server->io_channel = g_io_channel_unix_new (server->server_sock.fd);
|
||||
}
|
||||
return server->io_channel;
|
||||
|
||||
init_failed:
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_create_watch:
|
||||
* @server: a #GstRTSPServer
|
||||
*
|
||||
* Create a #GSource for @server. The new source will have a default
|
||||
* #GIOFunc of gst_rtsp_server_io_func().
|
||||
*
|
||||
* Returns: the #GSource for @server or NULL when an error occured.
|
||||
*/
|
||||
GSource *
|
||||
gst_rtsp_server_create_watch (GstRTSPServer *server)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
if (server->io_watch == NULL) {
|
||||
GIOChannel *channel;
|
||||
|
||||
channel = gst_rtsp_server_get_io_channel (server);
|
||||
if (channel == NULL)
|
||||
goto no_channel;
|
||||
|
||||
/* create a watch for reads (new connections) and possible errors */
|
||||
server->io_watch = g_io_create_watch (channel, G_IO_IN |
|
||||
G_IO_ERR | G_IO_HUP | G_IO_NVAL);
|
||||
|
||||
/* configure the callback */
|
||||
g_source_set_callback (server->io_watch, (GSourceFunc) gst_rtsp_server_io_func, server, NULL);
|
||||
}
|
||||
return server->io_watch;
|
||||
|
||||
no_channel:
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_attach:
|
||||
* @server: a #GstRTSPServer
|
||||
|
@ -254,26 +485,20 @@ guint
|
|||
gst_rtsp_server_attach (GstRTSPServer *server, GMainContext *context)
|
||||
{
|
||||
guint res;
|
||||
GSource *source;
|
||||
|
||||
if (!gst_rtsp_server_sink_init_send (server))
|
||||
goto init_failed;
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), 0);
|
||||
|
||||
/* create IO channel for the socket */
|
||||
server->io_channel = g_io_channel_unix_new (server->server_sock.fd);
|
||||
source = gst_rtsp_server_create_watch (server);
|
||||
if (source == NULL)
|
||||
goto no_source;
|
||||
|
||||
/* create a watch for reads (new connections) and possible errors */
|
||||
server->io_watch = g_io_create_watch (server->io_channel, G_IO_IN |
|
||||
G_IO_ERR | G_IO_HUP | G_IO_NVAL);
|
||||
|
||||
/* configure the callback */
|
||||
g_source_set_callback (server->io_watch, (GSourceFunc) server_dispatch, server, NULL);
|
||||
|
||||
res = g_source_attach (server->io_watch, context);
|
||||
res = g_source_attach (source, context);
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
init_failed:
|
||||
no_source:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ struct _GstRTSPServer {
|
|||
GObject parent;
|
||||
|
||||
/* server information */
|
||||
int server_port;
|
||||
gint server_port;
|
||||
gint backlog;
|
||||
gchar *host;
|
||||
struct sockaddr_in server_sin;
|
||||
|
||||
|
@ -74,12 +75,26 @@ struct _GstRTSPServerClass {
|
|||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_rtsp_server_get_type (void);
|
||||
GType gst_rtsp_server_get_type (void);
|
||||
|
||||
GstRTSPServer * gst_rtsp_server_new (void);
|
||||
GstRTSPServer * gst_rtsp_server_new (void);
|
||||
|
||||
guint gst_rtsp_server_attach (GstRTSPServer *server,
|
||||
GMainContext *context);
|
||||
void gst_rtsp_server_set_port (GstRTSPServer *server, gint port);
|
||||
gint gst_rtsp_server_get_port (GstRTSPServer *server);
|
||||
|
||||
void gst_rtsp_server_set_backlog (GstRTSPServer *server, gint backlog);
|
||||
gint gst_rtsp_server_get_backlog (GstRTSPServer *server);
|
||||
|
||||
void gst_rtsp_server_set_session_pool (GstRTSPServer *server, GstRTSPSessionPool *pool);
|
||||
GstRTSPSessionPool * gst_rtsp_server_get_session_pool (GstRTSPServer *server);
|
||||
|
||||
gboolean gst_rtsp_server_io_func (GIOChannel *channel, GIOCondition condition,
|
||||
GstRTSPServer *server);
|
||||
|
||||
GIOChannel * gst_rtsp_server_get_io_channel (GstRTSPServer *server);
|
||||
GSource * gst_rtsp_server_create_watch (GstRTSPServer *server);
|
||||
guint gst_rtsp_server_attach (GstRTSPServer *server,
|
||||
GMainContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
Loading…
Reference in a new issue