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 GstRTSPLowerTrans protocols;
58 GstRTSPAddressPool *pool;
61 GHashTable *medias; /* protected by medias_lock */
64 #define DEFAULT_LAUNCH NULL
65 #define DEFAULT_SHARED FALSE
66 #define DEFAULT_SUSPEND_MODE GST_RTSP_SUSPEND_MODE_NONE
67 #define DEFAULT_EOS_SHUTDOWN FALSE
68 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
69 GST_RTSP_LOWER_TRANS_TCP
70 #define DEFAULT_BUFFER_SIZE 0x80000
86 SIGNAL_MEDIA_CONSTRUCTED,
87 SIGNAL_MEDIA_CONFIGURE,
91 GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
92 #define GST_CAT_DEFAULT rtsp_media_debug
94 static guint gst_rtsp_media_factory_signals[SIGNAL_LAST] = { 0 };
96 static void gst_rtsp_media_factory_get_property (GObject * object, guint propid,
97 GValue * value, GParamSpec * pspec);
98 static void gst_rtsp_media_factory_set_property (GObject * object, guint propid,
99 const GValue * value, GParamSpec * pspec);
100 static void gst_rtsp_media_factory_finalize (GObject * obj);
102 static gchar *default_gen_key (GstRTSPMediaFactory * factory,
103 const GstRTSPUrl * url);
104 static GstElement *default_create_element (GstRTSPMediaFactory * factory,
105 const GstRTSPUrl * url);
106 static GstRTSPMedia *default_construct (GstRTSPMediaFactory * factory,
107 const GstRTSPUrl * url);
108 static void default_configure (GstRTSPMediaFactory * factory,
109 GstRTSPMedia * media);
110 static GstElement *default_create_pipeline (GstRTSPMediaFactory * factory,
111 GstRTSPMedia * media);
113 G_DEFINE_TYPE (GstRTSPMediaFactory, gst_rtsp_media_factory, G_TYPE_OBJECT);
116 gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
118 GObjectClass *gobject_class;
120 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryPrivate));
122 gobject_class = G_OBJECT_CLASS (klass);
124 gobject_class->get_property = gst_rtsp_media_factory_get_property;
125 gobject_class->set_property = gst_rtsp_media_factory_set_property;
126 gobject_class->finalize = gst_rtsp_media_factory_finalize;
129 * GstRTSPMediaFactory::launch:
131 * The gst_parse_launch() line to use for constructing the pipeline in the
132 * default prepare vmethod.
134 * The pipeline description should return a GstBin as the toplevel element
135 * which can be accomplished by enclosing the dscription with brackets '('
138 * The description should return a pipeline with payloaders named pay0, pay1,
139 * etc.. Each of the payloaders will result in a stream.
141 * Support for dynamic payloaders can be accomplished by adding payloaders
142 * named dynpay0, dynpay1, etc..
144 g_object_class_install_property (gobject_class, PROP_LAUNCH,
145 g_param_spec_string ("launch", "Launch",
146 "A launch description of the pipeline", DEFAULT_LAUNCH,
147 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
149 g_object_class_install_property (gobject_class, PROP_SHARED,
150 g_param_spec_boolean ("shared", "Shared",
151 "If media from this factory is shared", DEFAULT_SHARED,
152 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
154 g_object_class_install_property (gobject_class, PROP_SUSPEND_MODE,
155 g_param_spec_enum ("suspend-mode", "Suspend Mode",
156 "Control how media will be suspended", GST_TYPE_RTSP_SUSPEND_MODE,
157 DEFAULT_SUSPEND_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
159 g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
160 g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
161 "Send EOS down the pipeline before shutting down",
162 DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
164 g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
165 g_param_spec_flags ("protocols", "Protocols",
166 "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
167 DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
169 g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
170 g_param_spec_uint ("buffer-size", "Buffer Size",
171 "The kernel UDP buffer size to use", 0, G_MAXUINT,
172 DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
174 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
175 g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
176 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
177 media_constructed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
178 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
180 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE] =
181 g_signal_new ("media-configure", G_TYPE_FROM_CLASS (klass),
182 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
183 media_configure), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
184 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
186 klass->gen_key = default_gen_key;
187 klass->create_element = default_create_element;
188 klass->construct = default_construct;
189 klass->configure = default_configure;
190 klass->create_pipeline = default_create_pipeline;
192 GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmediafactory", 0,
193 "GstRTSPMediaFactory");
197 gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
199 GstRTSPMediaFactoryPrivate *priv =
200 GST_RTSP_MEDIA_FACTORY_GET_PRIVATE (factory);
201 factory->priv = priv;
203 priv->launch = g_strdup (DEFAULT_LAUNCH);
204 priv->shared = DEFAULT_SHARED;
205 priv->suspend_mode = DEFAULT_SUSPEND_MODE;
206 priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
207 priv->protocols = DEFAULT_PROTOCOLS;
208 priv->buffer_size = DEFAULT_BUFFER_SIZE;
210 g_mutex_init (&priv->lock);
211 g_mutex_init (&priv->medias_lock);
212 priv->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
213 g_free, g_object_unref);
217 gst_rtsp_media_factory_finalize (GObject * obj)
219 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
220 GstRTSPMediaFactoryPrivate *priv = factory->priv;
222 if (priv->permissions)
223 gst_rtsp_permissions_unref (priv->permissions);
224 g_hash_table_unref (priv->medias);
225 g_mutex_clear (&priv->medias_lock);
226 g_free (priv->launch);
227 g_mutex_clear (&priv->lock);
229 g_object_unref (priv->pool);
231 G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
235 gst_rtsp_media_factory_get_property (GObject * object, guint propid,
236 GValue * value, GParamSpec * pspec)
238 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
242 g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
245 g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
247 case PROP_SUSPEND_MODE:
248 g_value_set_enum (value,
249 gst_rtsp_media_factory_get_suspend_mode (factory));
251 case PROP_EOS_SHUTDOWN:
252 g_value_set_boolean (value,
253 gst_rtsp_media_factory_is_eos_shutdown (factory));
256 g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
258 case PROP_BUFFER_SIZE:
259 g_value_set_uint (value,
260 gst_rtsp_media_factory_get_buffer_size (factory));
263 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
268 gst_rtsp_media_factory_set_property (GObject * object, guint propid,
269 const GValue * value, GParamSpec * pspec)
271 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
275 gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
278 gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
280 case PROP_SUSPEND_MODE:
281 gst_rtsp_media_factory_set_suspend_mode (factory,
282 g_value_get_enum (value));
284 case PROP_EOS_SHUTDOWN:
285 gst_rtsp_media_factory_set_eos_shutdown (factory,
286 g_value_get_boolean (value));
289 gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
291 case PROP_BUFFER_SIZE:
292 gst_rtsp_media_factory_set_buffer_size (factory,
293 g_value_get_uint (value));
296 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
301 * gst_rtsp_media_factory_new:
303 * Create a new #GstRTSPMediaFactory instance.
305 * Returns: a new #GstRTSPMediaFactory object.
307 GstRTSPMediaFactory *
308 gst_rtsp_media_factory_new (void)
310 GstRTSPMediaFactory *result;
312 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
318 * gst_rtsp_media_factory_set_permissions:
319 * @factory: a #GstRTSPMediaFactory
320 * @permissions: a #GstRTSPPermissions
322 * Set @permissions on @factory.
325 gst_rtsp_media_factory_set_permissions (GstRTSPMediaFactory * factory,
326 GstRTSPPermissions * permissions)
328 GstRTSPMediaFactoryPrivate *priv;
330 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
332 priv = factory->priv;
334 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
335 if (priv->permissions)
336 gst_rtsp_permissions_unref (priv->permissions);
337 if ((priv->permissions = permissions))
338 gst_rtsp_permissions_ref (permissions);
339 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
343 * gst_rtsp_media_factory_get_permissions:
344 * @factory: a #GstRTSPMediaFactory
346 * Get the permissions object from @factory.
348 * Returns: (transfer full): a #GstRTSPPermissions object, unref after usage.
351 gst_rtsp_media_factory_get_permissions (GstRTSPMediaFactory * factory)
353 GstRTSPMediaFactoryPrivate *priv;
354 GstRTSPPermissions *result;
356 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
358 priv = factory->priv;
360 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
361 if ((result = priv->permissions))
362 gst_rtsp_permissions_ref (result);
363 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
369 * gst_rtsp_media_factory_add_role:
370 * @factory: a #GstRTSPMediaFactory
372 * @fieldname: the first field name
373 * @...: additional arguments
375 * A convenience method to add @role with @fieldname and additional arguments to
376 * the permissions of @factory. If @factory had no permissions, new permissions
377 * will be created and the role will be added to it.
380 gst_rtsp_media_factory_add_role (GstRTSPMediaFactory * factory,
381 const gchar * role, const gchar * fieldname, ...)
383 GstRTSPMediaFactoryPrivate *priv;
386 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
387 g_return_if_fail (role != NULL);
388 g_return_if_fail (fieldname != NULL);
390 priv = factory->priv;
392 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
393 if (priv->permissions == NULL)
394 priv->permissions = gst_rtsp_permissions_new ();
396 va_start (var_args, fieldname);
397 gst_rtsp_permissions_add_role_valist (priv->permissions, role, fieldname,
400 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
404 * gst_rtsp_media_factory_set_launch:
405 * @factory: a #GstRTSPMediaFactory
406 * @launch: the launch description
409 * The gst_parse_launch() line to use for constructing the pipeline in the
410 * default prepare vmethod.
412 * The pipeline description should return a GstBin as the toplevel element
413 * which can be accomplished by enclosing the dscription with brackets '('
416 * The description should return a pipeline with payloaders named pay0, pay1,
417 * etc.. Each of the payloaders will result in a stream.
420 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
421 const gchar * launch)
423 GstRTSPMediaFactoryPrivate *priv;
425 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
426 g_return_if_fail (launch != NULL);
428 priv = factory->priv;
430 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
431 g_free (priv->launch);
432 priv->launch = g_strdup (launch);
433 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
437 * gst_rtsp_media_factory_get_launch:
438 * @factory: a #GstRTSPMediaFactory
440 * Get the gst_parse_launch() pipeline description that will be used in the
441 * default prepare vmethod.
443 * Returns: the configured launch description. g_free() after usage.
446 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
448 GstRTSPMediaFactoryPrivate *priv;
451 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
453 priv = factory->priv;
455 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
456 result = g_strdup (priv->launch);
457 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
463 * gst_rtsp_media_factory_set_suspend_mode:
464 * @factory: a #GstRTSPMediaFactory
465 * @mode: the new #GstRTSPSuspendMode
467 * Configure how media created from this factory will be suspended.
470 gst_rtsp_media_factory_set_suspend_mode (GstRTSPMediaFactory * factory,
471 GstRTSPSuspendMode mode)
473 GstRTSPMediaFactoryPrivate *priv;
475 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
477 priv = factory->priv;
479 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
480 priv->suspend_mode = mode;
481 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
485 * gst_rtsp_media_factory_get_suspend_mode:
486 * @factory: a #GstRTSPMediaFactory
488 * Get how media created from this factory will be suspended.
490 * Returns: a #GstRTSPSuspendMode.
493 gst_rtsp_media_factory_get_suspend_mode (GstRTSPMediaFactory * factory)
495 GstRTSPMediaFactoryPrivate *priv;
496 GstRTSPSuspendMode result;
498 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
499 GST_RTSP_SUSPEND_MODE_NONE);
501 priv = factory->priv;
503 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
504 result = priv->suspend_mode;
505 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
511 * gst_rtsp_media_factory_set_shared:
512 * @factory: a #GstRTSPMediaFactory
513 * @shared: the new value
515 * Configure if media created from this factory can be shared between clients.
518 gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
521 GstRTSPMediaFactoryPrivate *priv;
523 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
525 priv = factory->priv;
527 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
528 priv->shared = shared;
529 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
533 * gst_rtsp_media_factory_is_shared:
534 * @factory: a #GstRTSPMediaFactory
536 * Get if media created from this factory can be shared between clients.
538 * Returns: %TRUE if the media will be shared between clients.
541 gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
543 GstRTSPMediaFactoryPrivate *priv;
546 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
548 priv = factory->priv;
550 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
551 result = priv->shared;
552 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
558 * gst_rtsp_media_factory_set_eos_shutdown:
559 * @factory: a #GstRTSPMediaFactory
560 * @eos_shutdown: the new value
562 * Configure if media created from this factory will have an EOS sent to the
563 * pipeline before shutdown.
566 gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
567 gboolean eos_shutdown)
569 GstRTSPMediaFactoryPrivate *priv;
571 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
573 priv = factory->priv;
575 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
576 priv->eos_shutdown = eos_shutdown;
577 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
581 * gst_rtsp_media_factory_is_eos_shutdown:
582 * @factory: a #GstRTSPMediaFactory
584 * Get if media created from this factory will have an EOS event sent to the
585 * pipeline before shutdown.
587 * Returns: %TRUE if the media will receive EOS before shutdown.
590 gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
592 GstRTSPMediaFactoryPrivate *priv;
595 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
597 priv = factory->priv;
599 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
600 result = priv->eos_shutdown;
601 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
607 * gst_rtsp_media_factory_set_buffer_size:
608 * @factory: a #GstRTSPMedia
609 * @size: the new value
611 * Set the kernel UDP buffer size.
614 gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
617 GstRTSPMediaFactoryPrivate *priv;
619 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
621 priv = factory->priv;
623 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
624 priv->buffer_size = size;
625 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
629 * gst_rtsp_media_factory_get_buffer_size:
630 * @factory: a #GstRTSPMedia
632 * Get the kernel UDP buffer size.
634 * Returns: the kernel UDP buffer size.
637 gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
639 GstRTSPMediaFactoryPrivate *priv;
642 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
644 priv = factory->priv;
646 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
647 result = priv->buffer_size;
648 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
654 * gst_rtsp_media_factory_set_address_pool:
655 * @factory: a #GstRTSPMediaFactory
656 * @pool: a #GstRTSPAddressPool
658 * configure @pool to be used as the address pool of @factory.
661 gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
662 GstRTSPAddressPool * pool)
664 GstRTSPMediaFactoryPrivate *priv;
665 GstRTSPAddressPool *old;
667 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
669 priv = factory->priv;
671 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
672 if ((old = priv->pool) != pool)
673 priv->pool = pool ? g_object_ref (pool) : NULL;
676 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
679 g_object_unref (old);
683 * gst_rtsp_media_factory_get_address_pool:
684 * @factory: a #GstRTSPMediaFactory
686 * Get the #GstRTSPAddressPool used as the address pool of @factory.
688 * Returns: (transfer full): the #GstRTSPAddressPool of @factory. g_object_unref() after
692 gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
694 GstRTSPMediaFactoryPrivate *priv;
695 GstRTSPAddressPool *result;
697 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
699 priv = factory->priv;
701 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
702 if ((result = priv->pool))
703 g_object_ref (result);
704 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
710 * gst_rtsp_media_factory_set_protocols:
711 * @factory: a #GstRTSPMediaFactory
712 * @protocols: the new flags
714 * Configure the allowed lower transport for @factory.
717 gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
718 GstRTSPLowerTrans protocols)
720 GstRTSPMediaFactoryPrivate *priv;
722 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
724 priv = factory->priv;
726 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
727 priv->protocols = protocols;
728 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
732 * gst_rtsp_media_factory_get_protocols:
733 * @factory: a #GstRTSPMediaFactory
735 * Get the allowed protocols of @factory.
737 * Returns: a #GstRTSPLowerTrans
740 gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
742 GstRTSPMediaFactoryPrivate *priv;
743 GstRTSPLowerTrans res;
745 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
746 GST_RTSP_LOWER_TRANS_UNKNOWN);
748 priv = factory->priv;
750 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
751 res = priv->protocols;
752 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
758 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
760 return (media1 == media2);
764 media_unprepared (GstRTSPMedia * media, GWeakRef * ref)
766 GstRTSPMediaFactory *factory = g_weak_ref_get (ref);
767 GstRTSPMediaFactoryPrivate *priv;
772 priv = factory->priv;;
774 g_mutex_lock (&priv->medias_lock);
775 g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
776 g_mutex_unlock (&priv->medias_lock);
778 g_object_unref (factory);
782 weak_ref_new (gpointer obj)
784 GWeakRef *ref = g_slice_new (GWeakRef);
786 g_weak_ref_init (ref, obj);
791 weak_ref_free (GWeakRef * ref)
793 g_weak_ref_clear (ref);
794 g_slice_free (GWeakRef, ref);
798 * gst_rtsp_media_factory_construct:
799 * @factory: a #GstRTSPMediaFactory
802 * Construct the media object and create its streams. Implementations
803 * should create the needed gstreamer elements and add them to the result
804 * object. No state changes should be performed on them yet.
806 * One or more GstRTSPStream objects should be created from the result
807 * with gst_rtsp_media_create_stream ().
809 * After the media is constructed, it can be configured and then prepared
810 * with gst_rtsp_media_prepare ().
812 * Returns: (transfer full): a new #GstRTSPMedia if the media could be prepared.
815 gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
816 const GstRTSPUrl * url)
818 GstRTSPMediaFactoryPrivate *priv;
821 GstRTSPMediaFactoryClass *klass;
823 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
824 g_return_val_if_fail (url != NULL, NULL);
826 priv = factory->priv;;
827 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
829 /* convert the url to a key for the hashtable. NULL return or a NULL function
830 * will not cache anything for this factory. */
832 key = klass->gen_key (factory, url);
836 g_mutex_lock (&priv->medias_lock);
838 /* we have a key, see if we find a cached media */
839 media = g_hash_table_lookup (priv->medias, key);
841 g_object_ref (media);
846 /* nothing cached found, try to create one */
847 if (klass->construct) {
848 media = klass->construct (factory, url);
850 g_signal_emit (factory,
851 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
857 /* configure the media */
858 if (klass->configure)
859 klass->configure (factory, media);
861 g_signal_emit (factory,
862 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
865 /* check if we can cache this media */
866 if (gst_rtsp_media_is_shared (media)) {
867 /* insert in the hashtable, takes ownership of the key */
868 g_object_ref (media);
869 g_hash_table_insert (priv->medias, key, media);
872 if (!gst_rtsp_media_is_reusable (media)) {
873 /* when not reusable, connect to the unprepare signal to remove the item
874 * from our cache when it gets unprepared */
875 g_signal_connect_data (media, "unprepared",
876 (GCallback) media_unprepared, weak_ref_new (factory),
877 (GClosureNotify) weak_ref_free, 0);
881 g_mutex_unlock (&priv->medias_lock);
886 GST_INFO ("constructed media %p for url %s", media, url->abspath);
892 default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
895 const gchar *pre_query;
898 pre_query = url->query ? "?" : "";
899 query = url->query ? url->query : "";
902 g_strdup_printf ("%u%s%s%s", url->port, url->abspath, pre_query, query);
908 default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
910 GstRTSPMediaFactoryPrivate *priv = factory->priv;
912 GError *error = NULL;
914 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
915 /* we need a parse syntax */
916 if (priv->launch == NULL)
919 /* parse the user provided launch line */
920 element = gst_parse_launch (priv->launch, &error);
924 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
927 /* a recoverable error was encountered */
928 GST_WARNING ("recoverable parsing error: %s", error->message);
929 g_error_free (error);
936 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
937 g_critical ("no launch line specified");
942 g_critical ("could not parse launch syntax (%s): %s", priv->launch,
943 (error ? error->message : "unknown reason"));
944 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
946 g_error_free (error);
951 static GstRTSPMedia *
952 default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
955 GstElement *element, *pipeline;
956 GstRTSPMediaFactoryClass *klass;
958 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
960 if (!klass->create_pipeline)
963 element = gst_rtsp_media_factory_create_element (factory, url);
967 /* create a new empty media */
968 media = gst_rtsp_media_new (element);
970 gst_rtsp_media_collect_streams (media);
972 pipeline = klass->create_pipeline (factory, media);
973 if (pipeline == NULL)
981 g_critical ("no create_pipeline function");
986 g_critical ("could not create element");
991 g_critical ("can't create pipeline");
992 g_object_unref (media);
998 default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1000 GstElement *pipeline;
1002 pipeline = gst_pipeline_new ("media-pipeline");
1003 gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
1009 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1011 GstRTSPMediaFactoryPrivate *priv = factory->priv;
1012 gboolean shared, eos_shutdown;
1014 GstRTSPSuspendMode suspend_mode;
1015 GstRTSPLowerTrans protocols;
1016 GstRTSPAddressPool *pool;
1017 GstRTSPPermissions *perms;
1019 /* configure the sharedness */
1020 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1021 suspend_mode = priv->suspend_mode;
1022 shared = priv->shared;
1023 eos_shutdown = priv->eos_shutdown;
1024 size = priv->buffer_size;
1025 protocols = priv->protocols;
1026 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1028 gst_rtsp_media_set_suspend_mode (media, suspend_mode);
1029 gst_rtsp_media_set_shared (media, shared);
1030 gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
1031 gst_rtsp_media_set_buffer_size (media, size);
1032 gst_rtsp_media_set_protocols (media, protocols);
1034 if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
1035 gst_rtsp_media_set_address_pool (media, pool);
1036 g_object_unref (pool);
1038 if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
1039 gst_rtsp_media_set_permissions (media, perms);
1040 gst_rtsp_permissions_unref (perms);
1045 * gst_rtsp_media_factory_create_element:
1046 * @factory: a #GstRTSPMediaFactory
1047 * @url: the url used
1049 * Construct and return a #GstElement that is a #GstBin containing
1050 * the elements to use for streaming the media.
1052 * The bin should contain payloaders pay\%d for each stream. The default
1053 * implementation of this function returns the bin created from the
1056 * Returns: (transfer floating) a new #GstElement.
1059 gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
1060 const GstRTSPUrl * url)
1062 GstRTSPMediaFactoryClass *klass;
1065 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
1066 g_return_val_if_fail (url != NULL, NULL);
1068 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1070 if (klass->create_element)
1071 result = klass->create_element (factory, url);