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 */
34 gboolean eos_shutdown;
35 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->auth);
200 g_object_unref (priv->pool);
202 G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
206 gst_rtsp_media_factory_get_property (GObject * object, guint propid,
207 GValue * value, GParamSpec * pspec)
209 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
213 g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
216 g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
218 case PROP_EOS_SHUTDOWN:
219 g_value_set_boolean (value,
220 gst_rtsp_media_factory_is_eos_shutdown (factory));
223 g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
225 case PROP_BUFFER_SIZE:
226 g_value_set_uint (value,
227 gst_rtsp_media_factory_get_buffer_size (factory));
230 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
235 gst_rtsp_media_factory_set_property (GObject * object, guint propid,
236 const GValue * value, GParamSpec * pspec)
238 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
242 gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
245 gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
247 case PROP_EOS_SHUTDOWN:
248 gst_rtsp_media_factory_set_eos_shutdown (factory,
249 g_value_get_boolean (value));
252 gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
254 case PROP_BUFFER_SIZE:
255 gst_rtsp_media_factory_set_buffer_size (factory,
256 g_value_get_uint (value));
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
264 * gst_rtsp_media_factory_new:
266 * Create a new #GstRTSPMediaFactory instance.
268 * Returns: a new #GstRTSPMediaFactory object.
270 GstRTSPMediaFactory *
271 gst_rtsp_media_factory_new (void)
273 GstRTSPMediaFactory *result;
275 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
281 * gst_rtsp_media_factory_set_launch:
282 * @factory: a #GstRTSPMediaFactory
283 * @launch: the launch description
286 * The gst_parse_launch() line to use for constructing the pipeline in the
287 * default prepare vmethod.
289 * The pipeline description should return a GstBin as the toplevel element
290 * which can be accomplished by enclosing the dscription with brackets '('
293 * The description should return a pipeline with payloaders named pay0, pay1,
294 * etc.. Each of the payloaders will result in a stream.
297 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
298 const gchar * launch)
300 GstRTSPMediaFactoryPrivate *priv;
302 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
303 g_return_if_fail (launch != NULL);
305 priv = factory->priv;
307 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
308 g_free (priv->launch);
309 priv->launch = g_strdup (launch);
310 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
314 * gst_rtsp_media_factory_get_launch:
315 * @factory: a #GstRTSPMediaFactory
317 * Get the gst_parse_launch() pipeline description that will be used in the
318 * default prepare vmethod.
320 * Returns: the configured launch description. g_free() after usage.
323 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
325 GstRTSPMediaFactoryPrivate *priv;
328 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
330 priv = factory->priv;
332 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
333 result = g_strdup (priv->launch);
334 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
340 * gst_rtsp_media_factory_set_shared:
341 * @factory: a #GstRTSPMediaFactory
342 * @shared: the new value
344 * Configure if media created from this factory can be shared between clients.
347 gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
350 GstRTSPMediaFactoryPrivate *priv;
352 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
354 priv = factory->priv;
356 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
357 priv->shared = shared;
358 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
362 * gst_rtsp_media_factory_is_shared:
363 * @factory: a #GstRTSPMediaFactory
365 * Get if media created from this factory can be shared between clients.
367 * Returns: %TRUE if the media will be shared between clients.
370 gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
372 GstRTSPMediaFactoryPrivate *priv;
375 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
377 priv = factory->priv;
379 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
380 result = priv->shared;
381 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
387 * gst_rtsp_media_factory_set_eos_shutdown:
388 * @factory: a #GstRTSPMediaFactory
389 * @eos_shutdown: the new value
391 * Configure if media created from this factory will have an EOS sent to the
392 * pipeline before shutdown.
395 gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
396 gboolean eos_shutdown)
398 GstRTSPMediaFactoryPrivate *priv;
400 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
402 priv = factory->priv;
404 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
405 priv->eos_shutdown = eos_shutdown;
406 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
410 * gst_rtsp_media_factory_is_eos_shutdown:
411 * @factory: a #GstRTSPMediaFactory
413 * Get if media created from this factory will have an EOS event sent to the
414 * pipeline before shutdown.
416 * Returns: %TRUE if the media will receive EOS before shutdown.
419 gst_rtsp_media_factory_is_eos_shutdown (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->eos_shutdown;
430 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
436 * gst_rtsp_media_factory_set_buffer_size:
437 * @factory: a #GstRTSPMedia
438 * @size: the new value
440 * Set the kernel UDP buffer size.
443 gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
446 GstRTSPMediaFactoryPrivate *priv;
448 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
450 priv = factory->priv;
452 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
453 priv->buffer_size = size;
454 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
458 * gst_rtsp_media_factory_get_buffer_size:
459 * @factory: a #GstRTSPMedia
461 * Get the kernel UDP buffer size.
463 * Returns: the kernel UDP buffer size.
466 gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
468 GstRTSPMediaFactoryPrivate *priv;
471 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
473 priv = factory->priv;
475 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
476 result = priv->buffer_size;
477 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
483 * gst_rtsp_media_factory_set_address_pool:
484 * @factory: a #GstRTSPMediaFactory
485 * @pool: a #GstRTSPAddressPool
487 * configure @pool to be used as the address pool of @factory.
490 gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
491 GstRTSPAddressPool * pool)
493 GstRTSPMediaFactoryPrivate *priv;
494 GstRTSPAddressPool *old;
496 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
498 priv = factory->priv;
500 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
501 if ((old = priv->pool) != pool)
502 priv->pool = pool ? g_object_ref (pool) : NULL;
505 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
508 g_object_unref (old);
512 * gst_rtsp_media_factory_get_address_pool:
513 * @factory: a #GstRTSPMediaFactory
515 * Get the #GstRTSPAddressPool used as the address pool of @factory.
517 * Returns: (transfer full): the #GstRTSPAddressPool of @factory. g_object_unref() after
521 gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
523 GstRTSPMediaFactoryPrivate *priv;
524 GstRTSPAddressPool *result;
526 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
528 priv = factory->priv;
530 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
531 if ((result = priv->pool))
532 g_object_ref (result);
533 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
539 * gst_rtsp_media_factory_set_auth:
540 * @factory: a #GstRTSPMediaFactory
541 * @auth: a #GstRTSPAuth
543 * configure @auth to be used as the authentication manager of @factory.
546 gst_rtsp_media_factory_set_auth (GstRTSPMediaFactory * factory,
549 GstRTSPMediaFactoryPrivate *priv;
552 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
554 priv = factory->priv;
556 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
557 if ((old = priv->auth) != auth)
558 priv->auth = auth ? g_object_ref (auth) : NULL;
561 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
564 g_object_unref (old);
568 * gst_rtsp_media_factory_get_auth:
569 * @factory: a #GstRTSPMediaFactory
571 * Get the #GstRTSPAuth used as the authentication manager of @factory.
573 * Returns: (transfer full): the #GstRTSPAuth of @factory. g_object_unref() after
577 gst_rtsp_media_factory_get_auth (GstRTSPMediaFactory * factory)
579 GstRTSPMediaFactoryPrivate *priv;
582 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
584 priv = factory->priv;
586 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
587 if ((result = priv->auth))
588 g_object_ref (result);
589 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
595 * gst_rtsp_media_factory_set_protocols:
596 * @factory: a #GstRTSPMediaFactory
597 * @protocols: the new flags
599 * Configure the allowed lower transport for @factory.
602 gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
603 GstRTSPLowerTrans protocols)
605 GstRTSPMediaFactoryPrivate *priv;
607 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
609 priv = factory->priv;
611 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
612 priv->protocols = protocols;
613 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
617 * gst_rtsp_media_factory_get_protocols:
618 * @factory: a #GstRTSPMediaFactory
620 * Get the allowed protocols of @factory.
622 * Returns: a #GstRTSPLowerTrans
625 gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
627 GstRTSPMediaFactoryPrivate *priv;
628 GstRTSPLowerTrans res;
630 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
631 GST_RTSP_LOWER_TRANS_UNKNOWN);
633 priv = factory->priv;
635 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
636 res = priv->protocols;
637 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
643 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
645 return (media1 == media2);
649 media_unprepared (GstRTSPMedia * media, GWeakRef * ref)
651 GstRTSPMediaFactory *factory = g_weak_ref_get (ref);
652 GstRTSPMediaFactoryPrivate *priv;
657 priv = factory->priv;;
659 g_mutex_lock (&priv->medias_lock);
660 g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
661 g_mutex_unlock (&priv->medias_lock);
663 g_object_unref (factory);
667 weak_ref_new (gpointer obj)
669 GWeakRef *ref = g_slice_new (GWeakRef);
671 g_weak_ref_init (ref, obj);
676 weak_ref_free (GWeakRef * ref)
678 g_weak_ref_clear (ref);
679 g_slice_free (GWeakRef, ref);
683 * gst_rtsp_media_factory_construct:
684 * @factory: a #GstRTSPMediaFactory
687 * Construct the media object and create its streams. Implementations
688 * should create the needed gstreamer elements and add them to the result
689 * object. No state changes should be performed on them yet.
691 * One or more GstRTSPStream objects should be created from the result
692 * with gst_rtsp_media_create_stream ().
694 * After the media is constructed, it can be configured and then prepared
695 * with gst_rtsp_media_prepare ().
697 * Returns: (transfer full): a new #GstRTSPMedia if the media could be prepared.
700 gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
701 const GstRTSPUrl * url)
703 GstRTSPMediaFactoryPrivate *priv;
706 GstRTSPMediaFactoryClass *klass;
708 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
709 g_return_val_if_fail (url != NULL, NULL);
711 priv = factory->priv;;
712 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
714 /* convert the url to a key for the hashtable. NULL return or a NULL function
715 * will not cache anything for this factory. */
717 key = klass->gen_key (factory, url);
721 g_mutex_lock (&priv->medias_lock);
723 /* we have a key, see if we find a cached media */
724 media = g_hash_table_lookup (priv->medias, key);
726 g_object_ref (media);
731 /* nothing cached found, try to create one */
732 if (klass->construct) {
733 media = klass->construct (factory, url);
735 g_signal_emit (factory,
736 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
742 /* configure the media */
743 if (klass->configure)
744 klass->configure (factory, media);
746 g_signal_emit (factory,
747 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
750 /* check if we can cache this media */
751 if (gst_rtsp_media_is_shared (media)) {
752 /* insert in the hashtable, takes ownership of the key */
753 g_object_ref (media);
754 g_hash_table_insert (priv->medias, key, media);
757 if (!gst_rtsp_media_is_reusable (media)) {
758 /* when not reusable, connect to the unprepare signal to remove the item
759 * from our cache when it gets unprepared */
760 g_signal_connect_data (media, "unprepared",
761 (GCallback) media_unprepared, weak_ref_new (factory),
762 (GClosureNotify) weak_ref_free, 0);
766 g_mutex_unlock (&priv->medias_lock);
771 GST_INFO ("constructed media %p for url %s", media, url->abspath);
777 default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
780 const gchar *pre_query;
783 pre_query = url->query ? "?" : "";
784 query = url->query ? url->query : "";
787 g_strdup_printf ("%u%s%s%s", url->port, url->abspath, pre_query, query);
793 default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
795 GstRTSPMediaFactoryPrivate *priv = factory->priv;
797 GError *error = NULL;
799 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
800 /* we need a parse syntax */
801 if (priv->launch == NULL)
804 /* parse the user provided launch line */
805 element = gst_parse_launch (priv->launch, &error);
809 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
812 /* a recoverable error was encountered */
813 GST_WARNING ("recoverable parsing error: %s", error->message);
814 g_error_free (error);
821 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
822 g_critical ("no launch line specified");
827 g_critical ("could not parse launch syntax (%s): %s", priv->launch,
828 (error ? error->message : "unknown reason"));
829 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
831 g_error_free (error);
836 static GstRTSPMedia *
837 default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
840 GstElement *element, *pipeline;
841 GstRTSPMediaFactoryClass *klass;
843 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
845 if (!klass->create_pipeline)
848 element = gst_rtsp_media_factory_create_element (factory, url);
852 /* create a new empty media */
853 media = gst_rtsp_media_new (element);
855 gst_rtsp_media_collect_streams (media);
857 pipeline = klass->create_pipeline (factory, media);
858 if (pipeline == NULL)
866 g_critical ("no create_pipeline function");
871 g_critical ("could not create element");
876 g_critical ("can't create pipeline");
877 g_object_unref (media);
883 default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
885 GstElement *pipeline;
887 pipeline = gst_pipeline_new ("media-pipeline");
888 gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
894 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
896 GstRTSPMediaFactoryPrivate *priv = factory->priv;
897 gboolean shared, eos_shutdown;
900 GstRTSPLowerTrans protocols;
901 GstRTSPAddressPool *pool;
903 /* configure the sharedness */
904 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
905 shared = priv->shared;
906 eos_shutdown = priv->eos_shutdown;
907 size = priv->buffer_size;
908 protocols = priv->protocols;
909 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
911 gst_rtsp_media_set_shared (media, shared);
912 gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
913 gst_rtsp_media_set_buffer_size (media, size);
914 gst_rtsp_media_set_protocols (media, protocols);
916 if ((auth = gst_rtsp_media_factory_get_auth (factory))) {
917 gst_rtsp_media_set_auth (media, auth);
918 g_object_unref (auth);
920 if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
921 gst_rtsp_media_set_address_pool (media, pool);
922 g_object_unref (pool);
927 * gst_rtsp_media_factory_create_element:
928 * @factory: a #GstRTSPMediaFactory
931 * Construct and return a #GstElement that is a #GstBin containing
932 * the elements to use for streaming the media.
934 * The bin should contain payloaders pay%d for each stream. The default
935 * implementation of this function returns the bin created from the
938 * Returns: (transfer floating) a new #GstElement.
941 gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
942 const GstRTSPUrl * url)
944 GstRTSPMediaFactoryClass *klass;
947 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
948 g_return_val_if_fail (url != NULL, NULL);
950 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
952 if (klass->create_element)
953 result = klass->create_element (factory, url);