session: use path matching for session media

Use a path string instead of a uri to lookup session media in the sessions. Also
use path matching to find the largest possible path that matches.
This commit is contained in:
Wim Taymans 2013-07-03 12:37:48 +02:00
parent 8f79daef5e
commit 5a833f503e
5 changed files with 92 additions and 49 deletions

View file

@ -502,8 +502,7 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state)
goto no_mount_points;
/* find the factory for the uri first */
if (!(factory =
gst_rtsp_mount_points_match (priv->mount_points,
if (!(factory = gst_rtsp_mount_points_match (priv->mount_points,
state->uri->abspath, NULL)))
goto no_factory;
@ -698,6 +697,8 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPClientState * state)
GstRTSPSession *session;
GstRTSPSessionMedia *sessmedia;
GstRTSPStatusCode code;
const gchar *path;
gint matched;
if (!state->session)
goto no_session;
@ -707,8 +708,10 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPClientState * state)
if (!state->uri)
goto no_uri;
path = state->uri->abspath;
/* get a handle to the configuration of the media in the session */
sessmedia = gst_rtsp_session_get_media (session, state->uri);
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
if (!sessmedia)
goto not_found;
@ -863,6 +866,8 @@ handle_pause_request (GstRTSPClient * client, GstRTSPClientState * state)
GstRTSPSessionMedia *sessmedia;
GstRTSPStatusCode code;
GstRTSPState rtspstate;
const gchar *path;
gint matched;
if (!(session = state->session))
goto no_session;
@ -870,8 +875,10 @@ handle_pause_request (GstRTSPClient * client, GstRTSPClientState * state)
if (!state->uri)
goto no_uri;
path = state->uri->abspath;
/* get a handle to the configuration of the media in the session */
sessmedia = gst_rtsp_session_get_media (session, state->uri);
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
if (!sessmedia)
goto not_found;
@ -946,6 +953,8 @@ handle_play_request (GstRTSPClient * client, GstRTSPClientState * state)
GstRTSPResult res;
GstRTSPState rtspstate;
GstRTSPRangeUnit unit = GST_RTSP_RANGE_NPT;
const gchar *path;
gint matched;
if (!(session = state->session))
goto no_session;
@ -953,8 +962,10 @@ handle_play_request (GstRTSPClient * client, GstRTSPClientState * state)
if (!state->uri)
goto no_uri;
path = state->uri->abspath;
/* get a handle to the configuration of the media in the session */
sessmedia = gst_rtsp_session_get_media (session, state->uri);
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
if (!sessmedia)
goto not_found;
@ -1290,11 +1301,14 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
GstRTSPStream *stream;
GstRTSPState rtspstate;
GstRTSPClientClass *klass;
const gchar *path;
gint matched;
if (!state->uri)
goto no_uri;
uri = state->uri;
path = state->uri->abspath;
/* the uri contains the stream number we added in the SDP config, which is
* always /stream=%d so we need to strip that off
@ -1340,7 +1354,7 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
g_object_ref (session);
/* get a handle to the configuration of the media in the session, this can
* return NULL if this is a new url to manage in this session. */
sessmedia = gst_rtsp_session_get_media (session, uri);
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
} else {
/* create a session if this fails we probably reached our session limit or
* something. */
@ -1365,7 +1379,7 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
/* get a handle to the configuration of the media in the session */
if ((media = find_media (client, state))) {
/* manage the media in our session now */
sessmedia = gst_rtsp_session_manage_media (session, uri, media);
sessmedia = gst_rtsp_session_manage_media (session, path, media);
}
}

View file

