mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +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;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue