/** * gst_rtsp_session_next_timeout: * @session: a #GstRTSPSession * @now: the current system time * * Get the amount of milliseconds till the session will expire. * * Returns: the amount of milliseconds since the session will time out. */ gint gst_rtsp_session_next_timeout (GstRTSPSession * session, GTimeVal * now) { GstRTSPSessionPrivate *priv; gint res; GstClockTime last_access, now_ns; g_return_val_if_fail (GST_IS_RTSP_SESSION (session), -1); g_return_val_if_fail (now != NULL, -1); priv = session->priv; g_mutex_lock (&priv->lock); if (g_atomic_int_get (&priv->expire_count) != 0) { /* touch session when the expire count is not 0 */ g_get_current_time (&priv->last_access); } last_access = GST_TIMEVAL_TO_TIME (priv->last_access); /* add timeout allow for 5 seconds of extra time */ last_access += priv->timeout * GST_SECOND + (5 * GST_SECOND); g_mutex_unlock (&priv->lock); now_ns = GST_TIMEVAL_TO_TIME (*now); if (last_access > now_ns) res = GST_TIME_AS_MSECONDS (last_access - now_ns); else res = 0; return res; }
/** * 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->priv->sessionid; }
/** * gst_rtsp_session_prevent_expire: * @session: a #GstRTSPSession * * Prevent @session from expiring. */ void gst_rtsp_session_prevent_expire (GstRTSPSession * session) { g_return_if_fail (GST_IS_RTSP_SESSION (session)); g_atomic_int_add (&session->priv->expire_count, 1); }
/** * gst_rtsp_session_release_media: * @sess: a #GstRTSPSession * @media: a #GstRTSPMedia * * Release the managed @media in @sess, freeing the memory allocated by it. * * Returns: %TRUE if there are more media session left in @sess. */ gboolean gst_rtsp_session_release_media (GstRTSPSession * sess, GstRTSPSessionMedia * media) { GstRTSPSessionPrivate *priv; GList *find; gboolean more; g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), FALSE); g_return_val_if_fail (media != NULL, FALSE); priv = sess->priv; g_mutex_lock (&priv->lock); find = g_list_find (priv->medias, media); if (find) priv->medias = g_list_delete_link (priv->medias, find); more = (priv->medias != NULL); g_mutex_unlock (&priv->lock); if (find) g_object_unref (media); return more; }
/** * gst_rtsp_session_manage_media: * @sess: a #GstRTSPSession * @path: the path for the media * @media: (transfer full): a #GstRTSPMedia * * Manage the media object @obj in @sess. @path will be used to retrieve this * media from the session with gst_rtsp_session_get_media(). * * Ownership is taken from @media. * * Returns: (transfer none): a new @GstRTSPSessionMedia object. */ GstRTSPSessionMedia * gst_rtsp_session_manage_media (GstRTSPSession * sess, const gchar * path, GstRTSPMedia * media) { GstRTSPSessionPrivate *priv; GstRTSPSessionMedia *result; GstRTSPMediaStatus status; g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL); g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL); status = gst_rtsp_media_get_status (media); g_return_val_if_fail (status == GST_RTSP_MEDIA_STATUS_PREPARED || status == GST_RTSP_MEDIA_STATUS_SUSPENDED, NULL); priv = sess->priv; result = gst_rtsp_session_media_new (path, media); g_mutex_lock (&priv->lock); priv->medias = g_list_prepend (priv->medias, result); g_mutex_unlock (&priv->lock); GST_INFO ("manage new media %p in session %p", media, result); return result; }
/** * gst_rtsp_session_pool_remove: * @pool: a #GstRTSPSessionPool * @sess: (transfer none): a #GstRTSPSession * * Remove @sess from @pool, releasing the ref that the pool has on @sess. * * Returns: %TRUE if the session was found and removed. */ gboolean gst_rtsp_session_pool_remove (GstRTSPSessionPool * pool, GstRTSPSession * sess) { GstRTSPSessionPoolPrivate *priv; gboolean found; g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), FALSE); g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), FALSE); priv = pool->priv; g_mutex_lock (&priv->lock); g_object_ref (sess); found = g_hash_table_remove (priv->sessions, gst_rtsp_session_get_sessionid (sess)); if (found) priv->sessions_cookie++; g_mutex_unlock (&priv->lock); if (found) g_signal_emit (pool, gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED], 0, sess); g_object_unref (sess); return found; }
/** * 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) { GstRTSPSessionPrivate *priv; g_return_if_fail (GST_IS_RTSP_SESSION (session)); priv = session->priv; g_mutex_lock (&priv->lock); g_get_current_time (&priv->last_access); g_mutex_unlock (&priv->lock); }
/** * 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) { GstRTSPSessionPrivate *priv; g_return_if_fail (GST_IS_RTSP_SESSION (session)); priv = session->priv; g_mutex_lock (&priv->lock); priv->timeout = timeout; g_mutex_unlock (&priv->lock); }
/** * gst_rtsp_session_pool_remove: * @pool: a #GstRTSPSessionPool * @sess: a #GstRTSPSession * * Remove @sess from @pool, releasing the ref that the pool has on @sess. * * Returns: %TRUE if the session was found and removed. */ gboolean gst_rtsp_session_pool_remove (GstRTSPSessionPool * pool, GstRTSPSession * sess) { gboolean found; g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), FALSE); g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), FALSE); g_mutex_lock (&pool->lock); found = g_hash_table_remove (pool->sessions, sess->sessionid); g_mutex_unlock (&pool->lock); return found; }
/** * 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) { GstRTSPSessionPrivate *priv; guint res; g_return_val_if_fail (GST_IS_RTSP_SESSION (session), 0); priv = session->priv; g_mutex_lock (&priv->lock); res = priv->timeout; g_mutex_unlock (&priv->lock); return res; }
/** * gst_rtsp_session_get_header: * @session: a #GstRTSPSession * * Get the string that can be placed in the Session header field. * * Returns: (transfer full): the Session header of @session. g_free() after usage. */ gchar * gst_rtsp_session_get_header (GstRTSPSession * session) { GstRTSPSessionPrivate *priv; gchar *result; g_return_val_if_fail (GST_IS_RTSP_SESSION (session), NULL); priv = session->priv; g_mutex_lock (&priv->lock); if (priv->timeout != 60) result = g_strdup_printf ("%s; timeout=%d", priv->sessionid, priv->timeout); else result = g_strdup (priv->sessionid); g_mutex_unlock (&priv->lock); return result; }
/** * gst_rtsp_session_filter: * @sess: a #GstRTSPSession * @func: (scope call) (allow-none): a callback * @user_data: user data passed to @func * * Call @func for each media in @sess. The result value of @func determines * what happens to the media. @func will be called with @sess * locked so no further actions on @sess can be performed from @func. * * If @func returns #GST_RTSP_FILTER_REMOVE, the media will be removed from * @sess. * * If @func returns #GST_RTSP_FILTER_KEEP, the media will remain in @sess. * * If @func returns #GST_RTSP_FILTER_REF, the media will remain in @sess but * will also be added with an additional ref to the result #GList of this * function.. * * When @func is %NULL, #GST_RTSP_FILTER_REF will be assumed for all media. * * Returns: (element-type GstRTSPSessionMedia) (transfer full): a GList with all * media for which @func returned #GST_RTSP_FILTER_REF. After usage, each * element in the #GList should be unreffed before the list is freed. */ GList * gst_rtsp_session_filter (GstRTSPSession * sess, GstRTSPSessionFilterFunc func, gpointer user_data) { GstRTSPSessionPrivate *priv; GList *result, *walk, *next; g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL); priv = sess->priv; result = NULL; g_mutex_lock (&priv->lock); for (walk = priv->medias; walk; walk = next) { GstRTSPSessionMedia *media = walk->data; GstRTSPFilterResult res; next = g_list_next (walk); if (func) res = func (sess, media, user_data); else res = GST_RTSP_FILTER_REF; switch (res) { case GST_RTSP_FILTER_REMOVE: g_object_unref (media); priv->medias = g_list_delete_link (priv->medias, walk); break; case GST_RTSP_FILTER_REF: result = g_list_prepend (result, g_object_ref (media)); break; case GST_RTSP_FILTER_KEEP: default: break; } } g_mutex_unlock (&priv->lock); return result; }
/** * gst_rtsp_session_get_media: * @sess: a #GstRTSPSession * @path: the path for the media * @matched: (out): the amount of matched characters * * Get the session media for @path. @matched will contain the number of matched * characters of @path. * * Returns: (transfer none): the configuration for @path in @sess. */ GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path, gint * matched) { GstRTSPSessionPrivate *priv; GstRTSPSessionMedia *result; GList *walk; gint best; g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL); g_return_val_if_fail (path != NULL, NULL); priv = sess->priv; result = NULL; best = 0; g_mutex_lock (&priv->lock); for (walk = priv->medias; walk; walk = g_list_next (walk)) { GstRTSPSessionMedia *test; test = (GstRTSPSessionMedia *) walk->data; /* find largest match */ if (gst_rtsp_session_media_matches (test, path, matched)) { if (best < *matched) { result = test; best = *matched; } } } g_mutex_unlock (&priv->lock); *matched = best; return result; }