/**
 * 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;
}
Example #10
0
/**
 * 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;
}
Example #11
0
/**
 * 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;
}
Example #12
0
/**
 * 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;
}
Example #13
0
/**
 * 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;
}