mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
rtsp: make object details private
Make all object details private Add methods to access private bits
This commit is contained in:
parent
8665c3b494
commit
ad00c5e792
28 changed files with 2238 additions and 1284 deletions
|
@ -313,6 +313,7 @@ gst_rtsp_stream_set_mtu
|
|||
gst_rtsp_stream_join_bin
|
||||
gst_rtsp_stream_leave_bin
|
||||
gst_rtsp_stream_get_rtpinfo
|
||||
gst_rtsp_stream_get_caps
|
||||
gst_rtsp_stream_recv_rtcp
|
||||
gst_rtsp_stream_recv_rtp
|
||||
gst_rtsp_stream_add_transport
|
||||
|
|
|
@ -35,8 +35,8 @@ remove_sessions (GstRTSPServer * server)
|
|||
|
||||
g_print ("removing all sessions\n");
|
||||
pool = gst_rtsp_server_get_session_pool (server);
|
||||
gst_rtsp_session_pool_filter (pool, (GstRTSPSessionFilterFunc) remove_func,
|
||||
server);
|
||||
gst_rtsp_session_pool_filter (pool,
|
||||
(GstRTSPSessionPoolFilterFunc) remove_func, server);
|
||||
g_object_unref (pool);
|
||||
|
||||
return FALSE;
|
||||
|
|
|
@ -21,6 +21,16 @@
|
|||
|
||||
#include "rtsp-auth.h"
|
||||
|
||||
#define GST_RTSP_AUTH_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_AUTH, GstRTSPAuthPrivate))
|
||||
|
||||
struct _GstRTSPAuthPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
gchar *basic;
|
||||
GstRTSPMethod methods;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -48,6 +58,8 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPAuthPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gst_rtsp_auth_get_property;
|
||||
|
@ -63,9 +75,11 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass)
|
|||
static void
|
||||
gst_rtsp_auth_init (GstRTSPAuth * auth)
|
||||
{
|
||||
g_mutex_init (&auth->lock);
|
||||
auth->priv = GST_RTSP_AUTH_GET_PRIVATE (auth);
|
||||
|
||||
g_mutex_init (&auth->priv->lock);
|
||||
/* bitwise or of all methods that need authentication */
|
||||
auth->methods = GST_RTSP_DESCRIBE |
|
||||
auth->priv->methods = GST_RTSP_DESCRIBE |
|
||||
GST_RTSP_ANNOUNCE |
|
||||
GST_RTSP_GET_PARAMETER |
|
||||
GST_RTSP_SET_PARAMETER |
|
||||
|
@ -77,10 +91,11 @@ static void
|
|||
gst_rtsp_auth_finalize (GObject * obj)
|
||||
{
|
||||
GstRTSPAuth *auth = GST_RTSP_AUTH (obj);
|
||||
GstRTSPAuthPrivate *priv = auth->priv;
|
||||
|
||||
GST_INFO ("finalize auth %p", auth);
|
||||
g_free (auth->basic);
|
||||
g_mutex_clear (&auth->lock);
|
||||
g_free (priv->basic);
|
||||
g_mutex_clear (&priv->lock);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_auth_parent_class)->finalize (obj);
|
||||
}
|
||||
|
@ -132,12 +147,16 @@ gst_rtsp_auth_new (void)
|
|||
void
|
||||
gst_rtsp_auth_set_basic (GstRTSPAuth * auth, const gchar * basic)
|
||||
{
|
||||
GstRTSPAuthPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_AUTH (auth));
|
||||
|
||||
g_mutex_lock (&auth->lock);
|
||||
g_free (auth->basic);
|
||||
auth->basic = g_strdup (basic);
|
||||
g_mutex_unlock (&auth->lock);
|
||||
priv = auth->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
g_free (priv->basic);
|
||||
priv->basic = g_strdup (basic);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -190,10 +209,11 @@ static gboolean
|
|||
default_check_method (GstRTSPAuth * auth, GstRTSPClient * client,
|
||||
GQuark hint, GstRTSPClientState * state)
|
||||
{
|
||||
GstRTSPAuthPrivate *priv = auth->priv;
|
||||
gboolean result = TRUE;
|
||||
GstRTSPResult res;
|
||||
|
||||
if ((state->method & auth->methods) != 0) {
|
||||
if ((state->method & priv->methods) != 0) {
|
||||
gchar *authorization;
|
||||
|
||||
result = FALSE;
|
||||
|
@ -207,10 +227,10 @@ default_check_method (GstRTSPAuth * auth, GstRTSPClient * client,
|
|||
/* parse type */
|
||||
if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) {
|
||||
GST_DEBUG_OBJECT (auth, "check Basic auth");
|
||||
g_mutex_lock (&auth->lock);
|
||||
if (auth->basic && strcmp (&authorization[6], auth->basic) == 0)
|
||||
g_mutex_lock (&priv->lock);
|
||||
if (priv->basic && strcmp (&authorization[6], priv->basic) == 0)
|
||||
result = TRUE;
|
||||
g_mutex_unlock (&auth->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
} else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) {
|
||||
GST_DEBUG_OBJECT (auth, "check Digest auth");
|
||||
/* not implemented yet */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
typedef struct _GstRTSPAuth GstRTSPAuth;
|
||||
typedef struct _GstRTSPAuthClass GstRTSPAuthClass;
|
||||
typedef struct _GstRTSPAuthPrivate GstRTSPAuthPrivate;
|
||||
|
||||
#include "rtsp-client.h"
|
||||
|
||||
|
@ -46,10 +47,7 @@ G_BEGIN_DECLS
|
|||
struct _GstRTSPAuth {
|
||||
GObject parent;
|
||||
|
||||
/*< private >*/
|
||||
GMutex lock;
|
||||
gchar *basic;
|
||||
GstRTSPMethod methods;
|
||||
GstRTSPAuthPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstRTSPAuthClass {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,6 +28,7 @@ G_BEGIN_DECLS
|
|||
typedef struct _GstRTSPClient GstRTSPClient;
|
||||
typedef struct _GstRTSPClientClass GstRTSPClientClass;
|
||||
typedef struct _GstRTSPClientState GstRTSPClientState;
|
||||
typedef struct _GstRTSPClientPrivate GstRTSPClientPrivate;
|
||||
|
||||
#include "rtsp-media.h"
|
||||
#include "rtsp-mount-points.h"
|
||||
|
@ -90,51 +91,13 @@ typedef gboolean (*GstRTSPClientSendFunc) (GstRTSPClient *client,
|
|||
|
||||
/**
|
||||
* GstRTSPClient:
|
||||
* @lock: lock protecting the client object
|
||||
* @connection: the connection object handling the client request.
|
||||
* @watch: watch for the connection
|
||||
* @close_seq: sequence number of message with close header
|
||||
* @server_ip: ip address of the server
|
||||
* @is_ipv6: if we are IPv6
|
||||
* @use_client_settings: whether to allow client transport settings for multicast
|
||||
* @send_func: a #GstRTSPClientSendFunc called when an RTSP message needs to be
|
||||
* sent to the client.
|
||||
* @send_data: user data passed to @send_func
|
||||
* @send_notify: notify called when @send_data is no longer used.
|
||||
* @session_pool: handle to the session pool used by the client.
|
||||
* @mount_points: handle to the mount points used by the client.
|
||||
* @auth: authorization object
|
||||
* @uri: cached uri
|
||||
* @media: cached media
|
||||
* @transports: a list of #GstRTSPStreamTransport using @connection.
|
||||
* @sessions: a list of sessions managed by @connection.
|
||||
*
|
||||
* The client structure.
|
||||
*/
|
||||
struct _GstRTSPClient {
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
GstRTSPConnection *connection;
|
||||
GstRTSPWatch *watch;
|
||||
guint close_seq;
|
||||
gchar *server_ip;
|
||||
gboolean is_ipv6;
|
||||
gboolean use_client_settings;
|
||||
|
||||
GstRTSPClientSendFunc send_func;
|
||||
gpointer send_data;
|
||||
GDestroyNotify send_notify;
|
||||
|
||||
GstRTSPSessionPool *session_pool;
|
||||
GstRTSPMountPoints *mount_points;
|
||||
GstRTSPAuth *auth;
|
||||
|
||||
GstRTSPUrl *uri;
|
||||
GstRTSPMedia *media;
|
||||
|
||||
GList *transports;
|
||||
GList *sessions;
|
||||
GstRTSPClientPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstRTSPClientClass {
|
||||
|
|
|
@ -21,6 +21,22 @@
|
|||
|
||||
#include "rtsp-media-factory-uri.h"
|
||||
|
||||
#define GST_RTSP_MEDIA_FACTORY_URI_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY_URI, GstRTSPMediaFactoryURIPrivate))
|
||||
|
||||
struct _GstRTSPMediaFactoryURIPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
gchar *uri;
|
||||
gboolean use_gstpay;
|
||||
|
||||
GstCaps *raw_vcaps;
|
||||
GstCaps *raw_acaps;
|
||||
GList *demuxers;
|
||||
GList *payloaders;
|
||||
GList *decoders;
|
||||
};
|
||||
|
||||
#define DEFAULT_URI NULL
|
||||
#define DEFAULT_USE_GSTPAY FALSE
|
||||
|
||||
|
@ -156,41 +172,48 @@ payloader_filter (GstPluginFeature * feature, FilterData * data)
|
|||
static void
|
||||
gst_rtsp_media_factory_uri_init (GstRTSPMediaFactoryURI * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryURIPrivate *priv =
|
||||
GST_RTSP_MEDIA_FACTORY_URI_GET_PRIVATE (factory);
|
||||
FilterData data = { NULL, NULL, NULL };
|
||||
|
||||
GST_DEBUG_OBJECT (factory, "new");
|
||||
|
||||
factory->uri = g_strdup (DEFAULT_URI);
|
||||
factory->use_gstpay = DEFAULT_USE_GSTPAY;
|
||||
factory->priv = priv;
|
||||
|
||||
priv->uri = g_strdup (DEFAULT_URI);
|
||||
priv->use_gstpay = DEFAULT_USE_GSTPAY;
|
||||
g_mutex_init (&priv->lock);
|
||||
|
||||
/* get the feature list using the filter */
|
||||
gst_registry_feature_filter (gst_registry_get (), (GstPluginFeatureFilter)
|
||||
payloader_filter, FALSE, &data);
|
||||
/* sort */
|
||||
factory->demuxers =
|
||||
priv->demuxers =
|
||||
g_list_sort (data.demux, gst_plugin_feature_rank_compare_func);
|
||||
factory->payloaders =
|
||||
priv->payloaders =
|
||||
g_list_sort (data.payload, gst_plugin_feature_rank_compare_func);
|
||||
factory->decoders =
|
||||
priv->decoders =
|
||||
g_list_sort (data.decode, gst_plugin_feature_rank_compare_func);
|
||||
|
||||
factory->raw_vcaps = gst_static_caps_get (&raw_video_caps);
|
||||
factory->raw_acaps = gst_static_caps_get (&raw_audio_caps);
|
||||
priv->raw_vcaps = gst_static_caps_get (&raw_video_caps);
|
||||
priv->raw_acaps = gst_static_caps_get (&raw_audio_caps);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_media_factory_uri_finalize (GObject * obj)
|
||||
{
|
||||
GstRTSPMediaFactoryURI *factory = GST_RTSP_MEDIA_FACTORY_URI (obj);
|
||||
GstRTSPMediaFactoryURIPrivate *priv = factory->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (factory, "finalize");
|
||||
|
||||
g_free (factory->uri);
|
||||
gst_plugin_feature_list_free (factory->demuxers);
|
||||
gst_plugin_feature_list_free (factory->payloaders);
|
||||
gst_plugin_feature_list_free (factory->decoders);
|
||||
gst_caps_unref (factory->raw_vcaps);
|
||||
gst_caps_unref (factory->raw_acaps);
|
||||
g_free (priv->uri);
|
||||
gst_plugin_feature_list_free (priv->demuxers);
|
||||
gst_plugin_feature_list_free (priv->payloaders);
|
||||
gst_plugin_feature_list_free (priv->decoders);
|
||||
gst_caps_unref (priv->raw_vcaps);
|
||||
gst_caps_unref (priv->raw_acaps);
|
||||
g_mutex_clear (&priv->lock);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_media_factory_uri_parent_class)->finalize (obj);
|
||||
}
|
||||
|
@ -200,13 +223,14 @@ gst_rtsp_media_factory_uri_get_property (GObject * object, guint propid,
|
|||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRTSPMediaFactoryURI *factory = GST_RTSP_MEDIA_FACTORY_URI (object);
|
||||
GstRTSPMediaFactoryURIPrivate *priv = factory->priv;
|
||||
|
||||
switch (propid) {
|
||||
case PROP_URI:
|
||||
g_value_take_string (value, gst_rtsp_media_factory_uri_get_uri (factory));
|
||||
break;
|
||||
case PROP_USE_GSTPAY:
|
||||
g_value_set_boolean (value, factory->use_gstpay);
|
||||
g_value_set_boolean (value, priv->use_gstpay);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||
|
@ -218,13 +242,14 @@ gst_rtsp_media_factory_uri_set_property (GObject * object, guint propid,
|
|||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRTSPMediaFactoryURI *factory = GST_RTSP_MEDIA_FACTORY_URI (object);
|
||||
GstRTSPMediaFactoryURIPrivate *priv = factory->priv;
|
||||
|
||||
switch (propid) {
|
||||
case PROP_URI:
|
||||
gst_rtsp_media_factory_uri_set_uri (factory, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_USE_GSTPAY:
|
||||
factory->use_gstpay = g_value_get_boolean (value);
|
||||
priv->use_gstpay = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||
|
@ -259,13 +284,17 @@ void
|
|||
gst_rtsp_media_factory_uri_set_uri (GstRTSPMediaFactoryURI * factory,
|
||||
const gchar * uri)
|
||||
{
|
||||
GstRTSPMediaFactoryURIPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY_URI (factory));
|
||||
g_return_if_fail (uri != NULL);
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
g_free (factory->uri);
|
||||
factory->uri = g_strdup (uri);
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
priv = factory->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
g_free (priv->uri);
|
||||
priv->uri = g_strdup (uri);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,13 +308,16 @@ gst_rtsp_media_factory_uri_set_uri (GstRTSPMediaFactoryURI * factory,
|
|||
gchar *
|
||||
gst_rtsp_media_factory_uri_get_uri (GstRTSPMediaFactoryURI * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryURIPrivate *priv;
|
||||
gchar *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY_URI (factory), NULL);
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
result = g_strdup (factory->uri);
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
priv = factory->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
result = g_strdup (priv->uri);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -293,12 +325,13 @@ gst_rtsp_media_factory_uri_get_uri (GstRTSPMediaFactoryURI * factory)
|
|||
static GstElementFactory *
|
||||
find_payloader (GstRTSPMediaFactoryURI * urifact, GstCaps * caps)
|
||||
{
|
||||
GstRTSPMediaFactoryURIPrivate *priv = urifact->priv;
|
||||
GList *list;
|
||||
GstElementFactory *factory = NULL;
|
||||
gboolean autoplug_more = FALSE;
|
||||
|
||||
/* first find a demuxer that can link */
|
||||
list = gst_element_factory_list_filter (urifact->demuxers, caps,
|
||||
list = gst_element_factory_list_filter (priv->demuxers, caps,
|
||||
GST_PAD_SINK, FALSE);
|
||||
|
||||
if (list) {
|
||||
|
@ -340,17 +373,17 @@ find_payloader (GstRTSPMediaFactoryURI * urifact, GstCaps * caps)
|
|||
return NULL;
|
||||
|
||||
/* no demuxer try a depayloader */
|
||||
list = gst_element_factory_list_filter (urifact->payloaders, caps,
|
||||
list = gst_element_factory_list_filter (priv->payloaders, caps,
|
||||
GST_PAD_SINK, FALSE);
|
||||
|
||||
if (list == NULL) {
|
||||
if (urifact->use_gstpay) {
|
||||
if (priv->use_gstpay) {
|
||||
/* no depayloader or parser/demuxer, use gstpay when allowed */
|
||||
factory = gst_element_factory_find ("rtpgstpay");
|
||||
} else {
|
||||
/* no depayloader, try a decoder, we'll get to a payloader for a decoded
|
||||
* video or audio format, worst case. */
|
||||
list = gst_element_factory_list_filter (urifact->decoders, caps,
|
||||
list = gst_element_factory_list_filter (priv->decoders, caps,
|
||||
GST_PAD_SINK, FALSE);
|
||||
|
||||
if (list != NULL) {
|
||||
|
@ -405,6 +438,7 @@ static void
|
|||
pad_added_cb (GstElement * uribin, GstPad * pad, GstElement * element)
|
||||
{
|
||||
GstRTSPMediaFactoryURI *urifact;
|
||||
GstRTSPMediaFactoryURIPrivate *priv;
|
||||
FactoryData *data;
|
||||
GstElementFactory *factory;
|
||||
GstElement *payloader;
|
||||
|
@ -418,6 +452,7 @@ pad_added_cb (GstElement * uribin, GstPad * pad, GstElement * element)
|
|||
/* link the element now and expose the pad */
|
||||
data = g_object_get_data (G_OBJECT (element), factory_key);
|
||||
urifact = data->factory;
|
||||
priv = urifact->priv;
|
||||
|
||||
/* ref to make refcounting easier later */
|
||||
gst_object_ref (pad);
|
||||
|
@ -429,10 +464,10 @@ pad_added_cb (GstElement * uribin, GstPad * pad, GstElement * element)
|
|||
goto no_caps;
|
||||
|
||||
/* check for raw caps */
|
||||
if (gst_caps_can_intersect (caps, urifact->raw_vcaps)) {
|
||||
if (gst_caps_can_intersect (caps, priv->raw_vcaps)) {
|
||||
/* we have raw video caps, insert converter */
|
||||
convert = gst_element_factory_make ("videoconvert", NULL);
|
||||
} else if (gst_caps_can_intersect (caps, urifact->raw_acaps)) {
|
||||
} else if (gst_caps_can_intersect (caps, priv->raw_acaps)) {
|
||||
/* we have raw audio caps, insert converter */
|
||||
convert = gst_element_factory_make ("audioconvert", NULL);
|
||||
} else {
|
||||
|
@ -536,11 +571,13 @@ static GstElement *
|
|||
rtsp_media_factory_uri_create_element (GstRTSPMediaFactory * factory,
|
||||
const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPMediaFactoryURIPrivate *priv;
|
||||
GstElement *topbin, *element, *uribin;
|
||||
GstRTSPMediaFactoryURI *urifact;
|
||||
FactoryData *data;
|
||||
|
||||
urifact = GST_RTSP_MEDIA_FACTORY_URI_CAST (factory);
|
||||
priv = urifact->priv;
|
||||
|
||||
GST_LOG ("creating element");
|
||||
|
||||
|
@ -555,7 +592,7 @@ rtsp_media_factory_uri_create_element (GstRTSPMediaFactory * factory,
|
|||
if (uribin == NULL)
|
||||
goto no_uridecodebin;
|
||||
|
||||
g_object_set (uribin, "uri", urifact->uri, NULL);
|
||||
g_object_set (uribin, "uri", priv->uri, NULL);
|
||||
|
||||
/* keep factory data around */
|
||||
data = g_new0 (FactoryData, 1);
|
||||
|
|
|
@ -38,24 +38,17 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPMediaFactoryURI GstRTSPMediaFactoryURI;
|
||||
typedef struct _GstRTSPMediaFactoryURIClass GstRTSPMediaFactoryURIClass;
|
||||
typedef struct _GstRTSPMediaFactoryURIPrivate GstRTSPMediaFactoryURIPrivate;
|
||||
|
||||
/**
|
||||
* GstRTSPMediaFactoryURI:
|
||||
* @uri: the uri
|
||||
*
|
||||
* A media factory that creates a pipeline to play and uri.
|
||||
*/
|
||||
struct _GstRTSPMediaFactoryURI {
|
||||
GstRTSPMediaFactory parent;
|
||||
|
||||
gchar *uri;
|
||||
gboolean use_gstpay;
|
||||
|
||||
GstCaps *raw_vcaps;
|
||||
GstCaps *raw_acaps;
|
||||
GList *demuxers;
|
||||
GList *payloaders;
|
||||
GList *decoders;
|
||||
GstRTSPMediaFactoryURIPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,28 @@
|
|||
|
||||
#include "rtsp-media-factory.h"
|
||||
|
||||
#define GST_RTSP_MEDIA_FACTORY_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY, GstRTSPMediaFactoryPrivate))
|
||||
|
||||
#define GST_RTSP_MEDIA_FACTORY_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_CAST(f)->priv->lock))
|
||||
#define GST_RTSP_MEDIA_FACTORY_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
|
||||
#define GST_RTSP_MEDIA_FACTORY_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
|
||||
|
||||
struct _GstRTSPMediaFactoryPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
gchar *launch;
|
||||
gboolean shared;
|
||||
gboolean eos_shutdown;
|
||||
GstRTSPLowerTrans protocols;
|
||||
GstRTSPAuth *auth;
|
||||
guint buffer_size;
|
||||
GstRTSPAddressPool *pool;
|
||||
|
||||
GMutex medias_lock;
|
||||
GHashTable *medias;
|
||||
};
|
||||
|
||||
#define DEFAULT_LAUNCH NULL
|
||||
#define DEFAULT_SHARED FALSE
|
||||
#define DEFAULT_EOS_SHUTDOWN FALSE
|
||||
|
@ -72,6 +94,8 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gst_rtsp_media_factory_get_property;
|
||||
|
@ -144,15 +168,19 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
|
|||
static void
|
||||
gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
factory->launch = g_strdup (DEFAULT_LAUNCH);
|
||||
factory->shared = DEFAULT_SHARED;
|
||||
factory->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
|
||||
factory->protocols = DEFAULT_PROTOCOLS;
|
||||
factory->buffer_size = DEFAULT_BUFFER_SIZE;
|
||||
GstRTSPMediaFactoryPrivate *priv =
|
||||
GST_RTSP_MEDIA_FACTORY_GET_PRIVATE (factory);
|
||||
factory->priv = priv;
|
||||
|
||||
g_mutex_init (&factory->lock);
|
||||
g_mutex_init (&factory->medias_lock);
|
||||
factory->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
priv->launch = g_strdup (DEFAULT_LAUNCH);
|
||||
priv->shared = DEFAULT_SHARED;
|
||||
priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
|
||||
priv->protocols = DEFAULT_PROTOCOLS;
|
||||
priv->buffer_size = DEFAULT_BUFFER_SIZE;
|
||||
|
||||
g_mutex_init (&priv->lock);
|
||||
g_mutex_init (&priv->medias_lock);
|
||||
priv->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
}
|
||||
|
||||
|
@ -160,15 +188,16 @@ static void
|
|||
gst_rtsp_media_factory_finalize (GObject * obj)
|
||||
{
|
||||
GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
|
||||
GstRTSPMediaFactoryPrivate *priv = factory->priv;
|
||||
|
||||
g_hash_table_unref (factory->medias);
|
||||
g_mutex_clear (&factory->medias_lock);
|
||||
g_free (factory->launch);
|
||||
g_mutex_clear (&factory->lock);
|
||||
if (factory->auth)
|
||||
g_object_unref (factory->auth);
|
||||
if (factory->pool)
|
||||
g_object_unref (factory->pool);
|
||||
g_hash_table_unref (priv->medias);
|
||||
g_mutex_clear (&priv->medias_lock);
|
||||
g_free (priv->launch);
|
||||
g_mutex_clear (&priv->lock);
|
||||
if (priv->auth)
|
||||
g_object_unref (priv->auth);
|
||||
if (priv->pool)
|
||||
g_object_unref (priv->pool);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
|
||||
}
|
||||
|
@ -268,12 +297,16 @@ void
|
|||
gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
|
||||
const gchar * launch)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
g_return_if_fail (launch != NULL);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
g_free (factory->launch);
|
||||
factory->launch = g_strdup (launch);
|
||||
g_free (priv->launch);
|
||||
priv->launch = g_strdup (launch);
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
}
|
||||
|
||||
|
@ -289,12 +322,15 @@ gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
|
|||
gchar *
|
||||
gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
gchar *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
result = g_strdup (factory->launch);
|
||||
result = g_strdup (priv->launch);
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
return result;
|
||||
|
@ -311,10 +347,14 @@ void
|
|||
gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
|
||||
gboolean shared)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
factory->shared = shared;
|
||||
priv->shared = shared;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
}
|
||||
|
||||
|
@ -329,12 +369,15 @@ gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
|
|||
gboolean
|
||||
gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
result = factory->shared;
|
||||
result = priv->shared;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
return result;
|
||||
|
@ -352,10 +395,14 @@ void
|
|||
gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
|
||||
gboolean eos_shutdown)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
factory->eos_shutdown = eos_shutdown;
|
||||
priv->eos_shutdown = eos_shutdown;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
}
|
||||
|
||||
|
@ -371,12 +418,15 @@ gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
|
|||
gboolean
|
||||
gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
result = factory->eos_shutdown;
|
||||
result = priv->eos_shutdown;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
return result;
|
||||
|
@ -393,10 +443,14 @@ void
|
|||
gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
|
||||
guint size)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
factory->buffer_size = size;
|
||||
priv->buffer_size = size;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
}
|
||||
|
||||
|
@ -411,12 +465,15 @@ gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
|
|||
guint
|
||||
gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
guint result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
result = factory->buffer_size;
|
||||
result = priv->buffer_size;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
return result;
|
||||
|
@ -433,13 +490,16 @@ void
|
|||
gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
|
||||
GstRTSPAddressPool * pool)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
GstRTSPAddressPool *old;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
if ((old = factory->pool) != pool)
|
||||
factory->pool = pool ? g_object_ref (pool) : NULL;
|
||||
if ((old = priv->pool) != pool)
|
||||
priv->pool = pool ? g_object_ref (pool) : NULL;
|
||||
else
|
||||
old = NULL;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
@ -460,12 +520,15 @@ gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
|
|||
GstRTSPAddressPool *
|
||||
gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
GstRTSPAddressPool *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
if ((result = factory->pool))
|
||||
if ((result = priv->pool))
|
||||
g_object_ref (result);
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
|
@ -483,13 +546,16 @@ void
|
|||
gst_rtsp_media_factory_set_auth (GstRTSPMediaFactory * factory,
|
||||
GstRTSPAuth * auth)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
GstRTSPAuth *old;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
if ((old = factory->auth) != auth)
|
||||
factory->auth = auth ? g_object_ref (auth) : NULL;
|
||||
if ((old = priv->auth) != auth)
|
||||
priv->auth = auth ? g_object_ref (auth) : NULL;
|
||||
else
|
||||
old = NULL;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
@ -510,12 +576,15 @@ gst_rtsp_media_factory_set_auth (GstRTSPMediaFactory * factory,
|
|||
GstRTSPAuth *
|
||||
gst_rtsp_media_factory_get_auth (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
GstRTSPAuth *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
if ((result = factory->auth))
|
||||
if ((result = priv->auth))
|
||||
g_object_ref (result);
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
|
@ -533,10 +602,14 @@ void
|
|||
gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
|
||||
GstRTSPLowerTrans protocols)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
factory->protocols = protocols;
|
||||
priv->protocols = protocols;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
}
|
||||
|
||||
|
@ -551,13 +624,16 @@ gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
|
|||
GstRTSPLowerTrans
|
||||
gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
GstRTSPLowerTrans res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
|
||||
GST_RTSP_LOWER_TRANS_UNKNOWN);
|
||||
|
||||
priv = factory->priv;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
res = factory->protocols;
|
||||
res = priv->protocols;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
return res;
|
||||
|
@ -572,9 +648,11 @@ compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
|
|||
static void
|
||||
media_unprepared (GstRTSPMedia * media, GstRTSPMediaFactory * factory)
|
||||
{
|
||||
g_mutex_lock (&factory->medias_lock);
|
||||
g_hash_table_foreach_remove (factory->medias, (GHRFunc) compare_media, media);
|
||||
g_mutex_unlock (&factory->medias_lock);
|
||||
GstRTSPMediaFactoryPrivate *priv = factory->priv;;
|
||||
|
||||
g_mutex_lock (&priv->medias_lock);
|
||||
g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
|
||||
g_mutex_unlock (&priv->medias_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -598,6 +676,7 @@ GstRTSPMedia *
|
|||
gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
|
||||
const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
gchar *key;
|
||||
GstRTSPMedia *media;
|
||||
GstRTSPMediaFactoryClass *klass;
|
||||
|
@ -605,6 +684,7 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
|
|||
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
|
||||
g_return_val_if_fail (url != NULL, NULL);
|
||||
|
||||
priv = factory->priv;;
|
||||
klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
|
||||
|
||||
/* convert the url to a key for the hashtable. NULL return or a NULL function
|
||||
|
@ -614,10 +694,10 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
|
|||
else
|
||||
key = NULL;
|
||||
|
||||
g_mutex_lock (&factory->medias_lock);
|
||||
g_mutex_lock (&priv->medias_lock);
|
||||
if (key) {
|
||||
/* we have a key, see if we find a cached media */
|
||||
media = g_hash_table_lookup (factory->medias, key);
|
||||
media = g_hash_table_lookup (priv->medias, key);
|
||||
if (media)
|
||||
g_object_ref (media);
|
||||
} else
|
||||
|
@ -647,7 +727,7 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
|
|||
if (gst_rtsp_media_is_shared (media)) {
|
||||
/* insert in the hashtable, takes ownership of the key */
|
||||
g_object_ref (media);
|
||||
g_hash_table_insert (factory->medias, key, media);
|
||||
g_hash_table_insert (priv->medias, key, media);
|
||||
key = NULL;
|
||||
}
|
||||
if (!gst_rtsp_media_is_reusable (media)) {
|
||||
|
@ -658,7 +738,7 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
|
|||
}
|
||||
}
|
||||
}
|
||||
g_mutex_unlock (&factory->medias_lock);
|
||||
g_mutex_unlock (&priv->medias_lock);
|
||||
|
||||
if (key)
|
||||
g_free (key);
|
||||
|
@ -687,16 +767,17 @@ default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
|
|||
static GstElement *
|
||||
default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv = factory->priv;
|
||||
GstElement *element;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
/* we need a parse syntax */
|
||||
if (factory->launch == NULL)
|
||||
if (priv->launch == NULL)
|
||||
goto no_launch;
|
||||
|
||||
/* parse the user provided launch line */
|
||||
element = gst_parse_launch (factory->launch, &error);
|
||||
element = gst_parse_launch (priv->launch, &error);
|
||||
if (element == NULL)
|
||||
goto parse_error;
|
||||
|
||||
|
@ -719,7 +800,7 @@ no_launch:
|
|||
parse_error:
|
||||
{
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
g_critical ("could not parse launch syntax (%s): %s", factory->launch,
|
||||
g_critical ("could not parse launch syntax (%s): %s", priv->launch,
|
||||
(error ? error->message : "unknown reason"));
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
|
@ -731,7 +812,7 @@ static GstRTSPMedia *
|
|||
default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPMedia *media;
|
||||
GstElement *element;
|
||||
GstElement *element, *pipeline;
|
||||
GstRTSPMediaFactoryClass *klass;
|
||||
|
||||
klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
|
||||
|
@ -744,13 +825,12 @@ default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
|
|||
goto no_element;
|
||||
|
||||
/* create a new empty media */
|
||||
media = gst_rtsp_media_new ();
|
||||
media->element = element;
|
||||
media = gst_rtsp_media_new (element);
|
||||
|
||||
gst_rtsp_media_collect_streams (media);
|
||||
|
||||
media->pipeline = klass->create_pipeline (factory, media);
|
||||
if (media->pipeline == NULL)
|
||||
pipeline = klass->create_pipeline (factory, media);
|
||||
if (pipeline == NULL)
|
||||
goto no_pipeline;
|
||||
|
||||
return media;
|
||||
|
@ -779,25 +859,16 @@ default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
|
|||
{
|
||||
GstElement *pipeline;
|
||||
|
||||
if (media->element == NULL)
|
||||
goto no_element;
|
||||
|
||||
pipeline = gst_pipeline_new ("media-pipeline");
|
||||
gst_bin_add (GST_BIN_CAST (pipeline), media->element);
|
||||
gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
|
||||
|
||||
return pipeline;
|
||||
|
||||
/* ERRORS */
|
||||
no_element:
|
||||
{
|
||||
g_critical ("no element");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
|
||||
{
|
||||
GstRTSPMediaFactoryPrivate *priv = factory->priv;
|
||||
gboolean shared, eos_shutdown;
|
||||
guint size;
|
||||
GstRTSPAuth *auth;
|
||||
|
@ -806,10 +877,10 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
|
|||
|
||||
/* configure the sharedness */
|
||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||
shared = factory->shared;
|
||||
eos_shutdown = factory->eos_shutdown;
|
||||
size = factory->buffer_size;
|
||||
protocols = factory->protocols;
|
||||
shared = priv->shared;
|
||||
eos_shutdown = priv->eos_shutdown;
|
||||
size = priv->buffer_size;
|
||||
protocols = priv->protocols;
|
||||
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
|
||||
|
||||
gst_rtsp_media_set_shared (media, shared);
|
||||
|
|
|
@ -41,24 +41,11 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPMediaFactory GstRTSPMediaFactory;
|
||||
typedef struct _GstRTSPMediaFactoryClass GstRTSPMediaFactoryClass;
|
||||
|
||||
#define GST_RTSP_MEDIA_FACTORY_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_CAST(f)->lock))
|
||||
#define GST_RTSP_MEDIA_FACTORY_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
|
||||
#define GST_RTSP_MEDIA_FACTORY_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
|
||||
typedef struct _GstRTSPMediaFactoryPrivate GstRTSPMediaFactoryPrivate;
|
||||
|
||||
/**
|
||||
* GstRTSPMediaFactory:
|
||||
* @parent: the parent GObject
|
||||
* @lock: mutex protecting the datastructure.
|
||||
* @launch: the launch description
|
||||
* @shared: if media from this factory can be shared between clients
|
||||
* @eos_shutdown: if shutdown should first send EOS to the pipeline
|
||||
* @protocols: allowed transport protocols
|
||||
* @auth: the authentication manager
|
||||
* @buffer_size: the kernel udp buffer size
|
||||
* @pool: the multicast address pool to use
|
||||
* @medias_lock: mutex protecting the medias.
|
||||
* @medias: hashtable of shared media
|
||||
*
|
||||
* The definition and logic for constructing the pipeline for a media. The media
|
||||
* can contain multiple streams like audio and video.
|
||||
|
@ -66,17 +53,7 @@ typedef struct _GstRTSPMediaFactoryClass GstRTSPMediaFactoryClass;
|
|||
struct _GstRTSPMediaFactory {
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
gchar *launch;
|
||||
gboolean shared;
|
||||
gboolean eos_shutdown;
|
||||
GstRTSPLowerTrans protocols;
|
||||
GstRTSPAuth *auth;
|
||||
guint buffer_size;
|
||||
GstRTSPAddressPool *pool;
|
||||
|
||||
GMutex medias_lock;
|
||||
GHashTable *medias;
|
||||
GstRTSPMediaFactoryPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,6 +38,7 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPMedia GstRTSPMedia;
|
||||
typedef struct _GstRTSPMediaClass GstRTSPMediaClass;
|
||||
typedef struct _GstRTSPMediaPrivate GstRTSPMediaPrivate;
|
||||
|
||||
#include "rtsp-stream.h"
|
||||
#include "rtsp-auth.h"
|
||||
|
@ -64,36 +65,6 @@ typedef enum {
|
|||
|
||||
/**
|
||||
* GstRTSPMedia:
|
||||
* @parent: parent GObject
|
||||
* @lock: for protecting the object
|
||||
* @cond: for signaling the object
|
||||
* @shared: if this media can be shared between clients
|
||||
* @reusable: if this media can be reused after an unprepare
|
||||
* @protocols: the allowed lower transport for this stream
|
||||
* @reused: if this media has been reused
|
||||
* @is_ipv6: if this media is using ipv6
|
||||
* @eos_shutdown: if EOS should be sent on shutdown
|
||||
* @buffer_size: The UDP buffer size
|
||||
* @auth: the authentication service in use
|
||||
* @multicast_group: the multicast group to use
|
||||
* @element: the data providing element, owned by @pipeline
|
||||
* @streams: the different #GstRTSPStream provided by @element
|
||||
* @dynamic: list of dynamic elements managed by @element
|
||||
* @status: the status of the media pipeline
|
||||
* @n_active: the number of active connections
|
||||
* @adding: when elements are added to the pipeline
|
||||
* @pipeline: the toplevel pipeline
|
||||
* @fakesink: for making state changes async
|
||||
* @source: the bus watch for pipeline messages.
|
||||
* @id: the id of the watch
|
||||
* @is_live: if the pipeline is live
|
||||
* @seekable: if the pipeline can perform a seek
|
||||
* @buffering: if the pipeline is buffering
|
||||
* @target_state: the desired target state of the pipeline
|
||||
* @rtpbin: the rtpbin
|
||||
* @range: the range of the media being streamed
|
||||
* @range_start: range start in #GstClockTime
|
||||
* @range_stop: range stop in #GstClockTime
|
||||
*
|
||||
* A class that contains the GStreamer element along with a list of
|
||||
* #GstRTSPStream objects that can produce data.
|
||||
|
@ -103,45 +74,7 @@ typedef enum {
|
|||
struct _GstRTSPMedia {
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
GCond cond;
|
||||
|
||||
gboolean shared;
|
||||
gboolean reusable;
|
||||
GstRTSPLowerTrans protocols;
|
||||
gboolean reused;
|
||||
gboolean is_ipv6;
|
||||
gboolean eos_shutdown;
|
||||
guint buffer_size;
|
||||
GstRTSPAuth *auth;
|
||||
GstRTSPAddressPool*pool;
|
||||
|
||||
GstElement *element;
|
||||
GRecMutex state_lock;
|
||||
GPtrArray *streams;
|
||||
GList *dynamic;
|
||||
GstRTSPMediaStatus status;
|
||||
gint n_active;
|
||||
gboolean adding;
|
||||
|
||||
/* the pipeline for the media */
|
||||
GstElement *pipeline;
|
||||
GstElement *fakesink;
|
||||
GSource *source;
|
||||
guint id;
|
||||
|
||||
gboolean is_live;
|
||||
gboolean seekable;
|
||||
gboolean buffering;
|
||||
GstState target_state;
|
||||
|
||||
/* RTP session manager */
|
||||
GstElement *rtpbin;
|
||||
|
||||
/* the range of media */
|
||||
GstRTSPTimeRange range;
|
||||
GstClockTime range_start;
|
||||
GstClockTime range_stop;
|
||||
GstRTSPMediaPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -179,7 +112,11 @@ struct _GstRTSPMediaClass {
|
|||
GType gst_rtsp_media_get_type (void);
|
||||
|
||||
/* creating the media */
|
||||
GstRTSPMedia * gst_rtsp_media_new (void);
|
||||
GstRTSPMedia * gst_rtsp_media_new (GstElement *element);
|
||||
|
||||
void gst_rtsp_media_take_pipeline (GstRTSPMedia *media, GstPipeline *pipeline);
|
||||
|
||||
GstRTSPMediaStatus gst_rtsp_media_get_status (GstRTSPMedia *media);
|
||||
|
||||
void gst_rtsp_media_set_shared (GstRTSPMedia *media, gboolean shared);
|
||||
gboolean gst_rtsp_media_is_shared (GstRTSPMedia *media);
|
||||
|
|
|
@ -19,6 +19,15 @@
|
|||
|
||||
#include "rtsp-mount-points.h"
|
||||
|
||||
#define GST_RTSP_MOUNT_POINTS_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MOUNT_POINTS, GstRTSPMountPointsPrivate))
|
||||
|
||||
struct _GstRTSPMountPointsPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
GHashTable *mounts;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstRTSPMountPoints, gst_rtsp_mount_points, G_TYPE_OBJECT);
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
|
||||
|
@ -34,6 +43,8 @@ gst_rtsp_mount_points_class_init (GstRTSPMountPointsClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPMountPointsPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = gst_rtsp_mount_points_finalize;
|
||||
|
@ -47,10 +58,14 @@ gst_rtsp_mount_points_class_init (GstRTSPMountPointsClass * klass)
|
|||
static void
|
||||
gst_rtsp_mount_points_init (GstRTSPMountPoints * mounts)
|
||||
{
|
||||
GstRTSPMountPointsPrivate *priv = GST_RTSP_MOUNT_POINTS_GET_PRIVATE (mounts);
|
||||
|
||||
GST_DEBUG_OBJECT (mounts, "created");
|
||||
|
||||
g_mutex_init (&mounts->lock);
|
||||
mounts->mounts = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
mounts->priv = priv;
|
||||
|
||||
g_mutex_init (&priv->lock);
|
||||
priv->mounts = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
}
|
||||
|
||||
|
@ -58,11 +73,12 @@ static void
|
|||
gst_rtsp_mount_points_finalize (GObject * obj)
|
||||
{
|
||||
GstRTSPMountPoints *mounts = GST_RTSP_MOUNT_POINTS (obj);
|
||||
GstRTSPMountPointsPrivate *priv = mounts->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (mounts, "finalized");
|
||||
|
||||
g_hash_table_unref (mounts->mounts);
|
||||
g_mutex_clear (&mounts->lock);
|
||||
g_hash_table_unref (priv->mounts);
|
||||
g_mutex_clear (&priv->lock);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_mount_points_parent_class)->finalize (obj);
|
||||
}
|
||||
|
@ -87,16 +103,17 @@ gst_rtsp_mount_points_new (void)
|
|||
static GstRTSPMediaFactory *
|
||||
find_factory (GstRTSPMountPoints * mounts, const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPMountPointsPrivate *priv = mounts->priv;
|
||||
GstRTSPMediaFactory *result;
|
||||
|
||||
g_mutex_lock (&mounts->lock);
|
||||
g_mutex_lock (&priv->lock);
|
||||
/* find the location of the media in the hashtable we only use the absolute
|
||||
* path of the uri to find a media factory. If the factory depends on other
|
||||
* properties found in the url, this method should be overridden. */
|
||||
result = g_hash_table_lookup (mounts->mounts, url->abspath);
|
||||
result = g_hash_table_lookup (priv->mounts, url->abspath);
|
||||
if (result)
|
||||
g_object_ref (result);
|
||||
g_mutex_unlock (&mounts->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
GST_INFO ("found media factory %p for url abspath %s", result, url->abspath);
|
||||
|
||||
|
@ -150,13 +167,17 @@ void
|
|||
gst_rtsp_mount_points_add_factory (GstRTSPMountPoints * mounts,
|
||||
const gchar * path, GstRTSPMediaFactory * factory)
|
||||
{
|
||||
GstRTSPMountPointsPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
|
||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
g_mutex_lock (&mounts->lock);
|
||||
g_hash_table_insert (mounts->mounts, g_strdup (path), factory);
|
||||
g_mutex_unlock (&mounts->lock);
|
||||
priv = mounts->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
g_hash_table_insert (priv->mounts, g_strdup (path), factory);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,10 +191,14 @@ void
|
|||
gst_rtsp_mount_points_remove_factory (GstRTSPMountPoints * mounts,
|
||||
const gchar * path)
|
||||
{
|
||||
GstRTSPMountPointsPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
g_mutex_lock (&mounts->lock);
|
||||
g_hash_table_remove (mounts->mounts, path);
|
||||
g_mutex_unlock (&mounts->lock);
|
||||
priv = mounts->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
g_hash_table_remove (priv->mounts, path);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPMountPoints GstRTSPMountPoints;
|
||||
typedef struct _GstRTSPMountPointsClass GstRTSPMountPointsClass;
|
||||
typedef struct _GstRTSPMountPointsPrivate GstRTSPMountPointsPrivate;
|
||||
|
||||
/**
|
||||
* GstRTSPMountPoints:
|
||||
|
@ -50,8 +51,7 @@ typedef struct _GstRTSPMountPointsClass GstRTSPMountPointsClass;
|
|||
struct _GstRTSPMountPoints {
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
GHashTable *mounts;
|
||||
GstRTSPMountPointsPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,12 +38,12 @@ gst_rtsp_sdp_from_media (GstSDPMessage * sdp, GstSDPInfo * info,
|
|||
guint i, n_streams;
|
||||
gchar *rangestr;
|
||||
|
||||
if (media->status != GST_RTSP_MEDIA_STATUS_PREPARED)
|
||||
goto not_prepared;
|
||||
|
||||
n_streams = gst_rtsp_media_n_streams (media);
|
||||
|
||||
rangestr = gst_rtsp_media_get_range_string (media, FALSE);
|
||||
if (rangestr == NULL)
|
||||
goto not_prepared;
|
||||
|
||||
gst_sdp_message_add_attribute (sdp, "range", rangestr);
|
||||
g_free (rangestr);
|
||||
|
||||
|
@ -57,16 +57,19 @@ gst_rtsp_sdp_from_media (GstSDPMessage * sdp, GstSDPInfo * info,
|
|||
guint n_fields, j;
|
||||
gboolean first;
|
||||
GString *fmtp;
|
||||
GstCaps *caps;
|
||||
|
||||
stream = gst_rtsp_media_get_stream (media, i);
|
||||
caps = gst_rtsp_stream_get_caps (stream);
|
||||
|
||||
if (stream->caps == NULL) {
|
||||
if (caps == NULL) {
|
||||
g_warning ("ignoring stream %d without media type", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
s = gst_caps_get_structure (stream->caps, 0);
|
||||
s = gst_caps_get_structure (caps, 0);
|
||||
if (s == NULL) {
|
||||
gst_caps_unref (caps);
|
||||
g_warning ("ignoring stream %d without media type", i);
|
||||
continue;
|
||||
}
|
||||
|
@ -152,6 +155,7 @@ gst_rtsp_sdp_from_media (GstSDPMessage * sdp, GstSDPInfo * info,
|
|||
}
|
||||
gst_sdp_message_add_media (sdp, smedia);
|
||||
gst_sdp_media_free (smedia);
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -23,6 +23,38 @@
|
|||
#include "rtsp-server.h"
|
||||
#include "rtsp-client.h"
|
||||
|
||||
#define GST_RTSP_SERVER_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_SERVER, GstRTSPServerPrivate))
|
||||
|
||||
#define GST_RTSP_SERVER_GET_LOCK(server) (&(GST_RTSP_SERVER_CAST(server)->priv->lock))
|
||||
#define GST_RTSP_SERVER_LOCK(server) (g_mutex_lock(GST_RTSP_SERVER_GET_LOCK(server)))
|
||||
#define GST_RTSP_SERVER_UNLOCK(server) (g_mutex_unlock(GST_RTSP_SERVER_GET_LOCK(server)))
|
||||
|
||||
struct _GstRTSPServerPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
|
||||
/* server information */
|
||||
gchar *address;
|
||||
gchar *service;
|
||||
gint backlog;
|
||||
gint max_threads;
|
||||
|
||||
GSocket *socket;
|
||||
|
||||
/* sessions on this server */
|
||||
GstRTSPSessionPool *session_pool;
|
||||
|
||||
/* mount points for this server */
|
||||
GstRTSPMountPoints *mount_points;
|
||||
|
||||
/* authentication manager */
|
||||
GstRTSPAuth *auth;
|
||||
|
||||
/* the clients that are connected */
|
||||
GList *clients;
|
||||
};
|
||||
|
||||
#define DEFAULT_ADDRESS "0.0.0.0"
|
||||
#define DEFAULT_BOUND_PORT -1
|
||||
/* #define DEFAULT_ADDRESS "::0" */
|
||||
|
@ -80,6 +112,8 @@ gst_rtsp_server_class_init (GstRTSPServerClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPServerPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gst_rtsp_server_get_property;
|
||||
|
@ -185,36 +219,41 @@ gst_rtsp_server_class_init (GstRTSPServerClass * klass)
|
|||
static void
|
||||
gst_rtsp_server_init (GstRTSPServer * server)
|
||||
{
|
||||
g_mutex_init (&server->lock);
|
||||
server->address = g_strdup (DEFAULT_ADDRESS);
|
||||
server->service = g_strdup (DEFAULT_SERVICE);
|
||||
server->socket = NULL;
|
||||
server->backlog = DEFAULT_BACKLOG;
|
||||
server->session_pool = gst_rtsp_session_pool_new ();
|
||||
server->mount_points = gst_rtsp_mount_points_new ();
|
||||
server->max_threads = DEFAULT_MAX_THREADS;
|
||||
GstRTSPServerPrivate *priv = GST_RTSP_SERVER_GET_PRIVATE (server);
|
||||
|
||||
server->priv = priv;
|
||||
|
||||
g_mutex_init (&priv->lock);
|
||||
priv->address = g_strdup (DEFAULT_ADDRESS);
|
||||
priv->service = g_strdup (DEFAULT_SERVICE);
|
||||
priv->socket = NULL;
|
||||
priv->backlog = DEFAULT_BACKLOG;
|
||||
priv->session_pool = gst_rtsp_session_pool_new ();
|
||||
priv->mount_points = gst_rtsp_mount_points_new ();
|
||||
priv->max_threads = DEFAULT_MAX_THREADS;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_server_finalize (GObject * object)
|
||||
{
|
||||
GstRTSPServer *server = GST_RTSP_SERVER (object);
|
||||
GstRTSPServerPrivate *priv = server->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (server, "finalize server");
|
||||
|
||||
g_free (server->address);
|
||||
g_free (server->service);
|
||||
g_free (priv->address);
|
||||
g_free (priv->service);
|
||||
|
||||
if (server->socket)
|
||||
g_object_unref (server->socket);
|
||||
if (priv->socket)
|
||||
g_object_unref (priv->socket);
|
||||
|
||||
g_object_unref (server->session_pool);
|
||||
g_object_unref (server->mount_points);
|
||||
g_object_unref (priv->session_pool);
|
||||
g_object_unref (priv->mount_points);
|
||||
|
||||
if (server->auth)
|
||||
g_object_unref (server->auth);
|
||||
if (priv->auth)
|
||||
g_object_unref (priv->auth);
|
||||
|
||||
g_mutex_clear (&server->lock);
|
||||
g_mutex_clear (&priv->lock);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_server_parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -246,12 +285,16 @@ gst_rtsp_server_new (void)
|
|||
void
|
||||
gst_rtsp_server_set_address (GstRTSPServer * server, const gchar * address)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
g_return_if_fail (address != NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
g_free (server->address);
|
||||
server->address = g_strdup (address);
|
||||
g_free (priv->address);
|
||||
priv->address = g_strdup (address);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
}
|
||||
|
||||
|
@ -266,11 +309,15 @@ gst_rtsp_server_set_address (GstRTSPServer * server, const gchar * address)
|
|||
gchar *
|
||||
gst_rtsp_server_get_address (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
gchar *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
result = g_strdup (server->address);
|
||||
result = g_strdup (priv->address);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
return result;
|
||||
|
@ -287,16 +334,19 @@ gst_rtsp_server_get_address (GstRTSPServer * server)
|
|||
int
|
||||
gst_rtsp_server_get_bound_port (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GSocketAddress *address;
|
||||
int result = -1;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), result);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
if (server->socket == NULL)
|
||||
if (priv->socket == NULL)
|
||||
goto out;
|
||||
|
||||
address = g_socket_get_local_address (server->socket, NULL);
|
||||
address = g_socket_get_local_address (priv->socket, NULL);
|
||||
result = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
|
||||
g_object_unref (address);
|
||||
|
||||
|
@ -320,12 +370,16 @@ out:
|
|||
void
|
||||
gst_rtsp_server_set_service (GstRTSPServer * server, const gchar * service)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
g_return_if_fail (service != NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
g_free (server->service);
|
||||
server->service = g_strdup (service);
|
||||
g_free (priv->service);
|
||||
priv->service = g_strdup (service);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
}
|
||||
|
||||
|
@ -340,12 +394,15 @@ gst_rtsp_server_set_service (GstRTSPServer * server, const gchar * service)
|
|||
gchar *
|
||||
gst_rtsp_server_get_service (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
gchar *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
result = g_strdup (server->service);
|
||||
result = g_strdup (priv->service);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
return result;
|
||||
|
@ -364,10 +421,14 @@ gst_rtsp_server_get_service (GstRTSPServer * server)
|
|||
void
|
||||
gst_rtsp_server_set_backlog (GstRTSPServer * server, gint backlog)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
server->backlog = backlog;
|
||||
priv->backlog = backlog;
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
}
|
||||
|
||||
|
@ -382,12 +443,15 @@ gst_rtsp_server_set_backlog (GstRTSPServer * server, gint backlog)
|
|||
gint
|
||||
gst_rtsp_server_get_backlog (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
gint result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
result = server->backlog;
|
||||
result = priv->backlog;
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
return result;
|
||||
|
@ -404,16 +468,19 @@ void
|
|||
gst_rtsp_server_set_session_pool (GstRTSPServer * server,
|
||||
GstRTSPSessionPool * pool)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GstRTSPSessionPool *old;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
if (pool)
|
||||
g_object_ref (pool);
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
old = server->session_pool;
|
||||
server->session_pool = pool;
|
||||
old = priv->session_pool;
|
||||
priv->session_pool = pool;
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
if (old)
|
||||
|
@ -432,12 +499,15 @@ gst_rtsp_server_set_session_pool (GstRTSPServer * server,
|
|||
GstRTSPSessionPool *
|
||||
gst_rtsp_server_get_session_pool (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GstRTSPSessionPool *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
if ((result = server->session_pool))
|
||||
if ((result = priv->session_pool))
|
||||
g_object_ref (result);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
|
@ -455,16 +525,19 @@ void
|
|||
gst_rtsp_server_set_mount_points (GstRTSPServer * server,
|
||||
GstRTSPMountPoints * mounts)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GstRTSPMountPoints *old;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
if (mounts)
|
||||
g_object_ref (mounts);
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
old = server->mount_points;
|
||||
server->mount_points = mounts;
|
||||
old = priv->mount_points;
|
||||
priv->mount_points = mounts;
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
if (old)
|
||||
|
@ -484,12 +557,15 @@ gst_rtsp_server_set_mount_points (GstRTSPServer * server,
|
|||
GstRTSPMountPoints *
|
||||
gst_rtsp_server_get_mount_points (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GstRTSPMountPoints *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
if ((result = server->mount_points))
|
||||
if ((result = priv->mount_points))
|
||||
g_object_ref (result);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
|
@ -506,16 +582,19 @@ gst_rtsp_server_get_mount_points (GstRTSPServer * server)
|
|||
void
|
||||
gst_rtsp_server_set_auth (GstRTSPServer * server, GstRTSPAuth * auth)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GstRTSPAuth *old;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
if (auth)
|
||||
g_object_ref (auth);
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
old = server->auth;
|
||||
server->auth = auth;
|
||||
old = priv->auth;
|
||||
priv->auth = auth;
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
if (old)
|
||||
|
@ -535,12 +614,15 @@ gst_rtsp_server_set_auth (GstRTSPServer * server, GstRTSPAuth * auth)
|
|||
GstRTSPAuth *
|
||||
gst_rtsp_server_get_auth (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GstRTSPAuth *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
if ((result = server->auth))
|
||||
if ((result = priv->auth))
|
||||
g_object_ref (result);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
|
@ -559,10 +641,14 @@ gst_rtsp_server_get_auth (GstRTSPServer * server)
|
|||
void
|
||||
gst_rtsp_server_set_max_threads (GstRTSPServer * server, gint max_threads)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SERVER (server));
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
server->max_threads = max_threads;
|
||||
priv->max_threads = max_threads;
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
}
|
||||
|
||||
|
@ -578,12 +664,15 @@ gst_rtsp_server_set_max_threads (GstRTSPServer * server, gint max_threads)
|
|||
gint
|
||||
gst_rtsp_server_get_max_threads (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
gint res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
res = server->max_threads;
|
||||
res = priv->max_threads;
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
return res;
|
||||
|
@ -668,6 +757,7 @@ GSocket *
|
|||
gst_rtsp_server_create_socket (GstRTSPServer * server,
|
||||
GCancellable * cancellable, GError ** error)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GSocketConnectable *conn;
|
||||
GSocketAddressEnumerator *enumerator;
|
||||
GSocket *socket = NULL;
|
||||
|
@ -680,16 +770,18 @@ gst_rtsp_server_create_socket (GstRTSPServer * server,
|
|||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
GST_DEBUG_OBJECT (server, "getting address info of %s/%s", server->address,
|
||||
server->service);
|
||||
GST_DEBUG_OBJECT (server, "getting address info of %s/%s", priv->address,
|
||||
priv->service);
|
||||
|
||||
/* resolve the server IP address */
|
||||
port = atoi (server->service);
|
||||
if (port != 0 || !strcmp (server->service, "0"))
|
||||
conn = g_network_address_new (server->address, port);
|
||||
port = atoi (priv->service);
|
||||
if (port != 0 || !strcmp (priv->service, "0"))
|
||||
conn = g_network_address_new (priv->address, port);
|
||||
else
|
||||
conn = g_network_service_new (server->service, "tcp", server->address);
|
||||
conn = g_network_service_new (priv->service, "tcp", priv->address);
|
||||
|
||||
enumerator = g_socket_connectable_enumerate (conn);
|
||||
g_object_unref (conn);
|
||||
|
@ -764,13 +856,13 @@ gst_rtsp_server_create_socket (GstRTSPServer * server,
|
|||
g_socket_set_blocking (socket, FALSE);
|
||||
|
||||
/* set listen backlog */
|
||||
g_socket_set_listen_backlog (socket, server->backlog);
|
||||
g_socket_set_listen_backlog (socket, priv->backlog);
|
||||
|
||||
if (!g_socket_listen (socket, error))
|
||||
goto listen_failed;
|
||||
|
||||
GST_DEBUG_OBJECT (server, "listening on server socket %p with queue of %d",
|
||||
socket, server->backlog);
|
||||
socket, priv->backlog);
|
||||
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
|
@ -854,13 +946,14 @@ static void
|
|||
unmanage_client (GstRTSPClient * client, ClientContext * ctx)
|
||||
{
|
||||
GstRTSPServer *server = ctx->server;
|
||||
GstRTSPServerPrivate *priv = server->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (server, "unmanage client %p", client);
|
||||
|
||||
g_object_ref (server);
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
server->clients = g_list_remove (server->clients, ctx);
|
||||
priv->clients = g_list_remove (priv->clients, ctx);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
if (ctx->loop)
|
||||
|
@ -877,13 +970,14 @@ static void
|
|||
manage_client (GstRTSPServer * server, GstRTSPClient * client)
|
||||
{
|
||||
ClientContext *ctx;
|
||||
GstRTSPServerPrivate *priv = server->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (server, "manage client %p", client);
|
||||
|
||||
ctx = g_slice_new0 (ClientContext);
|
||||
ctx->server = server;
|
||||
ctx->client = client;
|
||||
if (server->max_threads == 0) {
|
||||
if (priv->max_threads == 0) {
|
||||
GSource *source;
|
||||
|
||||
/* find the context to add the watch */
|
||||
|
@ -899,7 +993,7 @@ manage_client (GstRTSPServer * server, GstRTSPClient * client)
|
|||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
g_signal_connect (client, "closed", (GCallback) unmanage_client, ctx);
|
||||
server->clients = g_list_prepend (server->clients, ctx);
|
||||
priv->clients = g_list_prepend (priv->clients, ctx);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
if (ctx->loop) {
|
||||
|
@ -913,17 +1007,18 @@ static GstRTSPClient *
|
|||
default_create_client (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPClient *client;
|
||||
GstRTSPServerPrivate *priv = server->priv;
|
||||
|
||||
/* a new client connected, create a session to handle the client. */
|
||||
client = gst_rtsp_client_new ();
|
||||
|
||||
/* set the session pool that this client should use */
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
gst_rtsp_client_set_session_pool (client, server->session_pool);
|
||||
gst_rtsp_client_set_session_pool (client, priv->session_pool);
|
||||
/* set the mount points that this client should use */
|
||||
gst_rtsp_client_set_mount_points (client, server->mount_points);
|
||||
gst_rtsp_client_set_mount_points (client, priv->mount_points);
|
||||
/* set authentication manager */
|
||||
gst_rtsp_client_set_auth (client, server->auth);
|
||||
gst_rtsp_client_set_auth (client, priv->auth);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
return client;
|
||||
|
@ -1073,9 +1168,12 @@ accept_failed:
|
|||
static void
|
||||
watch_destroyed (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPServerPrivate *priv = server->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (server, "source destroyed");
|
||||
g_object_unref (server->socket);
|
||||
server->socket = NULL;
|
||||
|
||||
g_object_unref (priv->socket);
|
||||
priv->socket = NULL;
|
||||
g_object_unref (server);
|
||||
}
|
||||
|
||||
|
@ -1100,18 +1198,21 @@ GSource *
|
|||
gst_rtsp_server_create_source (GstRTSPServer * server,
|
||||
GCancellable * cancellable, GError ** error)
|
||||
{
|
||||
GstRTSPServerPrivate *priv;
|
||||
GSocket *socket, *old;
|
||||
GSource *source;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
|
||||
|
||||
priv = server->priv;
|
||||
|
||||
socket = gst_rtsp_server_create_socket (server, NULL, error);
|
||||
if (socket == NULL)
|
||||
goto no_socket;
|
||||
|
||||
GST_RTSP_SERVER_LOCK (server);
|
||||
old = server->socket;
|
||||
server->socket = g_object_ref (socket);
|
||||
old = priv->socket;
|
||||
priv->socket = g_object_ref (socket);
|
||||
GST_RTSP_SERVER_UNLOCK (server);
|
||||
|
||||
if (old)
|
||||
|
|
|
@ -26,6 +26,7 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPServer GstRTSPServer;
|
||||
typedef struct _GstRTSPServerClass GstRTSPServerClass;
|
||||
typedef struct _GstRTSPServerPrivate GstRTSPServerPrivate;
|
||||
|
||||
#include "rtsp-session-pool.h"
|
||||
#include "rtsp-mount-points.h"
|
||||
|
@ -41,10 +42,6 @@ typedef struct _GstRTSPServerClass GstRTSPServerClass;
|
|||
#define GST_RTSP_SERVER_CAST(obj) ((GstRTSPServer*)(obj))
|
||||
#define GST_RTSP_SERVER_CLASS_CAST(klass) ((GstRTSPServerClass*)(klass))
|
||||
|
||||
#define GST_RTSP_SERVER_GET_LOCK(server) (&(GST_RTSP_SERVER_CAST(server)->lock))
|
||||
#define GST_RTSP_SERVER_LOCK(server) (g_mutex_lock(GST_RTSP_SERVER_GET_LOCK(server)))
|
||||
#define GST_RTSP_SERVER_UNLOCK(server) (g_mutex_unlock(GST_RTSP_SERVER_GET_LOCK(server)))
|
||||
|
||||
/**
|
||||
* GstRTSPServer:
|
||||
*
|
||||
|
@ -54,27 +51,7 @@ typedef struct _GstRTSPServerClass GstRTSPServerClass;
|
|||
struct _GstRTSPServer {
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
/* server information */
|
||||
gchar *address;
|
||||
gchar *service;
|
||||
gint backlog;
|
||||
gint max_threads;
|
||||
|
||||
GSocket *socket;
|
||||
|
||||
/* sessions on this server */
|
||||
GstRTSPSessionPool *session_pool;
|
||||
|
||||
/* mount points for this server */
|
||||
GstRTSPMountPoints *mount_points;
|
||||
|
||||
/* authentication manager */
|
||||
GstRTSPAuth *auth;
|
||||
|
||||
/* the clients that are connected */
|
||||
GList *clients;
|
||||
GstRTSPServerPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,6 +20,20 @@
|
|||
|
||||
#include "rtsp-session.h"
|
||||
|
||||
#define GST_RTSP_SESSION_MEDIA_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_SESSION_MEDIA, GstRTSPSessionMediaPrivate))
|
||||
|
||||
struct _GstRTSPSessionMediaPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
GstRTSPUrl *url;
|
||||
GstRTSPMedia *media;
|
||||
GstRTSPState state;
|
||||
guint counter;
|
||||
|
||||
GPtrArray *transports;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -38,6 +52,8 @@ gst_rtsp_session_media_class_init (GstRTSPSessionMediaClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPSessionMediaPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = gst_rtsp_session_media_finalize;
|
||||
|
@ -49,26 +65,32 @@ gst_rtsp_session_media_class_init (GstRTSPSessionMediaClass * klass)
|
|||
static void
|
||||
gst_rtsp_session_media_init (GstRTSPSessionMedia * media)
|
||||
{
|
||||
g_mutex_init (&media->lock);
|
||||
media->state = GST_RTSP_STATE_INIT;
|
||||
GstRTSPSessionMediaPrivate *priv = GST_RTSP_SESSION_MEDIA_GET_PRIVATE (media);
|
||||
|
||||
media->priv = priv;
|
||||
|
||||
g_mutex_init (&priv->lock);
|
||||
priv->state = GST_RTSP_STATE_INIT;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_session_media_finalize (GObject * obj)
|
||||
{
|
||||
GstRTSPSessionMedia *media;
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
|
||||
media = GST_RTSP_SESSION_MEDIA (obj);
|
||||
priv = media->priv;
|
||||
|
||||
GST_INFO ("free session media %p", media);
|
||||
|
||||
gst_rtsp_session_media_set_state (media, GST_STATE_NULL);
|
||||
|
||||
g_ptr_array_unref (media->transports);
|
||||
g_ptr_array_unref (priv->transports);
|
||||
|
||||
gst_rtsp_url_free (media->url);
|
||||
g_object_unref (media->media);
|
||||
g_mutex_clear (&media->lock);
|
||||
gst_rtsp_url_free (priv->url);
|
||||
g_object_unref (priv->media);
|
||||
g_mutex_clear (&priv->lock);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_session_media_parent_class)->finalize (obj);
|
||||
}
|
||||
|
@ -95,25 +117,65 @@ free_session_media (gpointer data)
|
|||
GstRTSPSessionMedia *
|
||||
gst_rtsp_session_media_new (const GstRTSPUrl * url, GstRTSPMedia * media)
|
||||
{
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
GstRTSPSessionMedia *result;
|
||||
guint n_streams;
|
||||
|
||||
g_return_val_if_fail (url != NULL, NULL);
|
||||
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
|
||||
g_return_val_if_fail (media->status == GST_RTSP_MEDIA_STATUS_PREPARED, NULL);
|
||||
g_return_val_if_fail (gst_rtsp_media_get_status (media) ==
|
||||
GST_RTSP_MEDIA_STATUS_PREPARED, NULL);
|
||||
|
||||
result = g_object_new (GST_TYPE_RTSP_SESSION_MEDIA, NULL);
|
||||
result->url = gst_rtsp_url_copy ((GstRTSPUrl *) url);
|
||||
result->media = media;
|
||||
priv = result->priv;
|
||||
|
||||
priv->url = gst_rtsp_url_copy ((GstRTSPUrl *) url);
|
||||
priv->media = media;
|
||||
|
||||
/* prealloc the streams now, filled with NULL */
|
||||
n_streams = gst_rtsp_media_n_streams (media);
|
||||
result->transports = g_ptr_array_new_full (n_streams, free_session_media);
|
||||
g_ptr_array_set_size (result->transports, n_streams);
|
||||
priv->transports = g_ptr_array_new_full (n_streams, free_session_media);
|
||||
g_ptr_array_set_size (priv->transports, n_streams);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_media_matches_url:
|
||||
* @media: a #GstRTSPSessionMedia
|
||||
* @url: a #GstRTSPUrl
|
||||
*
|
||||
* Check if the url of @media matches @url.
|
||||
*
|
||||
* Returns: %TRUE when @url matches the url of @media.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_session_media_matches_url (GstRTSPSessionMedia * media,
|
||||
const GstRTSPUrl * url)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), FALSE);
|
||||
g_return_val_if_fail (url != NULL, FALSE);
|
||||
|
||||
return g_str_equal (media->priv->url->abspath, url->abspath);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_media_get_media:
|
||||
* @media: a #GstRTSPSessionMedia
|
||||
*
|
||||
* Get the #GstRTSPMedia that was used when constructing @media
|
||||
*
|
||||
* Returns: (transfer none): the #GstRTSPMedia of @media. Remains valid as long
|
||||
* as @media is valid.
|
||||
*/
|
||||
GstRTSPMedia *
|
||||
gst_rtsp_session_media_get_media (GstRTSPSessionMedia * media)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), NULL);
|
||||
|
||||
return media->priv->media;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_media_set_transport:
|
||||
* @media: a #GstRTSPSessionMedia
|
||||
|
@ -128,21 +190,26 @@ GstRTSPStreamTransport *
|
|||
gst_rtsp_session_media_set_transport (GstRTSPSessionMedia * media,
|
||||
GstRTSPStream * stream, GstRTSPTransport * tr)
|
||||
{
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
GstRTSPStreamTransport *result;
|
||||
guint idx;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), NULL);
|
||||
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
|
||||
g_return_val_if_fail (stream->idx < media->transports->len, NULL);
|
||||
g_return_val_if_fail (tr != NULL, NULL);
|
||||
priv = media->priv;
|
||||
idx = gst_rtsp_stream_get_index (stream);
|
||||
g_return_val_if_fail (idx < priv->transports->len, NULL);
|
||||
|
||||
g_mutex_lock (&media->lock);
|
||||
result = g_ptr_array_index (media->transports, stream->idx);
|
||||
g_mutex_lock (&priv->lock);
|
||||
result = g_ptr_array_index (priv->transports, idx);
|
||||
if (result == NULL) {
|
||||
result = gst_rtsp_stream_transport_new (stream, tr);
|
||||
g_ptr_array_index (media->transports, stream->idx) = result;
|
||||
g_mutex_unlock (&media->lock);
|
||||
g_ptr_array_index (priv->transports, idx) = result;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
} else {
|
||||
gst_rtsp_stream_transport_set_transport (result, tr);
|
||||
g_mutex_unlock (&media->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -161,14 +228,16 @@ gst_rtsp_session_media_set_transport (GstRTSPSessionMedia * media,
|
|||
GstRTSPStreamTransport *
|
||||
gst_rtsp_session_media_get_transport (GstRTSPSessionMedia * media, guint idx)
|
||||
{
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
GstRTSPStreamTransport *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), NULL);
|
||||
g_return_val_if_fail (idx < media->transports->len, NULL);
|
||||
priv = media->priv;
|
||||
g_return_val_if_fail (idx < priv->transports->len, NULL);
|
||||
|
||||
g_mutex_lock (&media->lock);
|
||||
result = g_ptr_array_index (media->transports, idx);
|
||||
g_mutex_unlock (&media->lock);
|
||||
g_mutex_lock (&priv->lock);
|
||||
result = g_ptr_array_index (priv->transports, idx);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -187,12 +256,16 @@ gboolean
|
|||
gst_rtsp_session_media_alloc_channels (GstRTSPSessionMedia * media,
|
||||
GstRTSPRange * range)
|
||||
{
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), FALSE);
|
||||
|
||||
g_mutex_lock (&media->lock);
|
||||
range->min = media->counter++;
|
||||
range->max = media->counter++;
|
||||
g_mutex_unlock (&media->lock);
|
||||
priv = media->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
range->min = priv->counter++;
|
||||
range->max = priv->counter++;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -209,13 +282,64 @@ gst_rtsp_session_media_alloc_channels (GstRTSPSessionMedia * media,
|
|||
gboolean
|
||||
gst_rtsp_session_media_set_state (GstRTSPSessionMedia * media, GstState state)
|
||||
{
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), FALSE);
|
||||
|
||||
g_mutex_lock (&media->lock);
|
||||
ret = gst_rtsp_media_set_state (media->media, state, media->transports);
|
||||
g_mutex_unlock (&media->lock);
|
||||
priv = media->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
ret = gst_rtsp_media_set_state (priv->media, state, priv->transports);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_media_set_rtsp_state:
|
||||
* @media: a #GstRTSPSessionMedia
|
||||
* @state: a #GstRTSPState
|
||||
*
|
||||
* Set the RTSP state of @media to @state.
|
||||
*/
|
||||
void
|
||||
gst_rtsp_session_media_set_rtsp_state (GstRTSPSessionMedia * media,
|
||||
GstRTSPState state)
|
||||
{
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SESSION_MEDIA (media));
|
||||
|
||||
priv = media->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
priv->state = state;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_media_set_rtsp_state:
|
||||
* @media: a #GstRTSPSessionMedia
|
||||
*
|
||||
* Get the current RTSP state of @media.
|
||||
*
|
||||
* Returns: the current RTSP state of @media.
|
||||
*/
|
||||
GstRTSPState
|
||||
gst_rtsp_session_media_get_rtsp_state (GstRTSPSessionMedia * media)
|
||||
{
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
GstRTSPState ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media),
|
||||
GST_RTSP_STATE_INVALID);
|
||||
|
||||
priv = media->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
ret = priv->state;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPSessionMedia GstRTSPSessionMedia;
|
||||
typedef struct _GstRTSPSessionMediaClass GstRTSPSessionMediaClass;
|
||||
typedef struct _GstRTSPSessionMediaPrivate GstRTSPSessionMediaPrivate;
|
||||
|
||||
/**
|
||||
* GstRTSPSessionMedia:
|
||||
|
@ -53,13 +54,7 @@ struct _GstRTSPSessionMedia
|
|||
{
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
GstRTSPUrl *url;
|
||||
GstRTSPMedia *media;
|
||||
GstRTSPState state;
|
||||
guint counter;
|
||||
|
||||
GPtrArray *transports;
|
||||
GstRTSPSessionMediaPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstRTSPSessionMediaClass
|
||||
|
@ -71,10 +66,20 @@ GType gst_rtsp_session_media_get_type (void);
|
|||
|
||||
GstRTSPSessionMedia * gst_rtsp_session_media_new (const GstRTSPUrl *url,
|
||||
GstRTSPMedia *media);
|
||||
|
||||
gboolean gst_rtsp_session_media_matches_url (GstRTSPSessionMedia *media,
|
||||
const GstRTSPUrl *url);
|
||||
GstRTSPMedia * gst_rtsp_session_media_get_media (GstRTSPSessionMedia *media);
|
||||
|
||||
/* control media */
|
||||
|
||||
gboolean gst_rtsp_session_media_set_state (GstRTSPSessionMedia *media,
|
||||
GstState state);
|
||||
|
||||
void gst_rtsp_session_media_set_rtsp_state (GstRTSPSessionMedia *media,
|
||||
GstRTSPState state);
|
||||
GstRTSPState gst_rtsp_session_media_get_rtsp_state (GstRTSPSessionMedia *media);
|
||||
|
||||
/* get stream transport config */
|
||||
GstRTSPStreamTransport * gst_rtsp_session_media_set_transport (GstRTSPSessionMedia *media,
|
||||
GstRTSPStream *stream,
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
|
||||
#include "rtsp-session-pool.h"
|
||||
|
||||
#define GST_RTSP_SESSION_POOL_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_SESSION_POOL, GstRTSPSessionPoolPrivate))
|
||||
|
||||
struct _GstRTSPSessionPoolPrivate
|
||||
{
|
||||
guint max_sessions;
|
||||
|
||||
GMutex lock;
|
||||
GHashTable *sessions;
|
||||
};
|
||||
|
||||
#define DEFAULT_MAX_SESSIONS 0
|
||||
|
||||
enum
|
||||
|
@ -54,6 +65,8 @@ gst_rtsp_session_pool_class_init (GstRTSPSessionPoolClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPSessionPoolPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gst_rtsp_session_pool_get_property;
|
||||
|
@ -75,19 +88,24 @@ gst_rtsp_session_pool_class_init (GstRTSPSessionPoolClass * klass)
|
|||
static void
|
||||
gst_rtsp_session_pool_init (GstRTSPSessionPool * pool)
|
||||
{
|
||||
g_mutex_init (&pool->lock);
|
||||
pool->sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
GstRTSPSessionPoolPrivate *priv = GST_RTSP_SESSION_POOL_GET_PRIVATE (pool);
|
||||
|
||||
pool->priv = priv;
|
||||
|
||||
g_mutex_init (&priv->lock);
|
||||
priv->sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, g_object_unref);
|
||||
pool->max_sessions = DEFAULT_MAX_SESSIONS;
|
||||
priv->max_sessions = DEFAULT_MAX_SESSIONS;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_session_pool_finalize (GObject * object)
|
||||
{
|
||||
GstRTSPSessionPool *pool = GST_RTSP_SESSION_POOL (object);
|
||||
GstRTSPSessionPoolPrivate *priv = pool->priv;
|
||||
|
||||
g_mutex_clear (&pool->lock);
|
||||
g_hash_table_unref (pool->sessions);
|
||||
g_mutex_clear (&priv->lock);
|
||||
g_hash_table_unref (priv->sessions);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_session_pool_parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -152,11 +170,15 @@ gst_rtsp_session_pool_new (void)
|
|||
void
|
||||
gst_rtsp_session_pool_set_max_sessions (GstRTSPSessionPool * pool, guint max)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SESSION_POOL (pool));
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
pool->max_sessions = max;
|
||||
g_mutex_unlock (&pool->lock);
|
||||
priv = pool->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
priv->max_sessions = max;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,13 +193,16 @@ gst_rtsp_session_pool_set_max_sessions (GstRTSPSessionPool * pool, guint max)
|
|||
guint
|
||||
gst_rtsp_session_pool_get_max_sessions (GstRTSPSessionPool * pool)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
guint result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0);
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
result = pool->max_sessions;
|
||||
g_mutex_unlock (&pool->lock);
|
||||
priv = pool->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
result = priv->max_sessions;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -193,13 +218,16 @@ gst_rtsp_session_pool_get_max_sessions (GstRTSPSessionPool * pool)
|
|||
guint
|
||||
gst_rtsp_session_pool_get_n_sessions (GstRTSPSessionPool * pool)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
guint result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0);
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
result = g_hash_table_size (pool->sessions);
|
||||
g_mutex_unlock (&pool->lock);
|
||||
priv = pool->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
result = g_hash_table_size (priv->sessions);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -218,18 +246,21 @@ gst_rtsp_session_pool_get_n_sessions (GstRTSPSessionPool * pool)
|
|||
GstRTSPSession *
|
||||
gst_rtsp_session_pool_find (GstRTSPSessionPool * pool, const gchar * sessionid)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
GstRTSPSession *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL);
|
||||
g_return_val_if_fail (sessionid != NULL, NULL);
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
result = g_hash_table_lookup (pool->sessions, sessionid);
|
||||
priv = pool->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
result = g_hash_table_lookup (priv->sessions, sessionid);
|
||||
if (result) {
|
||||
g_object_ref (result);
|
||||
gst_rtsp_session_touch (result);
|
||||
}
|
||||
g_mutex_unlock (&pool->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -260,6 +291,7 @@ create_session_id (GstRTSPSessionPool * pool)
|
|||
GstRTSPSession *
|
||||
gst_rtsp_session_pool_create (GstRTSPSessionPool * pool)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
GstRTSPSession *result = NULL;
|
||||
GstRTSPSessionPoolClass *klass;
|
||||
gchar *id = NULL;
|
||||
|
@ -267,6 +299,8 @@ gst_rtsp_session_pool_create (GstRTSPSessionPool * pool)
|
|||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL);
|
||||
|
||||
priv = pool->priv;
|
||||
|
||||
klass = GST_RTSP_SESSION_POOL_GET_CLASS (pool);
|
||||
|
||||
retry = 0;
|
||||
|
@ -281,14 +315,14 @@ gst_rtsp_session_pool_create (GstRTSPSessionPool * pool)
|
|||
if (id == NULL)
|
||||
goto no_session;
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
g_mutex_lock (&priv->lock);
|
||||
/* check session limit */
|
||||
if (pool->max_sessions > 0) {
|
||||
if (g_hash_table_size (pool->sessions) >= pool->max_sessions)
|
||||
if (priv->max_sessions > 0) {
|
||||
if (g_hash_table_size (priv->sessions) >= priv->max_sessions)
|
||||
goto too_many_sessions;
|
||||
}
|
||||
/* check if the sessionid existed */
|
||||
result = g_hash_table_lookup (pool->sessions, id);
|
||||
result = g_hash_table_lookup (priv->sessions, id);
|
||||
if (result) {
|
||||
/* found, retry with a different session id */
|
||||
result = NULL;
|
||||
|
@ -300,9 +334,10 @@ gst_rtsp_session_pool_create (GstRTSPSessionPool * pool)
|
|||
result = gst_rtsp_session_new (id);
|
||||
/* take additional ref for the pool */
|
||||
g_object_ref (result);
|
||||
g_hash_table_insert (pool->sessions, result->sessionid, result);
|
||||
g_hash_table_insert (priv->sessions,
|
||||
(gchar *) gst_rtsp_session_get_sessionid (result), result);
|
||||
}
|
||||
g_mutex_unlock (&pool->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
g_free (id);
|
||||
} while (result == NULL);
|
||||
|
@ -323,14 +358,14 @@ no_session:
|
|||
collision:
|
||||
{
|
||||
GST_WARNING ("can't find unique sessionid for GstRTSPSessionPool %p", pool);
|
||||
g_mutex_unlock (&pool->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
g_free (id);
|
||||
return NULL;
|
||||
}
|
||||
too_many_sessions:
|
||||
{
|
||||
GST_WARNING ("session pool reached max sessions of %d", pool->max_sessions);
|
||||
g_mutex_unlock (&pool->lock);
|
||||
GST_WARNING ("session pool reached max sessions of %d", priv->max_sessions);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
g_free (id);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -348,14 +383,19 @@ too_many_sessions:
|
|||
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);
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
found = g_hash_table_remove (pool->sessions, sess->sessionid);
|
||||
g_mutex_unlock (&pool->lock);
|
||||
priv = pool->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
found =
|
||||
g_hash_table_remove (priv->sessions,
|
||||
gst_rtsp_session_get_sessionid (sess));
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
@ -378,18 +418,21 @@ cleanup_func (gchar * sessionid, GstRTSPSession * sess, GTimeVal * now)
|
|||
guint
|
||||
gst_rtsp_session_pool_cleanup (GstRTSPSessionPool * pool)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
guint result;
|
||||
GTimeVal now;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0);
|
||||
|
||||
priv = pool->priv;
|
||||
|
||||
g_get_current_time (&now);
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
g_mutex_lock (&priv->lock);
|
||||
result =
|
||||
g_hash_table_foreach_remove (pool->sessions, (GHRFunc) cleanup_func,
|
||||
g_hash_table_foreach_remove (priv->sessions, (GHRFunc) cleanup_func,
|
||||
&now);
|
||||
g_mutex_unlock (&pool->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -397,7 +440,7 @@ gst_rtsp_session_pool_cleanup (GstRTSPSessionPool * pool)
|
|||
typedef struct
|
||||
{
|
||||
GstRTSPSessionPool *pool;
|
||||
GstRTSPSessionFilterFunc func;
|
||||
GstRTSPSessionPoolFilterFunc func;
|
||||
gpointer user_data;
|
||||
GList *list;
|
||||
} FilterData;
|
||||
|
@ -443,21 +486,24 @@ filter_func (gchar * sessionid, GstRTSPSession * sess, FilterData * data)
|
|||
*/
|
||||
GList *
|
||||
gst_rtsp_session_pool_filter (GstRTSPSessionPool * pool,
|
||||
GstRTSPSessionFilterFunc func, gpointer user_data)
|
||||
GstRTSPSessionPoolFilterFunc func, gpointer user_data)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
FilterData data;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL);
|
||||
g_return_val_if_fail (func != NULL, NULL);
|
||||
|
||||
priv = pool->priv;
|
||||
|
||||
data.pool = pool;
|
||||
data.func = func;
|
||||
data.user_data = user_data;
|
||||
data.list = NULL;
|
||||
|
||||
g_mutex_lock (&pool->lock);
|
||||
g_hash_table_foreach_remove (pool->sessions, (GHRFunc) filter_func, &data);
|
||||
g_mutex_unlock (&pool->lock);
|
||||
g_mutex_lock (&priv->lock);
|
||||
g_hash_table_foreach_remove (priv->sessions, (GHRFunc) filter_func, &data);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return data.list;
|
||||
}
|
||||
|
@ -489,15 +535,17 @@ collect_timeout (gchar * sessionid, GstRTSPSession * sess, GstPoolSource * psrc)
|
|||
static gboolean
|
||||
gst_pool_source_prepare (GSource * source, gint * timeout)
|
||||
{
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
GstPoolSource *psrc;
|
||||
gboolean result;
|
||||
|
||||
psrc = (GstPoolSource *) source;
|
||||
psrc->timeout = -1;
|
||||
priv = psrc->pool->priv;
|
||||
|
||||
g_mutex_lock (&psrc->pool->lock);
|
||||
g_hash_table_foreach (psrc->pool->sessions, (GHFunc) collect_timeout, psrc);
|
||||
g_mutex_unlock (&psrc->pool->lock);
|
||||
g_mutex_lock (&priv->lock);
|
||||
g_hash_table_foreach (priv->sessions, (GHFunc) collect_timeout, psrc);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
if (timeout)
|
||||
*timeout = psrc->timeout;
|
||||
|
|
|
@ -27,6 +27,7 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPSessionPool GstRTSPSessionPool;
|
||||
typedef struct _GstRTSPSessionPoolClass GstRTSPSessionPoolClass;
|
||||
typedef struct _GstRTSPSessionPoolPrivate GstRTSPSessionPoolPrivate;
|
||||
|
||||
#include "rtsp-session.h"
|
||||
|
||||
|
@ -51,10 +52,7 @@ typedef struct _GstRTSPSessionPoolClass GstRTSPSessionPoolClass;
|
|||
struct _GstRTSPSessionPool {
|
||||
GObject parent;
|
||||
|
||||
guint max_sessions;
|
||||
|
||||
GMutex lock;
|
||||
GHashTable *sessions;
|
||||
GstRTSPSessionPoolPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -83,22 +81,7 @@ struct _GstRTSPSessionPoolClass {
|
|||
typedef gboolean (*GstRTSPSessionPoolFunc) (GstRTSPSessionPool *pool, gpointer user_data);
|
||||
|
||||
/**
|
||||
* GstRTSPFilterResult:
|
||||
* @GST_RTSP_FILTER_REMOVE: Remove session
|
||||
* @GST_RTSP_FILTER_KEEP: Keep session in the pool
|
||||
* @GST_RTSP_FILTER_REF: Ref session in the result list
|
||||
*
|
||||
* Possible return values for gst_rtsp_session_pool_filter().
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_RTSP_FILTER_REMOVE,
|
||||
GST_RTSP_FILTER_KEEP,
|
||||
GST_RTSP_FILTER_REF,
|
||||
} GstRTSPFilterResult;
|
||||
|
||||
/**
|
||||
* GstRTSPSessionFilterFunc:
|
||||
* GstRTSPSessionPoolFilterFunc:
|
||||
* @pool: a #GstRTSPSessionPool object
|
||||
* @session: a #GstRTSPSession in @pool
|
||||
* @user_data: user data that has been given to gst_rtsp_session_pool_filter()
|
||||
|
@ -117,9 +100,9 @@ typedef enum
|
|||
*
|
||||
* Returns: a #GstRTSPFilterResult.
|
||||
*/
|
||||
typedef GstRTSPFilterResult (*GstRTSPSessionFilterFunc) (GstRTSPSessionPool *pool,
|
||||
GstRTSPSession *session,
|
||||
gpointer user_data);
|
||||
typedef GstRTSPFilterResult (*GstRTSPSessionPoolFilterFunc) (GstRTSPSessionPool *pool,
|
||||
GstRTSPSession *session,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
GType gst_rtsp_session_pool_get_type (void);
|
||||
|
@ -142,7 +125,7 @@ gboolean gst_rtsp_session_pool_remove (GstRTSPSessionPoo
|
|||
|
||||
/* perform session maintenance */
|
||||
GList * gst_rtsp_session_pool_filter (GstRTSPSessionPool *pool,
|
||||
GstRTSPSessionFilterFunc func,
|
||||
GstRTSPSessionPoolFilterFunc func,
|
||||
gpointer user_data);
|
||||
guint gst_rtsp_session_pool_cleanup (GstRTSPSessionPool *pool);
|
||||
GSource * gst_rtsp_session_pool_create_watch (GstRTSPSessionPool *pool);
|
||||
|
|
|
@ -20,6 +20,22 @@
|
|||
|
||||
#include "rtsp-session.h"
|
||||
|
||||
#define GST_RTSP_SESSION_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_SESSION, GstRTSPSessionPrivate))
|
||||
|
||||
struct _GstRTSPSessionPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
gchar *sessionid;
|
||||
|
||||
guint timeout;
|
||||
GTimeVal create_time;
|
||||
GTimeVal last_access;
|
||||
gint expire_count;
|
||||
|
||||
GList *medias;
|
||||
};
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#define DEFAULT_TIMEOUT 60
|
||||
|
@ -48,6 +64,8 @@ gst_rtsp_session_class_init (GstRTSPSessionClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPSessionPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gst_rtsp_session_get_property;
|
||||
|
@ -71,9 +89,13 @@ gst_rtsp_session_class_init (GstRTSPSessionClass * klass)
|
|||
static void
|
||||
gst_rtsp_session_init (GstRTSPSession * session)
|
||||
{
|
||||
g_mutex_init (&session->lock);
|
||||
session->timeout = DEFAULT_TIMEOUT;
|
||||
g_get_current_time (&session->create_time);
|
||||
GstRTSPSessionPrivate *priv = GST_RTSP_SESSION_GET_PRIVATE (session);
|
||||
|
||||
session->priv = priv;
|
||||
|
||||
g_mutex_init (&priv->lock);
|
||||
priv->timeout = DEFAULT_TIMEOUT;
|
||||
g_get_current_time (&priv->create_time);
|
||||
gst_rtsp_session_touch (session);
|
||||
}
|
||||
|
||||
|
@ -81,17 +103,19 @@ static void
|
|||
gst_rtsp_session_finalize (GObject * obj)
|
||||
{
|
||||
GstRTSPSession *session;
|
||||
GstRTSPSessionPrivate *priv;
|
||||
|
||||
session = GST_RTSP_SESSION (obj);
|
||||
priv = session->priv;
|
||||
|
||||
GST_INFO ("finalize session %p", session);
|
||||
|
||||
/* free all media */
|
||||
g_list_free_full (session->medias, g_object_unref);
|
||||
g_list_free_full (priv->medias, g_object_unref);
|
||||
|
||||
/* free session id */
|
||||
g_free (session->sessionid);
|
||||
g_mutex_clear (&session->lock);
|
||||
g_free (priv->sessionid);
|
||||
g_mutex_clear (&priv->lock);
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_session_parent_class)->finalize (obj);
|
||||
}
|
||||
|
@ -101,10 +125,11 @@ gst_rtsp_session_get_property (GObject * object, guint propid,
|
|||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRTSPSession *session = GST_RTSP_SESSION (object);
|
||||
GstRTSPSessionPrivate *priv = session->priv;
|
||||
|
||||
switch (propid) {
|
||||
case PROP_SESSIONID:
|
||||
g_value_set_string (value, session->sessionid);
|
||||
g_value_set_string (value, priv->sessionid);
|
||||
break;
|
||||
case PROP_TIMEOUT:
|
||||
g_value_set_uint (value, gst_rtsp_session_get_timeout (session));
|
||||
|
@ -119,11 +144,12 @@ gst_rtsp_session_set_property (GObject * object, guint propid,
|
|||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRTSPSession *session = GST_RTSP_SESSION (object);
|
||||
GstRTSPSessionPrivate *priv = session->priv;
|
||||
|
||||
switch (propid) {
|
||||
case PROP_SESSIONID:
|
||||
g_free (session->sessionid);
|
||||
session->sessionid = g_value_dup_string (value);
|
||||
g_free (priv->sessionid);
|
||||
priv->sessionid = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_TIMEOUT:
|
||||
gst_rtsp_session_set_timeout (session, g_value_get_uint (value));
|
||||
|
@ -150,18 +176,22 @@ GstRTSPSessionMedia *
|
|||
gst_rtsp_session_manage_media (GstRTSPSession * sess, const GstRTSPUrl * uri,
|
||||
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 (GST_IS_RTSP_MEDIA (media), NULL);
|
||||
g_return_val_if_fail (media->status == GST_RTSP_MEDIA_STATUS_PREPARED, 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);
|
||||
|
||||
g_mutex_lock (&sess->lock);
|
||||
sess->medias = g_list_prepend (sess->medias, result);
|
||||
g_mutex_unlock (&sess->lock);
|
||||
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);
|
||||
|
||||
|
@ -181,18 +211,21 @@ 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);
|
||||
|
||||
g_mutex_lock (&sess->lock);
|
||||
find = g_list_find (sess->medias, media);
|
||||
priv = sess->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
find = g_list_find (priv->medias, media);
|
||||
if (find)
|
||||
sess->medias = g_list_delete_link (sess->medias, find);
|
||||
more = (sess->medias != NULL);
|
||||
g_mutex_unlock (&sess->lock);
|
||||
priv->medias = g_list_delete_link (priv->medias, find);
|
||||
more = (priv->medias != NULL);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
if (find)
|
||||
g_object_unref (media);
|
||||
|
@ -212,24 +245,87 @@ gst_rtsp_session_release_media (GstRTSPSession * sess,
|
|||
GstRTSPSessionMedia *
|
||||
gst_rtsp_session_get_media (GstRTSPSession * sess, const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPSessionPrivate *priv;
|
||||
GstRTSPSessionMedia *result;
|
||||
GList *walk;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL);
|
||||
g_return_val_if_fail (url != NULL, NULL);
|
||||
|
||||
priv = sess->priv;
|
||||
result = NULL;
|
||||
|
||||
g_mutex_lock (&sess->lock);
|
||||
for (walk = sess->medias; walk; walk = g_list_next (walk)) {
|
||||
g_mutex_lock (&priv->lock);
|
||||
for (walk = priv->medias; walk; walk = g_list_next (walk)) {
|
||||
result = (GstRTSPSessionMedia *) walk->data;
|
||||
|
||||
if (g_str_equal (result->url->abspath, url->abspath))
|
||||
if (gst_rtsp_session_media_matches_url (result, url))
|
||||
break;
|
||||
|
||||
result = NULL;
|
||||
}
|
||||
g_mutex_unlock (&sess->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_filter:
|
||||
* @sess: a #GstRTSPSession
|
||||
* @func: (scope call): 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..
|
||||
*
|
||||
* 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);
|
||||
g_return_val_if_fail (func != NULL, NULL);
|
||||
|
||||
priv = sess->priv;
|
||||
|
||||
result = NULL;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
for (walk = priv->medias; walk; walk = next) {
|
||||
GstRTSPSessionMedia *media = walk->data;
|
||||
|
||||
next = g_list_next (walk);
|
||||
|
||||
switch (func (sess, media, user_data)) {
|
||||
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;
|
||||
}
|
||||
|
@ -266,7 +362,7 @@ gst_rtsp_session_get_sessionid (GstRTSPSession * session)
|
|||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION (session), NULL);
|
||||
|
||||
return session->sessionid;
|
||||
return session->priv->sessionid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -280,17 +376,19 @@ gst_rtsp_session_get_sessionid (GstRTSPSession * session)
|
|||
gchar *
|
||||
gst_rtsp_session_get_header (GstRTSPSession * session)
|
||||
{
|
||||
GstRTSPSessionPrivate *priv;
|
||||
gchar *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION (session), NULL);
|
||||
|
||||
g_mutex_lock (&session->lock);
|
||||
if (session->timeout != 60)
|
||||
result = g_strdup_printf ("%s; timeout=%d", session->sessionid,
|
||||
session->timeout);
|
||||
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 (session->sessionid);
|
||||
g_mutex_unlock (&session->lock);
|
||||
result = g_strdup (priv->sessionid);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -306,11 +404,15 @@ gst_rtsp_session_get_header (GstRTSPSession * session)
|
|||
void
|
||||
gst_rtsp_session_set_timeout (GstRTSPSession * session, guint timeout)
|
||||
{
|
||||
GstRTSPSessionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SESSION (session));
|
||||
|
||||
g_mutex_lock (&session->lock);
|
||||
session->timeout = timeout;
|
||||
g_mutex_unlock (&session->lock);
|
||||
priv = session->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
priv->timeout = timeout;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -324,13 +426,16 @@ gst_rtsp_session_set_timeout (GstRTSPSession * session, guint timeout)
|
|||
guint
|
||||
gst_rtsp_session_get_timeout (GstRTSPSession * session)
|
||||
{
|
||||
GstRTSPSessionPrivate *priv;
|
||||
guint res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_SESSION (session), 0);
|
||||
|
||||
g_mutex_lock (&session->lock);
|
||||
res = session->timeout;
|
||||
g_mutex_unlock (&session->lock);
|
||||
priv = session->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
res = priv->timeout;
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -344,11 +449,15 @@ gst_rtsp_session_get_timeout (GstRTSPSession * session)
|
|||
void
|
||||
gst_rtsp_session_touch (GstRTSPSession * session)
|
||||
{
|
||||
GstRTSPSessionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_SESSION (session));
|
||||
|
||||
g_mutex_lock (&session->lock);
|
||||
g_get_current_time (&session->last_access);
|
||||
g_mutex_unlock (&session->lock);
|
||||
priv = session->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
g_get_current_time (&priv->last_access);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -362,7 +471,7 @@ gst_rtsp_session_prevent_expire (GstRTSPSession * session)
|
|||
{
|
||||
g_return_if_fail (GST_IS_RTSP_SESSION (session));
|
||||
|
||||
g_atomic_int_add (&session->expire_count, 1);
|
||||
g_atomic_int_add (&session->priv->expire_count, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,7 +484,7 @@ gst_rtsp_session_prevent_expire (GstRTSPSession * session)
|
|||
void
|
||||
gst_rtsp_session_allow_expire (GstRTSPSession * session)
|
||||
{
|
||||
g_atomic_int_add (&session->expire_count, -1);
|
||||
g_atomic_int_add (&session->priv->expire_count, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -390,22 +499,25 @@ gst_rtsp_session_allow_expire (GstRTSPSession * session)
|
|||
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);
|
||||
|
||||
g_mutex_lock (&session->lock);
|
||||
if (g_atomic_int_get (&session->expire_count) != 0) {
|
||||
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 (&session->last_access);
|
||||
g_get_current_time (&priv->last_access);
|
||||
}
|
||||
|
||||
last_access = GST_TIMEVAL_TO_TIME (session->last_access);
|
||||
last_access = GST_TIMEVAL_TO_TIME (priv->last_access);
|
||||
/* add timeout allow for 5 seconds of extra time */
|
||||
last_access += session->timeout * GST_SECOND + (5 * GST_SECOND);
|
||||
g_mutex_unlock (&session->lock);
|
||||
last_access += priv->timeout * GST_SECOND + (5 * GST_SECOND);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
now_ns = GST_TIMEVAL_TO_TIME (*now);
|
||||
|
||||
|
|
|
@ -37,19 +37,28 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPSession GstRTSPSession;
|
||||
typedef struct _GstRTSPSessionClass GstRTSPSessionClass;
|
||||
typedef struct _GstRTSPSessionPrivate GstRTSPSessionPrivate;
|
||||
|
||||
/**
|
||||
* GstRTSPFilterResult:
|
||||
* @GST_RTSP_FILTER_REMOVE: Remove session
|
||||
* @GST_RTSP_FILTER_KEEP: Keep session in the pool
|
||||
* @GST_RTSP_FILTER_REF: Ref session in the result list
|
||||
*
|
||||
* Possible return values for gst_rtsp_session_pool_filter().
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_RTSP_FILTER_REMOVE,
|
||||
GST_RTSP_FILTER_KEEP,
|
||||
GST_RTSP_FILTER_REF,
|
||||
} GstRTSPFilterResult;
|
||||
|
||||
#include "rtsp-media.h"
|
||||
#include "rtsp-session-media.h"
|
||||
|
||||
/**
|
||||
* GstRTSPSession:
|
||||
* @parent: the parent GObject
|
||||
* @sessionid: the session id of the session
|
||||
* @timeout: the timeout of the session
|
||||
* @create_time: the time when the session was created
|
||||
* @last_access: the time the session was last accessed
|
||||
* @expire_count: the expire prevention counter
|
||||
* @medias: a list of #GstRTSPSessionMedia managed in this session
|
||||
*
|
||||
* Session information kept by the server for a specific client.
|
||||
* One client session, identified with a session id, can handle multiple medias
|
||||
|
@ -58,15 +67,7 @@ typedef struct _GstRTSPSessionClass GstRTSPSessionClass;
|
|||
struct _GstRTSPSession {
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
gchar *sessionid;
|
||||
|
||||
guint timeout;
|
||||
GTimeVal create_time;
|
||||
GTimeVal last_access;
|
||||
gint expire_count;
|
||||
|
||||
GList *medias;
|
||||
GstRTSPSessionPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstRTSPSessionClass {
|
||||
|
@ -102,6 +103,35 @@ gboolean gst_rtsp_session_release_media (GstRTSPSession *se
|
|||
GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess,
|
||||
const GstRTSPUrl *url);
|
||||
|
||||
/**
|
||||
* GstRTSPSessionFilterFunc:
|
||||
* @sess: a #GstRTSPSession object
|
||||
* @media: a #GstRTSPSessionMedia in @sess
|
||||
* @user_data: user data that has been given to gst_rtsp_session_filter()
|
||||
*
|
||||
* This function will be called by the gst_rtsp_session_filter(). An
|
||||
* implementation should return a value of #GstRTSPFilterResult.
|
||||
*
|
||||
* When this function returns #GST_RTSP_FILTER_REMOVE, @media will be removed
|
||||
* from @sess.
|
||||
*
|
||||
* A return value of #GST_RTSP_FILTER_KEEP will leave @media untouched in
|
||||
* @sess.
|
||||
*
|
||||
* A value of GST_RTSP_FILTER_REF will add @media to the result #GList of
|
||||
* gst_rtsp_session_filter().
|
||||
*
|
||||
* Returns: a #GstRTSPFilterResult.
|
||||
*/
|
||||
typedef GstRTSPFilterResult (*GstRTSPSessionFilterFunc) (GstRTSPSession *sess,
|
||||
GstRTSPSessionMedia *media,
|
||||
gpointer user_data);
|
||||
|
||||
GList * gst_rtsp_session_filter (GstRTSPSession *sess,
|
||||
GstRTSPSessionFilterFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTSP_SESSION_H__ */
|
||||
|
|
|
@ -20,11 +20,31 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gst/app/gstappsrc.h>
|
||||
#include <gst/app/gstappsink.h>
|
||||
|
||||
#include "rtsp-stream-transport.h"
|
||||
|
||||
#define GST_RTSP_STREAM_TRANSPORT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_STREAM_TRANSPORT, GstRTSPStreamTransportPrivate))
|
||||
|
||||
struct _GstRTSPStreamTransportPrivate
|
||||
{
|
||||
GstRTSPStream *stream;
|
||||
|
||||
GstRTSPSendFunc send_rtp;
|
||||
GstRTSPSendFunc send_rtcp;
|
||||
gpointer user_data;
|
||||
GDestroyNotify notify;
|
||||
|
||||
GstRTSPKeepAliveFunc keep_alive;
|
||||
gpointer ka_user_data;
|
||||
GDestroyNotify ka_notify;
|
||||
gboolean active;
|
||||
gboolean timed_out;
|
||||
|
||||
GstRTSPTransport *transport;
|
||||
|
||||
GObject *rtpsource;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -44,6 +64,8 @@ gst_rtsp_stream_transport_class_init (GstRTSPStreamTransportClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstRTSPStreamTransportPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = gst_rtsp_stream_transport_finalize;
|
||||
|
@ -55,25 +77,31 @@ gst_rtsp_stream_transport_class_init (GstRTSPStreamTransportClass * klass)
|
|||
static void
|
||||
gst_rtsp_stream_transport_init (GstRTSPStreamTransport * trans)
|
||||
{
|
||||
GstRTSPStreamTransportPrivate *priv =
|
||||
GST_RTSP_STREAM_TRANSPORT_GET_PRIVATE (trans);
|
||||
|
||||
trans->priv = priv;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_stream_transport_finalize (GObject * obj)
|
||||
{
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
GstRTSPStreamTransport *trans;
|
||||
|
||||
trans = GST_RTSP_STREAM_TRANSPORT (obj);
|
||||
priv = trans->priv;
|
||||
|
||||
/* remove callbacks now */
|
||||
gst_rtsp_stream_transport_set_callbacks (trans, NULL, NULL, NULL, NULL);
|
||||
gst_rtsp_stream_transport_set_keepalive (trans, NULL, NULL, NULL);
|
||||
|
||||
if (trans->transport)
|
||||
gst_rtsp_transport_free (trans->transport);
|
||||
if (priv->transport)
|
||||
gst_rtsp_transport_free (priv->transport);
|
||||
|
||||
#if 0
|
||||
if (trans->rtpsource)
|
||||
g_object_set_qdata (trans->rtpsource, ssrc_stream_map_key, NULL);
|
||||
if (priv->rtpsource)
|
||||
g_object_set_qdata (priv->rtpsource, ssrc_stream_map_key, NULL);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (gst_rtsp_stream_transport_parent_class)->finalize (obj);
|
||||
|
@ -92,18 +120,36 @@ gst_rtsp_stream_transport_finalize (GObject * obj)
|
|||
GstRTSPStreamTransport *
|
||||
gst_rtsp_stream_transport_new (GstRTSPStream * stream, GstRTSPTransport * tr)
|
||||
{
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
GstRTSPStreamTransport *trans;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
|
||||
g_return_val_if_fail (tr != NULL, NULL);
|
||||
|
||||
trans = g_object_new (GST_TYPE_RTSP_STREAM_TRANSPORT, NULL);
|
||||
trans->stream = stream;
|
||||
trans->transport = tr;
|
||||
priv = trans->priv;
|
||||
priv->stream = stream;
|
||||
priv->transport = tr;
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_stream_transport_get_stream:
|
||||
* @trans: a #GstRTSPStreamTransport
|
||||
*
|
||||
* Get the #GstRTSPStream used when constructing @trans.
|
||||
*
|
||||
* Returns: (transfer none): the stream used when constructing @trans.
|
||||
*/
|
||||
GstRTSPStream *
|
||||
gst_rtsp_stream_transport_get_stream (GstRTSPStreamTransport * trans)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
|
||||
|
||||
return trans->priv->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_stream_transport_set_callbacks:
|
||||
* @trans: a #GstRTSPStreamTransport
|
||||
|
@ -120,12 +166,18 @@ gst_rtsp_stream_transport_set_callbacks (GstRTSPStreamTransport * trans,
|
|||
GstRTSPSendFunc send_rtp, GstRTSPSendFunc send_rtcp,
|
||||
gpointer user_data, GDestroyNotify notify)
|
||||
{
|
||||
trans->send_rtp = send_rtp;
|
||||
trans->send_rtcp = send_rtcp;
|
||||
if (trans->notify)
|
||||
trans->notify (trans->user_data);
|
||||
trans->user_data = user_data;
|
||||
trans->notify = notify;
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
|
||||
|
||||
priv = trans->priv;
|
||||
|
||||
priv->send_rtp = send_rtp;
|
||||
priv->send_rtcp = send_rtcp;
|
||||
if (priv->notify)
|
||||
priv->notify (priv->user_data);
|
||||
priv->user_data = user_data;
|
||||
priv->notify = notify;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,11 +194,17 @@ void
|
|||
gst_rtsp_stream_transport_set_keepalive (GstRTSPStreamTransport * trans,
|
||||
GstRTSPKeepAliveFunc keep_alive, gpointer user_data, GDestroyNotify notify)
|
||||
{
|
||||
trans->keep_alive = keep_alive;
|
||||
if (trans->ka_notify)
|
||||
trans->ka_notify (trans->ka_user_data);
|
||||
trans->ka_user_data = user_data;
|
||||
trans->ka_notify = notify;
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
|
||||
|
||||
priv = trans->priv;
|
||||
|
||||
priv->keep_alive = keep_alive;
|
||||
if (priv->ka_notify)
|
||||
priv->ka_notify (priv->ka_user_data);
|
||||
priv->ka_user_data = user_data;
|
||||
priv->ka_notify = notify;
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,13 +220,100 @@ void
|
|||
gst_rtsp_stream_transport_set_transport (GstRTSPStreamTransport * trans,
|
||||
GstRTSPTransport * tr)
|
||||
{
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
|
||||
g_return_if_fail (tr != NULL);
|
||||
|
||||
priv = trans->priv;
|
||||
|
||||
/* keep track of the transports in the stream. */
|
||||
if (trans->transport)
|
||||
gst_rtsp_transport_free (trans->transport);
|
||||
trans->transport = tr;
|
||||
if (priv->transport)
|
||||
gst_rtsp_transport_free (priv->transport);
|
||||
priv->transport = tr;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_stream_transport_get_transport:
|
||||
* @trans: a #GstRTSPStreamTransport
|
||||
*
|
||||
* Get the transport configured in @trans.
|
||||
*
|
||||
* Returns: (transfer none): the transport configured in @trans. It remains
|
||||
* valid for as long as @trans is valid.
|
||||
*/
|
||||
const GstRTSPTransport *
|
||||
gst_rtsp_stream_transport_get_transport (GstRTSPStreamTransport * trans)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
|
||||
|
||||
return trans->priv->transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_stream_transport_set_active:
|
||||
* @trans: a #GstRTSPStreamTransport
|
||||
* @active: new state of @trans
|
||||
*
|
||||
* Activate or deactivate datatransfer configured in @trans.
|
||||
*
|
||||
* Returns: %TRUE when the state was changed.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_stream_transport_set_active (GstRTSPStreamTransport * trans,
|
||||
gboolean active)
|
||||
{
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
|
||||
|
||||
priv = trans->priv;
|
||||
|
||||
if (priv->active == active)
|
||||
return FALSE;
|
||||
|
||||
if (active)
|
||||
res = gst_rtsp_stream_add_transport (priv->stream, trans);
|
||||
else
|
||||
res = gst_rtsp_stream_remove_transport (priv->stream, trans);
|
||||
|
||||
if (res)
|
||||
priv->active = active;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_stream_transport_set_timed_out:
|
||||
* @trans: a #GstRTSPStreamTransport
|
||||
* @timedout: timed out value
|
||||
*
|
||||
* Set the timed out state of @trans to @timedout
|
||||
*/
|
||||
void
|
||||
gst_rtsp_stream_transport_set_timed_out (GstRTSPStreamTransport * trans,
|
||||
gboolean timedout)
|
||||
{
|
||||
g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
|
||||
|
||||
trans->priv->timed_out = timedout;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_stream_transport_is_timed_out:
|
||||
* @trans: a #GstRTSPStreamTransport
|
||||
*
|
||||
* Check if @trans is timed out.
|
||||
*
|
||||
* Returns: %TRUE if @trans timed out.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_stream_transport_is_timed_out (GstRTSPStreamTransport * trans)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
|
||||
|
||||
return trans->priv->timed_out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,12 +329,15 @@ gboolean
|
|||
gst_rtsp_stream_transport_send_rtp (GstRTSPStreamTransport * trans,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
gboolean res = FALSE;
|
||||
|
||||
if (trans->send_rtp)
|
||||
priv = trans->priv;
|
||||
|
||||
if (priv->send_rtp)
|
||||
res =
|
||||
trans->send_rtp (buffer, trans->transport->interleaved.min,
|
||||
trans->user_data);
|
||||
priv->send_rtp (buffer, priv->transport->interleaved.min,
|
||||
priv->user_data);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -207,12 +355,15 @@ gboolean
|
|||
gst_rtsp_stream_transport_send_rtcp (GstRTSPStreamTransport * trans,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
gboolean res = FALSE;
|
||||
|
||||
if (trans->send_rtcp)
|
||||
priv = trans->priv;
|
||||
|
||||
if (priv->send_rtcp)
|
||||
res =
|
||||
trans->send_rtcp (buffer, trans->transport->interleaved.max,
|
||||
trans->user_data);
|
||||
priv->send_rtcp (buffer, priv->transport->interleaved.max,
|
||||
priv->user_data);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -226,6 +377,10 @@ gst_rtsp_stream_transport_send_rtcp (GstRTSPStreamTransport * trans,
|
|||
void
|
||||
gst_rtsp_stream_transport_keep_alive (GstRTSPStreamTransport * trans)
|
||||
{
|
||||
if (trans->keep_alive)
|
||||
trans->keep_alive (trans->ka_user_data);
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
|
||||
priv = trans->priv;
|
||||
|
||||
if (priv->keep_alive)
|
||||
priv->keep_alive (priv->ka_user_data);
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPStreamTransport GstRTSPStreamTransport;
|
||||
typedef struct _GstRTSPStreamTransportClass GstRTSPStreamTransportClass;
|
||||
typedef struct _GstRTSPStreamTransportPrivate GstRTSPStreamTransportPrivate;
|
||||
|
||||
#include "rtsp-stream.h"
|
||||
#include "rtsp-address-pool.h"
|
||||
|
||||
typedef gboolean (*GstRTSPSendFunc) (GstBuffer *buffer, guint8 channel, gpointer user_data);
|
||||
typedef void (*GstRTSPKeepAliveFunc) (gpointer user_data);
|
||||
|
@ -48,41 +48,13 @@ typedef void (*GstRTSPKeepAliveFunc) (gpointer user_data);
|
|||
/**
|
||||
* GstRTSPStreamTransport:
|
||||
* @parent: parent instance
|
||||
* @stream: the GstRTSPStream we manage
|
||||
* @send_rtp: callback for sending RTP messages
|
||||
* @send_rtcp: callback for sending RTCP messages
|
||||
* @user_data: user data passed in the callbacks
|
||||
* @notify: free function for the user_data.
|
||||
* @keep_alive: keep alive callback
|
||||
* @ka_user_data: data passed to @keep_alive
|
||||
* @ka_notify: called when @ka_user_data is freed
|
||||
* @active: if we are actively sending
|
||||
* @timeout: if we timed out
|
||||
* @transport: a transport description
|
||||
* @addr: an optional address
|
||||
* @rtpsource: the receiver rtp source object
|
||||
*
|
||||
* A Transport description for stream @idx
|
||||
* A Transport description for a stream
|
||||
*/
|
||||
struct _GstRTSPStreamTransport {
|
||||
GObject parent;
|
||||
|
||||
GstRTSPStream *stream;
|
||||
|
||||
GstRTSPSendFunc send_rtp;
|
||||
GstRTSPSendFunc send_rtcp;
|
||||
gpointer user_data;
|
||||
GDestroyNotify notify;
|
||||
|
||||
GstRTSPKeepAliveFunc keep_alive;
|
||||
gpointer ka_user_data;
|
||||
GDestroyNotify ka_notify;
|
||||
gboolean active;
|
||||
gboolean timeout;
|
||||
|
||||
GstRTSPTransport *transport;
|
||||
|
||||
GObject *rtpsource;
|
||||
GstRTSPStreamTransportPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstRTSPStreamTransportClass {
|
||||
|
@ -94,8 +66,11 @@ GType gst_rtsp_stream_transport_get_type (void);
|
|||
GstRTSPStreamTransport * gst_rtsp_stream_transport_new (GstRTSPStream *stream,
|
||||
GstRTSPTransport *tr);
|
||||
|
||||
GstRTSPStream * gst_rtsp_stream_transport_get_stream (GstRTSPStreamTransport *trans);
|
||||
|
||||
void gst_rtsp_stream_transport_set_transport (GstRTSPStreamTransport *trans,
|
||||
GstRTSPTransport * tr);
|
||||
const GstRTSPTransport * gst_rtsp_stream_transport_get_transport (GstRTSPStreamTransport *trans);
|
||||
|
||||
void gst_rtsp_stream_transport_set_callbacks (GstRTSPStreamTransport *trans,
|
||||
GstRTSPSendFunc send_rtp,
|
||||
|
@ -107,6 +82,15 @@ void gst_rtsp_stream_transport_set_keepalive (GstRTSPStreamT
|
|||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
gboolean gst_rtsp_stream_transport_set_active (GstRTSPStreamTransport *trans,
|
||||
gboolean active);
|
||||
|
||||
void gst_rtsp_stream_transport_set_timed_out (GstRTSPStreamTransport *trans,
|
||||
gboolean timedout);
|
||||
gboolean gst_rtsp_stream_transport_is_timed_out (GstRTSPStreamTransport *trans);
|
||||
|
||||
|
||||
|
||||
gboolean gst_rtsp_stream_transport_send_rtp (GstRTSPStreamTransport *trans,
|
||||
GstBuffer *buffer);
|
||||
gboolean gst_rtsp_stream_transport_send_rtcp (GstRTSPStreamTransport *trans,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,6 +38,7 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstRTSPStream GstRTSPStream;
|
||||
typedef struct _GstRTSPStreamClass GstRTSPStreamClass;
|
||||
typedef struct _GstRTSPStreamPrivate GstRTSPStreamPrivate;
|
||||
|
||||
#include "rtsp-stream-transport.h"
|
||||
#include "rtsp-address-pool.h"
|
||||
|
@ -45,79 +46,13 @@ typedef struct _GstRTSPStreamClass GstRTSPStreamClass;
|
|||
/**
|
||||
* GstRTSPStream:
|
||||
* @parent: the parent instance
|
||||
* @lock: mutex protecting the stream
|
||||
* @idx: the stream index
|
||||
* @srcpad: the srcpad of the stream
|
||||
* @payloader: the payloader of the format
|
||||
* @is_ipv6: should this stream be IPv6
|
||||
* @buffer_size: the UDP buffer size
|
||||
* @is_joined: if the stream is joined in a bin
|
||||
* @send_rtp_sink: sinkpad for sending RTP buffers
|
||||
* @recv_sink: sinkpad for receiving RTP/RTCP buffers
|
||||
* @send_src: srcpad for sending RTP/RTCP buffers
|
||||
* @session: the RTP session object
|
||||
* @udpsrc: the udp source elements for RTP/RTCP
|
||||
* @udpsink: the udp sink elements for RTP/RTCP
|
||||
* @appsrc: the app source elements for RTP/RTCP
|
||||
* @appqueue: the app queue elements for RTP/RTCP
|
||||
* @appsink: the app sink elements for RTP/RTCP
|
||||
* @tee: tee for the sending to udpsink and appsink
|
||||
* @funnel: tee for the receiving from udpsrc and appsrc
|
||||
* @server_port: the server ports for this stream
|
||||
* @pool: the address pool for this stream
|
||||
* @addr: the address for this stream
|
||||
* @caps_sig: the signal id for detecting caps
|
||||
* @caps: the caps of the stream
|
||||
* @n_active: the number of active transports in @transports
|
||||
* @transports: list of #GstStreamTransport being streamed to
|
||||
*
|
||||
* The definition of a media stream. The streams are identified by @idx.
|
||||
* The definition of a media stream.
|
||||
*/
|
||||
struct _GstRTSPStream {
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
guint idx;
|
||||
GstPad *srcpad;
|
||||
GstElement *payloader;
|
||||
gboolean is_ipv6;
|
||||
guint buffer_size;
|
||||
gboolean is_joined;
|
||||
|
||||
/* pads on the rtpbin */
|
||||
GstPad *send_rtp_sink;
|
||||
GstPad *recv_sink[2];
|
||||
GstPad *send_src[2];
|
||||
|
||||
/* the RTPSession object */
|
||||
GObject *session;
|
||||
|
||||
/* sinks used for sending and receiving RTP and RTCP, they share
|
||||
* sockets */
|
||||
GstElement *udpsrc[2];
|
||||
GstElement *udpsink[2];
|
||||
/* for TCP transport */
|
||||
GstElement *appsrc[2];
|
||||
GstElement *appqueue[2];
|
||||
GstElement *appsink[2];
|
||||
|
||||
GstElement *tee[2];
|
||||
GstElement *funnel[2];
|
||||
|
||||
/* server ports for sending/receiving */
|
||||
GstRTSPRange server_port;
|
||||
|
||||
/* multicast addresses */
|
||||
GstRTSPAddressPool *pool;
|
||||
GstRTSPAddress *addr;
|
||||
|
||||
/* the caps of the stream */
|
||||
gulong caps_sig;
|
||||
GstCaps *caps;
|
||||
|
||||
/* transports we stream to */
|
||||
guint n_active;
|
||||
GList *transports;
|
||||
GstRTSPStreamPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstRTSPStreamClass {
|
||||
|
@ -128,9 +63,10 @@ GType gst_rtsp_stream_get_type (void);
|
|||
|
||||
GstRTSPStream * gst_rtsp_stream_new (guint idx, GstElement *payloader,
|
||||
GstPad *srcpad);
|
||||
guint gst_rtsp_stream_get_index (GstRTSPStream *stream);
|
||||
|
||||
void gst_rtsp_stream_set_mtu (GstRTSPStream * stream, guint mtu);
|
||||
guint gst_rtsp_stream_get_mtu (GstRTSPStream * stream);
|
||||
void gst_rtsp_stream_set_mtu (GstRTSPStream *stream, guint mtu);
|
||||
guint gst_rtsp_stream_get_mtu (GstRTSPStream *stream);
|
||||
|
||||
void gst_rtsp_stream_set_address_pool (GstRTSPStream *stream, GstRTSPAddressPool *pool);
|
||||
GstRTSPAddressPool *
|
||||
|
@ -138,14 +74,20 @@ GstRTSPAddressPool *
|
|||
|
||||
GstRTSPAddress * gst_rtsp_stream_get_address (GstRTSPStream *stream);
|
||||
|
||||
gboolean gst_rtsp_stream_join_bin (GstRTSPStream * stream,
|
||||
gboolean gst_rtsp_stream_join_bin (GstRTSPStream *stream,
|
||||
GstBin *bin, GstElement *rtpbin,
|
||||
GstState state);
|
||||
gboolean gst_rtsp_stream_leave_bin (GstRTSPStream * stream,
|
||||
gboolean gst_rtsp_stream_leave_bin (GstRTSPStream *stream,
|
||||
GstBin *bin, GstElement *rtpbin);
|
||||
|
||||
gboolean gst_rtsp_stream_get_rtpinfo (GstRTSPStream * stream,
|
||||
guint *rtptime, guint * seq);
|
||||
void gst_rtsp_stream_get_server_port (GstRTSPStream *stream,
|
||||
GstRTSPRange *server_port);
|
||||
void gst_rtsp_stream_get_ssrc (GstRTSPStream *stream,
|
||||
guint *ssrc);
|
||||
|
||||
gboolean gst_rtsp_stream_get_rtpinfo (GstRTSPStream *stream,
|
||||
guint *rtptime, guint *seq);
|
||||
GstCaps * gst_rtsp_stream_get_caps (GstRTSPStream *stream);
|
||||
|
||||
GstFlowReturn gst_rtsp_stream_recv_rtp (GstRTSPStream *stream,
|
||||
GstBuffer *buffer);
|
||||
|
|
|
@ -93,7 +93,7 @@ GST_START_TEST (test_media)
|
|||
{
|
||||
GstRTSPMedia *media;
|
||||
|
||||
media = gst_rtsp_media_new ();
|
||||
media = gst_rtsp_media_new (NULL);
|
||||
fail_unless (GST_IS_RTSP_MEDIA (media));
|
||||
g_object_unref (media);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue