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 #include "rtsp-media-factory.h"
22 #define GST_RTSP_MEDIA_FACTORY_GET_PRIVATE(obj) \
23 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY, GstRTSPMediaFactoryPrivate))
25 #define GST_RTSP_MEDIA_FACTORY_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_CAST(f)->priv->lock))
26 #define GST_RTSP_MEDIA_FACTORY_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
27 #define GST_RTSP_MEDIA_FACTORY_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
29 struct _GstRTSPMediaFactoryPrivate
31 GMutex lock; /* protects everything but medias */
32 GstRTSPPermissions *permissions;
35 gboolean eos_shutdown;
36 GstRTSPLowerTrans protocols;
38 GstRTSPAddressPool *pool;
41 GHashTable *medias; /* protected by medias_lock */
44 #define DEFAULT_LAUNCH NULL
45 #define DEFAULT_SHARED FALSE
46 #define DEFAULT_EOS_SHUTDOWN FALSE
47 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_TCP
48 #define DEFAULT_BUFFER_SIZE 0x80000
63 SIGNAL_MEDIA_CONSTRUCTED,
64 SIGNAL_MEDIA_CONFIGURE,
68 GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
69 #define GST_CAT_DEFAULT rtsp_media_debug
71 static guint gst_rtsp_media_factory_signals[SIGNAL_LAST] = { 0 };
73 static void gst_rtsp_media_factory_get_property (GObject * object, guint propid,
74 GValue * value, GParamSpec * pspec);
75 static void gst_rtsp_media_factory_set_property (GObject * object, guint propid,
76 const GValue * value, GParamSpec * pspec);
77 static void gst_rtsp_media_factory_finalize (GObject * obj);
79 static gchar *default_gen_key (GstRTSPMediaFactory * factory,
80 const GstRTSPUrl * url);
81 static GstElement *default_create_element (GstRTSPMediaFactory * factory,
82 const GstRTSPUrl * url);
83 static GstRTSPMedia *default_construct (GstRTSPMediaFactory * factory,
84 const GstRTSPUrl * url);
85 static void default_configure (GstRTSPMediaFactory * factory,
86 GstRTSPMedia * media);
87 static GstElement *default_create_pipeline (GstRTSPMediaFactory * factory,
88 GstRTSPMedia * media);
90 G_DEFINE_TYPE (GstRTSPMediaFactory, gst_rtsp_media_factory, G_TYPE_OBJECT);
93 gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
95 GObjectClass *gobject_class;
97 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryPrivate));
99 gobject_class = G_OBJECT_CLASS (klass);
101 gobject_class->get_property = gst_rtsp_media_factory_get_property;
102 gobject_class->set_property = gst_rtsp_media_factory_set_property;
103 gobject_class->finalize = gst_rtsp_media_factory_finalize;
106 * GstRTSPMediaFactory::launch:
108 * The gst_parse_launch() line to use for constructing the pipeline in the
109 * default prepare vmethod.
111 * The pipeline description should return a GstBin as the toplevel element
112 * which can be accomplished by enclosing the dscription with brackets '('
115 * The description should return a pipeline with payloaders named pay0, pay1,
116 * etc.. Each of the payloaders will result in a stream.
118 * Support for dynamic payloaders can be accomplished by adding payloaders
119 * named dynpay0, dynpay1, etc..
121 g_object_class_install_property (gobject_class, PROP_LAUNCH,
122 g_param_spec_string ("launch", "Launch",
123 "A launch description of the pipeline", DEFAULT_LAUNCH,
124 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
126 g_object_class_install_property (gobject_class, PROP_SHARED,
127 g_param_spec_boolean ("shared", "Shared",
128 "If media from this factory is shared", DEFAULT_SHARED,
129 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
131 g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
132 g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
133 "Send EOS down the pipeline before shutting down",
134 DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
136 g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
137 g_param_spec_flags ("protocols", "Protocols",
138 "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
139 DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
141 g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
142 g_param_spec_uint ("buffer-size", "Buffer Size",
143 "The kernel UDP buffer size to use", 0, G_MAXUINT,
144 DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
147 g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
148 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
149 media_constructed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
150 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
152 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE] =
153 g_signal_new ("media-configure", G_TYPE_FROM_CLASS (klass),
154 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
155 media_configure), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
156 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
158 klass->gen_key = default_gen_key;
159 klass->create_element = default_create_element;
160 klass->construct = default_construct;
161 klass->configure = default_configure;
162 klass->create_pipeline = default_create_pipeline;
164 GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmediafactory", 0,
165 "GstRTSPMediaFactory");
169 gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
171 GstRTSPMediaFactoryPrivate *priv =
172 GST_RTSP_MEDIA_FACTORY_GET_PRIVATE (factory);
173 factory->priv = priv;
175 priv->launch = g_strdup (DEFAULT_LAUNCH);
176 priv->shared = DEFAULT_SHARED;
177 priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
178 priv->protocols = DEFAULT_PROTOCOLS;
179 priv->buffer_size = DEFAULT_BUFFER_SIZE;
181 g_mutex_init (&priv->lock);
182 g_mutex_init (&priv->medias_lock);
183 priv->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
184 g_free, g_object_unref);
188 gst_rtsp_media_factory_finalize (GObject * obj)
190 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
191 GstRTSPMediaFactoryPrivate *priv = factory->priv;
193 g_hash_table_unref (priv->medias);
194 g_mutex_clear (&priv->medias_lock);
195 g_free (priv->launch);
196 g_mutex_clear (&priv->lock);
198 g_object_unref (priv->pool);
200 G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
204 gst_rtsp_media_factory_get_property (GObject * object, guint propid,
205 GValue * value, GParamSpec * pspec)
207 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
211 g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
214 g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
216 case PROP_EOS_SHUTDOWN:
217 g_value_set_boolean (value,
218 gst_rtsp_media_factory_is_eos_shutdown (factory));
221 g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
223 case PROP_BUFFER_SIZE:
224 g_value_set_uint (value,
225 gst_rtsp_media_factory_get_buffer_size (factory));
228 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
233 gst_rtsp_media_factory_set_property (GObject * object, guint propid,
234 const GValue * value, GParamSpec * pspec)
236 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
240 gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
243 gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
245 case PROP_EOS_SHUTDOWN:
246 gst_rtsp_media_factory_set_eos_shutdown (factory,
247 g_value_get_boolean (value));
250 gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
252 case PROP_BUFFER_SIZE:
253 gst_rtsp_media_factory_set_buffer_size (factory,
254 g_value_get_uint (value));
257 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
262 * gst_rtsp_media_factory_new:
264 * Create a new #GstRTSPMediaFactory instance.
266 * Returns: a new #GstRTSPMediaFactory object.
268 GstRTSPMediaFactory *
269 gst_rtsp_media_factory_new (void)
271 GstRTSPMediaFactory *result;
273 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
279 * gst_rtsp_media_factory_set_permissions:
280 * @factory: a #GstRTSPMediaFactory
281 * @permissions: a #GstRTSPPermissions
283 * Set @permissions on @factory.
286 gst_rtsp_media_factory_set_permissions (GstRTSPMediaFactory * factory,
287 GstRTSPPermissions * permissions)
289 GstRTSPMediaFactoryPrivate *priv;
291 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
293 priv = factory->priv;
295 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
296 if (priv->permissions)
297 gst_rtsp_permissions_unref (priv->permissions);
298 if ((priv->permissions = permissions))
299 gst_rtsp_permissions_ref (permissions);
300 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
304 * gst_rtsp_media_factory_get_permissions:
305 * @factory: a #GstRTSPMediaFactory
307 * Get the permissions object from @factory.
309 * Returns: (transfer full): a #GstRTSPPermissions object, unref after usage.
312 gst_rtsp_media_factory_get_permissions (GstRTSPMediaFactory * factory)
314 GstRTSPMediaFactoryPrivate *priv;
315 GstRTSPPermissions *result;
317 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
319 priv = factory->priv;
321 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
322 if ((result = priv->permissions))
323 gst_rtsp_permissions_ref (result);
324 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
330 * gst_rtsp_media_factory_set_launch:
331 * @factory: a #GstRTSPMediaFactory
332 * @launch: the launch description
335 * The gst_parse_launch() line to use for constructing the pipeline in the
336 * default prepare vmethod.
338 * The pipeline description should return a GstBin as the toplevel element
339 * which can be accomplished by enclosing the dscription with brackets '('
342 * The description should return a pipeline with payloaders named pay0, pay1,
343 * etc.. Each of the payloaders will result in a stream.
346 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
347 const gchar * launch)
349 GstRTSPMediaFactoryPrivate *priv;
351 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
352 g_return_if_fail (launch != NULL);
354 priv = factory->priv;
356 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
357 g_free (priv->launch);
358 priv->launch = g_strdup (launch);
359 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
363 * gst_rtsp_media_factory_get_launch:
364 * @factory: a #GstRTSPMediaFactory
366 * Get the gst_parse_launch() pipeline description that will be used in the
367 * default prepare vmethod.
369 * Returns: the configured launch description. g_free() after usage.
372 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
374 GstRTSPMediaFactoryPrivate *priv;
377 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
379 priv = factory->priv;
381 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
382 result = g_strdup (priv->launch);
383 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
389 * gst_rtsp_media_factory_set_shared:
390 * @factory: a #GstRTSPMediaFactory
391 * @shared: the new value
393 * Configure if media created from this factory can be shared between clients.
396 gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
399 GstRTSPMediaFactoryPrivate *priv;
401 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
403 priv = factory->priv;
405 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
406 priv->shared = shared;
407 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
411 * gst_rtsp_media_factory_is_shared:
412 * @factory: a #GstRTSPMediaFactory
414 * Get if media created from this factory can be shared between clients.
416 * Returns: %TRUE if the media will be shared between clients.
419 gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
421 GstRTSPMediaFactoryPrivate *priv;
424 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
426 priv = factory->priv;
428 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
429 result = priv->shared;
430 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
436 * gst_rtsp_media_factory_set_eos_shutdown:
437 * @factory: a #GstRTSPMediaFactory
438 * @eos_shutdown: the new value
440 * Configure if media created from this factory will have an EOS sent to the
441 * pipeline before shutdown.
444 gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
445 gboolean eos_shutdown)
447 GstRTSPMediaFactoryPrivate *priv;
449 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
451 priv = factory->priv;
453 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
454 priv->eos_shutdown = eos_shutdown;
455 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
459 * gst_rtsp_media_factory_is_eos_shutdown:
460 * @factory: a #GstRTSPMediaFactory
462 * Get if media created from this factory will have an EOS event sent to the
463 * pipeline before shutdown.
465 * Returns: %TRUE if the media will receive EOS before shutdown.
468 gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
470 GstRTSPMediaFactoryPrivate *priv;
473 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
475 priv = factory->priv;
477 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
478 result = priv->eos_shutdown;
479 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
485 * gst_rtsp_media_factory_set_buffer_size:
486 * @factory: a #GstRTSPMedia
487 * @size: the new value
489 * Set the kernel UDP buffer size.
492 gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
495 GstRTSPMediaFactoryPrivate *priv;
497 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
499 priv = factory->priv;
501 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
502 priv->buffer_size = size;
503 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
507 * gst_rtsp_media_factory_get_buffer_size:
508 * @factory: a #GstRTSPMedia
510 * Get the kernel UDP buffer size.
512 * Returns: the kernel UDP buffer size.
515 gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
517 GstRTSPMediaFactoryPrivate *priv;
520 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
522 priv = factory->priv;
524 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
525 result = priv->buffer_size;
526 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
532 * gst_rtsp_media_factory_set_address_pool:
533 * @factory: a #GstRTSPMediaFactory
534 * @pool: a #GstRTSPAddressPool
536 * configure @pool to be used as the address pool of @factory.
539 gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
540 GstRTSPAddressPool * pool)
542 GstRTSPMediaFactoryPrivate *priv;
543 GstRTSPAddressPool *old;
545 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
547 priv = factory->priv;
549 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
550 if ((old = priv->pool) != pool)
551 priv->pool = pool ? g_object_ref (pool) : NULL;
554 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
557 g_object_unref (old);
561 * gst_rtsp_media_factory_get_address_pool:
562 * @factory: a #GstRTSPMediaFactory
564 * Get the #GstRTSPAddressPool used as the address pool of @factory.
566 * Returns: (transfer full): the #GstRTSPAddressPool of @factory. g_object_unref() after
570 gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
572 GstRTSPMediaFactoryPrivate *priv;
573 GstRTSPAddressPool *result;
575 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
577 priv = factory->priv;
579 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
580 if ((result = priv->pool))
581 g_object_ref (result);
582 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
588 * gst_rtsp_media_factory_set_protocols:
589 * @factory: a #GstRTSPMediaFactory
590 * @protocols: the new flags
592 * Configure the allowed lower transport for @factory.
595 gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
596 GstRTSPLowerTrans protocols)
598 GstRTSPMediaFactoryPrivate *priv;
600 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
602 priv = factory->priv;
604 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
605 priv->protocols = protocols;
606 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
610 * gst_rtsp_media_factory_get_protocols:
611 * @factory: a #GstRTSPMediaFactory
613 * Get the allowed protocols of @factory.
615 * Returns: a #GstRTSPLowerTrans
618 gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
620 GstRTSPMediaFactoryPrivate *priv;
621 GstRTSPLowerTrans res;
623 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
624 GST_RTSP_LOWER_TRANS_UNKNOWN);
626 priv = factory->priv;
628 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
629 res = priv->protocols;
630 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
636 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
638 return (media1 == media2);
642 media_unprepared (GstRTSPMedia * media, GWeakRef * ref)
644 GstRTSPMediaFactory *factory = g_weak_ref_get (ref);
645 GstRTSPMediaFactoryPrivate *priv;
650 priv = factory->priv;;
652 g_mutex_lock (&priv->medias_lock);
653 g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
654 g_mutex_unlock (&priv->medias_lock);
656 g_object_unref (factory);
660 weak_ref_new (gpointer obj)
662 GWeakRef *ref = g_slice_new (GWeakRef);
664 g_weak_ref_init (ref, obj);
669 weak_ref_free (GWeakRef * ref)
671 g_weak_ref_clear (ref);
672 g_slice_free (GWeakRef, ref);
676 * gst_rtsp_media_factory_construct:
677 * @factory: a #GstRTSPMediaFactory
680 * Construct the media object and create its streams. Implementations
681 * should create the needed gstreamer elements and add them to the result
682 * object. No state changes should be performed on them yet.
684 * One or more GstRTSPStream objects should be created from the result
685 * with gst_rtsp_media_create_stream ().
687 * After the media is constructed, it can be configured and then prepared
688 * with gst_rtsp_media_prepare ().
690 * Returns: (transfer full): a new #GstRTSPMedia if the media could be prepared.
693 gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
694 const GstRTSPUrl * url)
696 GstRTSPMediaFactoryPrivate *priv;
699 GstRTSPMediaFactoryClass *klass;
701 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
702 g_return_val_if_fail (url != NULL, NULL);
704 priv = factory->priv;;
705 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
707 /* convert the url to a key for the hashtable. NULL return or a NULL function
708 * will not cache anything for this factory. */
710 key = klass->gen_key (factory, url);
714 g_mutex_lock (&priv->medias_lock);
716 /* we have a key, see if we find a cached media */
717 media = g_hash_table_lookup (priv->medias, key);
719 g_object_ref (media);
724 /* nothing cached found, try to create one */
725 if (klass->construct) {
726 media = klass->construct (factory, url);
728 g_signal_emit (factory,
729 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
735 /* configure the media */
736 if (klass->configure)
737 klass->configure (factory, media);
739 g_signal_emit (factory,
740 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
743 /* check if we can cache this media */
744 if (gst_rtsp_media_is_shared (media)) {
745 /* insert in the hashtable, takes ownership of the key */
746 g_object_ref (media);
747 g_hash_table_insert (priv->medias, key, media);
750 if (!gst_rtsp_media_is_reusable (media)) {
751 /* when not reusable, connect to the unprepare signal to remove the item
752 * from our cache when it gets unprepared */
753 g_signal_connect_data (media, "unprepared",
754 (GCallback) media_unprepared, weak_ref_new (factory),
755 (GClosureNotify) weak_ref_free, 0);
759 g_mutex_unlock (&priv->medias_lock);
764 GST_INFO ("constructed media %p for url %s", media, url->abspath);
770 default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
773 const gchar *pre_query;
776 pre_query = url->query ? "?" : "";
777 query = url->query ? url->query : "";
780 g_strdup_printf ("%u%s%s%s", url->port, url->abspath, pre_query, query);
786 default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
788 GstRTSPMediaFactoryPrivate *priv = factory->priv;
790 GError *error = NULL;
792 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
793 /* we need a parse syntax */
794 if (priv->launch == NULL)
797 /* parse the user provided launch line */
798 element = gst_parse_launch (priv->launch, &error);
802 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
805 /* a recoverable error was encountered */
806 GST_WARNING ("recoverable parsing error: %s", error->message);
807 g_error_free (error);
814 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
815 g_critical ("no launch line specified");
820 g_critical ("could not parse launch syntax (%s): %s", priv->launch,
821 (error ? error->message : "unknown reason"));
822 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
824 g_error_free (error);
829 static GstRTSPMedia *
830 default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
833 GstElement *element, *pipeline;
834 GstRTSPMediaFactoryClass *klass;
836 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
838 if (!klass->create_pipeline)
841 element = gst_rtsp_media_factory_create_element (factory, url);
845 /* create a new empty media */
846 media = gst_rtsp_media_new (element);
848 gst_rtsp_media_collect_streams (media);
850 pipeline = klass->create_pipeline (factory, media);
851 if (pipeline == NULL)
859 g_critical ("no create_pipeline function");
864 g_critical ("could not create element");
869 g_critical ("can't create pipeline");
870 g_object_unref (media);
876 default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
878 GstElement *pipeline;
880 pipeline = gst_pipeline_new ("media-pipeline");
881 gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
887 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
889 GstRTSPMediaFactoryPrivate *priv = factory->priv;
890 gboolean shared, eos_shutdown;
892 GstRTSPLowerTrans protocols;
893 GstRTSPAddressPool *pool;
894 GstRTSPPermissions *perms;
896 /* configure the sharedness */
897 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
898 shared = priv->shared;
899 eos_shutdown = priv->eos_shutdown;
900 size = priv->buffer_size;
901 protocols = priv->protocols;
902 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
904 gst_rtsp_media_set_shared (media, shared);
905 gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
906 gst_rtsp_media_set_buffer_size (media, size);
907 gst_rtsp_media_set_protocols (media, protocols);
909 if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
910 gst_rtsp_media_set_address_pool (media, pool);
911 g_object_unref (pool);
913 if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
914 gst_rtsp_media_set_permissions (media, perms);
915 gst_rtsp_permissions_unref (perms);
920 * gst_rtsp_media_factory_create_element:
921 * @factory: a #GstRTSPMediaFactory
924 * Construct and return a #GstElement that is a #GstBin containing
925 * the elements to use for streaming the media.
927 * The bin should contain payloaders pay%d for each stream. The default
928 * implementation of this function returns the bin created from the
931 * Returns: (transfer floating) a new #GstElement.
934 gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
935 const GstRTSPUrl * url)
937 GstRTSPMediaFactoryClass *klass;
940 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
941 g_return_val_if_fail (url != NULL, NULL);
943 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
945 if (klass->create_element)
946 result = klass->create_element (factory, url);