*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#include <string.h>
#include "rtsp-session.h"
-#undef DEBUG
+#define GST_RTSP_SESSION_MEDIA_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_SESSION_MEDIA, GstRTSPSessionMediaPrivate))
-#define DEFAULT_TIMEOUT 60
+struct _GstRTSPSessionMediaPrivate
+{
+ GMutex lock;
+ GstRTSPUrl *url; /* unmutable */
+ GstRTSPMedia *media; /* unmutable */
+ GstRTSPState state; /* protected by lock */
+ guint counter; /* protected by lock */
+
+ GPtrArray *transports; /* protected by lock */
+};
enum
{
{
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;
static void
gst_rtsp_session_media_init (GstRTSPSessionMedia * media)
{
- 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);
+ 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);
}
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_get_transport:
+ * gst_rtsp_session_media_matches_url:
* @media: a #GstRTSPSessionMedia
- * @idx: the stream index
+ * @url: a #GstRTSPUrl
*
- * Get a previously created or create a new #GstRTSPStreamTransport at @idx.
+ * Check if the url of @media matches @url.
*
- * Returns: a #GstRTSPStreamTransport that is valid until the session of @media
- * is unreffed.
+ * Returns: %TRUE when @url matches the url of @media.
*/
-GstRTSPStreamTransport *
-gst_rtsp_session_media_get_transport (GstRTSPSessionMedia * media, guint idx)
+gboolean
+gst_rtsp_session_media_matches_url (GstRTSPSessionMedia * media,
+ const GstRTSPUrl * url)
{
- GstRTSPStreamTransport *result;
+ 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);
- g_return_val_if_fail (media->media != NULL, NULL);
- if (idx >= media->transports->len)
- return NULL;
+ return media->priv->media;
+}
- result = g_ptr_array_index (media->transports, idx);
- if (result == NULL) {
- GstRTSPStream *stream;
+/**
+ * gst_rtsp_session_media_get_base_time:
+ * @media: a #GstRTSPSessionMedia
+ *
+ * Get the base_time of the #GstRTSPMedia in @media
+ *
+ * Returns: the base_time of the media.
+ */
+GstClockTime
+gst_rtsp_session_media_get_base_time (GstRTSPSessionMedia * media)
+{
+ g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), GST_CLOCK_TIME_NONE);
- stream = gst_rtsp_media_get_stream (media->media, idx);
- if (stream == NULL)
- goto no_media;
+ return gst_rtsp_media_get_base_time (media->priv->media);
+}
- result = gst_rtsp_stream_transport_new (stream);
+/**
+ * gst_rtsp_session_media_set_transport:
+ * @media: a #GstRTSPSessionMedia
+ * @stream: a #GstRTSPStream
+ * @tr: a #GstRTSPTransport
+ *
+ * Configure the transport for @stream to @tr in @media.
+ *
+ * Returns: (transfer none): the new or updated #GstRTSPStreamTransport for @stream.
+ */
+GstRTSPStreamTransport *
+gst_rtsp_session_media_set_transport (GstRTSPSessionMedia * media,
+ GstRTSPStream * stream, GstRTSPTransport * tr)
+{
+ GstRTSPSessionMediaPrivate *priv;
+ GstRTSPStreamTransport *result;
+ guint idx;
- g_ptr_array_index (media->transports, idx) = result;
+ 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 (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 (&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 (priv->transports, idx) = result;
+ g_mutex_unlock (&priv->lock);
+ } else {
+ gst_rtsp_stream_transport_set_transport (result, tr);
+ g_mutex_unlock (&priv->lock);
}
+
return result;
+}
- /* ERRORS */
-no_media:
- {
- return NULL;
- }
+/**
+ * gst_rtsp_session_media_get_transport:
+ * @media: a #GstRTSPSessionMedia
+ * @idx: the stream index
+ *
+ * Get a previously created #GstRTSPStreamTransport for the stream at @idx.
+ *
+ * Returns: (transfer none): a #GstRTSPStreamTransport that is valid until the
+ * session of @media is unreffed.
+ */
+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);
+ priv = media->priv;
+ g_return_val_if_fail (idx < priv->transports->len, NULL);
+
+ g_mutex_lock (&priv->lock);
+ result = g_ptr_array_index (priv->transports, idx);
+ g_mutex_unlock (&priv->lock);
+
+ return result;
}
/**
gst_rtsp_session_media_alloc_channels (GstRTSPSessionMedia * media,
GstRTSPRange * range)
{
+ GstRTSPSessionMediaPrivate *priv;
+
g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), FALSE);
- range->min = media->counter++;
- range->max = media->counter++;
+ priv = media->priv;
+
+ g_mutex_lock (&priv->lock);
+ range->min = priv->counter++;
+ range->max = priv->counter++;
+ g_mutex_unlock (&priv->lock);
return TRUE;
}
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);
- ret = gst_rtsp_media_set_state (media->media, state, media->transports);
+ 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;
}