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 gboolean eos_shutdown;
55 GstRTSPLowerTrans protocols;
57 GstRTSPAddressPool *pool;
60 GHashTable *medias; /* protected by medias_lock */
63 #define DEFAULT_LAUNCH NULL
64 #define DEFAULT_SHARED FALSE
65 #define DEFAULT_EOS_SHUTDOWN FALSE
66 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
67 GST_RTSP_LOWER_TRANS_TCP
68 #define DEFAULT_BUFFER_SIZE 0x80000
83 SIGNAL_MEDIA_CONSTRUCTED,
84 SIGNAL_MEDIA_CONFIGURE,
88 GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
89 #define GST_CAT_DEFAULT rtsp_media_debug
91 static guint gst_rtsp_media_factory_signals[SIGNAL_LAST] = { 0 };
93 static void gst_rtsp_media_factory_get_property (GObject * object, guint propid,
94 GValue * value, GParamSpec * pspec);
95 static void gst_rtsp_media_factory_set_property (GObject * object, guint propid,
96 const GValue * value, GParamSpec * pspec);
97 static void gst_rtsp_media_factory_finalize (GObject * obj);
99 static gchar *default_gen_key (GstRTSPMediaFactory * factory,
100 const GstRTSPUrl * url);
101 static GstElement *default_create_element (GstRTSPMediaFactory * factory,
102 const GstRTSPUrl * url);
103 static GstRTSPMedia *default_construct (GstRTSPMediaFactory * factory,
104 const GstRTSPUrl * url);
105 static void default_configure (GstRTSPMediaFactory * factory,
106 GstRTSPMedia * media);
107 static GstElement *default_create_pipeline (GstRTSPMediaFactory * factory,
108 GstRTSPMedia * media);
110 G_DEFINE_TYPE (GstRTSPMediaFactory, gst_rtsp_media_factory, G_TYPE_OBJECT);
113 gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
115 GObjectClass *gobject_class;
117 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryPrivate));
119 gobject_class = G_OBJECT_CLASS (klass);
121 gobject_class->get_property = gst_rtsp_media_factory_get_property;
122 gobject_class->set_property = gst_rtsp_media_factory_set_property;
123 gobject_class->finalize = gst_rtsp_media_factory_finalize;
126 * GstRTSPMediaFactory::launch:
128 * The gst_parse_launch() line to use for constructing the pipeline in the
129 * default prepare vmethod.
131 * The pipeline description should return a GstBin as the toplevel element
132 * which can be accomplished by enclosing the dscription with brackets '('
135 * The description should return a pipeline with payloaders named pay0, pay1,
136 * etc.. Each of the payloaders will result in a stream.
138 * Support for dynamic payloaders can be accomplished by adding payloaders
139 * named dynpay0, dynpay1, etc..
141 g_object_class_install_property (gobject_class, PROP_LAUNCH,
142 g_param_spec_string ("launch", "Launch",
143 "A launch description of the pipeline", DEFAULT_LAUNCH,
144 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146 g_object_class_install_property (gobject_class, PROP_SHARED,
147 g_param_spec_boolean ("shared", "Shared",
148 "If media from this factory is shared", DEFAULT_SHARED,
149 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
151 g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
152 g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
153 "Send EOS down the pipeline before shutting down",
154 DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156 g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
157 g_param_spec_flags ("protocols", "Protocols",
158 "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
159 DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
161 g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
162 g_param_spec_uint ("buffer-size", "Buffer Size",
163 "The kernel UDP buffer size to use", 0, G_MAXUINT,
164 DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
166 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
167 g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
168 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
169 media_constructed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
170 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
172 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE] =
173 g_signal_new ("media-configure", G_TYPE_FROM_CLASS (klass),
174 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
175 media_configure), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
176 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
178 klass->gen_key = default_gen_key;
179 klass->create_element = default_create_element;
180 klass->construct = default_construct;
181 klass->configure = default_configure;
182 klass->create_pipeline = default_create_pipeline;
184 GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmediafactory", 0,
185 "GstRTSPMediaFactory");
189 gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
191 GstRTSPMediaFactoryPrivate *priv =
192 GST_RTSP_MEDIA_FACTORY_GET_PRIVATE (factory);
193 factory->priv = priv;
195 priv->launch = g_strdup (DEFAULT_LAUNCH);
196 priv->shared = DEFAULT_SHARED;
197 priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
198 priv->protocols = DEFAULT_PROTOCOLS;
199 priv->buffer_size = DEFAULT_BUFFER_SIZE;
201 g_mutex_init (&priv->lock);
202 g_mutex_init (&priv->medias_lock);
203 priv->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
204 g_free, g_object_unref);
208 gst_rtsp_media_factory_finalize (GObject * obj)
210 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
211 GstRTSPMediaFactoryPrivate *priv = factory->priv;
213 if (priv->permissions)
214 gst_rtsp_permissions_unref (priv->permissions);
215 g_hash_table_unref (priv->medias);
216 g_mutex_clear (&priv->medias_lock);
217 g_free (priv->launch);
218 g_mutex_clear (&priv->lock);
220 g_object_unref (priv->pool);
222 G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
226 gst_rtsp_media_factory_get_property (GObject * object, guint propid,
227 GValue * value, GParamSpec * pspec)
229 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
233 g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
236 g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
238 case PROP_EOS_SHUTDOWN:
239 g_value_set_boolean (value,
240 gst_rtsp_media_factory_is_eos_shutdown (factory));
243 g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
245 case PROP_BUFFER_SIZE:
246 g_value_set_uint (value,
247 gst_rtsp_media_factory_get_buffer_size (factory));
250 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
255 gst_rtsp_media_factory_set_property (GObject * object, guint propid,
256 const GValue * value, GParamSpec * pspec)
258 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
262 gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
265 gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
267 case PROP_EOS_SHUTDOWN:
268 gst_rtsp_media_factory_set_eos_shutdown (factory,
269 g_value_get_boolean (value));
272 gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
274 case PROP_BUFFER_SIZE:
275 gst_rtsp_media_factory_set_buffer_size (factory,
276 g_value_get_uint (value));
279 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
284 * gst_rtsp_media_factory_new:
286 * Create a new #GstRTSPMediaFactory instance.
288 * Returns: a new #GstRTSPMediaFactory object.
290 GstRTSPMediaFactory *
291 gst_rtsp_media_factory_new (void)
293 GstRTSPMediaFactory *result;
295 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
301 * gst_rtsp_media_factory_set_permissions:
302 * @factory: a #GstRTSPMediaFactory
303 * @permissions: a #GstRTSPPermissions
305 * Set @permissions on @factory.
308 gst_rtsp_media_factory_set_permissions (GstRTSPMediaFactory * factory,
309 GstRTSPPermissions * permissions)
311 GstRTSPMediaFactoryPrivate *priv;
313 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
315 priv = factory->priv;
317 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
318 if (priv->permissions)
319 gst_rtsp_permissions_unref (priv->permissions);
320 if ((priv->permissions = permissions))
321 gst_rtsp_permissions_ref (permissions);
322 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
326 * gst_rtsp_media_factory_get_permissions:
327 * @factory: a #GstRTSPMediaFactory
329 * Get the permissions object from @factory.
331 * Returns: (transfer full): a #GstRTSPPermissions object, unref after usage.
334 gst_rtsp_media_factory_get_permissions (GstRTSPMediaFactory * factory)
336 GstRTSPMediaFactoryPrivate *priv;
337 GstRTSPPermissions *result;
339 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
341 priv = factory->priv;
343 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
344 if ((result = priv->permissions))
345 gst_rtsp_permissions_ref (result);
346 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
352 * gst_rtsp_media_factory_add_role:
353 * @factory: a #GstRTSPMediaFactory
355 * @fieldname: the first field name
356 * @...: additional arguments
358 * A convenience method to add @role with @fieldname and additional arguments to
359 * the permissions of @factory. If @factory had no permissions, new permissions
360 * will be created and the role will be added to it.
363 gst_rtsp_media_factory_add_role (GstRTSPMediaFactory * factory,
364 const gchar * role, const gchar * fieldname, ...)
366 GstRTSPMediaFactoryPrivate *priv;
369 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
370 g_return_if_fail (role != NULL);
371 g_return_if_fail (fieldname != NULL);
373 priv = factory->priv;
375 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
376 if (priv->permissions == NULL)
377 priv->permissions = gst_rtsp_permissions_new ();
379 va_start (var_args, fieldname);
380 gst_rtsp_permissions_add_role_valist (priv->permissions, role, fieldname,
383 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
387 * gst_rtsp_media_factory_set_launch:
388 * @factory: a #GstRTSPMediaFactory
389 * @launch: the launch description
392 * The gst_parse_launch() line to use for constructing the pipeline in the
393 * default prepare vmethod.
395 * The pipeline description should return a GstBin as the toplevel element
396 * which can be accomplished by enclosing the dscription with brackets '('
399 * The description should return a pipeline with payloaders named pay0, pay1,
400 * etc.. Each of the payloaders will result in a stream.
403 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
404 const gchar * launch)
406 GstRTSPMediaFactoryPrivate *priv;
408 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
409 g_return_if_fail (launch != NULL);
411 priv = factory->priv;
413 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
414 g_free (priv->launch);
415 priv->launch = g_strdup (launch);
416 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
420 * gst_rtsp_media_factory_get_launch:
421 * @factory: a #GstRTSPMediaFactory
423 * Get the gst_parse_launch() pipeline description that will be used in the
424 * default prepare vmethod.
426 * Returns: the configured launch description. g_free() after usage.
429 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
431 GstRTSPMediaFactoryPrivate *priv;
434 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
436 priv = factory->priv;
438 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
439 result = g_strdup (priv->launch);
440 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
446 * gst_rtsp_media_factory_set_shared:
447 * @factory: a #GstRTSPMediaFactory
448 * @shared: the new value
450 * Configure if media created from this factory can be shared between clients.
453 gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
456 GstRTSPMediaFactoryPrivate *priv;
458 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
460 priv = factory->priv;
462 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
463 priv->shared = shared;
464 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
468 * gst_rtsp_media_factory_is_shared:
469 * @factory: a #GstRTSPMediaFactory
471 * Get if media created from this factory can be shared between clients.
473 * Returns: %TRUE if the media will be shared between clients.
476 gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
478 GstRTSPMediaFactoryPrivate *priv;
481 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
483 priv = factory->priv;
485 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
486 result = priv->shared;
487 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
493 * gst_rtsp_media_factory_set_eos_shutdown:
494 * @factory: a #GstRTSPMediaFactory
495 * @eos_shutdown: the new value
497 * Configure if media created from this factory will have an EOS sent to the
498 * pipeline before shutdown.
501 gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
502 gboolean eos_shutdown)
504 GstRTSPMediaFactoryPrivate *priv;
506 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
508 priv = factory->priv;
510 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
511 priv->eos_shutdown = eos_shutdown;
512 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
516 * gst_rtsp_media_factory_is_eos_shutdown:
517 * @factory: a #GstRTSPMediaFactory
519 * Get if media created from this factory will have an EOS event sent to the
520 * pipeline before shutdown.
522 * Returns: %TRUE if the media will receive EOS before shutdown.
525 gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
527 GstRTSPMediaFactoryPrivate *priv;
530 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
532 priv = factory->priv;
534 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
535 result = priv->eos_shutdown;
536 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
542 * gst_rtsp_media_factory_set_buffer_size:
543 * @factory: a #GstRTSPMedia
544 * @size: the new value
546 * Set the kernel UDP buffer size.
549 gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
552 GstRTSPMediaFactoryPrivate *priv;
554 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
556 priv = factory->priv;
558 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
559 priv->buffer_size = size;
560 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
564 * gst_rtsp_media_factory_get_buffer_size:
565 * @factory: a #GstRTSPMedia
567 * Get the kernel UDP buffer size.
569 * Returns: the kernel UDP buffer size.
572 gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
574 GstRTSPMediaFactoryPrivate *priv;
577 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
579 priv = factory->priv;
581 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
582 result = priv->buffer_size;
583 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
589 * gst_rtsp_media_factory_set_address_pool:
590 * @factory: a #GstRTSPMediaFactory
591 * @pool: a #GstRTSPAddressPool
593 * configure @pool to be used as the address pool of @factory.
596 gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
597 GstRTSPAddressPool * pool)
599 GstRTSPMediaFactoryPrivate *priv;
600 GstRTSPAddressPool *old;
602 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
604 priv = factory->priv;
606 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
607 if ((old = priv->pool) != pool)
608 priv->pool = pool ? g_object_ref (pool) : NULL;
611 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
614 g_object_unref (old);
618 * gst_rtsp_media_factory_get_address_pool:
619 * @factory: a #GstRTSPMediaFactory
621 * Get the #GstRTSPAddressPool used as the address pool of @factory.
623 * Returns: (transfer full): the #GstRTSPAddressPool of @factory. g_object_unref() after
627 gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
629 GstRTSPMediaFactoryPrivate *priv;
630 GstRTSPAddressPool *result;
632 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
634 priv = factory->priv;
636 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
637 if ((result = priv->pool))
638 g_object_ref (result);
639 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
645 * gst_rtsp_media_factory_set_protocols:
646 * @factory: a #GstRTSPMediaFactory
647 * @protocols: the new flags
649 * Configure the allowed lower transport for @factory.
652 gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
653 GstRTSPLowerTrans protocols)
655 GstRTSPMediaFactoryPrivate *priv;
657 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
659 priv = factory->priv;
661 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
662 priv->protocols = protocols;
663 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
667 * gst_rtsp_media_factory_get_protocols:
668 * @factory: a #GstRTSPMediaFactory
670 * Get the allowed protocols of @factory.
672 * Returns: a #GstRTSPLowerTrans
675 gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
677 GstRTSPMediaFactoryPrivate *priv;
678 GstRTSPLowerTrans res;
680 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
681 GST_RTSP_LOWER_TRANS_UNKNOWN);
683 priv = factory->priv;
685 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
686 res = priv->protocols;
687 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
693 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
695 return (media1 == media2);
699 media_unprepared (GstRTSPMedia * media, GWeakRef * ref)
701 GstRTSPMediaFactory *factory = g_weak_ref_get (ref);
702 GstRTSPMediaFactoryPrivate *priv;
707 priv = factory->priv;;
709 g_mutex_lock (&priv->medias_lock);
710 g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
711 g_mutex_unlock (&priv->medias_lock);
713 g_object_unref (factory);
717 weak_ref_new (gpointer obj)
719 GWeakRef *ref = g_slice_new (GWeakRef);
721 g_weak_ref_init (ref, obj);
726 weak_ref_free (GWeakRef * ref)
728 g_weak_ref_clear (ref);
729 g_slice_free (GWeakRef, ref);
733 * gst_rtsp_media_factory_construct:
734 * @factory: a #GstRTSPMediaFactory
737 * Construct the media object and create its streams. Implementations
738 * should create the needed gstreamer elements and add them to the result
739 * object. No state changes should be performed on them yet.
741 * One or more GstRTSPStream objects should be created from the result
742 * with gst_rtsp_media_create_stream ().
744 * After the media is constructed, it can be configured and then prepared
745 * with gst_rtsp_media_prepare ().
747 * Returns: (transfer full): a new #GstRTSPMedia if the media could be prepared.
750 gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
751 const GstRTSPUrl * url)
753 GstRTSPMediaFactoryPrivate *priv;
756 GstRTSPMediaFactoryClass *klass;
758 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
759 g_return_val_if_fail (url != NULL, NULL);
761 priv = factory->priv;;
762 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
764 /* convert the url to a key for the hashtable. NULL return or a NULL function
765 * will not cache anything for this factory. */
767 key = klass->gen_key (factory, url);
771 g_mutex_lock (&priv->medias_lock);
773 /* we have a key, see if we find a cached media */
774 media = g_hash_table_lookup (priv->medias, key);
776 g_object_ref (media);
781 /* nothing cached found, try to create one */
782 if (klass->construct) {
783 media = klass->construct (factory, url);
785 g_signal_emit (factory,
786 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
792 /* configure the media */
793 if (klass->configure)
794 klass->configure (factory, media);
796 g_signal_emit (factory,
797 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
800 /* check if we can cache this media */
801 if (gst_rtsp_media_is_shared (media)) {
802 /* insert in the hashtable, takes ownership of the key */
803 g_object_ref (media);
804 g_hash_table_insert (priv->medias, key, media);
807 if (!gst_rtsp_media_is_reusable (media)) {
808 /* when not reusable, connect to the unprepare signal to remove the item
809 * from our cache when it gets unprepared */
810 g_signal_connect_data (media, "unprepared",
811 (GCallback) media_unprepared, weak_ref_new (factory),
812 (GClosureNotify) weak_ref_free, 0);
816 g_mutex_unlock (&priv->medias_lock);
821 GST_INFO ("constructed media %p for url %s", media, url->abspath);
827 default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
830 const gchar *pre_query;
833 pre_query = url->query ? "?" : "";
834 query = url->query ? url->query : "";
837 g_strdup_printf ("%u%s%s%s", url->port, url->abspath, pre_query, query);
843 default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
845 GstRTSPMediaFactoryPrivate *priv = factory->priv;
847 GError *error = NULL;
849 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
850 /* we need a parse syntax */
851 if (priv->launch == NULL)
854 /* parse the user provided launch line */
855 element = gst_parse_launch (priv->launch, &error);
859 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
862 /* a recoverable error was encountered */
863 GST_WARNING ("recoverable parsing error: %s", error->message);
864 g_error_free (error);
871 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
872 g_critical ("no launch line specified");
877 g_critical ("could not parse launch syntax (%s): %s", priv->launch,
878 (error ? error->message : "unknown reason"));
879 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
881 g_error_free (error);
886 static GstRTSPMedia *
887 default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
890 GstElement *element, *pipeline;
891 GstRTSPMediaFactoryClass *klass;
893 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
895 if (!klass->create_pipeline)
898 element = gst_rtsp_media_factory_create_element (factory, url);
902 /* create a new empty media */
903 media = gst_rtsp_media_new (element);
905 gst_rtsp_media_collect_streams (media);
907 pipeline = klass->create_pipeline (factory, media);
908 if (pipeline == NULL)
916 g_critical ("no create_pipeline function");
921 g_critical ("could not create element");
926 g_critical ("can't create pipeline");
927 g_object_unref (media);
933 default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
935 GstElement *pipeline;
937 pipeline = gst_pipeline_new ("media-pipeline");
938 gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
944 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
946 GstRTSPMediaFactoryPrivate *priv = factory->priv;
947 gboolean shared, eos_shutdown;
949 GstRTSPLowerTrans protocols;
950 GstRTSPAddressPool *pool;
951 GstRTSPPermissions *perms;
953 /* configure the sharedness */
954 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
955 shared = priv->shared;
956 eos_shutdown = priv->eos_shutdown;
957 size = priv->buffer_size;
958 protocols = priv->protocols;
959 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
961 gst_rtsp_media_set_shared (media, shared);
962 gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
963 gst_rtsp_media_set_buffer_size (media, size);
964 gst_rtsp_media_set_protocols (media, protocols);
966 if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
967 gst_rtsp_media_set_address_pool (media, pool);
968 g_object_unref (pool);
970 if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
971 gst_rtsp_media_set_permissions (media, perms);
972 gst_rtsp_permissions_unref (perms);
977 * gst_rtsp_media_factory_create_element:
978 * @factory: a #GstRTSPMediaFactory
981 * Construct and return a #GstElement that is a #GstBin containing
982 * the elements to use for streaming the media.
984 * The bin should contain payloaders pay\%d for each stream. The default
985 * implementation of this function returns the bin created from the
988 * Returns: (transfer floating) a new #GstElement.
991 gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
992 const GstRTSPUrl * url)
994 GstRTSPMediaFactoryClass *klass;
997 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
998 g_return_val_if_fail (url != NULL, NULL);
1000 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1002 if (klass->create_element)
1003 result = klass->create_element (factory, url);