mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
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:
parent
8f79daef5e
commit
5a833f503e
5 changed files with 92 additions and 49 deletions
|
@ -502,8 +502,7 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
goto no_mount_points;
|
goto no_mount_points;
|
||||||
|
|
||||||
/* find the factory for the uri first */
|
/* find the factory for the uri first */
|
||||||
if (!(factory =
|
if (!(factory = gst_rtsp_mount_points_match (priv->mount_points,
|
||||||
gst_rtsp_mount_points_match (priv->mount_points,
|
|
||||||
state->uri->abspath, NULL)))
|
state->uri->abspath, NULL)))
|
||||||
goto no_factory;
|
goto no_factory;
|
||||||
|
|
||||||
|
@ -698,6 +697,8 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
GstRTSPSession *session;
|
GstRTSPSession *session;
|
||||||
GstRTSPSessionMedia *sessmedia;
|
GstRTSPSessionMedia *sessmedia;
|
||||||
GstRTSPStatusCode code;
|
GstRTSPStatusCode code;
|
||||||
|
const gchar *path;
|
||||||
|
gint matched;
|
||||||
|
|
||||||
if (!state->session)
|
if (!state->session)
|
||||||
goto no_session;
|
goto no_session;
|
||||||
|
@ -707,8 +708,10 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
if (!state->uri)
|
if (!state->uri)
|
||||||
goto no_uri;
|
goto no_uri;
|
||||||
|
|
||||||
|
path = state->uri->abspath;
|
||||||
|
|
||||||
/* get a handle to the configuration of the media in the session */
|
/* 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)
|
if (!sessmedia)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -863,6 +866,8 @@ handle_pause_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
GstRTSPSessionMedia *sessmedia;
|
GstRTSPSessionMedia *sessmedia;
|
||||||
GstRTSPStatusCode code;
|
GstRTSPStatusCode code;
|
||||||
GstRTSPState rtspstate;
|
GstRTSPState rtspstate;
|
||||||
|
const gchar *path;
|
||||||
|
gint matched;
|
||||||
|
|
||||||
if (!(session = state->session))
|
if (!(session = state->session))
|
||||||
goto no_session;
|
goto no_session;
|
||||||
|
@ -870,8 +875,10 @@ handle_pause_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
if (!state->uri)
|
if (!state->uri)
|
||||||
goto no_uri;
|
goto no_uri;
|
||||||
|
|
||||||
|
path = state->uri->abspath;
|
||||||
|
|
||||||
/* get a handle to the configuration of the media in the session */
|
/* 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)
|
if (!sessmedia)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -946,6 +953,8 @@ handle_play_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
GstRTSPResult res;
|
GstRTSPResult res;
|
||||||
GstRTSPState rtspstate;
|
GstRTSPState rtspstate;
|
||||||
GstRTSPRangeUnit unit = GST_RTSP_RANGE_NPT;
|
GstRTSPRangeUnit unit = GST_RTSP_RANGE_NPT;
|
||||||
|
const gchar *path;
|
||||||
|
gint matched;
|
||||||
|
|
||||||
if (!(session = state->session))
|
if (!(session = state->session))
|
||||||
goto no_session;
|
goto no_session;
|
||||||
|
@ -953,8 +962,10 @@ handle_play_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
if (!state->uri)
|
if (!state->uri)
|
||||||
goto no_uri;
|
goto no_uri;
|
||||||
|
|
||||||
|
path = state->uri->abspath;
|
||||||
|
|
||||||
/* get a handle to the configuration of the media in the session */
|
/* 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)
|
if (!sessmedia)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -1290,11 +1301,14 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
GstRTSPStream *stream;
|
GstRTSPStream *stream;
|
||||||
GstRTSPState rtspstate;
|
GstRTSPState rtspstate;
|
||||||
GstRTSPClientClass *klass;
|
GstRTSPClientClass *klass;
|
||||||
|
const gchar *path;
|
||||||
|
gint matched;
|
||||||
|
|
||||||
if (!state->uri)
|
if (!state->uri)
|
||||||
goto no_uri;
|
goto no_uri;
|
||||||
|
|
||||||
uri = state->uri;
|
uri = state->uri;
|
||||||
|
path = state->uri->abspath;
|
||||||
|
|
||||||
/* the uri contains the stream number we added in the SDP config, which is
|
/* the uri contains the stream number we added in the SDP config, which is
|
||||||
* always /stream=%d so we need to strip that off
|
* 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);
|
g_object_ref (session);
|
||||||
/* get a handle to the configuration of the media in the session, this can
|
/* 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. */
|
* 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 {
|
} else {
|
||||||
/* create a session if this fails we probably reached our session limit or
|
/* create a session if this fails we probably reached our session limit or
|
||||||
* something. */
|
* something. */
|
||||||
|
@ -1365,7 +1379,7 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
|
||||||
/* get a handle to the configuration of the media in the session */
|
/* get a handle to the configuration of the media in the session */
|
||||||
if ((media = find_media (client, state))) {
|
if ((media = find_media (client, state))) {
|
||||||
/* manage the media in our session now */
|
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
struct _GstRTSPSessionMediaPrivate
|
struct _GstRTSPSessionMediaPrivate
|
||||||
{
|
{
|
||||||
GMutex lock;
|
GMutex lock;
|
||||||
GstRTSPUrl *url; /* unmutable */
|
gchar *path; /* unmutable */
|
||||||
|
gint path_len; /* unmutable */
|
||||||
GstRTSPMedia *media; /* unmutable */
|
GstRTSPMedia *media; /* unmutable */
|
||||||
GstRTSPState state; /* protected by lock */
|
GstRTSPState state; /* protected by lock */
|
||||||
guint counter; /* 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);
|
g_ptr_array_unref (priv->transports);
|
||||||
|
|
||||||
gst_rtsp_url_free (priv->url);
|
g_free (priv->path);
|
||||||
g_object_unref (priv->media);
|
g_object_unref (priv->media);
|
||||||
g_mutex_clear (&priv->lock);
|
g_mutex_clear (&priv->lock);
|
||||||
|
|
||||||
|
@ -104,24 +105,24 @@ free_session_media (gpointer data)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_media_new:
|
* gst_rtsp_session_media_new:
|
||||||
* @url: the #GstRTSPUrl
|
* @path: the path
|
||||||
* @media: the #GstRTSPMedia
|
* @media: the #GstRTSPMedia
|
||||||
*
|
*
|
||||||
* Create a new #GstRTPSessionMedia that manages the streams
|
* 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.
|
* Ownership is taken of @media.
|
||||||
*
|
*
|
||||||
* Returns: a new #GstRTSPSessionMedia.
|
* Returns: a new #GstRTSPSessionMedia.
|
||||||
*/
|
*/
|
||||||
GstRTSPSessionMedia *
|
GstRTSPSessionMedia *
|
||||||
gst_rtsp_session_media_new (const GstRTSPUrl * url, GstRTSPMedia * media)
|
gst_rtsp_session_media_new (const gchar * path, GstRTSPMedia * media)
|
||||||
{
|
{
|
||||||
GstRTSPSessionMediaPrivate *priv;
|
GstRTSPSessionMediaPrivate *priv;
|
||||||
GstRTSPSessionMedia *result;
|
GstRTSPSessionMedia *result;
|
||||||
guint n_streams;
|
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_IS_RTSP_MEDIA (media), NULL);
|
||||||
g_return_val_if_fail (gst_rtsp_media_get_status (media) ==
|
g_return_val_if_fail (gst_rtsp_media_get_status (media) ==
|
||||||
GST_RTSP_MEDIA_STATUS_PREPARED, NULL);
|
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);
|
result = g_object_new (GST_TYPE_RTSP_SESSION_MEDIA, NULL);
|
||||||
priv = result->priv;
|
priv = result->priv;
|
||||||
|
|
||||||
priv->url = gst_rtsp_url_copy ((GstRTSPUrl *) url);
|
priv->path = g_strdup (path);
|
||||||
|
priv->path_len = strlen (path);
|
||||||
priv->media = media;
|
priv->media = media;
|
||||||
|
|
||||||
/* prealloc the streams now, filled with NULL */
|
/* 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
|
* @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
|
gboolean
|
||||||
gst_rtsp_session_media_matches_url (GstRTSPSessionMedia * media,
|
gst_rtsp_session_media_matches (GstRTSPSessionMedia * media,
|
||||||
const GstRTSPUrl * url)
|
const gchar * path, gint * matched)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), FALSE);
|
GstRTSPSessionMediaPrivate *priv;
|
||||||
g_return_val_if_fail (url != NULL, FALSE);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,14 +41,8 @@ typedef struct _GstRTSPSessionMediaPrivate GstRTSPSessionMediaPrivate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRTSPSessionMedia:
|
* 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
|
struct _GstRTSPSessionMedia
|
||||||
{
|
{
|
||||||
|
@ -64,11 +58,12 @@ struct _GstRTSPSessionMediaClass
|
||||||
|
|
||||||
GType gst_rtsp_session_media_get_type (void);
|
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);
|
GstRTSPMedia *media);
|
||||||
|
|
||||||
gboolean gst_rtsp_session_media_matches_url (GstRTSPSessionMedia *media,
|
gboolean gst_rtsp_session_media_matches (GstRTSPSessionMedia *media,
|
||||||
const GstRTSPUrl *url);
|
const gchar *path,
|
||||||
|
gint * matched);
|
||||||
GstRTSPMedia * gst_rtsp_session_media_get_media (GstRTSPSessionMedia *media);
|
GstRTSPMedia * gst_rtsp_session_media_get_media (GstRTSPSessionMedia *media);
|
||||||
|
|
||||||
GstClockTime gst_rtsp_session_media_get_base_time (GstRTSPSessionMedia *media);
|
GstClockTime gst_rtsp_session_media_get_base_time (GstRTSPSessionMedia *media);
|
||||||
|
|
|
@ -162,10 +162,10 @@ gst_rtsp_session_set_property (GObject * object, guint propid,
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_manage_media:
|
* gst_rtsp_session_manage_media:
|
||||||
* @sess: a #GstRTSPSession
|
* @sess: a #GstRTSPSession
|
||||||
* @uri: the uri for the media
|
* @path: the path for the media
|
||||||
* @media: (transfer full): a #GstRTSPMedia
|
* @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().
|
* media from the session with gst_rtsp_session_get_media().
|
||||||
*
|
*
|
||||||
* Ownership is taken from @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.
|
* Returns: (transfer none): a new @GstRTSPSessionMedia object.
|
||||||
*/
|
*/
|
||||||
GstRTSPSessionMedia *
|
GstRTSPSessionMedia *
|
||||||
gst_rtsp_session_manage_media (GstRTSPSession * sess, const GstRTSPUrl * uri,
|
gst_rtsp_session_manage_media (GstRTSPSession * sess, const gchar * path,
|
||||||
GstRTSPMedia * media)
|
GstRTSPMedia * media)
|
||||||
{
|
{
|
||||||
GstRTSPSessionPrivate *priv;
|
GstRTSPSessionPrivate *priv;
|
||||||
GstRTSPSessionMedia *result;
|
GstRTSPSessionMedia *result;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL);
|
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_IS_RTSP_MEDIA (media), NULL);
|
||||||
g_return_val_if_fail (gst_rtsp_media_get_status (media) ==
|
g_return_val_if_fail (gst_rtsp_media_get_status (media) ==
|
||||||
GST_RTSP_MEDIA_STATUS_PREPARED, NULL);
|
GST_RTSP_MEDIA_STATUS_PREPARED, NULL);
|
||||||
|
|
||||||
priv = sess->priv;
|
priv = sess->priv;
|
||||||
|
|
||||||
result = gst_rtsp_session_media_new (uri, media);
|
result = gst_rtsp_session_media_new (path, media);
|
||||||
|
|
||||||
g_mutex_lock (&priv->lock);
|
g_mutex_lock (&priv->lock);
|
||||||
priv->medias = g_list_prepend (priv->medias, result);
|
priv->medias = g_list_prepend (priv->medias, result);
|
||||||
|
@ -236,36 +236,48 @@ gst_rtsp_session_release_media (GstRTSPSession * sess,
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_get_media:
|
* gst_rtsp_session_get_media:
|
||||||
* @sess: a #GstRTSPSession
|
* @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 *
|
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;
|
GstRTSPSessionPrivate *priv;
|
||||||
GstRTSPSessionMedia *result;
|
GstRTSPSessionMedia *result;
|
||||||
GList *walk;
|
GList *walk;
|
||||||
|
gint best;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL);
|
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;
|
priv = sess->priv;
|
||||||
result = NULL;
|
result = NULL;
|
||||||
|
best = 0;
|
||||||
|
|
||||||
g_mutex_lock (&priv->lock);
|
g_mutex_lock (&priv->lock);
|
||||||
for (walk = priv->medias; walk; walk = g_list_next (walk)) {
|
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))
|
test = (GstRTSPSessionMedia *) walk->data;
|
||||||
break;
|
|
||||||
|
|
||||||
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);
|
g_mutex_unlock (&priv->lock);
|
||||||
|
|
||||||
|
*matched = best;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,13 +95,14 @@ gboolean gst_rtsp_session_is_expired (GstRTSPSession *se
|
||||||
|
|
||||||
/* 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 gchar *path,
|
||||||
GstRTSPMedia *media);
|
GstRTSPMedia *media);
|
||||||
gboolean gst_rtsp_session_release_media (GstRTSPSession *sess,
|
gboolean gst_rtsp_session_release_media (GstRTSPSession *sess,
|
||||||
GstRTSPSessionMedia *media);
|
GstRTSPSessionMedia *media);
|
||||||
/* get media in a session */
|
/* get media in a session */
|
||||||
GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess,
|
GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess,
|
||||||
const GstRTSPUrl *url);
|
const gchar *path,
|
||||||
|
gint * matched);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRTSPSessionFilterFunc:
|
* GstRTSPSessionFilterFunc:
|
||||||
|
|
Loading…
Reference in a new issue