5dd9dc0a1b9dcbff796ee243cdec63b2f6421adb
[platform/upstream/gstreamer.git] / subprojects / gst-rtsp-server / gst / rtsp-server / rtsp-media-factory.c
1 /* GStreamer
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>
5  *
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.
10  *
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.
15  *
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.
20  */
21 /**
22  * SECTION:rtsp-media-factory
23  * @short_description: A factory for media pipelines
24  * @see_also: #GstRTSPMountPoints, #GstRTSPMedia
25  *
26  * The #GstRTSPMediaFactory is responsible for creating or recycling
27  * #GstRTSPMedia objects based on the passed URL.
28  *
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().
32  *
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
36  * the url matches.
37  *
38  * Last reviewed on 2013-07-11 (1.0.0)
39  */
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44 #include "rtsp-server-internal.h"
45 #include "rtsp-media-factory.h"
46
47 #define GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)       (&(GST_RTSP_MEDIA_FACTORY_CAST(f)->priv->lock))
48 #define GST_RTSP_MEDIA_FACTORY_LOCK(f)           (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
49 #define GST_RTSP_MEDIA_FACTORY_UNLOCK(f)         (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_GET_LOCK(f)))
50
51 struct _GstRTSPMediaFactoryPrivate
52 {
53   GMutex lock;                  /* protects everything but medias */
54   GstRTSPPermissions *permissions;
55   gchar *launch;
56   gboolean shared;
57   GstRTSPSuspendMode suspend_mode;
58   gboolean eos_shutdown;
59   GstRTSPProfile profiles;
60   GstRTSPLowerTrans protocols;
61   guint buffer_size;
62   gint dscp_qos;
63   GstRTSPAddressPool *pool;
64   GstRTSPTransportMode transport_mode;
65   gboolean stop_on_disconnect;
66   gchar *multicast_iface;
67   guint max_mcast_ttl;
68   gboolean bind_mcast_address;
69   gboolean enable_rtcp;
70
71   GstClockTime rtx_time;
72   guint latency;
73   gboolean do_retransmission;
74
75   GMutex medias_lock;
76   GHashTable *medias;           /* protected by medias_lock */
77
78   GType media_gtype;
79
80   GstClock *clock;
81
82   GstRTSPPublishClockMode publish_clock_mode;
83 };
84
85 #define DEFAULT_LAUNCH          NULL
86 #define DEFAULT_SHARED          FALSE
87 #define DEFAULT_SUSPEND_MODE    GST_RTSP_SUSPEND_MODE_NONE
88 #define DEFAULT_EOS_SHUTDOWN    FALSE
89 #define DEFAULT_PROFILES        GST_RTSP_PROFILE_AVP
90 #define DEFAULT_PROTOCOLS       GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
91                                         GST_RTSP_LOWER_TRANS_TCP
92 #define DEFAULT_BUFFER_SIZE     0x80000
93 #define DEFAULT_LATENCY         200
94 #define DEFAULT_MAX_MCAST_TTL   255
95 #define DEFAULT_BIND_MCAST_ADDRESS FALSE
96 #define DEFAULT_TRANSPORT_MODE  GST_RTSP_TRANSPORT_MODE_PLAY
97 #define DEFAULT_STOP_ON_DISCONNECT TRUE
98 #define DEFAULT_DO_RETRANSMISSION FALSE
99 #define DEFAULT_DSCP_QOS        (-1)
100 #define DEFAULT_ENABLE_RTCP     TRUE
101
102 enum
103 {
104   PROP_0,
105   PROP_LAUNCH,
106   PROP_SHARED,
107   PROP_SUSPEND_MODE,
108   PROP_EOS_SHUTDOWN,
109   PROP_PROFILES,
110   PROP_PROTOCOLS,
111   PROP_BUFFER_SIZE,
112   PROP_LATENCY,
113   PROP_TRANSPORT_MODE,
114   PROP_STOP_ON_DISCONNECT,
115   PROP_CLOCK,
116   PROP_MAX_MCAST_TTL,
117   PROP_BIND_MCAST_ADDRESS,
118   PROP_DSCP_QOS,
119   PROP_ENABLE_RTCP,
120   PROP_LAST
121 };
122
123 enum
124 {
125   SIGNAL_MEDIA_CONSTRUCTED,
126   SIGNAL_MEDIA_CONFIGURE,
127   SIGNAL_LAST
128 };
129
130 GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
131 #define GST_CAT_DEFAULT rtsp_media_debug
132
133 static guint gst_rtsp_media_factory_signals[SIGNAL_LAST] = { 0 };
134
135 static void gst_rtsp_media_factory_get_property (GObject * object, guint propid,
136     GValue * value, GParamSpec * pspec);
137 static void gst_rtsp_media_factory_set_property (GObject * object, guint propid,
138     const GValue * value, GParamSpec * pspec);
139 static void gst_rtsp_media_factory_finalize (GObject * obj);
140
141 static gchar *default_gen_key (GstRTSPMediaFactory * factory,
142     const GstRTSPUrl * url);
143 static GstElement *default_create_element (GstRTSPMediaFactory * factory,
144     const GstRTSPUrl * url);
145 static GstRTSPMedia *default_construct (GstRTSPMediaFactory * factory,
146     const GstRTSPUrl * url);
147 static void default_configure (GstRTSPMediaFactory * factory,
148     GstRTSPMedia * media);
149 static GstElement *default_create_pipeline (GstRTSPMediaFactory * factory,
150     GstRTSPMedia * media);
151
152 G_DEFINE_TYPE_WITH_PRIVATE (GstRTSPMediaFactory, gst_rtsp_media_factory,
153     G_TYPE_OBJECT);
154
155 static void
156 gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
157 {
158   GObjectClass *gobject_class;
159
160   gobject_class = G_OBJECT_CLASS (klass);
161
162   gobject_class->get_property = gst_rtsp_media_factory_get_property;
163   gobject_class->set_property = gst_rtsp_media_factory_set_property;
164   gobject_class->finalize = gst_rtsp_media_factory_finalize;
165
166   /**
167    * GstRTSPMediaFactory::launch:
168    *
169    * The gst_parse_launch() line to use for constructing the pipeline in the
170    * default prepare vmethod.
171    *
172    * The pipeline description should return a GstBin as the toplevel element
173    * which can be accomplished by enclosing the description with brackets '('
174    * ')'.
175    *
176    * The description should return a pipeline with payloaders named pay0, pay1,
177    * etc.. Each of the payloaders will result in a stream.
178    *
179    * Support for dynamic payloaders can be accomplished by adding payloaders
180    * named dynpay0, dynpay1, etc..
181    */
182   g_object_class_install_property (gobject_class, PROP_LAUNCH,
183       g_param_spec_string ("launch", "Launch",
184           "A launch description of the pipeline", DEFAULT_LAUNCH,
185           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
186
187   g_object_class_install_property (gobject_class, PROP_SHARED,
188       g_param_spec_boolean ("shared", "Shared",
189           "If media from this factory is shared", DEFAULT_SHARED,
190           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
191
192   g_object_class_install_property (gobject_class, PROP_SUSPEND_MODE,
193       g_param_spec_enum ("suspend-mode", "Suspend Mode",
194           "Control how media will be suspended", GST_TYPE_RTSP_SUSPEND_MODE,
195           DEFAULT_SUSPEND_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
196
197   g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
198       g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
199           "Send EOS down the pipeline before shutting down",
200           DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
201
202   g_object_class_install_property (gobject_class, PROP_PROFILES,
203       g_param_spec_flags ("profiles", "Profiles",
204           "Allowed transfer profiles", GST_TYPE_RTSP_PROFILE,
205           DEFAULT_PROFILES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
206
207   g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
208       g_param_spec_flags ("protocols", "Protocols",
209           "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
210           DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
211
212   g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
213       g_param_spec_uint ("buffer-size", "Buffer Size",
214           "The kernel UDP buffer size to use", 0, G_MAXUINT,
215           DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
216
217   g_object_class_install_property (gobject_class, PROP_LATENCY,
218       g_param_spec_uint ("latency", "Latency",
219           "Latency used for receiving media in milliseconds", 0, G_MAXUINT,
220           DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
221
222   g_object_class_install_property (gobject_class, PROP_TRANSPORT_MODE,
223       g_param_spec_flags ("transport-mode", "Transport Mode",
224           "If media from this factory is for PLAY or RECORD",
225           GST_TYPE_RTSP_TRANSPORT_MODE, DEFAULT_TRANSPORT_MODE,
226           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
227
228   g_object_class_install_property (gobject_class, PROP_STOP_ON_DISCONNECT,
229       g_param_spec_boolean ("stop-on-disconnect", "Stop On Disconnect",
230           "If media from this factory should be stopped "
231           "when a client disconnects without TEARDOWN",
232           DEFAULT_STOP_ON_DISCONNECT,
233           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
234
235   g_object_class_install_property (gobject_class, PROP_CLOCK,
236       g_param_spec_object ("clock", "Clock",
237           "Clock to be used by the pipelines created for all "
238           "medias of this factory", GST_TYPE_CLOCK,
239           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
240
241   g_object_class_install_property (gobject_class, PROP_MAX_MCAST_TTL,
242       g_param_spec_uint ("max-mcast-ttl", "Maximum multicast ttl",
243           "The maximum time-to-live value of outgoing multicast packets", 1,
244           255, DEFAULT_MAX_MCAST_TTL,
245           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
246
247   g_object_class_install_property (gobject_class, PROP_BIND_MCAST_ADDRESS,
248       g_param_spec_boolean ("bind-mcast-address", "Bind mcast address",
249           "Whether the multicast sockets should be bound to multicast addresses "
250           "or INADDR_ANY",
251           DEFAULT_BIND_MCAST_ADDRESS,
252           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
253
254   /**
255    * GstRTSPMediaFactory:enable-rtcp:
256    *
257    * Whether the created media should send and receive RTCP
258    *
259    * Since: 1.20
260    */
261   g_object_class_install_property (gobject_class, PROP_ENABLE_RTCP,
262       g_param_spec_boolean ("enable-rtcp", "Enable RTCP",
263           "Whether the created media should send and receive RTCP",
264           DEFAULT_ENABLE_RTCP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
265
266   g_object_class_install_property (gobject_class, PROP_DSCP_QOS,
267       g_param_spec_int ("dscp-qos", "DSCP QoS",
268           "The IP DSCP field to use", -1, 63,
269           DEFAULT_DSCP_QOS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
270
271   gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
272       g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
273       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
274           media_constructed), NULL, NULL, NULL,
275       G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
276
277   gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE] =
278       g_signal_new ("media-configure", G_TYPE_FROM_CLASS (klass),
279       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
280           media_configure), NULL, NULL, NULL,
281       G_TYPE_NONE, 1, GST_TYPE_RTSP_MEDIA);
282
283   klass->gen_key = default_gen_key;
284   klass->create_element = default_create_element;
285   klass->construct = default_construct;
286   klass->configure = default_configure;
287   klass->create_pipeline = default_create_pipeline;
288
289   GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmediafactory", 0,
290       "GstRTSPMediaFactory");
291 }
292
293 static void
294 gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
295 {
296   GstRTSPMediaFactoryPrivate *priv =
297       gst_rtsp_media_factory_get_instance_private (factory);
298   factory->priv = priv;
299
300   priv->launch = g_strdup (DEFAULT_LAUNCH);
301   priv->shared = DEFAULT_SHARED;
302   priv->suspend_mode = DEFAULT_SUSPEND_MODE;
303   priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
304   priv->profiles = DEFAULT_PROFILES;
305   priv->protocols = DEFAULT_PROTOCOLS;
306   priv->buffer_size = DEFAULT_BUFFER_SIZE;
307   priv->latency = DEFAULT_LATENCY;
308   priv->transport_mode = DEFAULT_TRANSPORT_MODE;
309   priv->stop_on_disconnect = DEFAULT_STOP_ON_DISCONNECT;
310   priv->publish_clock_mode = GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK;
311   priv->do_retransmission = DEFAULT_DO_RETRANSMISSION;
312   priv->max_mcast_ttl = DEFAULT_MAX_MCAST_TTL;
313   priv->bind_mcast_address = DEFAULT_BIND_MCAST_ADDRESS;
314   priv->enable_rtcp = DEFAULT_ENABLE_RTCP;
315   priv->dscp_qos = DEFAULT_DSCP_QOS;
316
317   g_mutex_init (&priv->lock);
318   g_mutex_init (&priv->medias_lock);
319   priv->medias = g_hash_table_new_full (g_str_hash, g_str_equal,
320       g_free, g_object_unref);
321   priv->media_gtype = GST_TYPE_RTSP_MEDIA;
322 }
323
324 static void
325 gst_rtsp_media_factory_finalize (GObject * obj)
326 {
327   GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
328   GstRTSPMediaFactoryPrivate *priv = factory->priv;
329
330   if (priv->clock)
331     gst_object_unref (priv->clock);
332   if (priv->permissions)
333     gst_rtsp_permissions_unref (priv->permissions);
334   g_hash_table_unref (priv->medias);
335   g_mutex_clear (&priv->medias_lock);
336   g_free (priv->launch);
337   g_mutex_clear (&priv->lock);
338   if (priv->pool)
339     g_object_unref (priv->pool);
340   g_free (priv->multicast_iface);
341
342   G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
343 }
344
345 static void
346 gst_rtsp_media_factory_get_property (GObject * object, guint propid,
347     GValue * value, GParamSpec * pspec)
348 {
349   GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
350
351   switch (propid) {
352     case PROP_LAUNCH:
353       g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
354       break;
355     case PROP_SHARED:
356       g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
357       break;
358     case PROP_SUSPEND_MODE:
359       g_value_set_enum (value,
360           gst_rtsp_media_factory_get_suspend_mode (factory));
361       break;
362     case PROP_EOS_SHUTDOWN:
363       g_value_set_boolean (value,
364           gst_rtsp_media_factory_is_eos_shutdown (factory));
365       break;
366     case PROP_PROFILES:
367       g_value_set_flags (value, gst_rtsp_media_factory_get_profiles (factory));
368       break;
369     case PROP_PROTOCOLS:
370       g_value_set_flags (value, gst_rtsp_media_factory_get_protocols (factory));
371       break;
372     case PROP_BUFFER_SIZE:
373       g_value_set_uint (value,
374           gst_rtsp_media_factory_get_buffer_size (factory));
375       break;
376     case PROP_LATENCY:
377       g_value_set_uint (value, gst_rtsp_media_factory_get_latency (factory));
378       break;
379     case PROP_TRANSPORT_MODE:
380       g_value_set_flags (value,
381           gst_rtsp_media_factory_get_transport_mode (factory));
382       break;
383     case PROP_STOP_ON_DISCONNECT:
384       g_value_set_boolean (value,
385           gst_rtsp_media_factory_is_stop_on_disonnect (factory));
386       break;
387     case PROP_CLOCK:
388       g_value_take_object (value, gst_rtsp_media_factory_get_clock (factory));
389       break;
390     case PROP_MAX_MCAST_TTL:
391       g_value_set_uint (value,
392           gst_rtsp_media_factory_get_max_mcast_ttl (factory));
393       break;
394     case PROP_BIND_MCAST_ADDRESS:
395       g_value_set_boolean (value,
396           gst_rtsp_media_factory_is_bind_mcast_address (factory));
397       break;
398     case PROP_DSCP_QOS:
399       g_value_set_int (value, gst_rtsp_media_factory_get_dscp_qos (factory));
400       break;
401     case PROP_ENABLE_RTCP:
402       g_value_set_boolean (value,
403           gst_rtsp_media_factory_is_enable_rtcp (factory));
404       break;
405     default:
406       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
407   }
408 }
409
410 static void
411 gst_rtsp_media_factory_set_property (GObject * object, guint propid,
412     const GValue * value, GParamSpec * pspec)
413 {
414   GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
415
416   switch (propid) {
417     case PROP_LAUNCH:
418       gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
419       break;
420     case PROP_SHARED:
421       gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
422       break;
423     case PROP_SUSPEND_MODE:
424       gst_rtsp_media_factory_set_suspend_mode (factory,
425           g_value_get_enum (value));
426       break;
427     case PROP_EOS_SHUTDOWN:
428       gst_rtsp_media_factory_set_eos_shutdown (factory,
429           g_value_get_boolean (value));
430       break;
431     case PROP_PROFILES:
432       gst_rtsp_media_factory_set_profiles (factory, g_value_get_flags (value));
433       break;
434     case PROP_PROTOCOLS:
435       gst_rtsp_media_factory_set_protocols (factory, g_value_get_flags (value));
436       break;
437     case PROP_BUFFER_SIZE:
438       gst_rtsp_media_factory_set_buffer_size (factory,
439           g_value_get_uint (value));
440       break;
441     case PROP_LATENCY:
442       gst_rtsp_media_factory_set_latency (factory, g_value_get_uint (value));
443       break;
444     case PROP_TRANSPORT_MODE:
445       gst_rtsp_media_factory_set_transport_mode (factory,
446           g_value_get_flags (value));
447       break;
448     case PROP_STOP_ON_DISCONNECT:
449       gst_rtsp_media_factory_set_stop_on_disconnect (factory,
450           g_value_get_boolean (value));
451       break;
452     case PROP_CLOCK:
453       gst_rtsp_media_factory_set_clock (factory, g_value_get_object (value));
454       break;
455     case PROP_MAX_MCAST_TTL:
456       gst_rtsp_media_factory_set_max_mcast_ttl (factory,
457           g_value_get_uint (value));
458       break;
459     case PROP_BIND_MCAST_ADDRESS:
460       gst_rtsp_media_factory_set_bind_mcast_address (factory,
461           g_value_get_boolean (value));
462       break;
463     case PROP_DSCP_QOS:
464       gst_rtsp_media_factory_set_dscp_qos (factory, g_value_get_int (value));
465       break;
466     case PROP_ENABLE_RTCP:
467       gst_rtsp_media_factory_set_enable_rtcp (factory,
468           g_value_get_boolean (value));
469       break;
470     default:
471       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
472   }
473 }
474
475 /**
476  * gst_rtsp_media_factory_new:
477  *
478  * Create a new #GstRTSPMediaFactory instance.
479  *
480  * Returns: (transfer full): a new #GstRTSPMediaFactory object.
481  */
482 GstRTSPMediaFactory *
483 gst_rtsp_media_factory_new (void)
484 {
485   GstRTSPMediaFactory *result;
486
487   result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
488
489   return result;
490 }
491
492 /**
493  * gst_rtsp_media_factory_set_permissions:
494  * @factory: a #GstRTSPMediaFactory
495  * @permissions: (transfer none) (nullable): a #GstRTSPPermissions
496  *
497  * Set @permissions on @factory.
498  */
499 void
500 gst_rtsp_media_factory_set_permissions (GstRTSPMediaFactory * factory,
501     GstRTSPPermissions * permissions)
502 {
503   GstRTSPMediaFactoryPrivate *priv;
504
505   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
506
507   priv = factory->priv;
508
509   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
510   if (priv->permissions)
511     gst_rtsp_permissions_unref (priv->permissions);
512   if ((priv->permissions = permissions))
513     gst_rtsp_permissions_ref (permissions);
514   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
515 }
516
517 /**
518  * gst_rtsp_media_factory_get_permissions:
519  * @factory: a #GstRTSPMediaFactory
520  *
521  * Get the permissions object from @factory.
522  *
523  * Returns: (transfer full) (nullable): a #GstRTSPPermissions object, unref after usage.
524  */
525 GstRTSPPermissions *
526 gst_rtsp_media_factory_get_permissions (GstRTSPMediaFactory * factory)
527 {
528   GstRTSPMediaFactoryPrivate *priv;
529   GstRTSPPermissions *result;
530
531   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
532
533   priv = factory->priv;
534
535   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
536   if ((result = priv->permissions))
537     gst_rtsp_permissions_ref (result);
538   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
539
540   return result;
541 }
542
543 /**
544  * gst_rtsp_media_factory_add_role:
545  * @factory: a #GstRTSPMediaFactory
546  * @role: a role
547  * @fieldname: the first field name
548  * @...: additional arguments
549  *
550  * A convenience method to add @role with @fieldname and additional arguments to
551  * the permissions of @factory. If @factory had no permissions, new permissions
552  * will be created and the role will be added to it.
553  */
554 void
555 gst_rtsp_media_factory_add_role (GstRTSPMediaFactory * factory,
556     const gchar * role, const gchar * fieldname, ...)
557 {
558   GstRTSPMediaFactoryPrivate *priv;
559   va_list var_args;
560
561   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
562   g_return_if_fail (role != NULL);
563   g_return_if_fail (fieldname != NULL);
564
565   priv = factory->priv;
566
567   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
568   if (priv->permissions == NULL)
569     priv->permissions = gst_rtsp_permissions_new ();
570
571   va_start (var_args, fieldname);
572   gst_rtsp_permissions_add_role_valist (priv->permissions, role, fieldname,
573       var_args);
574   va_end (var_args);
575   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
576 }
577
578 /**
579  * gst_rtsp_media_factory_add_role_from_structure:
580  *
581  * A convenience wrapper around gst_rtsp_permissions_add_role_from_structure().
582  * If @factory had no permissions, new permissions will be created and the
583  * role will be added to it.
584  *
585  * Since: 1.14
586  */
587 void
588 gst_rtsp_media_factory_add_role_from_structure (GstRTSPMediaFactory * factory,
589     GstStructure * structure)
590 {
591   GstRTSPMediaFactoryPrivate *priv;
592   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
593   g_return_if_fail (GST_IS_STRUCTURE (structure));
594
595   priv = factory->priv;
596
597   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
598   if (priv->permissions == NULL)
599     priv->permissions = gst_rtsp_permissions_new ();
600
601   gst_rtsp_permissions_add_role_from_structure (priv->permissions, structure);
602   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
603 }
604
605 /**
606  * gst_rtsp_media_factory_set_launch:
607  * @factory: a #GstRTSPMediaFactory
608  * @launch: the launch description
609  *
610  *
611  * The gst_parse_launch() line to use for constructing the pipeline in the
612  * default prepare vmethod.
613  *
614  * The pipeline description should return a GstBin as the toplevel element
615  * which can be accomplished by enclosing the description with brackets '('
616  * ')'.
617  *
618  * The description should return a pipeline with payloaders named pay0, pay1,
619  * etc.. Each of the payloaders will result in a stream.
620  */
621 void
622 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory * factory,
623     const gchar * launch)
624 {
625   GstRTSPMediaFactoryPrivate *priv;
626
627   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
628   g_return_if_fail (launch != NULL);
629
630   priv = factory->priv;
631
632   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
633   g_free (priv->launch);
634   priv->launch = g_strdup (launch);
635   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
636 }
637
638 /**
639  * gst_rtsp_media_factory_get_launch:
640  * @factory: a #GstRTSPMediaFactory
641  *
642  * Get the gst_parse_launch() pipeline description that will be used in the
643  * default prepare vmethod.
644  *
645  * Returns: (transfer full) (nullable): the configured launch description. g_free() after
646  * usage.
647  */
648 gchar *
649 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory)
650 {
651   GstRTSPMediaFactoryPrivate *priv;
652   gchar *result;
653
654   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
655
656   priv = factory->priv;
657
658   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
659   result = g_strdup (priv->launch);
660   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
661
662   return result;
663 }
664
665 /**
666  * gst_rtsp_media_factory_set_suspend_mode:
667  * @factory: a #GstRTSPMediaFactory
668  * @mode: the new #GstRTSPSuspendMode
669  *
670  * Configure how media created from this factory will be suspended.
671  */
672 void
673 gst_rtsp_media_factory_set_suspend_mode (GstRTSPMediaFactory * factory,
674     GstRTSPSuspendMode mode)
675 {
676   GstRTSPMediaFactoryPrivate *priv;
677
678   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
679
680   priv = factory->priv;
681
682   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
683   priv->suspend_mode = mode;
684   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
685 }
686
687 /**
688  * gst_rtsp_media_factory_get_suspend_mode:
689  * @factory: a #GstRTSPMediaFactory
690  *
691  * Get how media created from this factory will be suspended.
692  *
693  * Returns: a #GstRTSPSuspendMode.
694  */
695 GstRTSPSuspendMode
696 gst_rtsp_media_factory_get_suspend_mode (GstRTSPMediaFactory * factory)
697 {
698   GstRTSPMediaFactoryPrivate *priv;
699   GstRTSPSuspendMode result;
700
701   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
702       GST_RTSP_SUSPEND_MODE_NONE);
703
704   priv = factory->priv;
705
706   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
707   result = priv->suspend_mode;
708   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
709
710   return result;
711 }
712
713 /**
714  * gst_rtsp_media_factory_set_shared:
715  * @factory: a #GstRTSPMediaFactory
716  * @shared: the new value
717  *
718  * Configure if media created from this factory can be shared between clients.
719  */
720 void
721 gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory * factory,
722     gboolean shared)
723 {
724   GstRTSPMediaFactoryPrivate *priv;
725
726   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
727
728   priv = factory->priv;
729
730   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
731   priv->shared = shared;
732   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
733 }
734
735 /**
736  * gst_rtsp_media_factory_is_shared:
737  * @factory: a #GstRTSPMediaFactory
738  *
739  * Get if media created from this factory can be shared between clients.
740  *
741  * Returns: %TRUE if the media will be shared between clients.
742  */
743 gboolean
744 gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory * factory)
745 {
746   GstRTSPMediaFactoryPrivate *priv;
747   gboolean result;
748
749   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
750
751   priv = factory->priv;
752
753   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
754   result = priv->shared;
755   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
756
757   return result;
758 }
759
760 /**
761  * gst_rtsp_media_factory_set_eos_shutdown:
762  * @factory: a #GstRTSPMediaFactory
763  * @eos_shutdown: the new value
764  *
765  * Configure if media created from this factory will have an EOS sent to the
766  * pipeline before shutdown.
767  */
768 void
769 gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory * factory,
770     gboolean eos_shutdown)
771 {
772   GstRTSPMediaFactoryPrivate *priv;
773
774   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
775
776   priv = factory->priv;
777
778   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
779   priv->eos_shutdown = eos_shutdown;
780   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
781 }
782
783 /**
784  * gst_rtsp_media_factory_is_eos_shutdown:
785  * @factory: a #GstRTSPMediaFactory
786  *
787  * Get if media created from this factory will have an EOS event sent to the
788  * pipeline before shutdown.
789  *
790  * Returns: %TRUE if the media will receive EOS before shutdown.
791  */
792 gboolean
793 gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory * factory)
794 {
795   GstRTSPMediaFactoryPrivate *priv;
796   gboolean result;
797
798   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
799
800   priv = factory->priv;
801
802   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
803   result = priv->eos_shutdown;
804   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
805
806   return result;
807 }
808
809 /**
810  * gst_rtsp_media_factory_set_buffer_size:
811  * @factory: a #GstRTSPMedia
812  * @size: the new value
813  *
814  * Set the kernel UDP buffer size.
815  */
816 void
817 gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
818     guint size)
819 {
820   GstRTSPMediaFactoryPrivate *priv;
821
822   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
823
824   priv = factory->priv;
825
826   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
827   priv->buffer_size = size;
828   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
829 }
830
831 /**
832  * gst_rtsp_media_factory_get_buffer_size:
833  * @factory: a #GstRTSPMedia
834  *
835  * Get the kernel UDP buffer size.
836  *
837  * Returns: the kernel UDP buffer size.
838  */
839 guint
840 gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory)
841 {
842   GstRTSPMediaFactoryPrivate *priv;
843   guint result;
844
845   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
846
847   priv = factory->priv;
848
849   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
850   result = priv->buffer_size;
851   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
852
853   return result;
854 }
855
856 /**
857  * gst_rtsp_media_factory_set_dscp_qos:
858  * @factory: a #GstRTSPMediaFactory
859  * @dscp_qos: a new dscp qos value (0-63, or -1 to disable)
860  *
861  * Configure the media dscp qos to @dscp_qos.
862  *
863  * Since: 1.18
864  */
865 void
866 gst_rtsp_media_factory_set_dscp_qos (GstRTSPMediaFactory * factory,
867     gint dscp_qos)
868 {
869   GstRTSPMediaFactoryPrivate *priv;
870
871   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
872
873   if (dscp_qos < -1 || dscp_qos > 63) {
874     GST_WARNING_OBJECT (factory, "trying to set illegal dscp qos %d", dscp_qos);
875     return;
876   }
877
878   priv = factory->priv;
879
880   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
881   priv->dscp_qos = dscp_qos;
882   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
883 }
884
885 /**
886  * gst_rtsp_media_factory_get_dscp_qos:
887  * @factory: a #GstRTSPMediaFactory
888  *
889  * Get the configured media DSCP QoS.
890  *
891  * Returns: the media DSCP QoS value or -1 if disabled.
892  *
893  * Since: 1.18
894  */
895 gint
896 gst_rtsp_media_factory_get_dscp_qos (GstRTSPMediaFactory * factory)
897 {
898   GstRTSPMediaFactoryPrivate *priv;
899   guint result;
900
901   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
902
903   priv = factory->priv;
904
905   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
906   result = priv->dscp_qos;
907   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
908
909   return result;
910 }
911
912 /**
913  * gst_rtsp_media_factory_set_address_pool:
914  * @factory: a #GstRTSPMediaFactory
915  * @pool: (transfer none) (nullable): a #GstRTSPAddressPool
916  *
917  * configure @pool to be used as the address pool of @factory.
918  */
919 void
920 gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory,
921     GstRTSPAddressPool * pool)
922 {
923   GstRTSPMediaFactoryPrivate *priv;
924   GstRTSPAddressPool *old;
925
926   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
927
928   priv = factory->priv;
929
930   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
931   if ((old = priv->pool) != pool)
932     priv->pool = pool ? g_object_ref (pool) : NULL;
933   else
934     old = NULL;
935   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
936
937   if (old)
938     g_object_unref (old);
939 }
940
941 /**
942  * gst_rtsp_media_factory_get_address_pool:
943  * @factory: a #GstRTSPMediaFactory
944  *
945  * Get the #GstRTSPAddressPool used as the address pool of @factory.
946  *
947  * Returns: (transfer full) (nullable): the #GstRTSPAddressPool of @factory. g_object_unref() after
948  * usage.
949  */
950 GstRTSPAddressPool *
951 gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
952 {
953   GstRTSPMediaFactoryPrivate *priv;
954   GstRTSPAddressPool *result;
955
956   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
957
958   priv = factory->priv;
959
960   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
961   if ((result = priv->pool))
962     g_object_ref (result);
963   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
964
965   return result;
966 }
967
968 /**
969  * gst_rtsp_media_factory_set_multicast_iface:
970  * @factory: a #GstRTSPMediaFactory
971  * @multicast_iface: (transfer none) (nullable): a multicast interface name
972  *
973  * configure @multicast_iface to be used for @factory.
974  */
975 void
976 gst_rtsp_media_factory_set_multicast_iface (GstRTSPMediaFactory * media_factory,
977     const gchar * multicast_iface)
978 {
979   GstRTSPMediaFactoryPrivate *priv;
980   gchar *old;
981
982   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (media_factory));
983
984   priv = media_factory->priv;
985
986   GST_LOG_OBJECT (media_factory, "set multicast interface %s", multicast_iface);
987
988   g_mutex_lock (&priv->lock);
989   if ((old = priv->multicast_iface) != multicast_iface)
990     priv->multicast_iface = multicast_iface ? g_strdup (multicast_iface) : NULL;
991   else
992     old = NULL;
993   g_mutex_unlock (&priv->lock);
994
995   if (old)
996     g_free (old);
997 }
998
999 /**
1000  * gst_rtsp_media_factory_get_multicast_iface:
1001  * @factory: a #GstRTSPMediaFactory
1002  *
1003  * Get the multicast interface used for @factory.
1004  *
1005  * Returns: (transfer full) (nullable): the multicast interface for @factory. g_free() after
1006  * usage.
1007  */
1008 gchar *
1009 gst_rtsp_media_factory_get_multicast_iface (GstRTSPMediaFactory * media_factory)
1010 {
1011   GstRTSPMediaFactoryPrivate *priv;
1012   gchar *result;
1013
1014   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (media_factory), NULL);
1015
1016   priv = media_factory->priv;
1017
1018   g_mutex_lock (&priv->lock);
1019   if ((result = priv->multicast_iface))
1020     result = g_strdup (result);
1021   g_mutex_unlock (&priv->lock);
1022
1023   return result;
1024 }
1025
1026 /**
1027  * gst_rtsp_media_factory_set_profiles:
1028  * @factory: a #GstRTSPMediaFactory
1029  * @profiles: the new flags
1030  *
1031  * Configure the allowed profiles for @factory.
1032  */
1033 void
1034 gst_rtsp_media_factory_set_profiles (GstRTSPMediaFactory * factory,
1035     GstRTSPProfile profiles)
1036 {
1037   GstRTSPMediaFactoryPrivate *priv;
1038
1039   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1040
1041   priv = factory->priv;
1042
1043   GST_DEBUG_OBJECT (factory, "profiles %d", profiles);
1044
1045   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1046   priv->profiles = profiles;
1047   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1048 }
1049
1050 /**
1051  * gst_rtsp_media_factory_get_profiles:
1052  * @factory: a #GstRTSPMediaFactory
1053  *
1054  * Get the allowed profiles of @factory.
1055  *
1056  * Returns: a #GstRTSPProfile
1057  */
1058 GstRTSPProfile
1059 gst_rtsp_media_factory_get_profiles (GstRTSPMediaFactory * factory)
1060 {
1061   GstRTSPMediaFactoryPrivate *priv;
1062   GstRTSPProfile res;
1063
1064   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
1065       GST_RTSP_PROFILE_UNKNOWN);
1066
1067   priv = factory->priv;
1068
1069   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1070   res = priv->profiles;
1071   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1072
1073   return res;
1074 }
1075
1076 /**
1077  * gst_rtsp_media_factory_set_protocols:
1078  * @factory: a #GstRTSPMediaFactory
1079  * @protocols: the new flags
1080  *
1081  * Configure the allowed lower transport for @factory.
1082  */
1083 void
1084 gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory * factory,
1085     GstRTSPLowerTrans protocols)
1086 {
1087   GstRTSPMediaFactoryPrivate *priv;
1088
1089   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1090
1091   priv = factory->priv;
1092
1093   GST_DEBUG_OBJECT (factory, "protocols %d", protocols);
1094
1095   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1096   priv->protocols = protocols;
1097   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1098 }
1099
1100 /**
1101  * gst_rtsp_media_factory_get_protocols:
1102  * @factory: a #GstRTSPMediaFactory
1103  *
1104  * Get the allowed protocols of @factory.
1105  *
1106  * Returns: a #GstRTSPLowerTrans
1107  */
1108 GstRTSPLowerTrans
1109 gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory * factory)
1110 {
1111   GstRTSPMediaFactoryPrivate *priv;
1112   GstRTSPLowerTrans res;
1113
1114   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory),
1115       GST_RTSP_LOWER_TRANS_UNKNOWN);
1116
1117   priv = factory->priv;
1118
1119   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1120   res = priv->protocols;
1121   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1122
1123   return res;
1124 }
1125
1126 /**
1127  * gst_rtsp_media_factory_set_stop_on_disconnect:
1128  * @factory: a #GstRTSPMediaFactory
1129  * @stop_on_disconnect: the new value
1130  *
1131  * Configure if media created from this factory should be stopped
1132  * when a client disconnects without sending TEARDOWN.
1133  */
1134 void
1135 gst_rtsp_media_factory_set_stop_on_disconnect (GstRTSPMediaFactory * factory,
1136     gboolean stop_on_disconnect)
1137 {
1138   GstRTSPMediaFactoryPrivate *priv;
1139
1140   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1141
1142   priv = factory->priv;
1143
1144   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1145   priv->stop_on_disconnect = stop_on_disconnect;
1146   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1147 }
1148
1149 /**
1150  * gst_rtsp_media_factory_is_stop_on_disconnect:
1151  * @factory: a #GstRTSPMediaFactory
1152  *
1153  * Get if media created from this factory should be stopped when a client
1154  * disconnects without sending TEARDOWN.
1155  *
1156  * Returns: %TRUE if the media will be stopped when a client disconnects
1157  *     without sending TEARDOWN.
1158  */
1159 gboolean
1160 gst_rtsp_media_factory_is_stop_on_disonnect (GstRTSPMediaFactory * factory)
1161 {
1162   GstRTSPMediaFactoryPrivate *priv;
1163   gboolean result;
1164
1165   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), TRUE);
1166
1167   priv = factory->priv;
1168
1169   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1170   result = priv->stop_on_disconnect;
1171   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1172
1173   return result;
1174 }
1175
1176 /**
1177  * gst_rtsp_media_factory_set_retransmission_time:
1178  * @factory: a #GstRTSPMediaFactory
1179  * @time: a #GstClockTime
1180  *
1181  * Configure the time to store for possible retransmission
1182  */
1183 void
1184 gst_rtsp_media_factory_set_retransmission_time (GstRTSPMediaFactory * factory,
1185     GstClockTime time)
1186 {
1187   GstRTSPMediaFactoryPrivate *priv;
1188
1189   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1190
1191   priv = factory->priv;
1192
1193   GST_DEBUG_OBJECT (factory, "retransmission time %" G_GUINT64_FORMAT, time);
1194
1195   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1196   priv->rtx_time = time;
1197   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1198 }
1199
1200 /**
1201  * gst_rtsp_media_factory_get_retransmission_time:
1202  * @factory: a #GstRTSPMediaFactory
1203  *
1204  * Get the time that is stored for retransmission purposes
1205  *
1206  * Returns: a #GstClockTime
1207  */
1208 GstClockTime
1209 gst_rtsp_media_factory_get_retransmission_time (GstRTSPMediaFactory * factory)
1210 {
1211   GstRTSPMediaFactoryPrivate *priv;
1212   GstClockTime res;
1213
1214   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
1215
1216   priv = factory->priv;
1217
1218   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1219   res = priv->rtx_time;
1220   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1221
1222   return res;
1223 }
1224
1225 /**
1226  * gst_rtsp_media_factory_set_do_retransmission:
1227  *
1228  * Set whether retransmission requests will be sent for
1229  * receiving media
1230  *
1231  * Since: 1.16
1232  */
1233 void
1234 gst_rtsp_media_factory_set_do_retransmission (GstRTSPMediaFactory * factory,
1235     gboolean do_retransmission)
1236 {
1237   GstRTSPMediaFactoryPrivate *priv;
1238
1239   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1240
1241   priv = factory->priv;
1242
1243   GST_DEBUG_OBJECT (factory, "Do retransmission %d", do_retransmission);
1244
1245   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1246   priv->do_retransmission = do_retransmission;
1247   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1248 }
1249
1250 /**
1251  * gst_rtsp_media_factory_get_do_retransmission:
1252  *
1253  * Returns: Whether retransmission requests will be sent for receiving media
1254  *
1255  * Since: 1.16
1256  */
1257 gboolean
1258 gst_rtsp_media_factory_get_do_retransmission (GstRTSPMediaFactory * factory)
1259 {
1260   GstRTSPMediaFactoryPrivate *priv;
1261   gboolean res;
1262
1263   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
1264
1265   priv = factory->priv;
1266
1267   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1268   res = priv->do_retransmission;
1269   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1270
1271   return res;
1272 }
1273
1274 /**
1275  * gst_rtsp_media_factory_set_latency:
1276  * @factory: a #GstRTSPMediaFactory
1277  * @latency: latency in milliseconds
1278  *
1279  * Configure the latency used for receiving media
1280  */
1281 void
1282 gst_rtsp_media_factory_set_latency (GstRTSPMediaFactory * factory,
1283     guint latency)
1284 {
1285   GstRTSPMediaFactoryPrivate *priv;
1286
1287   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1288
1289   priv = factory->priv;
1290
1291   GST_DEBUG_OBJECT (factory, "latency %ums", latency);
1292
1293   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1294   priv->latency = latency;
1295   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1296 }
1297
1298 /**
1299  * gst_rtsp_media_factory_get_latency:
1300  * @factory: a #GstRTSPMediaFactory
1301  *
1302  * Get the latency that is used for receiving media
1303  *
1304  * Returns: latency in milliseconds
1305  */
1306 guint
1307 gst_rtsp_media_factory_get_latency (GstRTSPMediaFactory * factory)
1308 {
1309   GstRTSPMediaFactoryPrivate *priv;
1310   guint res;
1311
1312   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
1313
1314   priv = factory->priv;
1315
1316   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1317   res = priv->latency;
1318   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1319
1320   return res;
1321 }
1322
1323 static gboolean
1324 compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
1325 {
1326   return (media1 == media2);
1327 }
1328
1329 static void
1330 media_unprepared (GstRTSPMedia * media, GWeakRef * ref)
1331 {
1332   GstRTSPMediaFactory *factory = g_weak_ref_get (ref);
1333   GstRTSPMediaFactoryPrivate *priv;
1334
1335   if (!factory)
1336     return;
1337
1338   priv = factory->priv;
1339
1340   g_mutex_lock (&priv->medias_lock);
1341   g_hash_table_foreach_remove (priv->medias, (GHRFunc) compare_media, media);
1342   g_mutex_unlock (&priv->medias_lock);
1343
1344   g_object_unref (factory);
1345 }
1346
1347 static GWeakRef *
1348 weak_ref_new (gpointer obj)
1349 {
1350   GWeakRef *ref = g_slice_new (GWeakRef);
1351
1352   g_weak_ref_init (ref, obj);
1353   return ref;
1354 }
1355
1356 static void
1357 weak_ref_free (GWeakRef * ref)
1358 {
1359   g_weak_ref_clear (ref);
1360   g_slice_free (GWeakRef, ref);
1361 }
1362
1363 /**
1364  * gst_rtsp_media_factory_construct:
1365  * @factory: a #GstRTSPMediaFactory
1366  * @url: the url used
1367  *
1368  * Construct the media object and create its streams. Implementations
1369  * should create the needed gstreamer elements and add them to the result
1370  * object. No state changes should be performed on them yet.
1371  *
1372  * One or more GstRTSPStream objects should be created from the result
1373  * with gst_rtsp_media_create_stream ().
1374  *
1375  * After the media is constructed, it can be configured and then prepared
1376  * with gst_rtsp_media_prepare ().
1377  *
1378  * Returns: (transfer full): a new #GstRTSPMedia if the media could be prepared.
1379  */
1380 GstRTSPMedia *
1381 gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory,
1382     const GstRTSPUrl * url)
1383 {
1384   GstRTSPMediaFactoryPrivate *priv;
1385   gchar *key;
1386   GstRTSPMedia *media;
1387   GstRTSPMediaFactoryClass *klass;
1388
1389   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
1390   g_return_val_if_fail (url != NULL, NULL);
1391
1392   priv = factory->priv;
1393   klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1394
1395   /* convert the url to a key for the hashtable. NULL return or a NULL function
1396    * will not cache anything for this factory. */
1397   if (klass->gen_key)
1398     key = klass->gen_key (factory, url);
1399   else
1400     key = NULL;
1401
1402   g_mutex_lock (&priv->medias_lock);
1403   if (key) {
1404     /* we have a key, see if we find a cached media */
1405     media = g_hash_table_lookup (priv->medias, key);
1406     if (media)
1407       g_object_ref (media);
1408   } else
1409     media = NULL;
1410
1411   if (media == NULL) {
1412     /* nothing cached found, try to create one */
1413     if (klass->construct) {
1414       media = klass->construct (factory, url);
1415       if (media)
1416         g_signal_emit (factory,
1417             gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media,
1418             NULL);
1419     } else
1420       media = NULL;
1421
1422     if (media) {
1423       /* configure the media */
1424       if (klass->configure)
1425         klass->configure (factory, media);
1426
1427       g_signal_emit (factory,
1428           gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media,
1429           NULL);
1430
1431       /* check if we can cache this media */
1432       if (gst_rtsp_media_is_shared (media) && key) {
1433         /* insert in the hashtable, takes ownership of the key */
1434         g_object_ref (media);
1435         g_hash_table_insert (priv->medias, key, media);
1436         key = NULL;
1437       }
1438       if (!gst_rtsp_media_is_reusable (media)) {
1439         /* when not reusable, connect to the unprepare signal to remove the item
1440          * from our cache when it gets unprepared */
1441         g_signal_connect_data (media, "unprepared",
1442             (GCallback) media_unprepared, weak_ref_new (factory),
1443             (GClosureNotify) weak_ref_free, 0);
1444       }
1445     }
1446   }
1447   g_mutex_unlock (&priv->medias_lock);
1448
1449   if (key)
1450     g_free (key);
1451
1452   GST_INFO ("constructed media %p for url %s", media, url->abspath);
1453
1454   return media;
1455 }
1456
1457 /**
1458  * gst_rtsp_media_factory_set_media_gtype:
1459  * @factory: a #GstRTSPMediaFactory
1460  * @media_gtype: the GType of the class to create
1461  *
1462  * Configure the GType of the GstRTSPMedia subclass to
1463  * create (by default, overridden construct vmethods
1464  * may of course do something different)
1465  *
1466  * Since: 1.6
1467  */
1468 void
1469 gst_rtsp_media_factory_set_media_gtype (GstRTSPMediaFactory * factory,
1470     GType media_gtype)
1471 {
1472   GstRTSPMediaFactoryPrivate *priv;
1473
1474   g_return_if_fail (g_type_is_a (media_gtype, GST_TYPE_RTSP_MEDIA));
1475
1476   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1477   priv = factory->priv;
1478   priv->media_gtype = media_gtype;
1479   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1480 }
1481
1482 /**
1483  * gst_rtsp_media_factory_get_media_gtype:
1484  * @factory: a #GstRTSPMediaFactory
1485  *
1486  * Return the GType of the GstRTSPMedia subclass this
1487  * factory will create.
1488  *
1489  * Since: 1.6
1490  */
1491 GType
1492 gst_rtsp_media_factory_get_media_gtype (GstRTSPMediaFactory * factory)
1493 {
1494   GstRTSPMediaFactoryPrivate *priv;
1495   GType ret;
1496
1497   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1498   priv = factory->priv;
1499   ret = priv->media_gtype;
1500   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1501
1502   return ret;
1503 }
1504
1505 /**
1506  * gst_rtsp_media_factory_set_clock:
1507  * @factory: a #GstRTSPMediaFactory
1508  * @clock: (nullable): the clock to be used by the media factory
1509  *
1510  * Configures a specific clock to be used by the pipelines
1511  * of all medias created from this factory.
1512  *
1513  * Since: 1.8
1514  */
1515 void
1516 gst_rtsp_media_factory_set_clock (GstRTSPMediaFactory * factory,
1517     GstClock * clock)
1518 {
1519   GstClock **clock_p;
1520
1521   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1522   g_return_if_fail (GST_IS_CLOCK (clock) || clock == NULL);
1523
1524   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1525   clock_p = &factory->priv->clock;
1526   gst_object_replace ((GstObject **) clock_p, (GstObject *) clock);
1527   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1528 }
1529
1530 /**
1531  * gst_rtsp_media_factory_get_clock:
1532  * @factory: a #GstRTSPMediaFactory
1533  *
1534  * Returns the clock that is going to be used by the pipelines
1535  * of all medias created from this factory.
1536  *
1537  * Returns: (transfer full): The GstClock
1538  *
1539  * Since: 1.8
1540  */
1541 GstClock *
1542 gst_rtsp_media_factory_get_clock (GstRTSPMediaFactory * factory)
1543 {
1544   GstRTSPMediaFactoryPrivate *priv;
1545   GstClock *ret;
1546
1547   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
1548
1549   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1550   priv = factory->priv;
1551   ret = priv->clock ? gst_object_ref (priv->clock) : NULL;
1552   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1553
1554   return ret;
1555 }
1556
1557 /**
1558  * gst_rtsp_media_factory_set_publish_clock_mode:
1559  * @factory: a #GstRTSPMediaFactory
1560  * @mode: the clock publish mode
1561  *
1562  * Sets if and how the media clock should be published according to RFC7273.
1563  *
1564  * Since: 1.8
1565  */
1566 void
1567 gst_rtsp_media_factory_set_publish_clock_mode (GstRTSPMediaFactory * factory,
1568     GstRTSPPublishClockMode mode)
1569 {
1570   GstRTSPMediaFactoryPrivate *priv;
1571
1572   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1573   priv = factory->priv;
1574   priv->publish_clock_mode = mode;
1575   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1576 }
1577
1578 /**
1579  * gst_rtsp_media_factory_get_publish_clock_mode:
1580  * @factory: a #GstRTSPMediaFactory
1581  *
1582  * Gets if and how the media clock should be published according to RFC7273.
1583  *
1584  * Returns: The GstRTSPPublishClockMode
1585  *
1586  * Since: 1.8
1587  */
1588 GstRTSPPublishClockMode
1589 gst_rtsp_media_factory_get_publish_clock_mode (GstRTSPMediaFactory * factory)
1590 {
1591   GstRTSPMediaFactoryPrivate *priv;
1592   GstRTSPPublishClockMode ret;
1593
1594   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1595   priv = factory->priv;
1596   ret = priv->publish_clock_mode;
1597   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1598
1599   return ret;
1600 }
1601
1602 /**
1603  * gst_rtsp_media_factory_set_max_mcast_ttl:
1604  * @factory: a #GstRTSPMedia
1605  * @ttl: the new multicast ttl value
1606  *
1607  * Set the maximum time-to-live value of outgoing multicast packets.
1608  *
1609  * Returns: %TRUE if the requested ttl has been set successfully.
1610  *
1611  * Since: 1.16
1612  */
1613 gboolean
1614 gst_rtsp_media_factory_set_max_mcast_ttl (GstRTSPMediaFactory * factory,
1615     guint ttl)
1616 {
1617   GstRTSPMediaFactoryPrivate *priv;
1618
1619   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
1620
1621   priv = factory->priv;
1622
1623   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1624   if (ttl == 0 || ttl > DEFAULT_MAX_MCAST_TTL) {
1625     GST_WARNING_OBJECT (factory, "The requested mcast TTL value is not valid.");
1626     GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1627     return FALSE;
1628   }
1629   priv->max_mcast_ttl = ttl;
1630   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1631
1632   return TRUE;
1633 }
1634
1635 /**
1636  * gst_rtsp_media_factory_get_max_mcast_ttl:
1637  * @factory: a #GstRTSPMedia
1638  *
1639  * Get the the maximum time-to-live value of outgoing multicast packets.
1640  *
1641  * Returns: the maximum time-to-live value of outgoing multicast packets.
1642  *
1643  * Since: 1.16
1644  */
1645 guint
1646 gst_rtsp_media_factory_get_max_mcast_ttl (GstRTSPMediaFactory * factory)
1647 {
1648   GstRTSPMediaFactoryPrivate *priv;
1649   guint result;
1650
1651   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0);
1652
1653   priv = factory->priv;
1654
1655   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1656   result = priv->max_mcast_ttl;
1657   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1658
1659   return result;
1660 }
1661
1662 /**
1663  * gst_rtsp_media_factory_set_bind_mcast_address:
1664  * @factory: a #GstRTSPMediaFactory
1665  * @bind_mcast_addr: the new value
1666  *
1667  * Decide whether the multicast socket should be bound to a multicast address or
1668  * INADDR_ANY.
1669  *
1670  * Since: 1.16
1671  */
1672 void
1673 gst_rtsp_media_factory_set_bind_mcast_address (GstRTSPMediaFactory * factory,
1674     gboolean bind_mcast_addr)
1675 {
1676   GstRTSPMediaFactoryPrivate *priv;
1677
1678   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1679
1680   priv = factory->priv;
1681
1682   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1683   priv->bind_mcast_address = bind_mcast_addr;
1684   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1685 }
1686
1687 /**
1688  * gst_rtsp_media_factory_is_bind_mcast_address:
1689  * @factory: a #GstRTSPMediaFactory
1690  *
1691  * Check if multicast sockets are configured to be bound to multicast addresses.
1692  *
1693  * Returns: %TRUE if multicast sockets are configured to be bound to multicast addresses.
1694  *
1695  * Since: 1.16
1696  */
1697 gboolean
1698 gst_rtsp_media_factory_is_bind_mcast_address (GstRTSPMediaFactory * factory)
1699 {
1700   GstRTSPMediaFactoryPrivate *priv;
1701   gboolean result;
1702
1703   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
1704
1705   priv = factory->priv;
1706
1707   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1708   result = priv->bind_mcast_address;
1709   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1710
1711   return result;
1712 }
1713
1714 /**
1715  * gst_rtsp_media_factory_set_enable_rtcp:
1716  * @factory: a #GstRTSPMediaFactory
1717  * @enable: the new value
1718  *
1719  * Decide whether the created media should send and receive RTCP
1720  *
1721  * Since: 1.20
1722  */
1723 void
1724 gst_rtsp_media_factory_set_enable_rtcp (GstRTSPMediaFactory * factory,
1725     gboolean enable)
1726 {
1727   GstRTSPMediaFactoryPrivate *priv;
1728
1729   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
1730
1731   priv = factory->priv;
1732
1733   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1734   priv->enable_rtcp = enable;
1735   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1736 }
1737
1738 /**
1739  * gst_rtsp_media_factory_is_enable_rtcp:
1740  * @factory: a #GstRTSPMediaFactory
1741  *
1742  * Check if created media will send and receive RTCP
1743  *
1744  * Returns: %TRUE if created media will send and receive RTCP
1745  *
1746  * Since: 1.20
1747  */
1748 gboolean
1749 gst_rtsp_media_factory_is_enable_rtcp (GstRTSPMediaFactory * factory)
1750 {
1751   GstRTSPMediaFactoryPrivate *priv;
1752   gboolean result;
1753
1754   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
1755
1756   priv = factory->priv;
1757
1758   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1759   result = priv->enable_rtcp;
1760   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1761
1762   return result;
1763 }
1764
1765 static gchar *
1766 default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
1767 {
1768   gchar *result;
1769   const gchar *pre_query;
1770   const gchar *query;
1771   guint16 port;
1772
1773   pre_query = url->query ? "?" : "";
1774   query = url->query ? url->query : "";
1775
1776   gst_rtsp_url_get_port (url, &port);
1777
1778   result = g_strdup_printf ("%u%s%s%s", port, url->abspath, pre_query, query);
1779
1780   return result;
1781 }
1782
1783 static GstElement *
1784 default_create_element (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
1785 {
1786   GstRTSPMediaFactoryPrivate *priv = factory->priv;
1787   GstElement *element;
1788   GError *error = NULL;
1789
1790   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1791   /* we need a parse syntax */
1792   if (priv->launch == NULL)
1793     goto no_launch;
1794
1795   /* parse the user provided launch line */
1796   element =
1797       gst_parse_launch_full (priv->launch, NULL, GST_PARSE_FLAG_PLACE_IN_BIN,
1798       &error);
1799   if (element == NULL)
1800     goto parse_error;
1801
1802   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1803
1804   if (error != NULL) {
1805     /* a recoverable error was encountered */
1806     GST_WARNING ("recoverable parsing error: %s", error->message);
1807     g_error_free (error);
1808   }
1809   return element;
1810
1811   /* ERRORS */
1812 no_launch:
1813   {
1814     GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1815     g_critical ("no launch line specified");
1816     return NULL;
1817   }
1818 parse_error:
1819   {
1820     g_critical ("could not parse launch syntax (%s): %s", priv->launch,
1821         (error ? error->message : "unknown reason"));
1822     GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1823     if (error)
1824       g_error_free (error);
1825     return NULL;
1826   }
1827 }
1828
1829 static GstRTSPMedia *
1830 default_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
1831 {
1832   GstRTSPMedia *media;
1833   GstElement *element, *pipeline;
1834   GstRTSPMediaFactoryClass *klass;
1835   GType media_gtype;
1836   gboolean enable_rtcp;
1837
1838   klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1839
1840   if (!klass->create_pipeline)
1841     goto no_create;
1842
1843   element = gst_rtsp_media_factory_create_element (factory, url);
1844   if (element == NULL)
1845     goto no_element;
1846
1847   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1848   media_gtype = factory->priv->media_gtype;
1849   enable_rtcp = factory->priv->enable_rtcp;
1850   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1851
1852   /* create a new empty media */
1853   media =
1854       g_object_new (media_gtype, "element", element, "transport-mode",
1855       factory->priv->transport_mode, NULL);
1856
1857   /* We need to call this prior to collecting streams */
1858   gst_rtsp_media_set_enable_rtcp (media, enable_rtcp);
1859
1860   gst_rtsp_media_collect_streams (media);
1861
1862   pipeline = klass->create_pipeline (factory, media);
1863   if (pipeline == NULL)
1864     goto no_pipeline;
1865
1866   return media;
1867
1868   /* ERRORS */
1869 no_create:
1870   {
1871     g_critical ("no create_pipeline function");
1872     return NULL;
1873   }
1874 no_element:
1875   {
1876     g_critical ("could not create element");
1877     return NULL;
1878   }
1879 no_pipeline:
1880   {
1881     g_critical ("can't create pipeline");
1882     g_object_unref (media);
1883     return NULL;
1884   }
1885 }
1886
1887 static GstElement *
1888 default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1889 {
1890   GstElement *pipeline;
1891
1892   pipeline = gst_pipeline_new ("media-pipeline");
1893
1894   /* FIXME 2.0: This should be done by the caller, not the vfunc. Every
1895    * implementation of the vfunc has to call it otherwise at the end.
1896    * Also it does not allow use to add further behaviour here that could
1897    * be reused by subclasses that chain up */
1898   gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));
1899
1900   return pipeline;
1901 }
1902
1903 static void
1904 default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
1905 {
1906   GstRTSPMediaFactoryPrivate *priv = factory->priv;
1907   gboolean shared, eos_shutdown, stop_on_disconnect;
1908   guint size;
1909   gint dscp_qos;
1910   GstRTSPSuspendMode suspend_mode;
1911   GstRTSPProfile profiles;
1912   GstRTSPLowerTrans protocols;
1913   GstRTSPAddressPool *pool;
1914   GstRTSPPermissions *perms;
1915   GstClockTime rtx_time;
1916   guint latency;
1917   GstRTSPTransportMode transport_mode;
1918   GstClock *clock;
1919   gchar *multicast_iface;
1920   GstRTSPPublishClockMode publish_clock_mode;
1921   guint ttl;
1922   gboolean bind_mcast;
1923
1924   /* configure the sharedness */
1925   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
1926   suspend_mode = priv->suspend_mode;
1927   shared = priv->shared;
1928   eos_shutdown = priv->eos_shutdown;
1929   size = priv->buffer_size;
1930   dscp_qos = priv->dscp_qos;
1931   profiles = priv->profiles;
1932   protocols = priv->protocols;
1933   rtx_time = priv->rtx_time;
1934   latency = priv->latency;
1935   transport_mode = priv->transport_mode;
1936   stop_on_disconnect = priv->stop_on_disconnect;
1937   clock = priv->clock ? gst_object_ref (priv->clock) : NULL;
1938   publish_clock_mode = priv->publish_clock_mode;
1939   ttl = priv->max_mcast_ttl;
1940   bind_mcast = priv->bind_mcast_address;
1941   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
1942
1943   gst_rtsp_media_set_suspend_mode (media, suspend_mode);
1944   gst_rtsp_media_set_shared (media, shared);
1945   gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
1946   gst_rtsp_media_set_buffer_size (media, size);
1947   gst_rtsp_media_set_dscp_qos (media, dscp_qos);
1948   gst_rtsp_media_set_profiles (media, profiles);
1949   gst_rtsp_media_set_protocols (media, protocols);
1950   gst_rtsp_media_set_retransmission_time (media, rtx_time);
1951   gst_rtsp_media_set_do_retransmission (media, priv->do_retransmission);
1952   gst_rtsp_media_set_latency (media, latency);
1953   gst_rtsp_media_set_transport_mode (media, transport_mode);
1954   gst_rtsp_media_set_stop_on_disconnect (media, stop_on_disconnect);
1955   gst_rtsp_media_set_publish_clock_mode (media, publish_clock_mode);
1956   gst_rtsp_media_set_max_mcast_ttl (media, ttl);
1957   gst_rtsp_media_set_bind_mcast_address (media, bind_mcast);
1958
1959   if (clock) {
1960     gst_rtsp_media_set_clock (media, clock);
1961     gst_object_unref (clock);
1962   }
1963
1964   if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
1965     gst_rtsp_media_set_address_pool (media, pool);
1966     g_object_unref (pool);
1967   }
1968   if ((multicast_iface = gst_rtsp_media_factory_get_multicast_iface (factory))) {
1969     gst_rtsp_media_set_multicast_iface (media, multicast_iface);
1970     g_free (multicast_iface);
1971   }
1972   if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
1973     gst_rtsp_media_set_permissions (media, perms);
1974     gst_rtsp_permissions_unref (perms);
1975   }
1976 }
1977
1978 /**
1979  * gst_rtsp_media_factory_create_element:
1980  * @factory: a #GstRTSPMediaFactory
1981  * @url: the url used
1982  *
1983  * Construct and return a #GstElement that is a #GstBin containing
1984  * the elements to use for streaming the media.
1985  *
1986  * The bin should contain payloaders pay\%d for each stream. The default
1987  * implementation of this function returns the bin created from the
1988  * launch parameter.
1989  *
1990  * Returns: (transfer floating): a new #GstElement.
1991  */
1992 GstElement *
1993 gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
1994     const GstRTSPUrl * url)
1995 {
1996   GstRTSPMediaFactoryClass *klass;
1997   GstElement *result;
1998
1999   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL);
2000   g_return_val_if_fail (url != NULL, NULL);
2001
2002   klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
2003
2004   if (klass->create_element)
2005     result = klass->create_element (factory, url);
2006   else
2007     result = NULL;
2008
2009   return result;
2010 }
2011
2012 /**
2013  * gst_rtsp_media_factory_set_transport_mode:
2014  * @factory: a #GstRTSPMediaFactory
2015  * @mode: the new value
2016  *
2017  * Configure if this factory creates media for PLAY or RECORD modes.
2018  */
2019 void
2020 gst_rtsp_media_factory_set_transport_mode (GstRTSPMediaFactory * factory,
2021     GstRTSPTransportMode mode)
2022 {
2023   GstRTSPMediaFactoryPrivate *priv;
2024
2025   g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
2026
2027   priv = factory->priv;
2028
2029   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
2030   priv->transport_mode = mode;
2031   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
2032 }
2033
2034 /**
2035  * gst_rtsp_media_factory_get_transport_mode:
2036  * @factory: a #GstRTSPMediaFactory
2037  *
2038  * Get if media created from this factory can be used for PLAY or RECORD
2039  * methods.
2040  *
2041  * Returns: The transport mode.
2042  */
2043 GstRTSPTransportMode
2044 gst_rtsp_media_factory_get_transport_mode (GstRTSPMediaFactory * factory)
2045 {
2046   GstRTSPMediaFactoryPrivate *priv;
2047   GstRTSPTransportMode result;
2048
2049   g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
2050
2051   priv = factory->priv;
2052
2053   GST_RTSP_MEDIA_FACTORY_LOCK (factory);
2054   result = priv->transport_mode;
2055   GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
2056
2057   return result;
2058 }