2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 * SECTION:rtsp-media-factory
21 * @short_description: A factory for media pipelines
22 * @see_also: #GstRTSPMountPoints, #GstRTSPMedia
24 * The #GstRTSPMediaFactory is responsible for creating or recycling
25 * #GstRTSPMedia objects based on the passed URL.
27 * The default implementation of the object can create #GstRTSPMedia objects
28 * containing a pipeline created from a launch description set with
29 * gst_rtsp_media_factory_set_launch().
31 * Media from a factory can be shared by setting the shared flag with
32 * gst_rtsp_media_factory_set_shared(). When a factory is shared,
33 * gst_rtsp_media_factory_construct() will return the same #GstRTSPMedia when
36 * Last reviewed on 2013-07-11 (1.0.0)
39 #include "rtsp-media-factory.h"
41 #define GST_RTSP_MEDIA_FACTORY_GET_PRIVATE(obj) \
42 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY, GstRTSPMediaFactoryPrivate))
44 #define GST_RTSP_MEDIA_FACTORY_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_CAST(f)->priv->lock))
45 #define GST_RTSP_MEDIA_FACTORY_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
46 #define GST_RTSP_MEDIA_FACTORY_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
48 struct _GstRTSPMediaFactoryPrivate
50 GMutex lock; /* protects everything but medias */
51 GstRTSPPermissions *permissions;
54 GstRTSPSuspendMode suspend_mode;
55 gboolean eos_shutdown;
56 GstRTSPProfile profiles;
57 GstRTSPLowerTrans protocols;
59 GstRTSPAddressPool *pool;
62 GHashTable *medias; /* protected by medias_lock */
65 #define DEFAULT_LAUNCH NULL
66 #define DEFAULT_SHARED FALSE
67 #define DEFAULT_SUSPEND_MODE GST_RTSP_SUSPEND_MODE_NONE
68 #define DEFAULT_EOS_SHUTDOWN FALSE
69 #define DEFAULT_PROFILES GST_RTSP_PROFILE_AVP
70 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
71 GST_RTSP_LOWER_TRANS_TCP
72 #define DEFAULT_BUFFER_SIZE 0x80000
89 SIGNAL_MEDIA_CONSTRUCTED,
90 SIGNAL_MEDIA_CONFIGURE,
94 GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
95 #define GST_CAT_DEFAULT rtsp_media_debug
97 static guint gst_rtsp_media_factory_signals[SIGNAL_LAST] = { 0 };
99 static void gst_rtsp_media_factory_get_property (GObject * object, guint propid,
100 GValue * value, GParamSpec * pspec);
101 static void gst_rtsp_media_factory_set_property (GObject * object, guint propid,
102 const GValue * value, GParamSpec * pspec);
103 static void gst_rtsp_media_factory_finalize (GObject * obj);
105 static gchar *default_gen_key (GstRTSPMediaFactory * factory,
106 const GstRTSPUrl * url);
107 static GstElement *default_create_element (GstRTSPMediaFactory * factory,
108 const GstRTSPUrl * url);
109 static GstRTSPMedia *default_construct (GstRTSPMediaFactory * factory,
110 const GstRTSPUrl * url);
111 static void default_configure (GstRTSPMediaFactory * factory,
112 GstRTSPMedia * media);
113 static GstElement *default_create_pipeline (GstRTSPMediaFactory * factory,
114 GstRTSPMedia * media);
116 G_DEFINE_TYPE (GstRTSPMediaFactory, gst_rtsp_media_factory, G_TYPE_OBJECT);
119 gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
121 GObjectClass *gobject_class;
123 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryPrivate));
125 gobject_class = G_OBJECT_CLASS (klass);
127 gobject_class->get_property = gst_rtsp_media_factory_get_property;
128 gobject_class->set_property = gst_rtsp_media_factory_set_property;
129 gobject_class->finalize = gst_rtsp_media_factory_finalize;
132 * GstRTSPMediaFactory::launch:
134 * The gst_parse_launch() line to use for constructing the pipeline in the
135 * default prepare vmethod.
137 * The pipeline description should return a GstBin as the toplevel element
138 * which can be accomplished by enclosing the dscription with brackets '('
141 * The description should return a pipeline with payloaders named pay0, pay1,
142 * etc.. Each of the payloaders will result in a stream.
144 * Support for dynamic payloaders can be accomplished by adding payloaders
145 * named dynpay0, dynpay1, etc..
147 g_object_class_install_property (gobject_class, PROP_LAUNCH,
148 g_param_spec_string ("launch", "Launch",
149 "A launch description of the pipeline", DEFAULT_LAUNCH,
150 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
152 g_object_class_install_property (gobject_class, PROP_SHARED,
153 g_param_spec_boolean ("shared", "Shared",
154 "If media from this factory is shared", DEFAULT_SHARED,
155 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
157 g_object_class_install_property (gobject_class, PROP_SUSPEND_MODE,
158 g_param_spec_enum ("suspend-mode", "Suspend Mode",
159 "Control how media will be suspended", GST_TYPE_RTSP_SUSPEND_MODE,
160 DEFAULT_SUSPEND_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
162 g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
163 g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
164 "Send EOS down the pipeline before shutting down",
165 DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
167 g_object_class_install_property (gobject_class, PROP_PROFILES,
168 g_param_spec_flags ("profiles", "Profiles",
169 "Allowed transfer profiles", GST_TYPE_RTSP_PROFILE,
170 DEFAULT_PROFILES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
172 g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
173 g_param_spec_flags ("protocols", "Protocols",
174 "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
175 DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
177 g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
178 g_param_spec_uint ("buffer-size", "Buffer Size",
179 "The kernel UDP buffer size to use", 0, G_MAXUINT,
180 DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
182 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
183 g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
184 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
185 media_constructed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
186 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
188 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE] =
189 g_signal_new ("media-configure", G_TYPE_FROM_CLASS (klass),
190 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
191 media_configure), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
192 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
194 klass->gen_key = default_gen_key;
195 klass->create_element = default_create_element;
196 klass->construct = default_construct;
197 klass->configure = default_configure;
198 klass->create_pipeline = default_create_pipeline;
200 GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmediafactory", 0,
201 "GstRTSPMediaFactory");
205 gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
207 GstRTSPMediaFactoryPrivate *priv =
208 GST_RTSP_MEDIA_FACTORY_GET_PRIVATE (factory);
209 factory->priv = priv;
211 priv->launch = g_strdup (DEFAULT_LAUNCH);
212 priv->shared = DEFAULT_SHARED;
213 priv->suspend_mode = DEFAULT_SUSPEND_MODE;
214 priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
215 priv->profiles = DEFAULT_PROFILES;
216 priv->protocols = DEFAULT_PROTOCOLS;
217 priv->buffer_size = DEFAULT_BUFFER_SIZE;
219 g_mutex_init (&priv->lock);
220 g_mutex_init (&priv->medias_lock);
221 priv->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
222 g_free, g_object_unref);
226 gst_rtsp_media_factory_finalize (GObject * obj)
228 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
229 GstRTSPMediaFactoryPrivate *priv = factory->priv;
231 if (priv->permissions)
232 gst_rtsp_permissions_unref (priv->permissions);
233 g_hash_table_unref (priv->medias);
234 g_mutex_clear (&priv->medias_lock);
235 g_free (priv->launch);
236 g_mutex_clear (&priv->lock);
238 g_object_unref (priv->pool);
240 G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
244 gst_rtsp_media_factory_get_property (GObject * object, guint propid,
245 GValue * value, GParamSpec * pspec)
247 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
251 g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
254 g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
256 case PROP_SUSPEND_MODE:
257 g_value_set_enum (value,
258 gst_rtsp_media_factory_get_suspend_mode (factory));
260 case PROP_EOS_SHUTDOWN:
261 g_value_set_boolean (value,
262 gst_rtsp_media_factory_is_eos_shutdown (factory));
265 g_value_set_flags (value, gst_rtsp_media_factory_get_profiles (factory));
268 g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
270 case PROP_BUFFER_SIZE:
271 g_value_set_uint (value,
272 gst_rtsp_media_factory_get_buffer_size (factory));
275 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
280 gst_rtsp_media_factory_set_property (GObject * object, guint propid,
281 const GValue * value, GParamSpec * pspec)
283 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
287 gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
290 gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
292 case PROP_SUSPEND_MODE:
293 gst_rtsp_media_factory_set_suspend_mode (factory,
294 g_value_get_enum (value));
296 case PROP_EOS_SHUTDOWN:
297 gst_rtsp_media_factory_set_eos_shutdown (factory,
298 g_value_get_boolean (value));
301 gst_rtsp_media_factory_set_profiles (factory, g_value_get_flags (value));
304 gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
306 case PROP_BUFFER_SIZE:
307 gst_rtsp_media_factory_set_buffer_size (factory,
308 g_value_get_uint (value));
311 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
316 * gst_rtsp_media_factory_new:
318 * Create a new #GstRTSPMediaFactory instance.
320 * Returns: (transfer full): a new #GstRTSPMediaFactory object.
322 GstRTSPMediaFactory *
323 gst_rtsp_media_factory_new (void)
325 GstRTSPMediaFactory *result;
327 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
333 * gst_rtsp_media_factory_set_permissions:
334 * @factory: a #GstRTSPMediaFactory
335 * @permissions: (transfer none): a #GstRTSPPermissions
337 * Set @permissions on @factory.
340 gst_rtsp_media_factory_set_permissions (GstRTSPMediaFactory * factory,
341 GstRTSPPermissions * permissions)
343 GstRTSPMediaFactoryPrivate *priv;
345 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
347 priv = factory->priv;
349 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
350 if (priv->permissions)
351 gst_rtsp_permissions_unref (priv->permissions);
352 if ((priv->permissions = permissions))
353 gst_rtsp_permissions_ref (permissions);
354 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
358 * gst_rtsp_media_factory_get_permissions:
359 * @factory: a #GstRTSPMediaFactory
361 * Get the permissions object from @factory.
363 * Returns: (transfer full): a #GstRTSPPermissions object, unref after usage.
366 gst_rtsp_media_factory_get_permissions (GstRTSPMediaFactory * factory)
368 GstRTSPMediaFactoryPrivate *priv;
369 GstRTSPPermissions *result;
371 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
373 priv = factory->priv;
375 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
376 if ((result = priv->permissions))
377 gst_rtsp_permissions_ref (result);
378 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
384 * gst_rtsp_media_factory_add_role:
385 * @factory: a #GstRTSPMediaFactory
387 * @fieldname: the first field name
388 * @...: additional arguments
390 * A convenience method to add @role with @fieldname and additional arguments to
391 * the permissions of @factory. If @factory had no permissions, new permissions
392 * will be created and the role will be added to it.
395 gst_rtsp_media_factory_add_role (GstRTSPMediaFactory * factory,
396 const gchar * role, const gchar * fieldname, ...)
398 GstRTSPMediaFactoryPrivate *priv;
401 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
402 g_return_if_fail (role != NULL);
403 g_return_if_fail (fieldname != NULL);
405 priv = factory->priv;
407 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
408 if (priv->permissions == NULL)
409 priv->permissions = gst_rtsp_permissions_new ();
411 va_start (var_args, fieldname);
412 gst_rtsp_permissions_add_role_valist (priv->permissions, role, fieldname,
415 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
419 * gst_rtsp_media_factory_set_launch:
420 * @factory: a #GstRTSPMediaFactory
421 * @launch: the launch description
424 * The gst_parse_launch() line to use for constructing the pipeline in the
425 * default prepare vmethod.
427 * The pipeline description should return a GstBin as the toplevel element
428 * which can be accomplished by enclosing the dscription with brackets '('
431 * The description should return a pipeline with payloaders named pay0, pay1,
432 * etc.. Each of the payloaders will result in a stream.
435 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
436 const gchar * launch)
438 GstRTSPMediaFactoryPrivate *priv;
440 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
441 g_return_if_fail (launch != NULL);
443 priv = factory->priv;
445 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
446 g_free (priv->launch);
447 priv->launch = g_strdup (launch);
448 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
452 * gst_rtsp_media_factory_get_launch:
453 * @factory: a #GstRTSPMediaFactory
455 * Get the gst_parse_launch() pipeline description that will be used in the
456 * default prepare vmethod.
458 * Returns: (transfer full): the configured launch description. g_free() after
462 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
464 GstRTSPMediaFactoryPrivate *priv;
467 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
469 priv = factory->priv;
471 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
472 result = g_strdup (priv->launch);
473 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
479 * gst_rtsp_media_factory_set_suspend_mode:
480 * @factory: a #GstRTSPMediaFactory
481 * @mode: the new #GstRTSPSuspendMode
483 * Configure how media created from this factory will be suspended.
486 gst_rtsp_media_factory_set_suspend_mode (GstRTSPMediaFactory * factory,
487 GstRTSPSuspendMode mode)
489 GstRTSPMediaFactoryPrivate *priv;
491 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
493 priv = factory->priv;
495 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
496 priv->suspend_mode = mode;
497 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
501 * gst_rtsp_media_factory_get_suspend_mode:
502 * @factory: a #GstRTSPMediaFactory
504 * Get how media created from this factory will be suspended.
506 * Returns: a #GstRTSPSuspendMode.
509 gst_rtsp_media_factory_get_suspend_mode (GstRTSPMediaFactory * factory)
511 GstRTSPMediaFactoryPrivate *priv;
512 GstRTSPSuspendMode result;
514 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
515 GST_RTSP_SUSPEND_MODE_NONE);
517 priv = factory->priv;
519 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
520 result = priv->suspend_mode;
521 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
527 * gst_rtsp_media_factory_set_shared:
528 * @factory: a #GstRTSPMediaFactory
529 * @shared: the new value
531 * Configure if media created from this factory can be shared between clients.
534 gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
537 GstRTSPMediaFactoryPrivate *priv;
539 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
541 priv = factory->priv;
543 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
544 priv->shared = shared;
545 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
549 * gst_rtsp_media_factory_is_shared:
550 * @factory: a #GstRTSPMediaFactory
552 * Get if media created from this factory can be shared between clients.
554 * Returns: %TRUE if the media will be shared between clients.
557 gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
559 GstRTSPMediaFactoryPrivate *priv;
562 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
564 priv = factory->priv;
566 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
567 result = priv->shared;
568 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
574 * gst_rtsp_media_factory_set_eos_shutdown:
575 * @factory: a #GstRTSPMediaFactory
576 * @eos_shutdown: the new value
578 * Configure if media created from this factory will have an EOS sent to the
579 * pipeline before shutdown.
582 gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
583 gboolean eos_shutdown)
585 GstRTSPMediaFactoryPrivate *priv;
587 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
589 priv = factory->priv;
591 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
592 priv->eos_shutdown = eos_shutdown;
593 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
597 * gst_rtsp_media_factory_is_eos_shutdown:
598 * @factory: a #GstRTSPMediaFactory
600 * Get if media created from this factory will have an EOS event sent to the
601 * pipeline before shutdown.
603 * Returns: %TRUE if the media will receive EOS before shutdown.
606 gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
608 GstRTSPMediaFactoryPrivate *priv;
611 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
613 priv = factory->priv;
615 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
616 result = priv->eos_shutdown;
617 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
623 * gst_rtsp_media_factory_set_buffer_size:
624 * @factory: a #GstRTSPMedia
625 * @size: the new value
627 * Set the kernel UDP buffer size.
630 gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
633 GstRTSPMediaFactoryPrivate *priv;
635 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
637 priv = factory->priv;
639 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
640 priv->buffer_size = size;
641 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
645 * gst_rtsp_media_factory_get_buffer_size:
646 * @factory: a #GstRTSPMedia
648 * Get the kernel UDP buffer size.
650 * Returns: the kernel UDP buffer size.
653 gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
655 GstRTSPMediaFactoryPrivate *priv;
658 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
660 priv = factory->priv;
662 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
663 result = priv->buffer_size;
664 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
670 * gst_rtsp_media_factory_set_address_pool:
671 * @factory: a #GstRTSPMediaFactory
672 * @pool: (transfer none): a #GstRTSPAddressPool
674 * configure @pool to be used as the address pool of @factory.
677 gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
678 GstRTSPAddressPool * pool)
680 GstRTSPMediaFactoryPrivate *priv;
681 GstRTSPAddressPool *old;
683 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
685 priv = factory->priv;
687 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
688 if ((old = priv->pool) != pool)
689 priv->pool = pool ? g_object_ref (pool) : NULL;
692 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
695 g_object_unref (old);
699 * gst_rtsp_media_factory_get_address_pool:
700 * @factory: a #GstRTSPMediaFactory
702 * Get the #GstRTSPAddressPool used as the address pool of @factory.
704 * Returns: (transfer full): the #GstRTSPAddressPool of @factory. g_object_unref() after
708 gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
710 GstRTSPMediaFactoryPrivate *priv;
711 GstRTSPAddressPool *result;
713 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
715 priv = factory->priv;
717 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
718 if ((result = priv->pool))
719 g_object_ref (result);
720 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
726 * gst_rtsp_media_factory_set_profiles:
727 * @factory: a #GstRTSPMediaFactory
728 * @profiles: the new flags
730 * Configure the allowed profiles for @factory.
733 gst_rtsp_media_factory_set_profiles (GstRTSPMediaFactory * factory,
734 GstRTSPProfile profiles)
736 GstRTSPMediaFactoryPrivate *priv;
738 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
740 priv = factory->priv;
742 GST_DEBUG_OBJECT (factory, "profiles %d", profiles);
744 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
745 priv->profiles = profiles;
746 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
750 * gst_rtsp_media_factory_get_profiles:
751 * @factory: a #GstRTSPMediaFactory
753 * Get the allowed profiles of @factory.
755 * Returns: a #GstRTSPProfile
758 gst_rtsp_media_factory_get_profiles (GstRTSPMediaFactory * factory)
760 GstRTSPMediaFactoryPrivate *priv;
763 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
764 GST_RTSP_PROFILE_UNKNOWN);
766 priv = factory->priv;
768 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
769 res = priv->profiles;
770 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
776 * gst_rtsp_media_factory_set_protocols:
777 * @factory: a #GstRTSPMediaFactory
778 * @protocols: the new flags
780 * Configure the allowed lower transport for @factory.
783 gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
784 GstRTSPLowerTrans protocols)
786 GstRTSPMediaFactoryPrivate *priv;
788 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
790 priv = factory->priv;
792 GST_DEBUG_OBJECT (factory, "protocols %d", protocols);
794 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
795 priv->protocols = protocols;
796 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
800 * gst_rtsp_media_factory_get_protocols:
801 * @factory: a #GstRTSPMediaFactory
803 * Get the allowed protocols of @factory.
805 * Returns: a #GstRTSPLowerTrans
808 gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
810 GstRTSPMediaFactoryPrivate *priv;
811 GstRTSPLowerTrans res;
813 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
814 GST_RTSP_LOWER_TRANS_UNKNOWN);
816 priv = factory->priv;
818 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
819 res = priv->protocols;
820 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
826 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
828 return (media1 == media2);
832 media_unprepared (GstRTSPMedia * media, GWeakRef * ref)
834 GstRTSPMediaFactory *factory = g_weak_ref_get (ref);
835 GstRTSPMediaFactoryPrivate *priv;
840 priv = factory->priv;;
842 g_mutex_lock (&priv->medias_lock);
843 g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
844 g_mutex_unlock (&priv->medias_lock);
846 g_object_unref (factory);
850 weak_ref_new (gpointer obj)
852 GWeakRef *ref = g_slice_new (GWeakRef);
854 g_weak_ref_init (ref, obj);
859 weak_ref_free (GWeakRef * ref)
861 g_weak_ref_clear (ref);
862 g_slice_free (GWeakRef, ref);
866 * gst_rtsp_media_factory_construct:
867 * @factory: a #GstRTSPMediaFactory
870 * Construct the media object and create its streams. Implementations
871 * should create the needed gstreamer elements and add them to the result
872 * object. No state changes should be performed on them yet.
874 * One or more GstRTSPStream objects should be created from the result
875 * with gst_rtsp_media_create_stream ().
877 * After the media is constructed, it can be configured and then prepared
878 * with gst_rtsp_media_prepare ().
880 * Returns: (transfer full): a new #GstRTSPMedia if the media could be prepared.
883 gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
884 const GstRTSPUrl * url)
886 GstRTSPMediaFactoryPrivate *priv;
889 GstRTSPMediaFactoryClass *klass;
891 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
892 g_return_val_if_fail (url != NULL, NULL);
894 priv = factory->priv;;
895 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
897 /* convert the url to a key for the hashtable. NULL return or a NULL function
898 * will not cache anything for this factory. */
900 key = klass->gen_key (factory, url);
904 g_mutex_lock (&priv->medias_lock);
906 /* we have a key, see if we find a cached media */
907 media = g_hash_table_lookup (priv->medias, key);
909 g_object_ref (media);
914 /* nothing cached found, try to create one */
915 if (klass->construct) {
916 media = klass->construct (factory, url);
918 g_signal_emit (factory,
919 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
925 /* configure the media */
926 if (klass->configure)
927 klass->configure (factory, media);
929 g_signal_emit (factory,
930 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
933 /* check if we can cache this media */
934 if (gst_rtsp_media_is_shared (media)) {
935 /* insert in the hashtable, takes ownership of the key */
936 g_object_ref (media);
937 g_hash_table_insert (priv->medias, key, media);
940 if (!gst_rtsp_media_is_reusable (media)) {
941 /* when not reusable, connect to the unprepare signal to remove the item
942 * from our cache when it gets unprepared */
943 g_signal_connect_data (media, "unprepared",
944 (GCallback) media_unprepared, weak_ref_new (factory),
945 (GClosureNotify) weak_ref_free, 0);
949 g_mutex_unlock (&priv->medias_lock);
954 GST_INFO ("constructed media %p for url %s", media, url->abspath);
960 default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
963 const gchar *pre_query;
966 pre_query = url->query ? "?" : "";
967 query = url->query ? url->query : "";
970 g_strdup_printf ("%u%s%s%s", url->port, url->abspath, pre_query, query);
976 default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
978 GstRTSPMediaFactoryPrivate *priv = factory->priv;
980 GError *error = NULL;
982 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
983 /* we need a parse syntax */
984 if (priv->launch == NULL)
987 /* parse the user provided launch line */
988 element = gst_parse_launch (priv->launch, &error);
992 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
995 /* a recoverable error was encountered */
996 GST_WARNING ("recoverable parsing error: %s", error->message);
997 g_error_free (error);
1004 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1005 g_critical ("no launch line specified");
1010 g_critical ("could not parse launch syntax (%s): %s", priv->launch,
1011 (error ? error->message : "unknown reason"));
1012 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1014 g_error_free (error);
1019 static GstRTSPMedia *
1020 default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
1022 GstRTSPMedia *media;
1023 GstElement *element, *pipeline;
1024 GstRTSPMediaFactoryClass *klass;
1026 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1028 if (!klass->create_pipeline)
1031 element = gst_rtsp_media_factory_create_element (factory, url);
1032 if (element == NULL)
1035 /* create a new empty media */
1036 media = gst_rtsp_media_new (element);
1038 gst_rtsp_media_collect_streams (media);
1040 pipeline = klass->create_pipeline (factory, media);
1041 if (pipeline == NULL)
1049 g_critical ("no create_pipeline function");
1054 g_critical ("could not create element");
1059 g_critical ("can't create pipeline");
1060 g_object_unref (media);
1066 default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1068 GstElement *pipeline;
1070 pipeline = gst_pipeline_new ("media-pipeline");
1071 gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
1077 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1079 GstRTSPMediaFactoryPrivate *priv = factory->priv;
1080 gboolean shared, eos_shutdown;
1082 GstRTSPSuspendMode suspend_mode;
1083 GstRTSPProfile profiles;
1084 GstRTSPLowerTrans protocols;
1085 GstRTSPAddressPool *pool;
1086 GstRTSPPermissions *perms;
1088 /* configure the sharedness */
1089 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1090 suspend_mode = priv->suspend_mode;
1091 shared = priv->shared;
1092 eos_shutdown = priv->eos_shutdown;
1093 size = priv->buffer_size;
1094 profiles = priv->profiles;
1095 protocols = priv->protocols;
1096 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1098 gst_rtsp_media_set_suspend_mode (media, suspend_mode);
1099 gst_rtsp_media_set_shared (media, shared);
1100 gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
1101 gst_rtsp_media_set_buffer_size (media, size);
1102 gst_rtsp_media_set_profiles (media, profiles);
1103 gst_rtsp_media_set_protocols (media, protocols);
1105 if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
1106 gst_rtsp_media_set_address_pool (media, pool);
1107 g_object_unref (pool);
1109 if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
1110 gst_rtsp_media_set_permissions (media, perms);
1111 gst_rtsp_permissions_unref (perms);
1116 * gst_rtsp_media_factory_create_element:
1117 * @factory: a #GstRTSPMediaFactory
1118 * @url: the url used
1120 * Construct and return a #GstElement that is a #GstBin containing
1121 * the elements to use for streaming the media.
1123 * The bin should contain payloaders pay\%d for each stream. The default
1124 * implementation of this function returns the bin created from the
1127 * Returns: (transfer floating): a new #GstElement.
1130 gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
1131 const GstRTSPUrl * url)
1133 GstRTSPMediaFactoryClass *klass;
1136 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
1137 g_return_val_if_fail (url != NULL, NULL);
1139 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1141 if (klass->create_element)
1142 result = klass->create_element (factory, url);