mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
Add beginnings of session timeouts and limits
Add the timeout value to the Session header for unusual timeout values. Allow us to configure a limit to the amount of active sessions in a pool. Set a limit on the amount of retry we do after a sessionid collision. Add properties to the sessionid and the timeout of a session. Keep track of creation time and last access time for sessions.
This commit is contained in:
parent
e789a8fdf3
commit
aedd4652f3
5 changed files with 341 additions and 17 deletions
|
@ -561,8 +561,16 @@ handle_setup_request (GstRTSPClient *client, GstRTSPUrl *uri, GstRTSPMessage *re
|
||||||
gst_rtsp_message_init_response (&response, code, gst_rtsp_status_as_text (code), request);
|
gst_rtsp_message_init_response (&response, code, gst_rtsp_status_as_text (code), request);
|
||||||
|
|
||||||
/* add the new session header for new session ids */
|
/* add the new session header for new session ids */
|
||||||
if (need_session)
|
if (need_session) {
|
||||||
gst_rtsp_message_add_header (&response, GST_RTSP_HDR_SESSION, session->sessionid);
|
gchar *str;
|
||||||
|
|
||||||
|
if (session->timeout != 60)
|
||||||
|
str = g_strdup_printf ("%s; timeout=%d", session->sessionid, session->timeout);
|
||||||
|
else
|
||||||
|
str = g_strdup (session->sessionid);
|
||||||
|
|
||||||
|
gst_rtsp_message_take_header (&response, GST_RTSP_HDR_SESSION, str);
|
||||||
|
}
|
||||||
|
|
||||||
gst_rtsp_message_add_header (&response, GST_RTSP_HDR_TRANSPORT, trans_str);
|
gst_rtsp_message_add_header (&response, GST_RTSP_HDR_TRANSPORT, trans_str);
|
||||||
g_free (trans_str);
|
g_free (trans_str);
|
||||||
|
|
|
@ -21,6 +21,19 @@
|
||||||
|
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
|
#define DEFAULT_MAX_SESSIONS 0
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_MAX_SESSIONS,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gst_rtsp_session_pool_get_property (GObject *object, guint propid,
|
||||||
|
GValue *value, GParamSpec *pspec);
|
||||||
|
static void gst_rtsp_session_pool_set_property (GObject *object, guint propid,
|
||||||
|
const GValue *value, GParamSpec *pspec);
|
||||||
static void gst_rtsp_session_pool_finalize (GObject * object);
|
static void gst_rtsp_session_pool_finalize (GObject * object);
|
||||||
|
|
||||||
static gchar * create_session_id (GstRTSPSessionPool *pool);
|
static gchar * create_session_id (GstRTSPSessionPool *pool);
|
||||||
|
@ -34,8 +47,16 @@ gst_rtsp_session_pool_class_init (GstRTSPSessionPoolClass * klass)
|
||||||
|
|
||||||
gobject_class = G_OBJECT_CLASS (klass);
|
gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->get_property = gst_rtsp_session_pool_get_property;
|
||||||
|
gobject_class->set_property = gst_rtsp_session_pool_set_property;
|
||||||
gobject_class->finalize = gst_rtsp_session_pool_finalize;
|
gobject_class->finalize = gst_rtsp_session_pool_finalize;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MAX_SESSIONS,
|
||||||
|
g_param_spec_uint ("max-sessions", "Max Sessions",
|
||||||
|
"the maximum amount of sessions (0 = unlimited)",
|
||||||
|
0, G_MAXUINT, DEFAULT_MAX_SESSIONS,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
klass->create_session_id = create_session_id;
|
klass->create_session_id = create_session_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +66,7 @@ gst_rtsp_session_pool_init (GstRTSPSessionPool * pool)
|
||||||
pool->lock = g_mutex_new ();
|
pool->lock = g_mutex_new ();
|
||||||
pool->sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
pool->sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
NULL, g_object_unref);
|
NULL, g_object_unref);
|
||||||
|
pool->max_sessions = DEFAULT_MAX_SESSIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -58,6 +80,42 @@ gst_rtsp_session_pool_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (gst_rtsp_session_pool_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gst_rtsp_session_pool_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_rtsp_session_pool_get_property (GObject *object, guint propid,
|
||||||
|
GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GstRTSPSessionPool *pool = GST_RTSP_SESSION_POOL (object);
|
||||||
|
|
||||||
|
switch (propid) {
|
||||||
|
case PROP_MAX_SESSIONS:
|
||||||
|
g_mutex_lock (pool->lock);
|
||||||
|
g_value_set_uint (value, pool->max_sessions);
|
||||||
|
g_mutex_unlock (pool->lock);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_rtsp_session_pool_set_property (GObject *object, guint propid,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GstRTSPSessionPool *pool = GST_RTSP_SESSION_POOL (object);
|
||||||
|
|
||||||
|
switch (propid) {
|
||||||
|
case PROP_MAX_SESSIONS:
|
||||||
|
g_mutex_lock (pool->lock);
|
||||||
|
pool->max_sessions = g_value_get_uint (value);
|
||||||
|
g_mutex_unlock (pool->lock);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_pool_new:
|
* gst_rtsp_session_pool_new:
|
||||||
*
|
*
|
||||||
|
@ -75,12 +133,76 @@ gst_rtsp_session_pool_new (void)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_pool_set_max_sessions:
|
||||||
|
* @pool: a #GstRTSPSessionPool
|
||||||
|
* @max: the maximum number of sessions
|
||||||
|
*
|
||||||
|
* Configure the maximum allowed number of sessions in @pool to @max.
|
||||||
|
* A value of 0 means an unlimited amount of sessions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_rtsp_session_pool_set_max_sessions (GstRTSPSessionPool *pool, guint max)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_RTSP_SESSION_POOL (pool));
|
||||||
|
|
||||||
|
g_mutex_lock (pool->lock);
|
||||||
|
pool->max_sessions = max;
|
||||||
|
g_mutex_unlock (pool->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_pool_get_max_sessions:
|
||||||
|
* @pool: a #GstRTSPSessionPool
|
||||||
|
*
|
||||||
|
* Get the maximum allowed number of sessions in @pool. 0 means an unlimited
|
||||||
|
* amount of sessions.
|
||||||
|
*
|
||||||
|
* Returns: the maximum allowed number of sessions.
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
gst_rtsp_session_pool_get_max_sessions (GstRTSPSessionPool *pool)
|
||||||
|
{
|
||||||
|
guint result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0);
|
||||||
|
|
||||||
|
g_mutex_lock (pool->lock);
|
||||||
|
result = pool->max_sessions;
|
||||||
|
g_mutex_unlock (pool->lock);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_pool_get_n_sessions:
|
||||||
|
* @pool: a #GstRTSPSessionPool
|
||||||
|
*
|
||||||
|
* Get the amount of active sessions in @pool.
|
||||||
|
*
|
||||||
|
* Returns: the amount of active sessions in @pool.
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
gst_rtsp_session_pool_get_n_sessions (GstRTSPSessionPool *pool)
|
||||||
|
{
|
||||||
|
guint result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0);
|
||||||
|
|
||||||
|
g_mutex_lock (pool->lock);
|
||||||
|
result = g_hash_table_size (pool->sessions);
|
||||||
|
g_mutex_unlock (pool->lock);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_pool_find:
|
* gst_rtsp_session_pool_find:
|
||||||
* @pool: the pool to search
|
* @pool: the pool to search
|
||||||
* @sessionid: the session id
|
* @sessionid: the session id
|
||||||
*
|
*
|
||||||
* Find the session with @sessionid in @pool.
|
* Find the session with @sessionid in @pool. The access time of the session
|
||||||
|
* will be updated with gst_rtsp_session_touch().
|
||||||
*
|
*
|
||||||
* Returns: the #GstRTSPSession with @sessionid or %NULL when the session did
|
* Returns: the #GstRTSPSession with @sessionid or %NULL when the session did
|
||||||
* not exist. g_object_unref() after usage.
|
* not exist. g_object_unref() after usage.
|
||||||
|
@ -95,10 +217,13 @@ gst_rtsp_session_pool_find (GstRTSPSessionPool *pool, const gchar *sessionid)
|
||||||
|
|
||||||
g_mutex_lock (pool->lock);
|
g_mutex_lock (pool->lock);
|
||||||
result = g_hash_table_lookup (pool->sessions, sessionid);
|
result = g_hash_table_lookup (pool->sessions, sessionid);
|
||||||
if (result)
|
if (result)
|
||||||
g_object_ref (result);
|
g_object_ref (result);
|
||||||
g_mutex_unlock (pool->lock);
|
g_mutex_unlock (pool->lock);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
gst_rtsp_session_touch (result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,11 +254,13 @@ gst_rtsp_session_pool_create (GstRTSPSessionPool *pool)
|
||||||
GstRTSPSession *result = NULL;
|
GstRTSPSession *result = NULL;
|
||||||
GstRTSPSessionPoolClass *klass;
|
GstRTSPSessionPoolClass *klass;
|
||||||
gchar *id = NULL;
|
gchar *id = NULL;
|
||||||
|
guint retry;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL);
|
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL);
|
||||||
|
|
||||||
klass = GST_RTSP_SESSION_POOL_GET_CLASS (pool);
|
klass = GST_RTSP_SESSION_POOL_GET_CLASS (pool);
|
||||||
|
|
||||||
|
retry = 0;
|
||||||
do {
|
do {
|
||||||
/* start by creating a new random session id, we assume that this is random
|
/* start by creating a new random session id, we assume that this is random
|
||||||
* enough to not cause a collision, which we will check later */
|
* enough to not cause a collision, which we will check later */
|
||||||
|
@ -146,11 +273,19 @@ gst_rtsp_session_pool_create (GstRTSPSessionPool *pool)
|
||||||
goto no_session;
|
goto no_session;
|
||||||
|
|
||||||
g_mutex_lock (pool->lock);
|
g_mutex_lock (pool->lock);
|
||||||
|
/* check session limit */
|
||||||
|
if (pool->max_sessions > 0) {
|
||||||
|
if (g_hash_table_size (pool->sessions) >= pool->max_sessions)
|
||||||
|
goto too_many_sessions;
|
||||||
|
}
|
||||||
/* check if the sessionid existed */
|
/* check if the sessionid existed */
|
||||||
result = g_hash_table_lookup (pool->sessions, id);
|
result = g_hash_table_lookup (pool->sessions, id);
|
||||||
if (result) {
|
if (result) {
|
||||||
/* found, retry with a different session id*/
|
/* found, retry with a different session id */
|
||||||
result = NULL;
|
result = NULL;
|
||||||
|
retry++;
|
||||||
|
if (retry > 100)
|
||||||
|
goto collision;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* not found, create session and insert it in the pool */
|
/* not found, create session and insert it in the pool */
|
||||||
|
@ -177,6 +312,20 @@ no_session:
|
||||||
g_warning ("can't create session id with GstRTSPSessionPool %p", pool);
|
g_warning ("can't create session id with GstRTSPSessionPool %p", pool);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
collision:
|
||||||
|
{
|
||||||
|
g_warning ("can't find unique sessionid for GstRTSPSessionPool %p", pool);
|
||||||
|
g_mutex_unlock (pool->lock);
|
||||||
|
g_free (id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
too_many_sessions:
|
||||||
|
{
|
||||||
|
g_warning ("session pool reached max sessions of %d", pool->max_sessions);
|
||||||
|
g_mutex_unlock (pool->lock);
|
||||||
|
g_free (id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,20 +333,22 @@ no_session:
|
||||||
* @pool: a #GstRTSPSessionPool
|
* @pool: a #GstRTSPSessionPool
|
||||||
* @sess: a #GstRTSPSession
|
* @sess: a #GstRTSPSession
|
||||||
*
|
*
|
||||||
* Remove @sess from @pool and Clean it up.
|
* Remove @sess from @pool, releasing the ref that the pool has on @sess.
|
||||||
*
|
*
|
||||||
* Returns: a new #GstRTSPSession.
|
* Returns: %TRUE if the session was found and removed.
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_rtsp_session_pool_remove (GstRTSPSessionPool *pool, GstRTSPSession *sess)
|
gst_rtsp_session_pool_remove (GstRTSPSessionPool *pool, GstRTSPSession *sess)
|
||||||
{
|
{
|
||||||
gboolean found;
|
gboolean found;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_RTSP_SESSION_POOL (pool));
|
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), FALSE);
|
||||||
g_return_if_fail (GST_IS_RTSP_SESSION (sess));
|
g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), FALSE);
|
||||||
|
|
||||||
g_mutex_lock (pool->lock);
|
g_mutex_lock (pool->lock);
|
||||||
found = g_hash_table_remove (pool->sessions, sess->sessionid);
|
found = g_hash_table_remove (pool->sessions, sess->sessionid);
|
||||||
g_mutex_unlock (pool->lock);
|
g_mutex_unlock (pool->lock);
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ typedef struct _GstRTSPSessionPoolClass GstRTSPSessionPoolClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRTSPSessionPool:
|
* GstRTSPSessionPool:
|
||||||
*
|
* @max_sessions: the maximum number of sessions.
|
||||||
* @lock: locking the session hashtable
|
* @lock: locking the session hashtable
|
||||||
* @session: hashtable of sessions indexed by the session id.
|
* @session: hashtable of sessions indexed by the session id.
|
||||||
*
|
*
|
||||||
|
@ -50,6 +50,8 @@ typedef struct _GstRTSPSessionPoolClass GstRTSPSessionPoolClass;
|
||||||
struct _GstRTSPSessionPool {
|
struct _GstRTSPSessionPool {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
|
guint max_sessions;
|
||||||
|
|
||||||
GMutex *lock;
|
GMutex *lock;
|
||||||
GHashTable *sessions;
|
GHashTable *sessions;
|
||||||
};
|
};
|
||||||
|
@ -57,7 +59,7 @@ struct _GstRTSPSessionPool {
|
||||||
/**
|
/**
|
||||||
* GstRTSPSessionPoolClass:
|
* GstRTSPSessionPoolClass:
|
||||||
* @create_session_id: create a new random session id. Subclasses can create
|
* @create_session_id: create a new random session id. Subclasses can create
|
||||||
* custom session ids and should not check if the session exists.
|
* custom session ids and should not check if the session exists.
|
||||||
*/
|
*/
|
||||||
struct _GstRTSPSessionPoolClass {
|
struct _GstRTSPSessionPoolClass {
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
@ -67,12 +69,20 @@ struct _GstRTSPSessionPoolClass {
|
||||||
|
|
||||||
GType gst_rtsp_session_pool_get_type (void);
|
GType gst_rtsp_session_pool_get_type (void);
|
||||||
|
|
||||||
|
/* creating a session pool */
|
||||||
GstRTSPSessionPool * gst_rtsp_session_pool_new (void);
|
GstRTSPSessionPool * gst_rtsp_session_pool_new (void);
|
||||||
|
|
||||||
|
/* counting sessionss */
|
||||||
|
void gst_rtsp_session_pool_set_max_sessions (GstRTSPSessionPool *pool, guint max);
|
||||||
|
guint gst_rtsp_session_pool_get_max_sessions (GstRTSPSessionPool *pool);
|
||||||
|
|
||||||
|
guint gst_rtsp_session_pool_get_n_sessions (GstRTSPSessionPool *pool);
|
||||||
|
|
||||||
|
/* managing sessions */
|
||||||
|
GstRTSPSession * gst_rtsp_session_pool_create (GstRTSPSessionPool *pool);
|
||||||
GstRTSPSession * gst_rtsp_session_pool_find (GstRTSPSessionPool *pool,
|
GstRTSPSession * gst_rtsp_session_pool_find (GstRTSPSessionPool *pool,
|
||||||
const gchar *sessionid);
|
const gchar *sessionid);
|
||||||
GstRTSPSession * gst_rtsp_session_pool_create (GstRTSPSessionPool *pool);
|
gboolean gst_rtsp_session_pool_remove (GstRTSPSessionPool *pool,
|
||||||
void gst_rtsp_session_pool_remove (GstRTSPSessionPool *pool,
|
|
||||||
GstRTSPSession *sess);
|
GstRTSPSession *sess);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -22,6 +22,20 @@
|
||||||
|
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
|
#define DEFAULT_TIMEOUT 60
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_SESSIONID,
|
||||||
|
PROP_TIMEOUT,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gst_rtsp_session_get_property (GObject *object, guint propid,
|
||||||
|
GValue *value, GParamSpec *pspec);
|
||||||
|
static void gst_rtsp_session_set_property (GObject *object, guint propid,
|
||||||
|
const GValue *value, GParamSpec *pspec);
|
||||||
static void gst_rtsp_session_finalize (GObject * obj);
|
static void gst_rtsp_session_finalize (GObject * obj);
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstRTSPSession, gst_rtsp_session, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (GstRTSPSession, gst_rtsp_session, G_TYPE_OBJECT);
|
||||||
|
@ -33,12 +47,26 @@ gst_rtsp_session_class_init (GstRTSPSessionClass * klass)
|
||||||
|
|
||||||
gobject_class = G_OBJECT_CLASS (klass);
|
gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->get_property = gst_rtsp_session_get_property;
|
||||||
|
gobject_class->set_property = gst_rtsp_session_set_property;
|
||||||
gobject_class->finalize = gst_rtsp_session_finalize;
|
gobject_class->finalize = gst_rtsp_session_finalize;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_SESSIONID,
|
||||||
|
g_param_spec_string ("sessionid", "Sessionid", "the session id",
|
||||||
|
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_TIMEOUT,
|
||||||
|
g_param_spec_uint ("timeout", "timeout", "the timeout of the session (0 = never)",
|
||||||
|
0, G_MAXUINT, DEFAULT_TIMEOUT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtsp_session_init (GstRTSPSession * session)
|
gst_rtsp_session_init (GstRTSPSession * session)
|
||||||
{
|
{
|
||||||
|
session->timeout = DEFAULT_TIMEOUT;
|
||||||
|
g_get_current_time (&session->create_time);
|
||||||
|
gst_rtsp_session_touch (session);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -100,6 +128,43 @@ gst_rtsp_session_finalize (GObject * obj)
|
||||||
G_OBJECT_CLASS (gst_rtsp_session_parent_class)->finalize (obj);
|
G_OBJECT_CLASS (gst_rtsp_session_parent_class)->finalize (obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_rtsp_session_get_property (GObject *object, guint propid,
|
||||||
|
GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GstRTSPSession *session = GST_RTSP_SESSION (object);
|
||||||
|
|
||||||
|
switch (propid) {
|
||||||
|
case PROP_SESSIONID:
|
||||||
|
g_value_set_string (value, session->sessionid);
|
||||||
|
break;
|
||||||
|
case PROP_TIMEOUT:
|
||||||
|
g_value_set_uint (value, gst_rtsp_session_get_timeout (session));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_rtsp_session_set_property (GObject *object, guint propid,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GstRTSPSession *session = GST_RTSP_SESSION (object);
|
||||||
|
|
||||||
|
switch (propid) {
|
||||||
|
case PROP_SESSIONID:
|
||||||
|
g_free (session->sessionid);
|
||||||
|
session->sessionid = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
case PROP_TIMEOUT:
|
||||||
|
gst_rtsp_session_set_timeout (session, g_value_get_uint (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_manage_media:
|
* gst_rtsp_session_manage_media:
|
||||||
* @sess: a #GstRTSPSession
|
* @sess: a #GstRTSPSession
|
||||||
|
@ -262,12 +327,76 @@ gst_rtsp_session_new (const gchar *sessionid)
|
||||||
{
|
{
|
||||||
GstRTSPSession *result;
|
GstRTSPSession *result;
|
||||||
|
|
||||||
result = g_object_new (GST_TYPE_RTSP_SESSION, NULL);
|
g_return_val_if_fail (sessionid != NULL, NULL);
|
||||||
result->sessionid = g_strdup (sessionid);
|
|
||||||
|
result = g_object_new (GST_TYPE_RTSP_SESSION, "sessionid", sessionid, NULL);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_get_sessionid:
|
||||||
|
* @session: a #GstRTSPSession
|
||||||
|
*
|
||||||
|
* Get the sessionid of @session.
|
||||||
|
*
|
||||||
|
* Returns: the sessionid of @session. The value remains valid as long as
|
||||||
|
* @session is alive.
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
gst_rtsp_session_get_sessionid (GstRTSPSession *session)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_RTSP_SESSION (session), NULL);
|
||||||
|
|
||||||
|
return session->sessionid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_set_timeout:
|
||||||
|
* @session: a #GstRTSPSession
|
||||||
|
* @timeout: the new timeout
|
||||||
|
*
|
||||||
|
* Configure @session for a timeout of @timeout seconds. The session will be
|
||||||
|
* cleaned up when there is no activity for @timeout seconds.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_rtsp_session_set_timeout (GstRTSPSession *session, guint timeout)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_RTSP_SESSION (session));
|
||||||
|
|
||||||
|
session->timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_get_timeout:
|
||||||
|
* @session: a #GstRTSPSession
|
||||||
|
*
|
||||||
|
* Get the timeout value of @session.
|
||||||
|
*
|
||||||
|
* Returns: the timeout of @session in seconds.
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
gst_rtsp_session_get_timeout (GstRTSPSession *session)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_RTSP_SESSION (session), 0);
|
||||||
|
|
||||||
|
return session->timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_touch:
|
||||||
|
* @session: a #GstRTSPSession
|
||||||
|
*
|
||||||
|
* Update the last_access time of the session to the current time.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_rtsp_session_touch (GstRTSPSession *session)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_RTSP_SESSION (session));
|
||||||
|
|
||||||
|
g_get_current_time (&session->last_access);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_stream_init_udp:
|
* gst_rtsp_session_stream_init_udp:
|
||||||
* @stream: a #GstRTSPSessionStream
|
* @stream: a #GstRTSPSessionStream
|
||||||
|
@ -284,6 +413,9 @@ gst_rtsp_session_stream_set_transport (GstRTSPSessionStream *stream,
|
||||||
{
|
{
|
||||||
GstRTSPTransport *st;
|
GstRTSPTransport *st;
|
||||||
|
|
||||||
|
g_return_val_if_fail (stream != NULL, NULL);
|
||||||
|
g_return_val_if_fail (ct != NULL, NULL);
|
||||||
|
|
||||||
/* prepare the server transport */
|
/* prepare the server transport */
|
||||||
gst_rtsp_transport_new (&st);
|
gst_rtsp_transport_new (&st);
|
||||||
|
|
||||||
|
@ -316,6 +448,8 @@ gst_rtsp_session_media_play (GstRTSPSessionMedia *media)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (media != NULL, FALSE);
|
||||||
|
|
||||||
ret = gst_rtsp_media_play (media->media, media->streams);
|
ret = gst_rtsp_media_play (media->media, media->streams);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -334,6 +468,8 @@ gst_rtsp_session_media_pause (GstRTSPSessionMedia *media)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (media != NULL, FALSE);
|
||||||
|
|
||||||
ret = gst_rtsp_media_pause (media->media, media->streams);
|
ret = gst_rtsp_media_pause (media->media, media->streams);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -353,6 +489,8 @@ gst_rtsp_session_media_stop (GstRTSPSessionMedia *media)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (media != NULL, FALSE);
|
||||||
|
|
||||||
ret = gst_rtsp_media_stop (media->media, media->streams);
|
ret = gst_rtsp_media_stop (media->media, media->streams);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -81,16 +81,25 @@ struct _GstRTSPSessionMedia
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRTSPSession:
|
* GstRTSPSession:
|
||||||
|
* @sessionid: the session id of the session
|
||||||
|
* @timeout: the timeout of the session
|
||||||
|
* @create_time: the time when the session was created
|
||||||
|
* @last_access: the time the session was last accessed
|
||||||
|
* @media: a list of #GstRTSPSessionMedia managed in this session
|
||||||
*
|
*
|
||||||
* Session information kept by the server for a specific client.
|
* Session information kept by the server for a specific client.
|
||||||
* One client session, identified with a session id, can handle multiple medias
|
* One client session, identified with a session id, can handle multiple medias
|
||||||
* identified with the media object.
|
* identified with the url of a media.
|
||||||
*/
|
*/
|
||||||
struct _GstRTSPSession {
|
struct _GstRTSPSession {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
gchar *sessionid;
|
gchar *sessionid;
|
||||||
|
|
||||||
|
guint timeout;
|
||||||
|
GTimeVal create_time;
|
||||||
|
GTimeVal last_access;
|
||||||
|
|
||||||
GList *medias;
|
GList *medias;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,6 +112,14 @@ GType gst_rtsp_session_get_type (void);
|
||||||
/* create a new session */
|
/* create a new session */
|
||||||
GstRTSPSession * gst_rtsp_session_new (const gchar *sessionid);
|
GstRTSPSession * gst_rtsp_session_new (const gchar *sessionid);
|
||||||
|
|
||||||
|
const gchar * gst_rtsp_session_get_sessionid (GstRTSPSession *session);
|
||||||
|
|
||||||
|
void gst_rtsp_session_set_timeout (GstRTSPSession *session, guint timeout);
|
||||||
|
guint gst_rtsp_session_get_timeout (GstRTSPSession *session);
|
||||||
|
|
||||||
|
/* touch the session, update last_access */
|
||||||
|
void gst_rtsp_session_touch (GstRTSPSession *session);
|
||||||
|
|
||||||
/* handle media in a session */
|
/* handle media in a session */
|
||||||
GstRTSPSessionMedia * gst_rtsp_session_manage_media (GstRTSPSession *sess,
|
GstRTSPSessionMedia * gst_rtsp_session_manage_media (GstRTSPSession *sess,
|
||||||
const GstRTSPUrl *uri,
|
const GstRTSPUrl *uri,
|
||||||
|
|
Loading…
Reference in a new issue