media: disconnect from signal handlers in unprepare()
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-session-media.c
index e8eda2b..c475f8f 100644 (file)
 
 #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
 {
@@ -42,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;
@@ -53,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);
 }
@@ -99,26 +117,82 @@ 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_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);
+
+  return gst_rtsp_media_get_base_time (media->priv->media);
+}
+
+/**
  * gst_rtsp_session_media_set_transport:
  * @media: a #GstRTSPSessionMedia
  * @stream: a #GstRTSPStream
@@ -132,21 +206,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;
@@ -165,14 +244,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;
 }
@@ -191,12 +272,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;
 }
@@ -213,13 +298,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;
 }