2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
3 * Copyright (C) 2015 Centricular Ltd
4 * Author: Sebastian Dröge <sebastian@centricular.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 * SECTION:rtsp-media-factory
23 * @short_description: A factory for media pipelines
24 * @see_also: #GstRTSPMountPoints, #GstRTSPMedia
26 * The #GstRTSPMediaFactory is responsible for creating or recycling
27 * #GstRTSPMedia objects based on the passed URL.
29 * The default implementation of the object can create #GstRTSPMedia objects
30 * containing a pipeline created from a launch description set with
31 * gst_rtsp_media_factory_set_launch().
33 * Media from a factory can be shared by setting the shared flag with
34 * gst_rtsp_media_factory_set_shared(). When a factory is shared,
35 * gst_rtsp_media_factory_construct() will return the same #GstRTSPMedia when
38 * Last reviewed on 2013-07-11 (1.0.0)
41 #include "rtsp-media-factory.h"
43 #define GST_RTSP_MEDIA_FACTORY_GET_PRIVATE(obj) \
44 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY, GstRTSPMediaFactoryPrivate))
46 #define GST_RTSP_MEDIA_FACTORY_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_CAST(f)->priv->lock))
47 #define GST_RTSP_MEDIA_FACTORY_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
48 #define GST_RTSP_MEDIA_FACTORY_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
50 struct _GstRTSPMediaFactoryPrivate
52 GMutex lock; /* protects everything but medias */
53 GstRTSPPermissions *permissions;
56 GstRTSPSuspendMode suspend_mode;
57 gboolean eos_shutdown;
58 GstRTSPProfile profiles;
59 GstRTSPLowerTrans protocols;
61 GstRTSPAddressPool *pool;
62 GstRTSPTransportMode transport_mode;
64 GstClockTime rtx_time;
68 GHashTable *medias; /* protected by medias_lock */
73 #define DEFAULT_LAUNCH NULL
74 #define DEFAULT_SHARED FALSE
75 #define DEFAULT_SUSPEND_MODE GST_RTSP_SUSPEND_MODE_NONE
76 #define DEFAULT_EOS_SHUTDOWN FALSE
77 #define DEFAULT_PROFILES GST_RTSP_PROFILE_AVP
78 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
79 GST_RTSP_LOWER_TRANS_TCP
80 #define DEFAULT_BUFFER_SIZE 0x80000
81 #define DEFAULT_LATENCY 200
82 #define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY
101 SIGNAL_MEDIA_CONSTRUCTED,
102 SIGNAL_MEDIA_CONFIGURE,
106 GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
107 #define GST_CAT_DEFAULT rtsp_media_debug
109 static guint gst_rtsp_media_factory_signals[SIGNAL_LAST] = { 0 };
111 static void gst_rtsp_media_factory_get_property (GObject * object, guint propid,
112 GValue * value, GParamSpec * pspec);
113 static void gst_rtsp_media_factory_set_property (GObject * object, guint propid,
114 const GValue * value, GParamSpec * pspec);
115 static void gst_rtsp_media_factory_finalize (GObject * obj);
117 static gchar *default_gen_key (GstRTSPMediaFactory * factory,
118 const GstRTSPUrl * url);
119 static GstElement *default_create_element (GstRTSPMediaFactory * factory,
120 const GstRTSPUrl * url);
121 static GstRTSPMedia *default_construct (GstRTSPMediaFactory * factory,
122 const GstRTSPUrl * url);
123 static void default_configure (GstRTSPMediaFactory * factory,
124 GstRTSPMedia * media);
125 static GstElement *default_create_pipeline (GstRTSPMediaFactory * factory,
126 GstRTSPMedia * media);
128 G_DEFINE_TYPE (GstRTSPMediaFactory, gst_rtsp_media_factory, G_TYPE_OBJECT);
131 gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
133 GObjectClass *gobject_class;
135 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryPrivate));
137 gobject_class = G_OBJECT_CLASS (klass);
139 gobject_class->get_property = gst_rtsp_media_factory_get_property;
140 gobject_class->set_property = gst_rtsp_media_factory_set_property;
141 gobject_class->finalize = gst_rtsp_media_factory_finalize;
144 * GstRTSPMediaFactory::launch:
146 * The gst_parse_launch() line to use for constructing the pipeline in the
147 * default prepare vmethod.
149 * The pipeline description should return a GstBin as the toplevel element
150 * which can be accomplished by enclosing the dscription with brackets '('
153 * The description should return a pipeline with payloaders named pay0, pay1,
154 * etc.. Each of the payloaders will result in a stream.
156 * Support for dynamic payloaders can be accomplished by adding payloaders
157 * named dynpay0, dynpay1, etc..
159 g_object_class_install_property (gobject_class, PROP_LAUNCH,
160 g_param_spec_string ("launch", "Launch",
161 "A launch description of the pipeline", DEFAULT_LAUNCH,
162 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
164 g_object_class_install_property (gobject_class, PROP_SHARED,
165 g_param_spec_boolean ("shared", "Shared",
166 "If media from this factory is shared", DEFAULT_SHARED,
167 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
169 g_object_class_install_property (gobject_class, PROP_SUSPEND_MODE,
170 g_param_spec_enum ("suspend-mode", "Suspend Mode",
171 "Control how media will be suspended", GST_TYPE_RTSP_SUSPEND_MODE,
172 DEFAULT_SUSPEND_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
174 g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
175 g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
176 "Send EOS down the pipeline before shutting down",
177 DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
179 g_object_class_install_property (gobject_class, PROP_PROFILES,
180 g_param_spec_flags ("profiles", "Profiles",
181 "Allowed transfer profiles", GST_TYPE_RTSP_PROFILE,
182 DEFAULT_PROFILES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
184 g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
185 g_param_spec_flags ("protocols", "Protocols",
186 "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
187 DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
189 g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
190 g_param_spec_uint ("buffer-size", "Buffer Size",
191 "The kernel UDP buffer size to use", 0, G_MAXUINT,
192 DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
194 g_object_class_install_property (gobject_class, PROP_LATENCY,
195 g_param_spec_uint ("latency", "Latency",
196 "Latency used for receiving media in milliseconds", 0, G_MAXUINT,
197 DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
199 g_object_class_install_property (gobject_class, PROP_TRANSPORT_MODE,
200 g_param_spec_flags ("transport-mode", "Transport Mode",
201 "If media from this factory is for PLAY or RECORD",
202 GST_TYPE_RTSP_TRANSPORT_MODE, DEFAULT_TRANSPORT_MODE,
203 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
205 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
206 g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
207 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
208 media_constructed), NULL, NULL, g_cclosure_marshal_generic,
209 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
211 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE] =
212 g_signal_new ("media-configure", G_TYPE_FROM_CLASS (klass),
213 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
214 media_configure), NULL, NULL, g_cclosure_marshal_generic,
215 G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
217 klass->gen_key = default_gen_key;
218 klass->create_element = default_create_element;
219 klass->construct = default_construct;
220 klass->configure = default_configure;
221 klass->create_pipeline = default_create_pipeline;
223 GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmediafactory", 0,
224 "GstRTSPMediaFactory");
228 gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
230 GstRTSPMediaFactoryPrivate *priv =
231 GST_RTSP_MEDIA_FACTORY_GET_PRIVATE (factory);
232 factory->priv = priv;
234 priv->launch = g_strdup (DEFAULT_LAUNCH);
235 priv->shared = DEFAULT_SHARED;
236 priv->suspend_mode = DEFAULT_SUSPEND_MODE;
237 priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
238 priv->profiles = DEFAULT_PROFILES;
239 priv->protocols = DEFAULT_PROTOCOLS;
240 priv->buffer_size = DEFAULT_BUFFER_SIZE;
241 priv->latency = DEFAULT_LATENCY;
242 priv->transport_mode = DEFAULT_TRANSPORT_MODE;
244 g_mutex_init (&priv->lock);
245 g_mutex_init (&priv->medias_lock);
246 priv->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
247 g_free, g_object_unref);
248 priv->media_gtype = GST_TYPE_RTSP_MEDIA;
252 gst_rtsp_media_factory_finalize (GObject * obj)
254 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
255 GstRTSPMediaFactoryPrivate *priv = factory->priv;
257 if (priv->permissions)
258 gst_rtsp_permissions_unref (priv->permissions);
259 g_hash_table_unref (priv->medias);
260 g_mutex_clear (&priv->medias_lock);
261 g_free (priv->launch);
262 g_mutex_clear (&priv->lock);
264 g_object_unref (priv->pool);
266 G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
270 gst_rtsp_media_factory_get_property (GObject * object, guint propid,
271 GValue * value, GParamSpec * pspec)
273 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
277 g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
280 g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
282 case PROP_SUSPEND_MODE:
283 g_value_set_enum (value,
284 gst_rtsp_media_factory_get_suspend_mode (factory));
286 case PROP_EOS_SHUTDOWN:
287 g_value_set_boolean (value,
288 gst_rtsp_media_factory_is_eos_shutdown (factory));
291 g_value_set_flags (value, gst_rtsp_media_factory_get_profiles (factory));
294 g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
296 case PROP_BUFFER_SIZE:
297 g_value_set_uint (value,
298 gst_rtsp_media_factory_get_buffer_size (factory));
301 g_value_set_uint (value, gst_rtsp_media_factory_get_latency (factory));
303 case PROP_TRANSPORT_MODE:
304 g_value_set_flags (value,
305 gst_rtsp_media_factory_get_transport_mode (factory));
308 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
313 gst_rtsp_media_factory_set_property (GObject * object, guint propid,
314 const GValue * value, GParamSpec * pspec)
316 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
320 gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
323 gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
325 case PROP_SUSPEND_MODE:
326 gst_rtsp_media_factory_set_suspend_mode (factory,
327 g_value_get_enum (value));
329 case PROP_EOS_SHUTDOWN:
330 gst_rtsp_media_factory_set_eos_shutdown (factory,
331 g_value_get_boolean (value));
334 gst_rtsp_media_factory_set_profiles (factory, g_value_get_flags (value));
337 gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
339 case PROP_BUFFER_SIZE:
340 gst_rtsp_media_factory_set_buffer_size (factory,
341 g_value_get_uint (value));
344 gst_rtsp_media_factory_set_latency (factory, g_value_get_uint (value));
346 case PROP_TRANSPORT_MODE:
347 gst_rtsp_media_factory_set_transport_mode (factory,
348 g_value_get_flags (value));
351 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
356 * gst_rtsp_media_factory_new:
358 * Create a new #GstRTSPMediaFactory instance.
360 * Returns: (transfer full): a new #GstRTSPMediaFactory object.
362 GstRTSPMediaFactory *
363 gst_rtsp_media_factory_new (void)
365 GstRTSPMediaFactory *result;
367 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
373 * gst_rtsp_media_factory_set_permissions:
374 * @factory: a #GstRTSPMediaFactory
375 * @permissions: (transfer none): a #GstRTSPPermissions
377 * Set @permissions on @factory.
380 gst_rtsp_media_factory_set_permissions (GstRTSPMediaFactory * factory,
381 GstRTSPPermissions * permissions)
383 GstRTSPMediaFactoryPrivate *priv;
385 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
387 priv = factory->priv;
389 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
390 if (priv->permissions)
391 gst_rtsp_permissions_unref (priv->permissions);
392 if ((priv->permissions = permissions))
393 gst_rtsp_permissions_ref (permissions);
394 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
398 * gst_rtsp_media_factory_get_permissions:
399 * @factory: a #GstRTSPMediaFactory
401 * Get the permissions object from @factory.
403 * Returns: (transfer full): a #GstRTSPPermissions object, unref after usage.
406 gst_rtsp_media_factory_get_permissions (GstRTSPMediaFactory * factory)
408 GstRTSPMediaFactoryPrivate *priv;
409 GstRTSPPermissions *result;
411 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
413 priv = factory->priv;
415 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
416 if ((result = priv->permissions))
417 gst_rtsp_permissions_ref (result);
418 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
424 * gst_rtsp_media_factory_add_role:
425 * @factory: a #GstRTSPMediaFactory
427 * @fieldname: the first field name
428 * @...: additional arguments
430 * A convenience method to add @role with @fieldname and additional arguments to
431 * the permissions of @factory. If @factory had no permissions, new permissions
432 * will be created and the role will be added to it.
435 gst_rtsp_media_factory_add_role (GstRTSPMediaFactory * factory,
436 const gchar * role, const gchar * fieldname, ...)
438 GstRTSPMediaFactoryPrivate *priv;
441 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
442 g_return_if_fail (role != NULL);
443 g_return_if_fail (fieldname != NULL);
445 priv = factory->priv;
447 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
448 if (priv->permissions == NULL)
449 priv->permissions = gst_rtsp_permissions_new ();
451 va_start (var_args, fieldname);
452 gst_rtsp_permissions_add_role_valist (priv->permissions, role, fieldname,
455 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
459 * gst_rtsp_media_factory_set_launch:
460 * @factory: a #GstRTSPMediaFactory
461 * @launch: the launch description
464 * The gst_parse_launch() line to use for constructing the pipeline in the
465 * default prepare vmethod.
467 * The pipeline description should return a GstBin as the toplevel element
468 * which can be accomplished by enclosing the dscription with brackets '('
471 * The description should return a pipeline with payloaders named pay0, pay1,
472 * etc.. Each of the payloaders will result in a stream.
475 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
476 const gchar * launch)
478 GstRTSPMediaFactoryPrivate *priv;
480 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
481 g_return_if_fail (launch != NULL);
483 priv = factory->priv;
485 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
486 g_free (priv->launch);
487 priv->launch = g_strdup (launch);
488 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
492 * gst_rtsp_media_factory_get_launch:
493 * @factory: a #GstRTSPMediaFactory
495 * Get the gst_parse_launch() pipeline description that will be used in the
496 * default prepare vmethod.
498 * Returns: (transfer full): the configured launch description. g_free() after
502 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
504 GstRTSPMediaFactoryPrivate *priv;
507 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
509 priv = factory->priv;
511 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
512 result = g_strdup (priv->launch);
513 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
519 * gst_rtsp_media_factory_set_suspend_mode:
520 * @factory: a #GstRTSPMediaFactory
521 * @mode: the new #GstRTSPSuspendMode
523 * Configure how media created from this factory will be suspended.
526 gst_rtsp_media_factory_set_suspend_mode (GstRTSPMediaFactory * factory,
527 GstRTSPSuspendMode mode)
529 GstRTSPMediaFactoryPrivate *priv;
531 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
533 priv = factory->priv;
535 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
536 priv->suspend_mode = mode;
537 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
541 * gst_rtsp_media_factory_get_suspend_mode:
542 * @factory: a #GstRTSPMediaFactory
544 * Get how media created from this factory will be suspended.
546 * Returns: a #GstRTSPSuspendMode.
549 gst_rtsp_media_factory_get_suspend_mode (GstRTSPMediaFactory * factory)
551 GstRTSPMediaFactoryPrivate *priv;
552 GstRTSPSuspendMode result;
554 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
555 GST_RTSP_SUSPEND_MODE_NONE);
557 priv = factory->priv;
559 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
560 result = priv->suspend_mode;
561 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
567 * gst_rtsp_media_factory_set_shared:
568 * @factory: a #GstRTSPMediaFactory
569 * @shared: the new value
571 * Configure if media created from this factory can be shared between clients.
574 gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
577 GstRTSPMediaFactoryPrivate *priv;
579 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
581 priv = factory->priv;
583 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
584 priv->shared = shared;
585 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
589 * gst_rtsp_media_factory_is_shared:
590 * @factory: a #GstRTSPMediaFactory
592 * Get if media created from this factory can be shared between clients.
594 * Returns: %TRUE if the media will be shared between clients.
597 gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
599 GstRTSPMediaFactoryPrivate *priv;
602 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
604 priv = factory->priv;
606 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
607 result = priv->shared;
608 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
614 * gst_rtsp_media_factory_set_eos_shutdown:
615 * @factory: a #GstRTSPMediaFactory
616 * @eos_shutdown: the new value
618 * Configure if media created from this factory will have an EOS sent to the
619 * pipeline before shutdown.
622 gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
623 gboolean eos_shutdown)
625 GstRTSPMediaFactoryPrivate *priv;
627 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
629 priv = factory->priv;
631 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
632 priv->eos_shutdown = eos_shutdown;
633 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
637 * gst_rtsp_media_factory_is_eos_shutdown:
638 * @factory: a #GstRTSPMediaFactory
640 * Get if media created from this factory will have an EOS event sent to the
641 * pipeline before shutdown.
643 * Returns: %TRUE if the media will receive EOS before shutdown.
646 gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
648 GstRTSPMediaFactoryPrivate *priv;
651 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
653 priv = factory->priv;
655 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
656 result = priv->eos_shutdown;
657 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
663 * gst_rtsp_media_factory_set_buffer_size:
664 * @factory: a #GstRTSPMedia
665 * @size: the new value
667 * Set the kernel UDP buffer size.
670 gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
673 GstRTSPMediaFactoryPrivate *priv;
675 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
677 priv = factory->priv;
679 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
680 priv->buffer_size = size;
681 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
685 * gst_rtsp_media_factory_get_buffer_size:
686 * @factory: a #GstRTSPMedia
688 * Get the kernel UDP buffer size.
690 * Returns: the kernel UDP buffer size.
693 gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
695 GstRTSPMediaFactoryPrivate *priv;
698 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
700 priv = factory->priv;
702 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
703 result = priv->buffer_size;
704 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
710 * gst_rtsp_media_factory_set_address_pool:
711 * @factory: a #GstRTSPMediaFactory
712 * @pool: (transfer none): a #GstRTSPAddressPool
714 * configure @pool to be used as the address pool of @factory.
717 gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
718 GstRTSPAddressPool * pool)
720 GstRTSPMediaFactoryPrivate *priv;
721 GstRTSPAddressPool *old;
723 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
725 priv = factory->priv;
727 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
728 if ((old = priv->pool) != pool)
729 priv->pool = pool ? g_object_ref (pool) : NULL;
732 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
735 g_object_unref (old);
739 * gst_rtsp_media_factory_get_address_pool:
740 * @factory: a #GstRTSPMediaFactory
742 * Get the #GstRTSPAddressPool used as the address pool of @factory.
744 * Returns: (transfer full): the #GstRTSPAddressPool of @factory. g_object_unref() after
748 gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
750 GstRTSPMediaFactoryPrivate *priv;
751 GstRTSPAddressPool *result;
753 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
755 priv = factory->priv;
757 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
758 if ((result = priv->pool))
759 g_object_ref (result);
760 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
766 * gst_rtsp_media_factory_set_profiles:
767 * @factory: a #GstRTSPMediaFactory
768 * @profiles: the new flags
770 * Configure the allowed profiles for @factory.
773 gst_rtsp_media_factory_set_profiles (GstRTSPMediaFactory * factory,
774 GstRTSPProfile profiles)
776 GstRTSPMediaFactoryPrivate *priv;
778 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
780 priv = factory->priv;
782 GST_DEBUG_OBJECT (factory, "profiles %d", profiles);
784 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
785 priv->profiles = profiles;
786 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
790 * gst_rtsp_media_factory_get_profiles:
791 * @factory: a #GstRTSPMediaFactory
793 * Get the allowed profiles of @factory.
795 * Returns: a #GstRTSPProfile
798 gst_rtsp_media_factory_get_profiles (GstRTSPMediaFactory * factory)
800 GstRTSPMediaFactoryPrivate *priv;
803 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
804 GST_RTSP_PROFILE_UNKNOWN);
806 priv = factory->priv;
808 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
809 res = priv->profiles;
810 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
816 * gst_rtsp_media_factory_set_protocols:
817 * @factory: a #GstRTSPMediaFactory
818 * @protocols: the new flags
820 * Configure the allowed lower transport for @factory.
823 gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
824 GstRTSPLowerTrans protocols)
826 GstRTSPMediaFactoryPrivate *priv;
828 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
830 priv = factory->priv;
832 GST_DEBUG_OBJECT (factory, "protocols %d", protocols);
834 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
835 priv->protocols = protocols;
836 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
840 * gst_rtsp_media_factory_get_protocols:
841 * @factory: a #GstRTSPMediaFactory
843 * Get the allowed protocols of @factory.
845 * Returns: a #GstRTSPLowerTrans
848 gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
850 GstRTSPMediaFactoryPrivate *priv;
851 GstRTSPLowerTrans res;
853 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
854 GST_RTSP_LOWER_TRANS_UNKNOWN);
856 priv = factory->priv;
858 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
859 res = priv->protocols;
860 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
866 * gst_rtsp_media_factory_set_retransmission_time:
867 * @factory: a #GstRTSPMediaFactory
868 * @time: a #GstClockTime
870 * Configure the time to store for possible retransmission
873 gst_rtsp_media_factory_set_retransmission_time (GstRTSPMediaFactory * factory,
876 GstRTSPMediaFactoryPrivate *priv;
878 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
880 priv = factory->priv;
882 GST_DEBUG_OBJECT (factory, "retransmission time %" G_GUINT64_FORMAT, time);
884 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
885 priv->rtx_time = time;
886 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
890 * gst_rtsp_media_factory_get_retransmission_time:
891 * @factory: a #GstRTSPMediaFactory
893 * Get the time that is stored for retransmission purposes
895 * Returns: a #GstClockTime
898 gst_rtsp_media_factory_get_retransmission_time (GstRTSPMediaFactory * factory)
900 GstRTSPMediaFactoryPrivate *priv;
903 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
905 priv = factory->priv;
907 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
908 res = priv->rtx_time;
909 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
915 * gst_rtsp_media_factory_set_latency:
916 * @factory: a #GstRTSPMediaFactory
917 * @latency: latency in milliseconds
919 * Configure the latency used for receiving media
922 gst_rtsp_media_factory_set_latency (GstRTSPMediaFactory * factory,
925 GstRTSPMediaFactoryPrivate *priv;
927 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
929 priv = factory->priv;
931 GST_DEBUG_OBJECT (factory, "latency %ums", latency);
933 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
934 priv->latency = latency;
935 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
939 * gst_rtsp_media_factory_get_latency:
940 * @factory: a #GstRTSPMediaFactory
942 * Get the latency that is used for receiving media
944 * Returns: latency in milliseconds
947 gst_rtsp_media_factory_get_latency (GstRTSPMediaFactory * factory)
949 GstRTSPMediaFactoryPrivate *priv;
952 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
954 priv = factory->priv;
956 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
958 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
964 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
966 return (media1 == media2);
970 media_unprepared (GstRTSPMedia * media, GWeakRef * ref)
972 GstRTSPMediaFactory *factory = g_weak_ref_get (ref);
973 GstRTSPMediaFactoryPrivate *priv;
978 priv = factory->priv;;
980 g_mutex_lock (&priv->medias_lock);
981 g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
982 g_mutex_unlock (&priv->medias_lock);
984 g_object_unref (factory);
988 weak_ref_new (gpointer obj)
990 GWeakRef *ref = g_slice_new (GWeakRef);
992 g_weak_ref_init (ref, obj);
997 weak_ref_free (GWeakRef * ref)
999 g_weak_ref_clear (ref);
1000 g_slice_free (GWeakRef, ref);
1004 * gst_rtsp_media_factory_construct:
1005 * @factory: a #GstRTSPMediaFactory
1006 * @url: the url used
1008 * Construct the media object and create its streams. Implementations
1009 * should create the needed gstreamer elements and add them to the result
1010 * object. No state changes should be performed on them yet.
1012 * One or more GstRTSPStream objects should be created from the result
1013 * with gst_rtsp_media_create_stream ().
1015 * After the media is constructed, it can be configured and then prepared
1016 * with gst_rtsp_media_prepare ().
1018 * Returns: (transfer full): a new #GstRTSPMedia if the media could be prepared.
1021 gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
1022 const GstRTSPUrl * url)
1024 GstRTSPMediaFactoryPrivate *priv;
1026 GstRTSPMedia *media;
1027 GstRTSPMediaFactoryClass *klass;
1029 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
1030 g_return_val_if_fail (url != NULL, NULL);
1032 priv = factory->priv;;
1033 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1035 /* convert the url to a key for the hashtable. NULL return or a NULL function
1036 * will not cache anything for this factory. */
1038 key = klass->gen_key (factory, url);
1042 g_mutex_lock (&priv->medias_lock);
1044 /* we have a key, see if we find a cached media */
1045 media = g_hash_table_lookup (priv->medias, key);
1047 g_object_ref (media);
1051 if (media == NULL) {
1052 /* nothing cached found, try to create one */
1053 if (klass->construct) {
1054 media = klass->construct (factory, url);
1056 g_signal_emit (factory,
1057 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
1063 /* configure the media */
1064 if (klass->configure)
1065 klass->configure (factory, media);
1067 g_signal_emit (factory,
1068 gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
1071 /* check if we can cache this media */
1072 if (gst_rtsp_media_is_shared (media)) {
1073 /* insert in the hashtable, takes ownership of the key */
1074 g_object_ref (media);
1075 g_hash_table_insert (priv->medias, key, media);
1078 if (!gst_rtsp_media_is_reusable (media)) {
1079 /* when not reusable, connect to the unprepare signal to remove the item
1080 * from our cache when it gets unprepared */
1081 g_signal_connect_data (media, "unprepared",
1082 (GCallback) media_unprepared, weak_ref_new (factory),
1083 (GClosureNotify) weak_ref_free, 0);
1087 g_mutex_unlock (&priv->medias_lock);
1092 GST_INFO ("constructed media %p for url %s", media, url->abspath);
1098 * gst_rtsp_media_factory_set_media_gtype:
1099 * @factory: a #GstRTSPMediaFactory
1100 * @media_gtype: the GType of the class to create
1102 * Configure the GType of the GstRTSPMedia subclass to
1103 * create (by default, overridden construct vmethods
1104 * may of course do something different)
1109 gst_rtsp_media_factory_set_media_gtype (GstRTSPMediaFactory * factory,
1112 GstRTSPMediaFactoryPrivate *priv;
1114 g_return_if_fail (g_type_is_a (media_gtype, GST_TYPE_RTSP_MEDIA));
1116 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1117 priv = factory->priv;
1118 priv->media_gtype = media_gtype;
1119 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1123 * gst_rtsp_media_factory_get_media_gtype:
1124 * @factory: a #GstRTSPMediaFactory
1126 * Return the GType of the GstRTSPMedia subclass this
1127 * factory will create.
1132 gst_rtsp_media_factory_get_media_gtype (GstRTSPMediaFactory * factory)
1134 GstRTSPMediaFactoryPrivate *priv;
1137 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1138 priv = factory->priv;
1139 ret = priv->media_gtype;
1140 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1146 default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
1149 const gchar *pre_query;
1152 pre_query = url->query ? "?" : "";
1153 query = url->query ? url->query : "";
1156 g_strdup_printf ("%u%s%s%s", url->port, url->abspath, pre_query, query);
1162 default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
1164 GstRTSPMediaFactoryPrivate *priv = factory->priv;
1165 GstElement *element;
1166 GError *error = NULL;
1168 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1169 /* we need a parse syntax */
1170 if (priv->launch == NULL)
1173 /* parse the user provided launch line */
1174 element = gst_parse_launch (priv->launch, &error);
1175 if (element == NULL)
1178 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1180 if (error != NULL) {
1181 /* a recoverable error was encountered */
1182 GST_WARNING ("recoverable parsing error: %s", error->message);
1183 g_error_free (error);
1190 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1191 g_critical ("no launch line specified");
1196 g_critical ("could not parse launch syntax (%s): %s", priv->launch,
1197 (error ? error->message : "unknown reason"));
1198 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1200 g_error_free (error);
1205 static GstRTSPMedia *
1206 default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
1208 GstRTSPMedia *media;
1209 GstElement *element, *pipeline;
1210 GstRTSPMediaFactoryClass *klass;
1213 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1215 if (!klass->create_pipeline)
1218 element = gst_rtsp_media_factory_create_element (factory, url);
1219 if (element == NULL)
1222 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1223 media_gtype = factory->priv->media_gtype;
1224 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1226 /* create a new empty media */
1227 media = g_object_new (media_gtype, "element", element, NULL);
1229 gst_rtsp_media_collect_streams (media);
1231 pipeline = klass->create_pipeline (factory, media);
1232 if (pipeline == NULL)
1240 g_critical ("no create_pipeline function");
1245 g_critical ("could not create element");
1250 g_critical ("can't create pipeline");
1251 g_object_unref (media);
1257 default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1259 GstElement *pipeline;
1261 pipeline = gst_pipeline_new ("media-pipeline");
1262 gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
1268 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1270 GstRTSPMediaFactoryPrivate *priv = factory->priv;
1271 gboolean shared, eos_shutdown;
1273 GstRTSPSuspendMode suspend_mode;
1274 GstRTSPProfile profiles;
1275 GstRTSPLowerTrans protocols;
1276 GstRTSPAddressPool *pool;
1277 GstRTSPPermissions *perms;
1278 GstClockTime rtx_time;
1280 GstRTSPTransportMode transport_mode;
1282 /* configure the sharedness */
1283 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1284 suspend_mode = priv->suspend_mode;
1285 shared = priv->shared;
1286 eos_shutdown = priv->eos_shutdown;
1287 size = priv->buffer_size;
1288 profiles = priv->profiles;
1289 protocols = priv->protocols;
1290 rtx_time = priv->rtx_time;
1291 latency = priv->latency;
1292 transport_mode = priv->transport_mode;
1293 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1295 gst_rtsp_media_set_suspend_mode (media, suspend_mode);
1296 gst_rtsp_media_set_shared (media, shared);
1297 gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
1298 gst_rtsp_media_set_buffer_size (media, size);
1299 gst_rtsp_media_set_profiles (media, profiles);
1300 gst_rtsp_media_set_protocols (media, protocols);
1301 gst_rtsp_media_set_retransmission_time (media, rtx_time);
1302 gst_rtsp_media_set_latency (media, latency);
1303 gst_rtsp_media_set_transport_mode (media, transport_mode);
1305 if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
1306 gst_rtsp_media_set_address_pool (media, pool);
1307 g_object_unref (pool);
1309 if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
1310 gst_rtsp_media_set_permissions (media, perms);
1311 gst_rtsp_permissions_unref (perms);
1316 * gst_rtsp_media_factory_create_element:
1317 * @factory: a #GstRTSPMediaFactory
1318 * @url: the url used
1320 * Construct and return a #GstElement that is a #GstBin containing
1321 * the elements to use for streaming the media.
1323 * The bin should contain payloaders pay\%d for each stream. The default
1324 * implementation of this function returns the bin created from the
1327 * Returns: (transfer floating): a new #GstElement.
1330 gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
1331 const GstRTSPUrl * url)
1333 GstRTSPMediaFactoryClass *klass;
1336 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
1337 g_return_val_if_fail (url != NULL, NULL);
1339 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1341 if (klass->create_element)
1342 result = klass->create_element (factory, url);
1350 * gst_rtsp_media_factory_set_transport_mode:
1351 * @factory: a #GstRTSPMediaFactory
1352 * @mode: the new value
1354 * Configure if this factory creates media for PLAY or RECORD modes.
1357 gst_rtsp_media_factory_set_transport_mode (GstRTSPMediaFactory * factory,
1358 GstRTSPTransportMode mode)
1360 GstRTSPMediaFactoryPrivate *priv;
1362 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1364 priv = factory->priv;
1366 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1367 priv->transport_mode = mode;
1368 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1372 * gst_rtsp_media_factory_get_transport_mode:
1373 * @factory: a #GstRTSPMediaFactory
1375 * Get if media created from this factory can be used for PLAY or RECORD
1378 * Returns: The supported transport modes.
1380 GstRTSPTransportMode
1381 gst_rtsp_media_factory_get_transport_mode (GstRTSPMediaFactory * factory)
1383 GstRTSPMediaFactoryPrivate *priv;
1384 GstRTSPTransportMode result;
1386 g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
1388 priv = factory->priv;
1390 GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1391 result = priv->transport_mode;
1392 GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);