@ -26,7 +26,8 @@
struct _GstRTSPSessionMediaPrivate
{
GMutex lock;
GstRTSPUrl *url; /* unmutable */
gchar *path; /* unmutable */
gint path_len; /* unmutable */
GstRTSPMedia *media; /* unmutable */
GstRTSPState state; /* protected by lock */
guint counter; /* protected by lock */
@ -88,7 +89,7 @@ gst_rtsp_session_media_finalize (GObject * obj)
g_ptr_array_unref (priv->transports);
gst_rtsp_url_free (priv->url);
g_free (priv->path);
g_object_unref (priv->media);
g_mutex_clear (&priv->lock);
@ -104,24 +105,24 @@ free_session_media (gpointer data)
/**
* gst_rtsp_session_media_new:
* @url: the #GstRTSPUrl
* @path: the path
* @media: the #GstRTSPMedia
*
* Create a new #GstRTPSessionMedia that manages the streams
* in @media for @url. @media should be prepared.
* in @media for @path. @media should be prepared.
*
* Ownership is taken of @media.
*
* Returns: a new #GstRTSPSessionMedia.
*/
GstRTSPSessionMedia *
gst_rtsp_session_media_new (const GstRTSPUrl * url, GstRTSPMedia * media)
gst_rtsp_session_media_new (const gchar * path, GstRTSPMedia * media)
{
GstRTSPSessionMediaPrivate *priv;
GstRTSPSessionMedia *result;
guint n_streams;
g_return_val_if_fail (url != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
g_return_val_if_fail (gst_rtsp_media_get_status (media) ==
GST_RTSP_MEDIA_STATUS_PREPARED, NULL);
@ -129,7 +130,8 @@ gst_rtsp_session_media_new (const GstRTSPUrl * url, GstRTSPMedia * media)
result = g_object_new (GST_TYPE_RTSP_SESSION_MEDIA, NULL);
priv = result->priv;
priv->url = gst_rtsp_url_copy ((GstRTSPUrl *) url);
priv->path = g_strdup (path);
priv->path_len = strlen (path);
priv->media = media;
/* prealloc the streams now, filled with NULL */
@ -141,22 +143,41 @@ gst_rtsp_session_media_new (const GstRTSPUrl * url, GstRTSPMedia * media)
}
/**
* gst_rtsp_session_media_matches_url:
* gst_rtsp_session_media_matches:
* @media: a #GstRTSPSessionMedia
* @url: a #GstRTSPUrl
* @path: a path
* @matched: the amount of matched characters of @path
*
* Check if the url of @media matches @url.
* Check if the path of @media matches @path. It @path matches, the amount of
* matched characters is returned in @matched.
*
* Returns: %TRUE when @url matches the url of @media.
* Returns: %TRUE when @path matches the path of @media.
*/
gboolean
gst_rtsp_session_media_matches_url (GstRTSPSessionMedia * media,
const GstRTSPUrl * url)
gst_rtsp_session_media_matches (GstRTSPSessionMedia * media,
const gchar * path, gint * matched)
{
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), FALSE);
g_return_val_if_fail (url != NULL, FALSE);
GstRTSPSessionMediaPrivate *priv;
gint len;
return g_str_equal (media->priv->url->abspath, url->abspath);
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
g_return_val_if_fail (matched != NULL, FALSE);
priv = media->priv;
len = strlen (path);
/* path needs to be smaller than the media path */
if (len < priv->path_len)
return FALSE;
/* if media path is larger, it there should be a / following the path */
if (len > priv->path_len && path[priv->path_len] != '/')
return FALSE;
*matched = priv->path_len;
return strncmp (path, priv->path, priv->path_len) == 0;
}
/**

View file

@ -41,14 +41,8 @@ typedef struct _GstRTSPSessionMediaPrivate GstRTSPSessionMediaPrivate;
/**
* GstRTSPSessionMedia:
* @url: the url of the media
* @media: the pipeline for the media
* @state: the server state
* @counter: counter for channels
* @transports: array of #GstRTSPStreamTransport with the configuration
* for the transport for each selected stream from @media.
*
* State of a client session regarding a specific media identified by uri.
* State of a client session regarding a specific media identified by path.
*/
struct _GstRTSPSessionMedia
{
@ -64,11 +58,12 @@ struct _GstRTSPSessionMediaClass
GType gst_rtsp_session_media_get_type (void);
GstRTSPSessionMedia * gst_rtsp_session_media_new (const GstRTSPUrl *url,
GstRTSPSessionMedia * gst_rtsp_session_media_new (const gchar *path,
GstRTSPMedia *media);
gboolean gst_rtsp_session_media_matches_url (GstRTSPSessionMedia *media,
const GstRTSPUrl *url);
gboolean gst_rtsp_session_media_matches (GstRTSPSessionMedia *media,
const gchar *path,
gint * matched);
GstRTSPMedia * gst_rtsp_session_media_get_media (GstRTSPSessionMedia *media);
GstClockTime gst_rtsp_session_media_get_base_time (GstRTSPSessionMedia *media);

View file

@ -162,10 +162,10 @@ gst_rtsp_session_set_property (GObject * object, guint propid,
/**
* gst_rtsp_session_manage_media:
* @sess: a #GstRTSPSession
* @uri: the uri for the media
* @path: the path for the media
* @media: (transfer full): a #GstRTSPMedia
*
* Manage the media object @obj in @sess. @uri will be used to retrieve this
* 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.
@ -173,21 +173,21 @@ gst_rtsp_session_set_property (GObject * object, guint propid,
* Returns: (transfer none): a new @GstRTSPSessionMedia object.
*/
GstRTSPSessionMedia *
gst_rtsp_session_manage_media (GstRTSPSession * sess, const GstRTSPUrl * uri,
gst_rtsp_session_manage_media (GstRTSPSession * sess, const gchar * path,
GstRTSPMedia * media)
{
GstRTSPSessionPrivate *priv;
GstRTSPSessionMedia *result;
g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL);
g_return_val_if_fail (uri != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
g_return_val_if_fail (gst_rtsp_media_get_status (media) ==
GST_RTSP_MEDIA_STATUS_PREPARED, NULL);
priv = sess->priv;
result = gst_rtsp_session_media_new (uri, media);
result = gst_rtsp_session_media_new (path, media);
g_mutex_lock (&priv->lock);
priv->medias = g_list_prepend (priv->medias, result);
@ -236,36 +236,48 @@ gst_rtsp_session_release_media (GstRTSPSession * sess,
/**
* gst_rtsp_session_get_media:
* @sess: a #GstRTSPSession
* @url: the url for the media
* @path: the path for the media
* @matched: the amount of matched characters
*
* Get the session media of the @url.
* Get the session media for @path. @matched will contain the number of matched
* characters of @path.
*
* Returns: (transfer none): the configuration for @url in @sess.
* Returns: (transfer none): the configuration for @path in @sess.
*/
GstRTSPSessionMedia *
gst_rtsp_session_get_media (GstRTSPSession * sess, const GstRTSPUrl * url)
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 (url != NULL, 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)) {
result = (GstRTSPSessionMedia *) walk->data;
GstRTSPSessionMedia *test;
if (gst_rtsp_session_media_matches_url (result, url))
break;
test = (GstRTSPSessionMedia *) walk->data;
result = NULL;
/* 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;
}

View file

@ -95,13 +95,14 @@ gboolean gst_rtsp_session_is_expired (GstRTSPSession *se
/* handle media in a session */
GstRTSPSessionMedia * gst_rtsp_session_manage_media (GstRTSPSession *sess,
const GstRTSPUrl *uri,
const gchar *path,
GstRTSPMedia *media);
gboolean gst_rtsp_session_release_media (GstRTSPSession *sess,
GstRTSPSessionMedia *media);
/* get media in a session */
GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess,
const GstRTSPUrl *url);
const gchar *path,
gint * matched);
/**
* GstRTSPSessionFilterFunc: