rtsp-server: port to new thread API
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-media-factory.c
index dd0ef79..e7b60f7 100644 (file)
 
 #include "rtsp-media-factory.h"
 
-#define DEFAULT_LAUNCH         NULL
-#define DEFAULT_SHARED         FALSE
-#define DEFAULT_EOS_SHUTDOWN   FALSE
+#define DEFAULT_LAUNCH          NULL
+#define DEFAULT_SHARED          FALSE
+#define DEFAULT_EOS_SHUTDOWN    FALSE
+#define DEFAULT_PROTOCOLS       GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_TCP
+#define DEFAULT_BUFFER_SIZE     0x80000
+#define DEFAULT_MULTICAST_GROUP "224.2.0.1"
 
 enum
 {
@@ -29,12 +32,24 @@ enum
   PROP_LAUNCH,
   PROP_SHARED,
   PROP_EOS_SHUTDOWN,
+  PROP_PROTOCOLS,
+  PROP_BUFFER_SIZE,
+  PROP_MULTICAST_GROUP,
   PROP_LAST
 };
 
-GST_DEBUG_CATEGORY (rtsp_media_debug);
+enum
+{
+  SIGNAL_MEDIA_CONSTRUCTED,
+  SIGNAL_MEDIA_CONFIGURE,
+  SIGNAL_LAST
+};
+
+GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
 #define GST_CAT_DEFAULT rtsp_media_debug
 
+static guint gst_rtsp_media_factory_signals[SIGNAL_LAST] = { 0 };
+
 static void gst_rtsp_media_factory_get_property (GObject * object, guint propid,
     GValue * value, GParamSpec * pspec);
 static void gst_rtsp_media_factory_set_property (GObject * object, guint propid,
@@ -96,13 +111,41 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
           "Send EOS down the pipeline before shutting down",
           DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
+      g_param_spec_flags ("protocols", "Protocols",
+          "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
+          DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
+      g_param_spec_uint ("buffer-size", "Buffer Size",
+          "The kernel UDP buffer size to use", 0, G_MAXUINT,
+          DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MULTICAST_GROUP,
+      g_param_spec_string ("multicast-group", "Multicast Group",
+          "The Multicast group to send media to",
+          DEFAULT_MULTICAST_GROUP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
+      g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
+          media_constructed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+      G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
+
+  gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE] =
+      g_signal_new ("media-configure", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
+          media_configure), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+      G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
+
   klass->gen_key = default_gen_key;
   klass->get_element = default_get_element;
   klass->construct = default_construct;
   klass->configure = default_configure;
   klass->create_pipeline = default_create_pipeline;
 
-  GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmedia", 0, "GstRTSPMedia");
+  GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmediafactory", 0,
+      "GstRTSPMediaFactory");
 }
 
 static void
@@ -111,9 +154,12 @@ 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;
+  factory->multicast_group = g_strdup (DEFAULT_MULTICAST_GROUP);
 
-  factory->lock = g_mutex_new ();
-  factory->medias_lock = g_mutex_new ();
+  g_mutex_init (&factory->lock);
+  g_mutex_init (&factory->medias_lock);
   factory->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
       g_free, g_object_unref);
 }
@@ -124,9 +170,10 @@ gst_rtsp_media_factory_finalize (GObject * obj)
   GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
 
   g_hash_table_unref (factory->medias);
-  g_mutex_free (factory->medias_lock);
+  g_mutex_clear (&factory->medias_lock);
   g_free (factory->launch);
-  g_mutex_free (factory->lock);
+  g_free (factory->multicast_group);
+  g_mutex_clear (&factory->lock);
   if (factory->auth)
     g_object_unref (factory->auth);
 
@@ -150,6 +197,17 @@ gst_rtsp_media_factory_get_property (GObject * object, guint propid,
       g_value_set_boolean (value,
           gst_rtsp_media_factory_is_eos_shutdown (factory));
       break;
+    case PROP_PROTOCOLS:
+      g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
+      break;
+    case PROP_BUFFER_SIZE:
+      g_value_set_uint (value,
+          gst_rtsp_media_factory_get_buffer_size (factory));
+      break;
+    case PROP_MULTICAST_GROUP:
+      g_value_take_string (value,
+          gst_rtsp_media_factory_get_multicast_group (factory));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
   }
@@ -172,6 +230,17 @@ gst_rtsp_media_factory_set_property (GObject * object, guint propid,
       gst_rtsp_media_factory_set_eos_shutdown (factory,
           g_value_get_boolean (value));
       break;
+    case PROP_PROTOCOLS:
+      gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
+      break;
+    case PROP_BUFFER_SIZE:
+      gst_rtsp_media_factory_set_buffer_size (factory,
+          g_value_get_uint (value));
+      break;
+    case PROP_MULTICAST_GROUP:
+      gst_rtsp_media_factory_set_multicast_group (factory,
+          g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
   }
@@ -329,6 +398,87 @@ gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
 }
 
 /**
+ * gst_rtsp_media_factory_set_buffer_size:
+ * @factory: a #GstRTSPMedia
+ * @size: the new value
+ *
+ * Set the kernel UDP buffer size.
+ */
+void
+gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
+    guint size)
+{
+  g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
+
+  GST_RTSP_MEDIA_FACTORY_LOCK (factory);
+  factory->buffer_size = size;
+  GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
+}
+
+/**
+ * gst_rtsp_media_factory_get_buffer_size:
+ * @factory: a #GstRTSPMedia
+ *
+ * Get the kernel UDP buffer size.
+ *
+ * Returns: the kernel UDP buffer size.
+ */
+guint
+gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
+{
+  guint result;
+
+  g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
+
+  GST_RTSP_MEDIA_FACTORY_LOCK (factory);
+  result = factory->buffer_size;
+  GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
+
+  return result;
+}
+
+/**
+ * gst_rtsp_media_factory_set_multicast_group:
+ * @factory: a #GstRTSPMedia
+ * @mc: the new multicast group
+ *
+ * Set the multicast group that media from @factory will be streamed to.
+ */
+void
+gst_rtsp_media_factory_set_multicast_group (GstRTSPMediaFactory * factory,
+    const gchar * mc)
+{
+  g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
+
+  GST_RTSP_MEDIA_FACTORY_LOCK (factory);
+  g_free (factory->multicast_group);
+  factory->multicast_group = g_strdup (mc);
+  GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
+}
+
+/**
+ * gst_rtsp_media_factory_get_multicast_group:
+ * @factory: a #GstRTSPMedia
+ *
+ * Get the multicast group that media from @factory will be streamed to.
+ *
+ * Returns: the multicast group
+ */
+gchar *
+gst_rtsp_media_factory_get_multicast_group (GstRTSPMediaFactory * factory)
+{
+  gchar *result;
+
+  g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
+
+  GST_RTSP_MEDIA_FACTORY_LOCK (factory);
+  result = g_strdup (factory->multicast_group);
+  GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
+
+  return result;
+}
+
+/**
  * gst_rtsp_media_factory_set_auth:
  * @factory: a #GstRTSPMediaFactory
  * @auth: a #GstRTSPAuth
@@ -354,7 +504,6 @@ gst_rtsp_media_factory_set_auth (GstRTSPMediaFactory * factory,
   }
 }
 
-
 /**
  * gst_rtsp_media_factory_get_auth:
  * @factory: a #GstRTSPMediaFactory
@@ -365,7 +514,7 @@ gst_rtsp_media_factory_set_auth (GstRTSPMediaFactory * factory,
  * usage.
  */
 GstRTSPAuth *
-gst_rtsp_factory_get_auth (GstRTSPMediaFactory * factory)
+gst_rtsp_media_factory_get_auth (GstRTSPMediaFactory * factory)
 {
   GstRTSPAuth *result;
 
@@ -377,6 +526,38 @@ gst_rtsp_factory_get_auth (GstRTSPMediaFactory * factory)
   return result;
 }
 
+/**
+ * gst_rtsp_media_factory_set_protocols:
+ * @factory: a #GstRTSPMediaFactory
+ * @protocols: the new flags
+ *
+ * Configure the allowed lower transport for @factory.
+ */
+void
+gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
+    GstRTSPLowerTrans protocols)
+{
+  g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
+
+  factory->protocols = protocols;
+}
+
+/**
+ * gst_rtsp_media_factory_get_protocols:
+ * @factory: a #GstRTSPMediaFactory
+ *
+ * Get the allowed protocols of @factory.
+ *
+ * Returns: a #GstRTSPLowerTrans
+ */
+GstRTSPLowerTrans
+gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
+{
+  g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
+      GST_RTSP_LOWER_TRANS_UNKNOWN);
+
+  return factory->protocols;
+}
 
 static gboolean
 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
@@ -387,9 +568,9 @@ compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
 static void
 media_unprepared (GstRTSPMedia * media, GstRTSPMediaFactory * factory)
 {
-  g_mutex_lock (factory->medias_lock);
+  g_mutex_lock (&factory->medias_lock);
   g_hash_table_foreach_remove (factory->medias, (GHRFunc) compare_media, media);
-  g_mutex_unlock (factory->medias_lock);
+  g_mutex_unlock (&factory->medias_lock);
 }
 
 /**
@@ -424,7 +605,7 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
   else
     key = NULL;
 
-  g_mutex_lock (factory->medias_lock);
+  g_mutex_lock (&factory->medias_lock);
   if (key) {
     /* we have a key, see if we find a cached media */
     media = g_hash_table_lookup (factory->medias, key);
@@ -435,9 +616,13 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
 
   if (media == NULL) {
     /* nothing cached found, try to create one */
-    if (klass->construct)
+    if (klass->construct) {
       media = klass->construct (factory, url);
-    else
+      if (media)
+        g_signal_emit (factory,
+            gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
+            NULL);
+    } else
       media = NULL;
 
     if (media) {
@@ -445,6 +630,10 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
       if (klass->configure)
         klass->configure (factory, media);
 
+      g_signal_emit (factory,
+          gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
+          NULL);
+
       /* check if we can cache this media */
       if (gst_rtsp_media_is_shared (media)) {
         /* insert in the hashtable, takes ownership of the key */
@@ -460,7 +649,7 @@ gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
       }
     }
   }
-  g_mutex_unlock (factory->medias_lock);
+  g_mutex_unlock (&factory->medias_lock);
 
   if (key)
     g_free (key);
@@ -660,13 +849,30 @@ static void
 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
 {
   gboolean shared, eos_shutdown;
+  guint size;
+  GstRTSPAuth *auth;
+  GstRTSPLowerTrans protocols;
+  gchar *mc;
 
   /* configure the sharedness */
   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
   shared = factory->shared;
   eos_shutdown = factory->eos_shutdown;
+  size = factory->buffer_size;
+  protocols = factory->protocols;
   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
 
   gst_rtsp_media_set_shared (media, shared);
   gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
+  gst_rtsp_media_set_buffer_size (media, size);
+  gst_rtsp_media_set_protocols (media, protocols);
+
+  if ((auth = gst_rtsp_media_factory_get_auth (factory))) {
+    gst_rtsp_media_set_auth (media, auth);
+    g_object_unref (auth);
+  }
+  if ((mc = gst_rtsp_media_factory_get_multicast_group (factory))) {
+    gst_rtsp_media_set_multicast_group (media, mc);
+    g_free (mc);
+  }
 }