rtsp-media: unref clock (if set) when finalizing
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-media.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
23  * @short_description: The media pipeline
24  * @see_also: #GstRTSPMediaFactory, #GstRTSPStream, #GstRTSPSession,
25  *     #GstRTSPSessionMedia
26  *
27  * a #GstRTSPMedia contains the complete GStreamer pipeline to manage the
28  * streaming to the clients. The actual data transfer is done by the
29  * #GstRTSPStream objects that are created and exposed by the #GstRTSPMedia.
30  *
31  * The #GstRTSPMedia is usually created from a #GstRTSPMediaFactory when the
32  * client does a DESCRIBE or SETUP of a resource.
33  *
34  * A media is created with gst_rtsp_media_new() that takes the element that will
35  * provide the streaming elements. For each of the streams, a new #GstRTSPStream
36  * object needs to be made with the gst_rtsp_media_create_stream() which takes
37  * the payloader element and the source pad that produces the RTP stream.
38  *
39  * The pipeline of the media is set to PAUSED with gst_rtsp_media_prepare(). The
40  * prepare method will add rtpbin and sinks and sources to send and receive RTP
41  * and RTCP packets from the clients. Each stream srcpad is connected to an
42  * input into the internal rtpbin.
43  *
44  * It is also possible to dynamically create #GstRTSPStream objects during the
45  * prepare phase. With gst_rtsp_media_get_status() you can check the status of
46  * the prepare phase.
47  *
48  * After the media is prepared, it is ready for streaming. It will usually be
49  * managed in a session with gst_rtsp_session_manage_media(). See
50  * #GstRTSPSession and #GstRTSPSessionMedia.
51  *
52  * The state of the media can be controlled with gst_rtsp_media_set_state ().
53  * Seeking can be done with gst_rtsp_media_seek().
54  *
55  * With gst_rtsp_media_unprepare() the pipeline is stopped and shut down. When
56  * gst_rtsp_media_set_eos_shutdown() an EOS will be sent to the pipeline to
57  * cleanly shut down.
58  *
59  * With gst_rtsp_media_set_shared(), the media can be shared between multiple
60  * clients. With gst_rtsp_media_set_reusable() you can control if the pipeline
61  * can be prepared again after an unprepare.
62  *
63  * Last reviewed on 2013-07-11 (1.0.0)
64  */
65
66 #include <stdio.h>
67 #include <string.h>
68 #include <stdlib.h>
69
70 #include <gst/app/gstappsrc.h>
71 #include <gst/app/gstappsink.h>
72
73 #include <gst/sdp/gstmikey.h>
74 #include <gst/rtp/gstrtppayloads.h>
75
76 #define AES_128_KEY_LEN 16
77 #define AES_256_KEY_LEN 32
78
79 #define HMAC_32_KEY_LEN 4
80 #define HMAC_80_KEY_LEN 10
81
82 #include "rtsp-media.h"
83
84 struct _GstRTSPMediaPrivate
85 {
86   GMutex lock;
87   GCond cond;
88
89   /* protected by lock */
90   GstRTSPPermissions *permissions;
91   gboolean shared;
92   gboolean suspend_mode;
93   gboolean reusable;
94   GstRTSPProfile profiles;
95   GstRTSPLowerTrans protocols;
96   gboolean reused;
97   gboolean eos_shutdown;
98   guint buffer_size;
99   GstRTSPAddressPool *pool;
100   gchar *multicast_iface;
101   gboolean blocked;
102   GstRTSPTransportMode transport_mode;
103   gboolean stop_on_disconnect;
104
105   GstElement *element;
106   GRecMutex state_lock;         /* locking order: state lock, lock */
107   GPtrArray *streams;           /* protected by lock */
108   GList *dynamic;               /* protected by lock */
109   GstRTSPMediaStatus status;    /* protected by lock */
110   gint prepare_count;
111   gint n_active;
112   gboolean complete;
113
114   /* the pipeline for the media */
115   GstElement *pipeline;
116   GSource *source;
117   guint id;
118   GstRTSPThread *thread;
119   GList *pending_pipeline_elements;
120
121   gboolean time_provider;
122   GstNetTimeProvider *nettime;
123
124   gboolean is_live;
125   GstClockTimeDiff seekable;
126   gboolean buffering;
127   GstState target_state;
128
129   /* RTP session manager */
130   GstElement *rtpbin;
131
132   /* the range of media */
133   GstRTSPTimeRange range;       /* protected by lock */
134   GstClockTime range_start;
135   GstClockTime range_stop;
136
137   GList *payloads;              /* protected by lock */
138   GstClockTime rtx_time;        /* protected by lock */
139   gboolean do_retransmission;   /* protected by lock */
140   guint latency;                /* protected by lock */
141   GstClock *clock;              /* protected by lock */
142   GstRTSPPublishClockMode publish_clock_mode;
143
144   /* Dynamic element handling */
145   guint nb_dynamic_elements;
146   guint no_more_pads_pending;
147 };
148
149 #define DEFAULT_SHARED          FALSE
150 #define DEFAULT_SUSPEND_MODE    GST_RTSP_SUSPEND_MODE_NONE
151 #define DEFAULT_REUSABLE        FALSE
152 #define DEFAULT_PROFILES        GST_RTSP_PROFILE_AVP
153 #define DEFAULT_PROTOCOLS       GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
154                                         GST_RTSP_LOWER_TRANS_TCP
155 #define DEFAULT_EOS_SHUTDOWN    FALSE
156 #define DEFAULT_BUFFER_SIZE     0x80000
157 #define DEFAULT_TIME_PROVIDER   FALSE
158 #define DEFAULT_LATENCY         200
159 #define DEFAULT_TRANSPORT_MODE  GST_RTSP_TRANSPORT_MODE_PLAY
160 #define DEFAULT_STOP_ON_DISCONNECT TRUE
161
162 #define DEFAULT_DO_RETRANSMISSION FALSE
163
164 /* define to dump received RTCP packets */
165 #undef DUMP_STATS
166
167 enum
168 {
169   PROP_0,
170   PROP_SHARED,
171   PROP_SUSPEND_MODE,
172   PROP_REUSABLE,
173   PROP_PROFILES,
174   PROP_PROTOCOLS,
175   PROP_EOS_SHUTDOWN,
176   PROP_BUFFER_SIZE,
177   PROP_ELEMENT,
178   PROP_TIME_PROVIDER,
179   PROP_LATENCY,
180   PROP_TRANSPORT_MODE,
181   PROP_STOP_ON_DISCONNECT,
182   PROP_CLOCK,
183   PROP_LAST
184 };
185
186 enum
187 {
188   SIGNAL_NEW_STREAM,
189   SIGNAL_REMOVED_STREAM,
190   SIGNAL_PREPARED,
191   SIGNAL_UNPREPARED,
192   SIGNAL_TARGET_STATE,
193   SIGNAL_NEW_STATE,
194   SIGNAL_LAST
195 };
196
197 GST_DEBUG_CATEGORY_STATIC (rtsp_media_debug);
198 #define GST_CAT_DEFAULT rtsp_media_debug
199
200 static void gst_rtsp_media_get_property (GObject * object, guint propid,
201     GValue * value, GParamSpec * pspec);
202 static void gst_rtsp_media_set_property (GObject * object, guint propid,
203     const GValue * value, GParamSpec * pspec);
204 static void gst_rtsp_media_finalize (GObject * obj);
205
206 static gboolean default_handle_message (GstRTSPMedia * media,
207     GstMessage * message);
208 static void finish_unprepare (GstRTSPMedia * media);
209 static gboolean default_prepare (GstRTSPMedia * media, GstRTSPThread * thread);
210 static gboolean default_unprepare (GstRTSPMedia * media);
211 static gboolean default_suspend (GstRTSPMedia * media);
212 static gboolean default_unsuspend (GstRTSPMedia * media);
213 static gboolean default_convert_range (GstRTSPMedia * media,
214     GstRTSPTimeRange * range, GstRTSPRangeUnit unit);
215 static gboolean default_query_position (GstRTSPMedia * media,
216     gint64 * position);
217 static gboolean default_query_stop (GstRTSPMedia * media, gint64 * stop);
218 static GstElement *default_create_rtpbin (GstRTSPMedia * media);
219 static gboolean default_setup_sdp (GstRTSPMedia * media, GstSDPMessage * sdp,
220     GstSDPInfo * info);
221 static gboolean default_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp);
222
223 static gboolean wait_preroll (GstRTSPMedia * media);
224
225 static GstElement *find_payload_element (GstElement * payloader);
226
227 static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
228
229 static gboolean check_complete (GstRTSPMedia * media);
230
231 #define C_ENUM(v) ((gint) v)
232
233 GType
234 gst_rtsp_suspend_mode_get_type (void)
235 {
236   static gsize id = 0;
237   static const GEnumValue values[] = {
238     {C_ENUM (GST_RTSP_SUSPEND_MODE_NONE), "GST_RTSP_SUSPEND_MODE_NONE", "none"},
239     {C_ENUM (GST_RTSP_SUSPEND_MODE_PAUSE), "GST_RTSP_SUSPEND_MODE_PAUSE",
240         "pause"},
241     {C_ENUM (GST_RTSP_SUSPEND_MODE_RESET), "GST_RTSP_SUSPEND_MODE_RESET",
242         "reset"},
243     {0, NULL, NULL}
244   };
245
246   if (g_once_init_enter (&id)) {
247     GType tmp = g_enum_register_static ("GstRTSPSuspendMode", values);
248     g_once_init_leave (&id, tmp);
249   }
250   return (GType) id;
251 }
252
253 #define C_FLAGS(v) ((guint) v)
254
255 GType
256 gst_rtsp_transport_mode_get_type (void)
257 {
258   static gsize id = 0;
259   static const GFlagsValue values[] = {
260     {C_FLAGS (GST_RTSP_TRANSPORT_MODE_PLAY), "GST_RTSP_TRANSPORT_MODE_PLAY",
261         "play"},
262     {C_FLAGS (GST_RTSP_TRANSPORT_MODE_RECORD), "GST_RTSP_TRANSPORT_MODE_RECORD",
263         "record"},
264     {0, NULL, NULL}
265   };
266
267   if (g_once_init_enter (&id)) {
268     GType tmp = g_flags_register_static ("GstRTSPTransportMode", values);
269     g_once_init_leave (&id, tmp);
270   }
271   return (GType) id;
272 }
273
274 GType
275 gst_rtsp_publish_clock_mode_get_type (void)
276 {
277   static gsize id = 0;
278   static const GEnumValue values[] = {
279     {C_ENUM (GST_RTSP_PUBLISH_CLOCK_MODE_NONE),
280         "GST_RTSP_PUBLISH_CLOCK_MODE_NONE", "none"},
281     {C_ENUM (GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK),
282           "GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK",
283         "clock"},
284     {C_ENUM (GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK_AND_OFFSET),
285           "GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK_AND_OFFSET",
286         "clock-and-offset"},
287     {0, NULL, NULL}
288   };
289
290   if (g_once_init_enter (&id)) {
291     GType tmp = g_enum_register_static ("GstRTSPPublishClockMode", values);
292     g_once_init_leave (&id, tmp);
293   }
294   return (GType) id;
295 }
296
297 G_DEFINE_TYPE_WITH_PRIVATE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT);
298
299 static void
300 gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
301 {
302   GObjectClass *gobject_class;
303
304   gobject_class = G_OBJECT_CLASS (klass);
305
306   gobject_class->get_property = gst_rtsp_media_get_property;
307   gobject_class->set_property = gst_rtsp_media_set_property;
308   gobject_class->finalize = gst_rtsp_media_finalize;
309
310   g_object_class_install_property (gobject_class, PROP_SHARED,
311       g_param_spec_boolean ("shared", "Shared",
312           "If this media pipeline can be shared", DEFAULT_SHARED,
313           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
314
315   g_object_class_install_property (gobject_class, PROP_SUSPEND_MODE,
316       g_param_spec_enum ("suspend-mode", "Suspend Mode",
317           "How to suspend the media in PAUSED", GST_TYPE_RTSP_SUSPEND_MODE,
318           DEFAULT_SUSPEND_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
319
320   g_object_class_install_property (gobject_class, PROP_REUSABLE,
321       g_param_spec_boolean ("reusable", "Reusable",
322           "If this media pipeline can be reused after an unprepare",
323           DEFAULT_REUSABLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
324
325   g_object_class_install_property (gobject_class, PROP_PROFILES,
326       g_param_spec_flags ("profiles", "Profiles",
327           "Allowed transfer profiles", GST_TYPE_RTSP_PROFILE,
328           DEFAULT_PROFILES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
329
330   g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
331       g_param_spec_flags ("protocols", "Protocols",
332           "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
333           DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
334
335   g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
336       g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
337           "Send an EOS event to the pipeline before unpreparing",
338           DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
339
340   g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
341       g_param_spec_uint ("buffer-size", "Buffer Size",
342           "The kernel UDP buffer size to use", 0, G_MAXUINT,
343           DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
344
345   g_object_class_install_property (gobject_class, PROP_ELEMENT,
346       g_param_spec_object ("element", "The Element",
347           "The GstBin to use for streaming the media", GST_TYPE_ELEMENT,
348           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
349
350   g_object_class_install_property (gobject_class, PROP_TIME_PROVIDER,
351       g_param_spec_boolean ("time-provider", "Time Provider",
352           "Use a NetTimeProvider for clients",
353           DEFAULT_TIME_PROVIDER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
354
355   g_object_class_install_property (gobject_class, PROP_LATENCY,
356       g_param_spec_uint ("latency", "Latency",
357           "Latency used for receiving media in milliseconds", 0, G_MAXUINT,
358           DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
359
360   g_object_class_install_property (gobject_class, PROP_TRANSPORT_MODE,
361       g_param_spec_flags ("transport-mode", "Transport Mode",
362           "If this media pipeline can be used for PLAY or RECORD",
363           GST_TYPE_RTSP_TRANSPORT_MODE, DEFAULT_TRANSPORT_MODE,
364           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
365
366   g_object_class_install_property (gobject_class, PROP_STOP_ON_DISCONNECT,
367       g_param_spec_boolean ("stop-on-disconnect", "Stop On Disconnect",
368           "If this media pipeline should be stopped "
369           "when a client disconnects without TEARDOWN",
370           DEFAULT_STOP_ON_DISCONNECT,
371           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
372
373   g_object_class_install_property (gobject_class, PROP_CLOCK,
374       g_param_spec_object ("clock", "Clock",
375           "Clock to be used by the media pipeline",
376           GST_TYPE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
377
378   gst_rtsp_media_signals[SIGNAL_NEW_STREAM] =
379       g_signal_new ("new-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
380       G_STRUCT_OFFSET (GstRTSPMediaClass, new_stream), NULL, NULL,
381       g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_RTSP_STREAM);
382
383   gst_rtsp_media_signals[SIGNAL_REMOVED_STREAM] =
384       g_signal_new ("removed-stream", G_TYPE_FROM_CLASS (klass),
385       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaClass, removed_stream),
386       NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
387       GST_TYPE_RTSP_STREAM);
388
389   gst_rtsp_media_signals[SIGNAL_PREPARED] =
390       g_signal_new ("prepared", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
391       G_STRUCT_OFFSET (GstRTSPMediaClass, prepared), NULL, NULL,
392       g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
393
394   gst_rtsp_media_signals[SIGNAL_UNPREPARED] =
395       g_signal_new ("unprepared", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
396       G_STRUCT_OFFSET (GstRTSPMediaClass, unprepared), NULL, NULL,
397       g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
398
399   gst_rtsp_media_signals[SIGNAL_TARGET_STATE] =
400       g_signal_new ("target-state", G_TYPE_FROM_CLASS (klass),
401       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaClass, target_state),
402       NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_INT);
403
404   gst_rtsp_media_signals[SIGNAL_NEW_STATE] =
405       g_signal_new ("new-state", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
406       G_STRUCT_OFFSET (GstRTSPMediaClass, new_state), NULL, NULL,
407       g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_INT);
408
409   GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmedia", 0, "GstRTSPMedia");
410
411   klass->handle_message = default_handle_message;
412   klass->prepare = default_prepare;
413   klass->unprepare = default_unprepare;
414   klass->suspend = default_suspend;
415   klass->unsuspend = default_unsuspend;
416   klass->convert_range = default_convert_range;
417   klass->query_position = default_query_position;
418   klass->query_stop = default_query_stop;
419   klass->create_rtpbin = default_create_rtpbin;
420   klass->setup_sdp = default_setup_sdp;
421   klass->handle_sdp = default_handle_sdp;
422 }
423
424 static void
425 gst_rtsp_media_init (GstRTSPMedia * media)
426 {
427   GstRTSPMediaPrivate *priv = gst_rtsp_media_get_instance_private (media);
428
429   media->priv = priv;
430
431   priv->streams = g_ptr_array_new_with_free_func (g_object_unref);
432   g_mutex_init (&priv->lock);
433   g_cond_init (&priv->cond);
434   g_rec_mutex_init (&priv->state_lock);
435
436   priv->shared = DEFAULT_SHARED;
437   priv->suspend_mode = DEFAULT_SUSPEND_MODE;
438   priv->reusable = DEFAULT_REUSABLE;
439   priv->profiles = DEFAULT_PROFILES;
440   priv->protocols = DEFAULT_PROTOCOLS;
441   priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
442   priv->buffer_size = DEFAULT_BUFFER_SIZE;
443   priv->time_provider = DEFAULT_TIME_PROVIDER;
444   priv->transport_mode = DEFAULT_TRANSPORT_MODE;
445   priv->stop_on_disconnect = DEFAULT_STOP_ON_DISCONNECT;
446   priv->publish_clock_mode = GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK;
447   priv->do_retransmission = DEFAULT_DO_RETRANSMISSION;
448 }
449
450 static void
451 gst_rtsp_media_finalize (GObject * obj)
452 {
453   GstRTSPMediaPrivate *priv;
454   GstRTSPMedia *media;
455
456   media = GST_RTSP_MEDIA (obj);
457   priv = media->priv;
458
459   GST_INFO ("finalize media %p", media);
460
461   if (priv->permissions)
462     gst_rtsp_permissions_unref (priv->permissions);
463
464   g_ptr_array_unref (priv->streams);
465
466   g_list_free_full (priv->dynamic, gst_object_unref);
467   g_list_free_full (priv->pending_pipeline_elements, gst_object_unref);
468
469   if (priv->pipeline)
470     gst_object_unref (priv->pipeline);
471   if (priv->nettime)
472     gst_object_unref (priv->nettime);
473   gst_object_unref (priv->element);
474   if (priv->pool)
475     g_object_unref (priv->pool);
476   if (priv->payloads)
477     g_list_free (priv->payloads);
478   if (priv->clock)
479     gst_object_unref (priv->clock);
480   g_free (priv->multicast_iface);
481   g_mutex_clear (&priv->lock);
482   g_cond_clear (&priv->cond);
483   g_rec_mutex_clear (&priv->state_lock);
484
485   G_OBJECT_CLASS (gst_rtsp_media_parent_class)->finalize (obj);
486 }
487
488 static void
489 gst_rtsp_media_get_property (GObject * object, guint propid,
490     GValue * value, GParamSpec * pspec)
491 {
492   GstRTSPMedia *media = GST_RTSP_MEDIA (object);
493
494   switch (propid) {
495     case PROP_ELEMENT:
496       g_value_set_object (value, media->priv->element);
497       break;
498     case PROP_SHARED:
499       g_value_set_boolean (value, gst_rtsp_media_is_shared (media));
500       break;
501     case PROP_SUSPEND_MODE:
502       g_value_set_enum (value, gst_rtsp_media_get_suspend_mode (media));
503       break;
504     case PROP_REUSABLE:
505       g_value_set_boolean (value, gst_rtsp_media_is_reusable (media));
506       break;
507     case PROP_PROFILES:
508       g_value_set_flags (value, gst_rtsp_media_get_profiles (media));
509       break;
510     case PROP_PROTOCOLS:
511       g_value_set_flags (value, gst_rtsp_media_get_protocols (media));
512       break;
513     case PROP_EOS_SHUTDOWN:
514       g_value_set_boolean (value, gst_rtsp_media_is_eos_shutdown (media));
515       break;
516     case PROP_BUFFER_SIZE:
517       g_value_set_uint (value, gst_rtsp_media_get_buffer_size (media));
518       break;
519     case PROP_TIME_PROVIDER:
520       g_value_set_boolean (value, gst_rtsp_media_is_time_provider (media));
521       break;
522     case PROP_LATENCY:
523       g_value_set_uint (value, gst_rtsp_media_get_latency (media));
524       break;
525     case PROP_TRANSPORT_MODE:
526       g_value_set_flags (value, gst_rtsp_media_get_transport_mode (media));
527       break;
528     case PROP_STOP_ON_DISCONNECT:
529       g_value_set_boolean (value, gst_rtsp_media_is_stop_on_disconnect (media));
530       break;
531     case PROP_CLOCK:
532       g_value_take_object (value, gst_rtsp_media_get_clock (media));
533       break;
534     default:
535       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
536   }
537 }
538
539 static void
540 gst_rtsp_media_set_property (GObject * object, guint propid,
541     const GValue * value, GParamSpec * pspec)
542 {
543   GstRTSPMedia *media = GST_RTSP_MEDIA (object);
544
545   switch (propid) {
546     case PROP_ELEMENT:
547       media->priv->element = g_value_get_object (value);
548       gst_object_ref_sink (media->priv->element);
549       break;
550     case PROP_SHARED:
551       gst_rtsp_media_set_shared (media, g_value_get_boolean (value));
552       break;
553     case PROP_SUSPEND_MODE:
554       gst_rtsp_media_set_suspend_mode (media, g_value_get_enum (value));
555       break;
556     case PROP_REUSABLE:
557       gst_rtsp_media_set_reusable (media, g_value_get_boolean (value));
558       break;
559     case PROP_PROFILES:
560       gst_rtsp_media_set_profiles (media, g_value_get_flags (value));
561       break;
562     case PROP_PROTOCOLS:
563       gst_rtsp_media_set_protocols (media, g_value_get_flags (value));
564       break;
565     case PROP_EOS_SHUTDOWN:
566       gst_rtsp_media_set_eos_shutdown (media, g_value_get_boolean (value));
567       break;
568     case PROP_BUFFER_SIZE:
569       gst_rtsp_media_set_buffer_size (media, g_value_get_uint (value));
570       break;
571     case PROP_TIME_PROVIDER:
572       gst_rtsp_media_use_time_provider (media, g_value_get_boolean (value));
573       break;
574     case PROP_LATENCY:
575       gst_rtsp_media_set_latency (media, g_value_get_uint (value));
576       break;
577     case PROP_TRANSPORT_MODE:
578       gst_rtsp_media_set_transport_mode (media, g_value_get_flags (value));
579       break;
580     case PROP_STOP_ON_DISCONNECT:
581       gst_rtsp_media_set_stop_on_disconnect (media,
582           g_value_get_boolean (value));
583       break;
584     case PROP_CLOCK:
585       gst_rtsp_media_set_clock (media, g_value_get_object (value));
586       break;
587     default:
588       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
589   }
590 }
591
592 typedef struct
593 {
594   gint64 position;
595   gboolean complete_streams_only;
596   gboolean ret;
597 } DoQueryPositionData;
598
599 static void
600 do_query_position (GstRTSPStream * stream, DoQueryPositionData * data)
601 {
602   gint64 tmp;
603
604   if (!gst_rtsp_stream_is_sender (stream))
605     return;
606
607   if (data->complete_streams_only && !gst_rtsp_stream_is_complete (stream)) {
608     GST_DEBUG_OBJECT (stream, "stream not complete, do not query position");
609     return;
610   }
611
612   if (gst_rtsp_stream_query_position (stream, &tmp)) {
613     data->position = MIN (data->position, tmp);
614     data->ret = TRUE;
615   }
616
617   GST_INFO_OBJECT (stream, "media position: %" GST_TIME_FORMAT,
618       GST_TIME_ARGS (data->position));
619 }
620
621 static gboolean
622 default_query_position (GstRTSPMedia * media, gint64 * position)
623 {
624   GstRTSPMediaPrivate *priv;
625   DoQueryPositionData data;
626
627   priv = media->priv;
628
629   data.position = G_MAXINT64;
630   data.ret = FALSE;
631
632   /* if the media is complete, i.e. one or more streams have been configured
633    * with sinks, then we want to query the position on those streams only.
634    * a query on an incmplete stream may return a position that originates from
635    * an earlier preroll */
636   if (check_complete (media))
637     data.complete_streams_only = TRUE;
638   else
639     data.complete_streams_only = FALSE;
640
641   g_ptr_array_foreach (priv->streams, (GFunc) do_query_position, &data);
642
643   if (!data.ret)
644     *position = GST_CLOCK_TIME_NONE;
645   else
646     *position = data.position;
647
648   return data.ret;
649 }
650
651 typedef struct
652 {
653   gint64 stop;
654   gboolean ret;
655 } DoQueryStopData;
656
657 static void
658 do_query_stop (GstRTSPStream * stream, DoQueryStopData * data)
659 {
660   gint64 tmp = 0;
661
662   if (gst_rtsp_stream_query_stop (stream, &tmp)) {
663     data->stop = MAX (data->stop, tmp);
664     data->ret = TRUE;
665   }
666 }
667
668 static gboolean
669 default_query_stop (GstRTSPMedia * media, gint64 * stop)
670 {
671   GstRTSPMediaPrivate *priv;
672   DoQueryStopData data;
673
674   priv = media->priv;
675
676   data.stop = -1;
677   data.ret = FALSE;
678
679   g_ptr_array_foreach (priv->streams, (GFunc) do_query_stop, &data);
680
681   *stop = data.stop;
682
683   return data.ret;
684 }
685
686 static GstElement *
687 default_create_rtpbin (GstRTSPMedia * media)
688 {
689   GstElement *rtpbin;
690
691   rtpbin = gst_element_factory_make ("rtpbin", NULL);
692
693   return rtpbin;
694 }
695
696 static gboolean
697 is_receive_only (GstRTSPMedia * media)
698 {
699   GstRTSPMediaPrivate *priv = media->priv;
700   gboolean recive_only = TRUE;
701   guint i;
702
703   for (i = 0; i < priv->streams->len; i++) {
704     GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
705     if (gst_rtsp_stream_is_sender (stream) ||
706         !gst_rtsp_stream_is_receiver (stream)) {
707       recive_only = FALSE;
708       break;
709     }
710   }
711
712   return recive_only;
713 }
714
715 /* must be called with state lock */
716 static void
717 check_seekable (GstRTSPMedia * media)
718 {
719   GstQuery *query;
720   GstRTSPMediaPrivate *priv = media->priv;
721
722   /* Update the seekable state of the pipeline in case it changed */
723   if (is_receive_only (media)) {
724     /* TODO: Seeking for "receive-only"? */
725     priv->seekable = -1;
726   } else {
727     guint i, n = priv->streams->len;
728
729     for (i = 0; i < n; i++) {
730       GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
731
732       if (gst_rtsp_stream_get_publish_clock_mode (stream) ==
733           GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK_AND_OFFSET) {
734         priv->seekable = -1;
735         return;
736       }
737     }
738   }
739
740   query = gst_query_new_seeking (GST_FORMAT_TIME);
741   if (gst_element_query (priv->pipeline, query)) {
742     GstFormat format;
743     gboolean seekable;
744     gint64 start, end;
745
746     gst_query_parse_seeking (query, &format, &seekable, &start, &end);
747     priv->seekable = seekable ? G_MAXINT64 : 0;
748   } else if (priv->streams->len) {
749     gboolean seekable = TRUE;
750     guint i, n = priv->streams->len;
751
752     GST_DEBUG_OBJECT (media, "Checking %d streams", n);
753     for (i = 0; i < n; i++) {
754       GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
755       seekable &= gst_rtsp_stream_seekable (stream);
756     }
757     priv->seekable = seekable ? G_MAXINT64 : -1;
758   }
759
760   GST_DEBUG_OBJECT (media, "seekable:%" G_GINT64_FORMAT, priv->seekable);
761
762   gst_query_unref (query);
763 }
764
765 /* must be called with state lock */
766 static gboolean
767 check_complete (GstRTSPMedia * media)
768 {
769   GstRTSPMediaPrivate *priv = media->priv;
770
771   guint i, n = priv->streams->len;
772
773   for (i = 0; i < n; i++) {
774     GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
775
776     if (gst_rtsp_stream_is_complete (stream))
777       return TRUE;
778   }
779
780   return FALSE;
781 }
782
783 /* must be called with state lock */
784 static void
785 collect_media_stats (GstRTSPMedia * media)
786 {
787   GstRTSPMediaPrivate *priv = media->priv;
788   gint64 position = 0, stop = -1;
789
790   if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED &&
791       priv->status != GST_RTSP_MEDIA_STATUS_PREPARING)
792     return;
793
794   priv->range.unit = GST_RTSP_RANGE_NPT;
795
796   GST_INFO ("collect media stats");
797
798   if (priv->is_live) {
799     priv->range.min.type = GST_RTSP_TIME_NOW;
800     priv->range.min.seconds = -1;
801     priv->range_start = -1;
802     priv->range.max.type = GST_RTSP_TIME_END;
803     priv->range.max.seconds = -1;
804     priv->range_stop = -1;
805   } else {
806     GstRTSPMediaClass *klass;
807     gboolean ret;
808
809     klass = GST_RTSP_MEDIA_GET_CLASS (media);
810
811     /* get the position */
812     ret = FALSE;
813     if (klass->query_position)
814       ret = klass->query_position (media, &position);
815
816     if (!ret) {
817       GST_INFO ("position query failed");
818       position = 0;
819     }
820
821     /* get the current segment stop */
822     ret = FALSE;
823     if (klass->query_stop)
824       ret = klass->query_stop (media, &stop);
825
826     if (!ret) {
827       GST_INFO ("stop query failed");
828       stop = -1;
829     }
830
831     GST_INFO ("stats: position %" GST_TIME_FORMAT ", stop %"
832         GST_TIME_FORMAT, GST_TIME_ARGS (position), GST_TIME_ARGS (stop));
833
834     if (position == -1) {
835       priv->range.min.type = GST_RTSP_TIME_NOW;
836       priv->range.min.seconds = -1;
837       priv->range_start = -1;
838     } else {
839       priv->range.min.type = GST_RTSP_TIME_SECONDS;
840       priv->range.min.seconds = ((gdouble) position) / GST_SECOND;
841       priv->range_start = position;
842     }
843     if (stop == -1) {
844       priv->range.max.type = GST_RTSP_TIME_END;
845       priv->range.max.seconds = -1;
846       priv->range_stop = -1;
847     } else {
848       priv->range.max.type = GST_RTSP_TIME_SECONDS;
849       priv->range.max.seconds = ((gdouble) stop) / GST_SECOND;
850       priv->range_stop = stop;
851     }
852
853     check_seekable (media);
854   }
855 }
856
857 /**
858  * gst_rtsp_media_new:
859  * @element: (transfer full): a #GstElement
860  *
861  * Create a new #GstRTSPMedia instance. @element is the bin element that
862  * provides the different streams. The #GstRTSPMedia object contains the
863  * element to produce RTP data for one or more related (audio/video/..)
864  * streams.
865  *
866  * Ownership is taken of @element.
867  *
868  * Returns: (transfer full): a new #GstRTSPMedia object.
869  */
870 GstRTSPMedia *
871 gst_rtsp_media_new (GstElement * element)
872 {
873   GstRTSPMedia *result;
874
875   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
876
877   result = g_object_new (GST_TYPE_RTSP_MEDIA, "element", element, NULL);
878
879   return result;
880 }
881
882 /**
883  * gst_rtsp_media_get_element:
884  * @media: a #GstRTSPMedia
885  *
886  * Get the element that was used when constructing @media.
887  *
888  * Returns: (transfer full): a #GstElement. Unref after usage.
889  */
890 GstElement *
891 gst_rtsp_media_get_element (GstRTSPMedia * media)
892 {
893   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
894
895   return gst_object_ref (media->priv->element);
896 }
897
898 /**
899  * gst_rtsp_media_take_pipeline:
900  * @media: a #GstRTSPMedia
901  * @pipeline: (transfer full): a #GstPipeline
902  *
903  * Set @pipeline as the #GstPipeline for @media. Ownership is
904  * taken of @pipeline.
905  */
906 void
907 gst_rtsp_media_take_pipeline (GstRTSPMedia * media, GstPipeline * pipeline)
908 {
909   GstRTSPMediaPrivate *priv;
910   GstElement *old;
911   GstNetTimeProvider *nettime;
912   GList *l;
913
914   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
915   g_return_if_fail (GST_IS_PIPELINE (pipeline));
916
917   priv = media->priv;
918
919   g_mutex_lock (&priv->lock);
920   old = priv->pipeline;
921   priv->pipeline = GST_ELEMENT_CAST (pipeline);
922   nettime = priv->nettime;
923   priv->nettime = NULL;
924   g_mutex_unlock (&priv->lock);
925
926   if (old)
927     gst_object_unref (old);
928
929   if (nettime)
930     gst_object_unref (nettime);
931
932   gst_bin_add (GST_BIN_CAST (pipeline), priv->element);
933
934   for (l = priv->pending_pipeline_elements; l; l = l->next) {
935     gst_bin_add (GST_BIN_CAST (pipeline), l->data);
936   }
937   g_list_free (priv->pending_pipeline_elements);
938   priv->pending_pipeline_elements = NULL;
939 }
940
941 /**
942  * gst_rtsp_media_set_permissions:
943  * @media: a #GstRTSPMedia
944  * @permissions: (transfer none) (nullable): a #GstRTSPPermissions
945  *
946  * Set @permissions on @media.
947  */
948 void
949 gst_rtsp_media_set_permissions (GstRTSPMedia * media,
950     GstRTSPPermissions * permissions)
951 {
952   GstRTSPMediaPrivate *priv;
953
954   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
955
956   priv = media->priv;
957
958   g_mutex_lock (&priv->lock);
959   if (priv->permissions)
960     gst_rtsp_permissions_unref (priv->permissions);
961   if ((priv->permissions = permissions))
962     gst_rtsp_permissions_ref (permissions);
963   g_mutex_unlock (&priv->lock);
964 }
965
966 /**
967  * gst_rtsp_media_get_permissions:
968  * @media: a #GstRTSPMedia
969  *
970  * Get the permissions object from @media.
971  *
972  * Returns: (transfer full) (nullable): a #GstRTSPPermissions object, unref after usage.
973  */
974 GstRTSPPermissions *
975 gst_rtsp_media_get_permissions (GstRTSPMedia * media)
976 {
977   GstRTSPMediaPrivate *priv;
978   GstRTSPPermissions *result;
979
980   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
981
982   priv = media->priv;
983
984   g_mutex_lock (&priv->lock);
985   if ((result = priv->permissions))
986     gst_rtsp_permissions_ref (result);
987   g_mutex_unlock (&priv->lock);
988
989   return result;
990 }
991
992 /**
993  * gst_rtsp_media_set_suspend_mode:
994  * @media: a #GstRTSPMedia
995  * @mode: the new #GstRTSPSuspendMode
996  *
997  * Control how @ media will be suspended after the SDP has been generated and
998  * after a PAUSE request has been performed.
999  *
1000  * Media must be unprepared when setting the suspend mode.
1001  */
1002 void
1003 gst_rtsp_media_set_suspend_mode (GstRTSPMedia * media, GstRTSPSuspendMode mode)
1004 {
1005   GstRTSPMediaPrivate *priv;
1006
1007   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1008
1009   priv = media->priv;
1010
1011   g_rec_mutex_lock (&priv->state_lock);
1012   if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARED)
1013     goto was_prepared;
1014   priv->suspend_mode = mode;
1015   g_rec_mutex_unlock (&priv->state_lock);
1016
1017   return;
1018
1019   /* ERRORS */
1020 was_prepared:
1021   {
1022     GST_WARNING ("media %p was prepared", media);
1023     g_rec_mutex_unlock (&priv->state_lock);
1024   }
1025 }
1026
1027 /**
1028  * gst_rtsp_media_get_suspend_mode:
1029  * @media: a #GstRTSPMedia
1030  *
1031  * Get how @media will be suspended.
1032  *
1033  * Returns: #GstRTSPSuspendMode.
1034  */
1035 GstRTSPSuspendMode
1036 gst_rtsp_media_get_suspend_mode (GstRTSPMedia * media)
1037 {
1038   GstRTSPMediaPrivate *priv;
1039   GstRTSPSuspendMode res;
1040
1041   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), GST_RTSP_SUSPEND_MODE_NONE);
1042
1043   priv = media->priv;
1044
1045   g_rec_mutex_lock (&priv->state_lock);
1046   res = priv->suspend_mode;
1047   g_rec_mutex_unlock (&priv->state_lock);
1048
1049   return res;
1050 }
1051
1052 /**
1053  * gst_rtsp_media_set_shared:
1054  * @media: a #GstRTSPMedia
1055  * @shared: the new value
1056  *
1057  * Set or unset if the pipeline for @media can be shared will multiple clients.
1058  * When @shared is %TRUE, client requests for this media will share the media
1059  * pipeline.
1060  */
1061 void
1062 gst_rtsp_media_set_shared (GstRTSPMedia * media, gboolean shared)
1063 {
1064   GstRTSPMediaPrivate *priv;
1065
1066   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1067
1068   priv = media->priv;
1069
1070   g_mutex_lock (&priv->lock);
1071   priv->shared = shared;
1072   g_mutex_unlock (&priv->lock);
1073 }
1074
1075 /**
1076  * gst_rtsp_media_is_shared:
1077  * @media: a #GstRTSPMedia
1078  *
1079  * Check if the pipeline for @media can be shared between multiple clients.
1080  *
1081  * Returns: %TRUE if the media can be shared between clients.
1082  */
1083 gboolean
1084 gst_rtsp_media_is_shared (GstRTSPMedia * media)
1085 {
1086   GstRTSPMediaPrivate *priv;
1087   gboolean res;
1088
1089   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
1090
1091   priv = media->priv;
1092
1093   g_mutex_lock (&priv->lock);
1094   res = priv->shared;
1095   g_mutex_unlock (&priv->lock);
1096
1097   return res;
1098 }
1099
1100 /**
1101  * gst_rtsp_media_set_reusable:
1102  * @media: a #GstRTSPMedia
1103  * @reusable: the new value
1104  *
1105  * Set or unset if the pipeline for @media can be reused after the pipeline has
1106  * been unprepared.
1107  */
1108 void
1109 gst_rtsp_media_set_reusable (GstRTSPMedia * media, gboolean reusable)
1110 {
1111   GstRTSPMediaPrivate *priv;
1112
1113   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1114
1115   priv = media->priv;
1116
1117   g_mutex_lock (&priv->lock);
1118   priv->reusable = reusable;
1119   g_mutex_unlock (&priv->lock);
1120 }
1121
1122 /**
1123  * gst_rtsp_media_is_reusable:
1124  * @media: a #GstRTSPMedia
1125  *
1126  * Check if the pipeline for @media can be reused after an unprepare.
1127  *
1128  * Returns: %TRUE if the media can be reused
1129  */
1130 gboolean
1131 gst_rtsp_media_is_reusable (GstRTSPMedia * media)
1132 {
1133   GstRTSPMediaPrivate *priv;
1134   gboolean res;
1135
1136   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
1137
1138   priv = media->priv;
1139
1140   g_mutex_lock (&priv->lock);
1141   res = priv->reusable;
1142   g_mutex_unlock (&priv->lock);
1143
1144   return res;
1145 }
1146
1147 static void
1148 do_set_profiles (GstRTSPStream * stream, GstRTSPProfile * profiles)
1149 {
1150   gst_rtsp_stream_set_profiles (stream, *profiles);
1151 }
1152
1153 /**
1154  * gst_rtsp_media_set_profiles:
1155  * @media: a #GstRTSPMedia
1156  * @profiles: the new flags
1157  *
1158  * Configure the allowed lower transport for @media.
1159  */
1160 void
1161 gst_rtsp_media_set_profiles (GstRTSPMedia * media, GstRTSPProfile profiles)
1162 {
1163   GstRTSPMediaPrivate *priv;
1164
1165   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1166
1167   priv = media->priv;
1168
1169   g_mutex_lock (&priv->lock);
1170   priv->profiles = profiles;
1171   g_ptr_array_foreach (priv->streams, (GFunc) do_set_profiles, &profiles);
1172   g_mutex_unlock (&priv->lock);
1173 }
1174
1175 /**
1176  * gst_rtsp_media_get_profiles:
1177  * @media: a #GstRTSPMedia
1178  *
1179  * Get the allowed profiles of @media.
1180  *
1181  * Returns: a #GstRTSPProfile
1182  */
1183 GstRTSPProfile
1184 gst_rtsp_media_get_profiles (GstRTSPMedia * media)
1185 {
1186   GstRTSPMediaPrivate *priv;
1187   GstRTSPProfile res;
1188
1189   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), GST_RTSP_PROFILE_UNKNOWN);
1190
1191   priv = media->priv;
1192
1193   g_mutex_lock (&priv->lock);
1194   res = priv->profiles;
1195   g_mutex_unlock (&priv->lock);
1196
1197   return res;
1198 }
1199
1200 static void
1201 do_set_protocols (GstRTSPStream * stream, GstRTSPLowerTrans * protocols)
1202 {
1203   gst_rtsp_stream_set_protocols (stream, *protocols);
1204 }
1205
1206 /**
1207  * gst_rtsp_media_set_protocols:
1208  * @media: a #GstRTSPMedia
1209  * @protocols: the new flags
1210  *
1211  * Configure the allowed lower transport for @media.
1212  */
1213 void
1214 gst_rtsp_media_set_protocols (GstRTSPMedia * media, GstRTSPLowerTrans protocols)
1215 {
1216   GstRTSPMediaPrivate *priv;
1217
1218   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1219
1220   priv = media->priv;
1221
1222   g_mutex_lock (&priv->lock);
1223   priv->protocols = protocols;
1224   g_ptr_array_foreach (priv->streams, (GFunc) do_set_protocols, &protocols);
1225   g_mutex_unlock (&priv->lock);
1226 }
1227
1228 /**
1229  * gst_rtsp_media_get_protocols:
1230  * @media: a #GstRTSPMedia
1231  *
1232  * Get the allowed protocols of @media.
1233  *
1234  * Returns: a #GstRTSPLowerTrans
1235  */
1236 GstRTSPLowerTrans
1237 gst_rtsp_media_get_protocols (GstRTSPMedia * media)
1238 {
1239   GstRTSPMediaPrivate *priv;
1240   GstRTSPLowerTrans res;
1241
1242   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media),
1243       GST_RTSP_LOWER_TRANS_UNKNOWN);
1244
1245   priv = media->priv;
1246
1247   g_mutex_lock (&priv->lock);
1248   res = priv->protocols;
1249   g_mutex_unlock (&priv->lock);
1250
1251   return res;
1252 }
1253
1254 /**
1255  * gst_rtsp_media_set_eos_shutdown:
1256  * @media: a #GstRTSPMedia
1257  * @eos_shutdown: the new value
1258  *
1259  * Set or unset if an EOS event will be sent to the pipeline for @media before
1260  * it is unprepared.
1261  */
1262 void
1263 gst_rtsp_media_set_eos_shutdown (GstRTSPMedia * media, gboolean eos_shutdown)
1264 {
1265   GstRTSPMediaPrivate *priv;
1266
1267   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1268
1269   priv = media->priv;
1270
1271   g_mutex_lock (&priv->lock);
1272   priv->eos_shutdown = eos_shutdown;
1273   g_mutex_unlock (&priv->lock);
1274 }
1275
1276 /**
1277  * gst_rtsp_media_is_eos_shutdown:
1278  * @media: a #GstRTSPMedia
1279  *
1280  * Check if the pipeline for @media will send an EOS down the pipeline before
1281  * unpreparing.
1282  *
1283  * Returns: %TRUE if the media will send EOS before unpreparing.
1284  */
1285 gboolean
1286 gst_rtsp_media_is_eos_shutdown (GstRTSPMedia * media)
1287 {
1288   GstRTSPMediaPrivate *priv;
1289   gboolean res;
1290
1291   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
1292
1293   priv = media->priv;
1294
1295   g_mutex_lock (&priv->lock);
1296   res = priv->eos_shutdown;
1297   g_mutex_unlock (&priv->lock);
1298
1299   return res;
1300 }
1301
1302 /**
1303  * gst_rtsp_media_set_buffer_size:
1304  * @media: a #GstRTSPMedia
1305  * @size: the new value
1306  *
1307  * Set the kernel UDP buffer size.
1308  */
1309 void
1310 gst_rtsp_media_set_buffer_size (GstRTSPMedia * media, guint size)
1311 {
1312   GstRTSPMediaPrivate *priv;
1313   guint i;
1314
1315   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1316
1317   GST_LOG_OBJECT (media, "set buffer size %u", size);
1318
1319   priv = media->priv;
1320
1321   g_mutex_lock (&priv->lock);
1322   priv->buffer_size = size;
1323
1324   for (i = 0; i < priv->streams->len; i++) {
1325     GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
1326     gst_rtsp_stream_set_buffer_size (stream, size);
1327   }
1328   g_mutex_unlock (&priv->lock);
1329 }
1330
1331 /**
1332  * gst_rtsp_media_get_buffer_size:
1333  * @media: a #GstRTSPMedia
1334  *
1335  * Get the kernel UDP buffer size.
1336  *
1337  * Returns: the kernel UDP buffer size.
1338  */
1339 guint
1340 gst_rtsp_media_get_buffer_size (GstRTSPMedia * media)
1341 {
1342   GstRTSPMediaPrivate *priv;
1343   guint res;
1344
1345   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
1346
1347   priv = media->priv;
1348
1349   g_mutex_lock (&priv->lock);
1350   res = priv->buffer_size;
1351   g_mutex_unlock (&priv->lock);
1352
1353   return res;
1354 }
1355
1356 /**
1357  * gst_rtsp_media_set_stop_on_disconnect:
1358  * @media: a #GstRTSPMedia
1359  * @stop_on_disconnect: the new value
1360  *
1361  * Set or unset if the pipeline for @media should be stopped when a
1362  * client disconnects without sending TEARDOWN.
1363  */
1364 void
1365 gst_rtsp_media_set_stop_on_disconnect (GstRTSPMedia * media,
1366     gboolean stop_on_disconnect)
1367 {
1368   GstRTSPMediaPrivate *priv;
1369
1370   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1371
1372   priv = media->priv;
1373
1374   g_mutex_lock (&priv->lock);
1375   priv->stop_on_disconnect = stop_on_disconnect;
1376   g_mutex_unlock (&priv->lock);
1377 }
1378
1379 /**
1380  * gst_rtsp_media_is_stop_on_disconnect:
1381  * @media: a #GstRTSPMedia
1382  *
1383  * Check if the pipeline for @media will be stopped when a client disconnects
1384  * without sending TEARDOWN.
1385  *
1386  * Returns: %TRUE if the media will be stopped when a client disconnects
1387  *     without sending TEARDOWN.
1388  */
1389 gboolean
1390 gst_rtsp_media_is_stop_on_disconnect (GstRTSPMedia * media)
1391 {
1392   GstRTSPMediaPrivate *priv;
1393   gboolean res;
1394
1395   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), TRUE);
1396
1397   priv = media->priv;
1398
1399   g_mutex_lock (&priv->lock);
1400   res = priv->stop_on_disconnect;
1401   g_mutex_unlock (&priv->lock);
1402
1403   return res;
1404 }
1405
1406 /**
1407  * gst_rtsp_media_set_retransmission_time:
1408  * @media: a #GstRTSPMedia
1409  * @time: the new value
1410  *
1411  * Set the amount of time to store retransmission packets.
1412  */
1413 void
1414 gst_rtsp_media_set_retransmission_time (GstRTSPMedia * media, GstClockTime time)
1415 {
1416   GstRTSPMediaPrivate *priv;
1417   guint i;
1418
1419   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1420
1421   GST_LOG_OBJECT (media, "set retransmission time %" G_GUINT64_FORMAT, time);
1422
1423   priv = media->priv;
1424
1425   g_mutex_lock (&priv->lock);
1426   priv->rtx_time = time;
1427   for (i = 0; i < priv->streams->len; i++) {
1428     GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
1429
1430     gst_rtsp_stream_set_retransmission_time (stream, time);
1431   }
1432   g_mutex_unlock (&priv->lock);
1433 }
1434
1435 /**
1436  * gst_rtsp_media_get_retransmission_time:
1437  * @media: a #GstRTSPMedia
1438  *
1439  * Get the amount of time to store retransmission data.
1440  *
1441  * Returns: the amount of time to store retransmission data.
1442  */
1443 GstClockTime
1444 gst_rtsp_media_get_retransmission_time (GstRTSPMedia * media)
1445 {
1446   GstRTSPMediaPrivate *priv;
1447   GstClockTime res;
1448
1449   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
1450
1451   priv = media->priv;
1452
1453   g_mutex_lock (&priv->lock);
1454   res = priv->rtx_time;
1455   g_mutex_unlock (&priv->lock);
1456
1457   return res;
1458 }
1459
1460 /**
1461  * gst_rtsp_media_set_do_retransmission:
1462  *
1463  * Set whether retransmission requests will be sent
1464  *
1465  * Since: 1.16
1466  */
1467 void
1468 gst_rtsp_media_set_do_retransmission (GstRTSPMedia * media,
1469     gboolean do_retransmission)
1470 {
1471   GstRTSPMediaPrivate *priv;
1472
1473   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1474
1475   priv = media->priv;
1476
1477   g_mutex_lock (&priv->lock);
1478   priv->do_retransmission = do_retransmission;
1479
1480   if (priv->rtpbin)
1481     g_object_set (priv->rtpbin, "do-retransmission", do_retransmission, NULL);
1482   g_mutex_unlock (&priv->lock);
1483 }
1484
1485 /**
1486  * gst_rtsp_media_get_do_retransmission:
1487  *
1488  * Returns: Whether retransmission requests will be sent
1489  *
1490  * Since: 1.16
1491  */
1492 gboolean
1493 gst_rtsp_media_get_do_retransmission (GstRTSPMedia * media)
1494 {
1495   GstRTSPMediaPrivate *priv;
1496   gboolean res;
1497
1498   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), 0);
1499
1500   priv = media->priv;
1501
1502   g_mutex_lock (&priv->lock);
1503   res = priv->do_retransmission;
1504   g_mutex_unlock (&priv->lock);
1505
1506   return res;
1507 }
1508
1509 /**
1510  * gst_rtsp_media_set_latency:
1511  * @media: a #GstRTSPMedia
1512  * @latency: latency in milliseconds
1513  *
1514  * Configure the latency used for receiving media.
1515  */
1516 void
1517 gst_rtsp_media_set_latency (GstRTSPMedia * media, guint latency)
1518 {
1519   GstRTSPMediaPrivate *priv;
1520   guint i;
1521
1522   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1523
1524   GST_LOG_OBJECT (media, "set latency %ums", latency);
1525
1526   priv = media->priv;
1527
1528   g_mutex_lock (&priv->lock);
1529   priv->latency = latency;
1530   if (priv->rtpbin) {
1531     g_object_set (priv->rtpbin, "latency", latency, NULL);
1532
1533     for (i = 0; i < media->priv->streams->len; i++) {
1534       GObject *storage = NULL;
1535
1536       g_signal_emit_by_name (G_OBJECT (media->priv->rtpbin), "get-storage",
1537           i, &storage);
1538       if (storage)
1539         g_object_set (storage, "size-time",
1540             (media->priv->latency + 50) * GST_MSECOND, NULL);
1541     }
1542   }
1543
1544   g_mutex_unlock (&priv->lock);
1545 }
1546
1547 /**
1548  * gst_rtsp_media_get_latency:
1549  * @media: a #GstRTSPMedia
1550  *
1551  * Get the latency that is used for receiving media.
1552  *
1553  * Returns: latency in milliseconds
1554  */
1555 guint
1556 gst_rtsp_media_get_latency (GstRTSPMedia * media)
1557 {
1558   GstRTSPMediaPrivate *priv;
1559   guint res;
1560
1561   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
1562
1563   priv = media->priv;
1564
1565   g_mutex_lock (&priv->lock);
1566   res = priv->latency;
1567   g_mutex_unlock (&priv->lock);
1568
1569   return res;
1570 }
1571
1572 /**
1573  * gst_rtsp_media_use_time_provider:
1574  * @media: a #GstRTSPMedia
1575  * @time_provider: if a #GstNetTimeProvider should be used
1576  *
1577  * Set @media to provide a #GstNetTimeProvider.
1578  */
1579 void
1580 gst_rtsp_media_use_time_provider (GstRTSPMedia * media, gboolean time_provider)
1581 {
1582   GstRTSPMediaPrivate *priv;
1583
1584   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1585
1586   priv = media->priv;
1587
1588   g_mutex_lock (&priv->lock);
1589   priv->time_provider = time_provider;
1590   g_mutex_unlock (&priv->lock);
1591 }
1592
1593 /**
1594  * gst_rtsp_media_is_time_provider:
1595  * @media: a #GstRTSPMedia
1596  *
1597  * Check if @media can provide a #GstNetTimeProvider for its pipeline clock.
1598  *
1599  * Use gst_rtsp_media_get_time_provider() to get the network clock.
1600  *
1601  * Returns: %TRUE if @media can provide a #GstNetTimeProvider.
1602  */
1603 gboolean
1604 gst_rtsp_media_is_time_provider (GstRTSPMedia * media)
1605 {
1606   GstRTSPMediaPrivate *priv;
1607   gboolean res;
1608
1609   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
1610
1611   priv = media->priv;
1612
1613   g_mutex_lock (&priv->lock);
1614   res = priv->time_provider;
1615   g_mutex_unlock (&priv->lock);
1616
1617   return res;
1618 }
1619
1620 /**
1621  * gst_rtsp_media_set_clock:
1622  * @media: a #GstRTSPMedia
1623  * @clock: (nullable): #GstClock to be used
1624  *
1625  * Configure the clock used for the media.
1626  */
1627 void
1628 gst_rtsp_media_set_clock (GstRTSPMedia * media, GstClock * clock)
1629 {
1630   GstRTSPMediaPrivate *priv;
1631
1632   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1633   g_return_if_fail (GST_IS_CLOCK (clock) || clock == NULL);
1634
1635   GST_LOG_OBJECT (media, "setting clock %" GST_PTR_FORMAT, clock);
1636
1637   priv = media->priv;
1638
1639   g_mutex_lock (&priv->lock);
1640   if (priv->clock)
1641     gst_object_unref (priv->clock);
1642   priv->clock = clock ? gst_object_ref (clock) : NULL;
1643   if (priv->pipeline) {
1644     if (clock)
1645       gst_pipeline_use_clock (GST_PIPELINE_CAST (priv->pipeline), clock);
1646     else
1647       gst_pipeline_auto_clock (GST_PIPELINE_CAST (priv->pipeline));
1648   }
1649
1650   g_mutex_unlock (&priv->lock);
1651 }
1652
1653 /**
1654  * gst_rtsp_media_set_publish_clock_mode:
1655  * @media: a #GstRTSPMedia
1656  * @mode: the clock publish mode
1657  *
1658  * Sets if and how the media clock should be published according to RFC7273.
1659  *
1660  * Since: 1.8
1661  */
1662 void
1663 gst_rtsp_media_set_publish_clock_mode (GstRTSPMedia * media,
1664     GstRTSPPublishClockMode mode)
1665 {
1666   GstRTSPMediaPrivate *priv;
1667   guint i, n;
1668
1669   priv = media->priv;
1670   g_mutex_lock (&priv->lock);
1671   priv->publish_clock_mode = mode;
1672
1673   n = priv->streams->len;
1674   for (i = 0; i < n; i++) {
1675     GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
1676
1677     gst_rtsp_stream_set_publish_clock_mode (stream, mode);
1678   }
1679   g_mutex_unlock (&priv->lock);
1680 }
1681
1682 /**
1683  * gst_rtsp_media_get_publish_clock_mode:
1684  * @media: a #GstRTSPMedia
1685  *
1686  * Gets if and how the media clock should be published according to RFC7273.
1687  *
1688  * Returns: The GstRTSPPublishClockMode
1689  *
1690  * Since: 1.8
1691  */
1692 GstRTSPPublishClockMode
1693 gst_rtsp_media_get_publish_clock_mode (GstRTSPMedia * media)
1694 {
1695   GstRTSPMediaPrivate *priv;
1696   GstRTSPPublishClockMode ret;
1697
1698   priv = media->priv;
1699   g_mutex_lock (&priv->lock);
1700   ret = priv->publish_clock_mode;
1701   g_mutex_unlock (&priv->lock);
1702
1703   return ret;
1704 }
1705
1706 /**
1707  * gst_rtsp_media_set_address_pool:
1708  * @media: a #GstRTSPMedia
1709  * @pool: (transfer none) (nullable): a #GstRTSPAddressPool
1710  *
1711  * configure @pool to be used as the address pool of @media.
1712  */
1713 void
1714 gst_rtsp_media_set_address_pool (GstRTSPMedia * media,
1715     GstRTSPAddressPool * pool)
1716 {
1717   GstRTSPMediaPrivate *priv;
1718   GstRTSPAddressPool *old;
1719
1720   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1721
1722   priv = media->priv;
1723
1724   GST_LOG_OBJECT (media, "set address pool %p", pool);
1725
1726   g_mutex_lock (&priv->lock);
1727   if ((old = priv->pool) != pool)
1728     priv->pool = pool ? g_object_ref (pool) : NULL;
1729   else
1730     old = NULL;
1731   g_ptr_array_foreach (priv->streams, (GFunc) gst_rtsp_stream_set_address_pool,
1732       pool);
1733   g_mutex_unlock (&priv->lock);
1734
1735   if (old)
1736     g_object_unref (old);
1737 }
1738
1739 /**
1740  * gst_rtsp_media_get_address_pool:
1741  * @media: a #GstRTSPMedia
1742  *
1743  * Get the #GstRTSPAddressPool used as the address pool of @media.
1744  *
1745  * Returns: (transfer full) (nullable): the #GstRTSPAddressPool of @media.
1746  * g_object_unref() after usage.
1747  */
1748 GstRTSPAddressPool *
1749 gst_rtsp_media_get_address_pool (GstRTSPMedia * media)
1750 {
1751   GstRTSPMediaPrivate *priv;
1752   GstRTSPAddressPool *result;
1753
1754   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
1755
1756   priv = media->priv;
1757
1758   g_mutex_lock (&priv->lock);
1759   if ((result = priv->pool))
1760     g_object_ref (result);
1761   g_mutex_unlock (&priv->lock);
1762
1763   return result;
1764 }
1765
1766 /**
1767  * gst_rtsp_media_set_multicast_iface:
1768  * @media: a #GstRTSPMedia
1769  * @multicast_iface: (transfer none) (nullable): a multicast interface name
1770  *
1771  * configure @multicast_iface to be used for @media.
1772  */
1773 void
1774 gst_rtsp_media_set_multicast_iface (GstRTSPMedia * media,
1775     const gchar * multicast_iface)
1776 {
1777   GstRTSPMediaPrivate *priv;
1778   gchar *old;
1779
1780   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1781
1782   priv = media->priv;
1783
1784   GST_LOG_OBJECT (media, "set multicast interface %s", multicast_iface);
1785
1786   g_mutex_lock (&priv->lock);
1787   if ((old = priv->multicast_iface) != multicast_iface)
1788     priv->multicast_iface = multicast_iface ? g_strdup (multicast_iface) : NULL;
1789   else
1790     old = NULL;
1791   g_ptr_array_foreach (priv->streams,
1792       (GFunc) gst_rtsp_stream_set_multicast_iface, (gchar *) multicast_iface);
1793   g_mutex_unlock (&priv->lock);
1794
1795   if (old)
1796     g_free (old);
1797 }
1798
1799 /**
1800  * gst_rtsp_media_get_multicast_iface:
1801  * @media: a #GstRTSPMedia
1802  *
1803  * Get the multicast interface used for @media.
1804  *
1805  * Returns: (transfer full) (nullable): the multicast interface for @media.
1806  * g_free() after usage.
1807  */
1808 gchar *
1809 gst_rtsp_media_get_multicast_iface (GstRTSPMedia * media)
1810 {
1811   GstRTSPMediaPrivate *priv;
1812   gchar *result;
1813
1814   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
1815
1816   priv = media->priv;
1817
1818   g_mutex_lock (&priv->lock);
1819   if ((result = priv->multicast_iface))
1820     result = g_strdup (result);
1821   g_mutex_unlock (&priv->lock);
1822
1823   return result;
1824 }
1825
1826 static GList *
1827 _find_payload_types (GstRTSPMedia * media)
1828 {
1829   gint i, n;
1830   GQueue queue = G_QUEUE_INIT;
1831
1832   n = media->priv->streams->len;
1833   for (i = 0; i < n; i++) {
1834     GstRTSPStream *stream = g_ptr_array_index (media->priv->streams, i);
1835     guint pt = gst_rtsp_stream_get_pt (stream);
1836
1837     g_queue_push_tail (&queue, GUINT_TO_POINTER (pt));
1838   }
1839
1840   return queue.head;
1841 }
1842
1843 static guint
1844 _next_available_pt (GList * payloads)
1845 {
1846   guint i;
1847
1848   for (i = 96; i <= 127; i++) {
1849     GList *iter = g_list_find (payloads, GINT_TO_POINTER (i));
1850     if (!iter)
1851       return GPOINTER_TO_UINT (i);
1852   }
1853
1854   return 0;
1855 }
1856
1857 /**
1858  * gst_rtsp_media_collect_streams:
1859  * @media: a #GstRTSPMedia
1860  *
1861  * Find all payloader elements, they should be named pay\%d in the
1862  * element of @media, and create #GstRTSPStreams for them.
1863  *
1864  * Collect all dynamic elements, named dynpay\%d, and add them to
1865  * the list of dynamic elements.
1866  *
1867  * Find all depayloader elements, they should be named depay\%d in the
1868  * element of @media, and create #GstRTSPStreams for them.
1869  */
1870 void
1871 gst_rtsp_media_collect_streams (GstRTSPMedia * media)
1872 {
1873   GstRTSPMediaPrivate *priv;
1874   GstElement *element, *elem;
1875   GstPad *pad;
1876   gint i;
1877   gboolean have_elem;
1878   gboolean more_elem_remaining = TRUE;
1879   GstRTSPTransportMode mode = 0;
1880
1881   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
1882
1883   priv = media->priv;
1884   element = priv->element;
1885
1886   have_elem = FALSE;
1887   for (i = 0; more_elem_remaining; i++) {
1888     gchar *name;
1889
1890     more_elem_remaining = FALSE;
1891
1892     name = g_strdup_printf ("pay%d", i);
1893     if ((elem = gst_bin_get_by_name (GST_BIN (element), name))) {
1894       GstElement *pay;
1895       GST_INFO ("found stream %d with payloader %p", i, elem);
1896
1897       /* take the pad of the payloader */
1898       pad = gst_element_get_static_pad (elem, "src");
1899
1900       /* find the real payload element in case elem is a GstBin */
1901       pay = find_payload_element (elem);
1902
1903       /* create the stream */
1904       if (pay == NULL) {
1905         GST_WARNING ("could not find real payloader, using bin");
1906         gst_rtsp_media_create_stream (media, elem, pad);
1907       } else {
1908         gst_rtsp_media_create_stream (media, pay, pad);
1909         gst_object_unref (pay);
1910       }
1911
1912       gst_object_unref (pad);
1913       gst_object_unref (elem);
1914
1915       have_elem = TRUE;
1916       more_elem_remaining = TRUE;
1917       mode |= GST_RTSP_TRANSPORT_MODE_PLAY;
1918     }
1919     g_free (name);
1920
1921     name = g_strdup_printf ("dynpay%d", i);
1922     if ((elem = gst_bin_get_by_name (GST_BIN (element), name))) {
1923       /* a stream that will dynamically create pads to provide RTP packets */
1924       GST_INFO ("found dynamic element %d, %p", i, elem);
1925
1926       g_mutex_lock (&priv->lock);
1927       priv->dynamic = g_list_prepend (priv->dynamic, elem);
1928       g_mutex_unlock (&priv->lock);
1929
1930       priv->nb_dynamic_elements++;
1931
1932       have_elem = TRUE;
1933       more_elem_remaining = TRUE;
1934       mode |= GST_RTSP_TRANSPORT_MODE_PLAY;
1935     }
1936     g_free (name);
1937
1938     name = g_strdup_printf ("depay%d", i);
1939     if ((elem = gst_bin_get_by_name (GST_BIN (element), name))) {
1940       GST_INFO ("found stream %d with depayloader %p", i, elem);
1941
1942       /* take the pad of the payloader */
1943       pad = gst_element_get_static_pad (elem, "sink");
1944       /* create the stream */
1945       gst_rtsp_media_create_stream (media, elem, pad);
1946       gst_object_unref (pad);
1947       gst_object_unref (elem);
1948
1949       have_elem = TRUE;
1950       more_elem_remaining = TRUE;
1951       mode |= GST_RTSP_TRANSPORT_MODE_RECORD;
1952     }
1953     g_free (name);
1954   }
1955
1956   if (have_elem) {
1957     if (priv->transport_mode != mode)
1958       GST_WARNING ("found different mode than expected (0x%02x != 0x%02d)",
1959           priv->transport_mode, mode);
1960   }
1961 }
1962
1963 typedef struct
1964 {
1965   GstElement *appsink, *appsrc;
1966   GstRTSPStream *stream;
1967 } AppSinkSrcData;
1968
1969 static GstFlowReturn
1970 appsink_new_sample (GstAppSink * appsink, gpointer user_data)
1971 {
1972   AppSinkSrcData *data = user_data;
1973   GstSample *sample;
1974   GstFlowReturn ret;
1975
1976   sample = gst_app_sink_pull_sample (appsink);
1977   if (!sample)
1978     return GST_FLOW_FLUSHING;
1979
1980
1981   ret = gst_app_src_push_sample (GST_APP_SRC (data->appsrc), sample);
1982   gst_sample_unref (sample);
1983   return ret;
1984 }
1985
1986 static GstAppSinkCallbacks appsink_callbacks = {
1987   NULL,
1988   NULL,
1989   appsink_new_sample,
1990 };
1991
1992 static GstPadProbeReturn
1993 appsink_pad_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1994 {
1995   AppSinkSrcData *data = user_data;
1996
1997   if (GST_IS_EVENT (info->data)
1998       && GST_EVENT_TYPE (info->data) == GST_EVENT_LATENCY) {
1999     GstClockTime min, max;
2000
2001     if (gst_base_sink_query_latency (GST_BASE_SINK (data->appsink), NULL, NULL,
2002             &min, &max)) {
2003       g_object_set (data->appsrc, "min-latency", min, "max-latency", max, NULL);
2004       GST_DEBUG ("setting latency to min %" GST_TIME_FORMAT " max %"
2005           GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max));
2006     }
2007   } else if (GST_IS_QUERY (info->data)) {
2008     GstPad *srcpad = gst_element_get_static_pad (data->appsrc, "src");
2009     if (gst_pad_peer_query (srcpad, GST_QUERY_CAST (info->data))) {
2010       gst_object_unref (srcpad);
2011       return GST_PAD_PROBE_HANDLED;
2012     }
2013     gst_object_unref (srcpad);
2014   }
2015
2016   return GST_PAD_PROBE_OK;
2017 }
2018
2019 static GstPadProbeReturn
2020 appsrc_pad_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2021 {
2022   AppSinkSrcData *data = user_data;
2023
2024   if (GST_IS_QUERY (info->data)) {
2025     GstPad *sinkpad = gst_element_get_static_pad (data->appsink, "sink");
2026     if (gst_pad_peer_query (sinkpad, GST_QUERY_CAST (info->data))) {
2027       gst_object_unref (sinkpad);
2028       return GST_PAD_PROBE_HANDLED;
2029     }
2030     gst_object_unref (sinkpad);
2031   }
2032
2033   return GST_PAD_PROBE_OK;
2034 }
2035
2036 /**
2037  * gst_rtsp_media_create_stream:
2038  * @media: a #GstRTSPMedia
2039  * @payloader: a #GstElement
2040  * @pad: a #GstPad
2041  *
2042  * Create a new stream in @media that provides RTP data on @pad.
2043  * @pad should be a pad of an element inside @media->element.
2044  *
2045  * Returns: (transfer none): a new #GstRTSPStream that remains valid for as long
2046  * as @media exists.
2047  */
2048 GstRTSPStream *
2049 gst_rtsp_media_create_stream (GstRTSPMedia * media, GstElement * payloader,
2050     GstPad * pad)
2051 {
2052   GstRTSPMediaPrivate *priv;
2053   GstRTSPStream *stream;
2054   GstPad *streampad;
2055   gchar *name;
2056   gint idx;
2057   AppSinkSrcData *data = NULL;
2058
2059   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
2060   g_return_val_if_fail (GST_IS_ELEMENT (payloader), NULL);
2061   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2062
2063   priv = media->priv;
2064
2065   g_mutex_lock (&priv->lock);
2066   idx = priv->streams->len;
2067
2068   GST_DEBUG ("media %p: creating stream with index %d", media, idx);
2069
2070   if (GST_PAD_IS_SRC (pad))
2071     name = g_strdup_printf ("src_%u", idx);
2072   else
2073     name = g_strdup_printf ("sink_%u", idx);
2074
2075   if ((GST_PAD_IS_SRC (pad) && priv->element->numsinkpads > 0) ||
2076       (GST_PAD_IS_SINK (pad) && priv->element->numsrcpads > 0)) {
2077     GstElement *appsink, *appsrc;
2078     GstPad *sinkpad, *srcpad;
2079
2080     appsink = gst_element_factory_make ("appsink", NULL);
2081     appsrc = gst_element_factory_make ("appsrc", NULL);
2082
2083     if (GST_PAD_IS_SINK (pad)) {
2084       srcpad = gst_element_get_static_pad (appsrc, "src");
2085
2086       gst_bin_add (GST_BIN (priv->element), appsrc);
2087
2088       gst_pad_link (srcpad, pad);
2089       gst_object_unref (srcpad);
2090
2091       streampad = gst_element_get_static_pad (appsink, "sink");
2092
2093       priv->pending_pipeline_elements =
2094           g_list_prepend (priv->pending_pipeline_elements, appsink);
2095     } else {
2096       sinkpad = gst_element_get_static_pad (appsink, "sink");
2097
2098       gst_pad_link (pad, sinkpad);
2099       gst_object_unref (sinkpad);
2100
2101       streampad = gst_element_get_static_pad (appsrc, "src");
2102
2103       priv->pending_pipeline_elements =
2104           g_list_prepend (priv->pending_pipeline_elements, appsrc);
2105     }
2106
2107     g_object_set (appsrc, "block", TRUE, "format", GST_FORMAT_TIME, "is-live",
2108         TRUE, NULL);
2109     g_object_set (appsink, "sync", FALSE, "async", FALSE, NULL);
2110
2111     data = g_new0 (AppSinkSrcData, 1);
2112     data->appsink = appsink;
2113     data->appsrc = appsrc;
2114
2115     sinkpad = gst_element_get_static_pad (appsink, "sink");
2116     gst_pad_add_probe (sinkpad,
2117         GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
2118         appsink_pad_probe, data, NULL);
2119     gst_object_unref (sinkpad);
2120
2121     srcpad = gst_element_get_static_pad (appsrc, "src");
2122     gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_QUERY_UPSTREAM,
2123         appsrc_pad_probe, data, NULL);
2124     gst_object_unref (srcpad);
2125
2126     gst_app_sink_set_callbacks (GST_APP_SINK (appsink), &appsink_callbacks,
2127         data, NULL);
2128     g_object_set_data_full (G_OBJECT (streampad), "media-appsink-appsrc", data,
2129         g_free);
2130   } else {
2131     streampad = gst_ghost_pad_new (name, pad);
2132     gst_pad_set_active (streampad, TRUE);
2133     gst_element_add_pad (priv->element, streampad);
2134   }
2135   g_free (name);
2136
2137   stream = gst_rtsp_stream_new (idx, payloader, streampad);
2138   if (data)
2139     data->stream = stream;
2140   if (priv->pool)
2141     gst_rtsp_stream_set_address_pool (stream, priv->pool);
2142   gst_rtsp_stream_set_multicast_iface (stream, priv->multicast_iface);
2143   gst_rtsp_stream_set_profiles (stream, priv->profiles);
2144   gst_rtsp_stream_set_protocols (stream, priv->protocols);
2145   gst_rtsp_stream_set_retransmission_time (stream, priv->rtx_time);
2146   gst_rtsp_stream_set_buffer_size (stream, priv->buffer_size);
2147   gst_rtsp_stream_set_publish_clock_mode (stream, priv->publish_clock_mode);
2148
2149   g_ptr_array_add (priv->streams, stream);
2150
2151   if (GST_PAD_IS_SRC (pad)) {
2152     gint i, n;
2153
2154     if (priv->payloads)
2155       g_list_free (priv->payloads);
2156     priv->payloads = _find_payload_types (media);
2157
2158     n = priv->streams->len;
2159     for (i = 0; i < n; i++) {
2160       GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
2161       guint rtx_pt = _next_available_pt (priv->payloads);
2162
2163       if (rtx_pt == 0) {
2164         GST_WARNING ("Ran out of space of dynamic payload types");
2165         break;
2166       }
2167
2168       gst_rtsp_stream_set_retransmission_pt (stream, rtx_pt);
2169
2170       priv->payloads =
2171           g_list_append (priv->payloads, GUINT_TO_POINTER (rtx_pt));
2172     }
2173   }
2174   g_mutex_unlock (&priv->lock);
2175
2176   g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_NEW_STREAM], 0, stream,
2177       NULL);
2178
2179   return stream;
2180 }
2181
2182 static void
2183 gst_rtsp_media_remove_stream (GstRTSPMedia * media, GstRTSPStream * stream)
2184 {
2185   GstRTSPMediaPrivate *priv;
2186   GstPad *srcpad;
2187   AppSinkSrcData *data;
2188
2189   priv = media->priv;
2190
2191   g_mutex_lock (&priv->lock);
2192   /* remove the ghostpad */
2193   srcpad = gst_rtsp_stream_get_srcpad (stream);
2194   data = g_object_get_data (G_OBJECT (srcpad), "media-appsink-appsrc");
2195   if (data) {
2196     if (GST_OBJECT_PARENT (data->appsrc) == GST_OBJECT_CAST (priv->pipeline))
2197       gst_bin_remove (GST_BIN_CAST (priv->pipeline), data->appsrc);
2198     else if (GST_OBJECT_PARENT (data->appsrc) ==
2199         GST_OBJECT_CAST (priv->element))
2200       gst_bin_remove (GST_BIN_CAST (priv->element), data->appsrc);
2201     if (GST_OBJECT_PARENT (data->appsink) == GST_OBJECT_CAST (priv->pipeline))
2202       gst_bin_remove (GST_BIN_CAST (priv->pipeline), data->appsink);
2203     else if (GST_OBJECT_PARENT (data->appsink) ==
2204         GST_OBJECT_CAST (priv->element))
2205       gst_bin_remove (GST_BIN_CAST (priv->element), data->appsink);
2206   } else {
2207     gst_element_remove_pad (priv->element, srcpad);
2208   }
2209   gst_object_unref (srcpad);
2210   /* now remove the stream */
2211   g_object_ref (stream);
2212   g_ptr_array_remove (priv->streams, stream);
2213   g_mutex_unlock (&priv->lock);
2214
2215   g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_REMOVED_STREAM], 0,
2216       stream, NULL);
2217
2218   g_object_unref (stream);
2219 }
2220
2221 /**
2222  * gst_rtsp_media_n_streams:
2223  * @media: a #GstRTSPMedia
2224  *
2225  * Get the number of streams in this media.
2226  *
2227  * Returns: The number of streams.
2228  */
2229 guint
2230 gst_rtsp_media_n_streams (GstRTSPMedia * media)
2231 {
2232   GstRTSPMediaPrivate *priv;
2233   guint res;
2234
2235   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), 0);
2236
2237   priv = media->priv;
2238
2239   g_mutex_lock (&priv->lock);
2240   res = priv->streams->len;
2241   g_mutex_unlock (&priv->lock);
2242
2243   return res;
2244 }
2245
2246 /**
2247  * gst_rtsp_media_get_stream:
2248  * @media: a #GstRTSPMedia
2249  * @idx: the stream index
2250  *
2251  * Retrieve the stream with index @idx from @media.
2252  *
2253  * Returns: (nullable) (transfer none): the #GstRTSPStream at index
2254  * @idx or %NULL when a stream with that index did not exist.
2255  */
2256 GstRTSPStream *
2257 gst_rtsp_media_get_stream (GstRTSPMedia * media, guint idx)
2258 {
2259   GstRTSPMediaPrivate *priv;
2260   GstRTSPStream *res;
2261
2262   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
2263
2264   priv = media->priv;
2265
2266   g_mutex_lock (&priv->lock);
2267   if (idx < priv->streams->len)
2268     res = g_ptr_array_index (priv->streams, idx);
2269   else
2270     res = NULL;
2271   g_mutex_unlock (&priv->lock);
2272
2273   return res;
2274 }
2275
2276 /**
2277  * gst_rtsp_media_find_stream:
2278  * @media: a #GstRTSPMedia
2279  * @control: the control of the stream
2280  *
2281  * Find a stream in @media with @control as the control uri.
2282  *
2283  * Returns: (nullable) (transfer none): the #GstRTSPStream with
2284  * control uri @control or %NULL when a stream with that control did
2285  * not exist.
2286  */
2287 GstRTSPStream *
2288 gst_rtsp_media_find_stream (GstRTSPMedia * media, const gchar * control)
2289 {
2290   GstRTSPMediaPrivate *priv;
2291   GstRTSPStream *res;
2292   gint i;
2293
2294   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
2295   g_return_val_if_fail (control != NULL, NULL);
2296
2297   priv = media->priv;
2298
2299   res = NULL;
2300
2301   g_mutex_lock (&priv->lock);
2302   for (i = 0; i < priv->streams->len; i++) {
2303     GstRTSPStream *test;
2304
2305     test = g_ptr_array_index (priv->streams, i);
2306     if (gst_rtsp_stream_has_control (test, control)) {
2307       res = test;
2308       break;
2309     }
2310   }
2311   g_mutex_unlock (&priv->lock);
2312
2313   return res;
2314 }
2315
2316 /* called with state-lock */
2317 static gboolean
2318 default_convert_range (GstRTSPMedia * media, GstRTSPTimeRange * range,
2319     GstRTSPRangeUnit unit)
2320 {
2321   return gst_rtsp_range_convert_units (range, unit);
2322 }
2323
2324 /**
2325  * gst_rtsp_media_get_range_string:
2326  * @media: a #GstRTSPMedia
2327  * @play: for the PLAY request
2328  * @unit: the unit to use for the string
2329  *
2330  * Get the current range as a string. @media must be prepared with
2331  * gst_rtsp_media_prepare ().
2332  *
2333  * Returns: (transfer full) (nullable): The range as a string, g_free() after usage.
2334  */
2335 gchar *
2336 gst_rtsp_media_get_range_string (GstRTSPMedia * media, gboolean play,
2337     GstRTSPRangeUnit unit)
2338 {
2339   GstRTSPMediaClass *klass;
2340   GstRTSPMediaPrivate *priv;
2341   gchar *result;
2342   GstRTSPTimeRange range;
2343
2344   klass = GST_RTSP_MEDIA_GET_CLASS (media);
2345   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
2346   g_return_val_if_fail (klass->convert_range != NULL, FALSE);
2347
2348   priv = media->priv;
2349
2350   g_rec_mutex_lock (&priv->state_lock);
2351   if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED &&
2352       priv->status != GST_RTSP_MEDIA_STATUS_SUSPENDED)
2353     goto not_prepared;
2354
2355   g_mutex_lock (&priv->lock);
2356
2357   /* Update the range value with current position/duration */
2358   collect_media_stats (media);
2359
2360   /* make copy */
2361   range = priv->range;
2362
2363   if (!play && priv->n_active > 0) {
2364     range.min.type = GST_RTSP_TIME_NOW;
2365     range.min.seconds = -1;
2366   }
2367   g_mutex_unlock (&priv->lock);
2368   g_rec_mutex_unlock (&priv->state_lock);
2369
2370   if (!klass->convert_range (media, &range, unit))
2371     goto conversion_failed;
2372
2373   result = gst_rtsp_range_to_string (&range);
2374
2375   return result;
2376
2377   /* ERRORS */
2378 not_prepared:
2379   {
2380     GST_WARNING ("media %p was not prepared", media);
2381     g_rec_mutex_unlock (&priv->state_lock);
2382     return NULL;
2383   }
2384 conversion_failed:
2385   {
2386     GST_WARNING ("range conversion to unit %d failed", unit);
2387     return NULL;
2388   }
2389 }
2390
2391 static void
2392 stream_update_blocked (GstRTSPStream * stream, GstRTSPMedia * media)
2393 {
2394   gst_rtsp_stream_set_blocked (stream, media->priv->blocked);
2395 }
2396
2397 static void
2398 media_streams_set_blocked (GstRTSPMedia * media, gboolean blocked)
2399 {
2400   GstRTSPMediaPrivate *priv = media->priv;
2401
2402   GST_DEBUG ("media %p set blocked %d", media, blocked);
2403   priv->blocked = blocked;
2404   g_ptr_array_foreach (priv->streams, (GFunc) stream_update_blocked, media);
2405 }
2406
2407 static void
2408 stream_unblock (GstRTSPStream * stream, GstRTSPMedia * media)
2409 {
2410   gst_rtsp_stream_unblock_linked (stream);
2411 }
2412
2413 static void
2414 media_unblock_linked (GstRTSPMedia * media)
2415 {
2416   GstRTSPMediaPrivate *priv = media->priv;
2417
2418   GST_DEBUG ("media %p unblocking linked streams", media);
2419   g_ptr_array_foreach (priv->streams, (GFunc) stream_unblock, media);
2420 }
2421
2422 static void
2423 gst_rtsp_media_set_status (GstRTSPMedia * media, GstRTSPMediaStatus status)
2424 {
2425   GstRTSPMediaPrivate *priv = media->priv;
2426
2427   g_mutex_lock (&priv->lock);
2428   priv->status = status;
2429   GST_DEBUG ("setting new status to %d", status);
2430   g_cond_broadcast (&priv->cond);
2431   g_mutex_unlock (&priv->lock);
2432 }
2433
2434 /**
2435  * gst_rtsp_media_get_status:
2436  * @media: a #GstRTSPMedia
2437  *
2438  * Get the status of @media. When @media is busy preparing, this function waits
2439  * until @media is prepared or in error.
2440  *
2441  * Returns: the status of @media.
2442  */
2443 GstRTSPMediaStatus
2444 gst_rtsp_media_get_status (GstRTSPMedia * media)
2445 {
2446   GstRTSPMediaPrivate *priv = media->priv;
2447   GstRTSPMediaStatus result;
2448   gint64 end_time;
2449
2450   g_mutex_lock (&priv->lock);
2451   end_time = g_get_monotonic_time () + 20 * G_TIME_SPAN_SECOND;
2452   /* while we are preparing, wait */
2453   while (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING) {
2454     GST_DEBUG ("waiting for status change");
2455     if (!g_cond_wait_until (&priv->cond, &priv->lock, end_time)) {
2456       GST_DEBUG ("timeout, assuming error status");
2457       priv->status = GST_RTSP_MEDIA_STATUS_ERROR;
2458     }
2459   }
2460   /* could be success or error */
2461   result = priv->status;
2462   GST_DEBUG ("got status %d", result);
2463   g_mutex_unlock (&priv->lock);
2464
2465   return result;
2466 }
2467
2468 /**
2469  * gst_rtsp_media_seek_full:
2470  * @media: a #GstRTSPMedia
2471  * @range: (transfer none): a #GstRTSPTimeRange
2472  * @flags: The minimal set of #GstSeekFlags to use
2473  *
2474  * Seek the pipeline of @media to @range. @media must be prepared with
2475  * gst_rtsp_media_prepare().
2476  *
2477  * Returns: %TRUE on success.
2478  */
2479 gboolean
2480 gst_rtsp_media_seek_full (GstRTSPMedia * media, GstRTSPTimeRange * range,
2481     GstSeekFlags flags)
2482 {
2483   GstRTSPMediaClass *klass;
2484   GstRTSPMediaPrivate *priv;
2485   gboolean res;
2486   GstClockTime start, stop;
2487   GstSeekType start_type, stop_type;
2488   gint64 current_position;
2489
2490   klass = GST_RTSP_MEDIA_GET_CLASS (media);
2491
2492   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
2493   g_return_val_if_fail (range != NULL, FALSE);
2494   g_return_val_if_fail (klass->convert_range != NULL, FALSE);
2495
2496   priv = media->priv;
2497
2498   g_rec_mutex_lock (&priv->state_lock);
2499   if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED)
2500     goto not_prepared;
2501
2502   /* check if the media pipeline is complete in order to perform a
2503    * seek operation on it */
2504   if (!check_complete (media))
2505     goto not_complete;
2506
2507   /* Update the seekable state of the pipeline in case it changed */
2508   check_seekable (media);
2509
2510   if (priv->seekable == 0) {
2511     GST_FIXME_OBJECT (media, "Handle going back to 0 for none live"
2512         " not seekable streams.");
2513
2514     goto not_seekable;
2515   } else if (priv->seekable < 0) {
2516     goto not_seekable;
2517   }
2518
2519   start_type = stop_type = GST_SEEK_TYPE_NONE;
2520
2521   if (!klass->convert_range (media, range, GST_RTSP_RANGE_NPT))
2522     goto not_supported;
2523   gst_rtsp_range_get_times (range, &start, &stop);
2524
2525   GST_INFO ("got %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
2526       GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2527   GST_INFO ("current %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
2528       GST_TIME_ARGS (priv->range_start), GST_TIME_ARGS (priv->range_stop));
2529
2530   current_position = -1;
2531   if (klass->query_position)
2532     klass->query_position (media, &current_position);
2533   GST_INFO ("current media position %" GST_TIME_FORMAT,
2534       GST_TIME_ARGS (current_position));
2535
2536   if (start != GST_CLOCK_TIME_NONE)
2537     start_type = GST_SEEK_TYPE_SET;
2538
2539   if (priv->range_stop == stop)
2540     stop = GST_CLOCK_TIME_NONE;
2541   else if (stop != GST_CLOCK_TIME_NONE)
2542     stop_type = GST_SEEK_TYPE_SET;
2543
2544   if (start != GST_CLOCK_TIME_NONE || stop != GST_CLOCK_TIME_NONE) {
2545     gboolean had_flags = flags != 0;
2546
2547     GST_INFO ("seeking to %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
2548         GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2549
2550     /* depends on the current playing state of the pipeline. We might need to
2551      * queue this until we get EOS. */
2552     if (had_flags)
2553       flags |= GST_SEEK_FLAG_FLUSH;
2554     else
2555       flags = GST_SEEK_FLAG_FLUSH;
2556
2557
2558     /* if range start was not supplied we must continue from current position.
2559      * but since we're doing a flushing seek, let us query the current position
2560      * so we end up at exactly the same position after the seek. */
2561     if (range->min.type == GST_RTSP_TIME_END) { /* Yepp, that's right! */
2562       if (current_position == -1) {
2563         GST_WARNING ("current position unknown");
2564       } else {
2565         GST_DEBUG ("doing accurate seek to %" GST_TIME_FORMAT,
2566             GST_TIME_ARGS (current_position));
2567         start = current_position;
2568         start_type = GST_SEEK_TYPE_SET;
2569         if (!had_flags)
2570           flags |= GST_SEEK_FLAG_ACCURATE;
2571       }
2572     } else {
2573       /* only set keyframe flag when modifying start */
2574       if (start_type != GST_SEEK_TYPE_NONE)
2575         if (!had_flags)
2576           flags |= GST_SEEK_FLAG_KEY_UNIT;
2577     }
2578
2579     if (start == current_position && stop_type == GST_SEEK_TYPE_NONE) {
2580       GST_DEBUG ("not seeking because no position change");
2581       res = TRUE;
2582     } else {
2583       gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
2584       if (priv->blocked)
2585         media_streams_set_blocked (media, TRUE);
2586
2587       /* FIXME, we only do forwards playback, no trick modes yet */
2588       res = gst_element_seek (priv->pipeline, 1.0, GST_FORMAT_TIME,
2589           flags, start_type, start, stop_type, stop);
2590
2591       /* and block for the seek to complete */
2592       GST_INFO ("done seeking %d", res);
2593       if (!res)
2594         goto seek_failed;
2595
2596       g_rec_mutex_unlock (&priv->state_lock);
2597
2598       /* wait until pipeline is prerolled again, this will also collect stats */
2599       if (!wait_preroll (media))
2600         goto preroll_failed;
2601
2602       g_rec_mutex_lock (&priv->state_lock);
2603       GST_INFO ("prerolled again");
2604     }
2605   } else {
2606     GST_INFO ("no seek needed");
2607     res = TRUE;
2608   }
2609   g_rec_mutex_unlock (&priv->state_lock);
2610
2611   return res;
2612
2613   /* ERRORS */
2614 not_prepared:
2615   {
2616     g_rec_mutex_unlock (&priv->state_lock);
2617     GST_INFO ("media %p is not prepared", media);
2618     return FALSE;
2619   }
2620 not_complete:
2621   {
2622     g_rec_mutex_unlock (&priv->state_lock);
2623     GST_INFO ("pipeline is not complete");
2624     return FALSE;
2625   }
2626 not_seekable:
2627   {
2628     g_rec_mutex_unlock (&priv->state_lock);
2629     GST_INFO ("pipeline is not seekable");
2630     return FALSE;
2631   }
2632 not_supported:
2633   {
2634     g_rec_mutex_unlock (&priv->state_lock);
2635     GST_WARNING ("conversion to npt not supported");
2636     return FALSE;
2637   }
2638 seek_failed:
2639   {
2640     g_rec_mutex_unlock (&priv->state_lock);
2641     GST_INFO ("seeking failed");
2642     gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
2643     return FALSE;
2644   }
2645 preroll_failed:
2646   {
2647     GST_WARNING ("failed to preroll after seek");
2648     return FALSE;
2649   }
2650 }
2651
2652
2653 /**
2654  * gst_rtsp_media_seek:
2655  * @media: a #GstRTSPMedia
2656  * @range: (transfer none): a #GstRTSPTimeRange
2657  *
2658  * Seek the pipeline of @media to @range. @media must be prepared with
2659  * gst_rtsp_media_prepare().
2660  *
2661  * Returns: %TRUE on success.
2662  */
2663 gboolean
2664 gst_rtsp_media_seek (GstRTSPMedia * media, GstRTSPTimeRange * range)
2665 {
2666   return gst_rtsp_media_seek_full (media, range, 0);
2667 }
2668
2669
2670 static void
2671 stream_collect_blocking (GstRTSPStream * stream, gboolean * blocked)
2672 {
2673   *blocked &= gst_rtsp_stream_is_blocking (stream);
2674 }
2675
2676 static gboolean
2677 media_streams_blocking (GstRTSPMedia * media)
2678 {
2679   gboolean blocking = TRUE;
2680
2681   g_ptr_array_foreach (media->priv->streams, (GFunc) stream_collect_blocking,
2682       &blocking);
2683
2684   return blocking;
2685 }
2686
2687 static GstStateChangeReturn
2688 set_state (GstRTSPMedia * media, GstState state)
2689 {
2690   GstRTSPMediaPrivate *priv = media->priv;
2691   GstStateChangeReturn ret;
2692
2693   GST_INFO ("set state to %s for media %p", gst_element_state_get_name (state),
2694       media);
2695   ret = gst_element_set_state (priv->pipeline, state);
2696
2697   return ret;
2698 }
2699
2700 static GstStateChangeReturn
2701 set_target_state (GstRTSPMedia * media, GstState state, gboolean do_state)
2702 {
2703   GstRTSPMediaPrivate *priv = media->priv;
2704   GstStateChangeReturn ret;
2705
2706   GST_INFO ("set target state to %s for media %p",
2707       gst_element_state_get_name (state), media);
2708   priv->target_state = state;
2709
2710   g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_TARGET_STATE], 0,
2711       priv->target_state, NULL);
2712
2713   if (do_state)
2714     ret = set_state (media, state);
2715   else
2716     ret = GST_STATE_CHANGE_SUCCESS;
2717
2718   return ret;
2719 }
2720
2721 /* called with state-lock */
2722 static gboolean
2723 default_handle_message (GstRTSPMedia * media, GstMessage * message)
2724 {
2725   GstRTSPMediaPrivate *priv = media->priv;
2726   GstMessageType type;
2727
2728   type = GST_MESSAGE_TYPE (message);
2729
2730   switch (type) {
2731     case GST_MESSAGE_STATE_CHANGED:
2732     {
2733       GstState old, new, pending;
2734
2735       if (GST_MESSAGE_SRC (message) != GST_OBJECT (priv->pipeline))
2736         break;
2737
2738       gst_message_parse_state_changed (message, &old, &new, &pending);
2739
2740       GST_DEBUG ("%p: went from %s to %s (pending %s)", media,
2741           gst_element_state_get_name (old), gst_element_state_get_name (new),
2742           gst_element_state_get_name (pending));
2743       if (priv->no_more_pads_pending == 0 && is_receive_only (media) &&
2744           old == GST_STATE_READY && new == GST_STATE_PAUSED) {
2745         GST_INFO ("%p: went to PAUSED, prepared now", media);
2746         collect_media_stats (media);
2747
2748         if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
2749           gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
2750       }
2751
2752       break;
2753     }
2754     case GST_MESSAGE_BUFFERING:
2755     {
2756       gint percent;
2757
2758       gst_message_parse_buffering (message, &percent);
2759
2760       /* no state management needed for live pipelines */
2761       if (priv->is_live)
2762         break;
2763
2764       if (percent == 100) {
2765         /* a 100% message means buffering is done */
2766         priv->buffering = FALSE;
2767         /* if the desired state is playing, go back */
2768         if (priv->target_state == GST_STATE_PLAYING) {
2769           GST_INFO ("Buffering done, setting pipeline to PLAYING");
2770           set_state (media, GST_STATE_PLAYING);
2771         } else {
2772           GST_INFO ("Buffering done");
2773         }
2774       } else {
2775         /* buffering busy */
2776         if (priv->buffering == FALSE) {
2777           if (priv->target_state == GST_STATE_PLAYING) {
2778             /* we were not buffering but PLAYING, PAUSE  the pipeline. */
2779             GST_INFO ("Buffering, setting pipeline to PAUSED ...");
2780             set_state (media, GST_STATE_PAUSED);
2781           } else {
2782             GST_INFO ("Buffering ...");
2783           }
2784         }
2785         priv->buffering = TRUE;
2786       }
2787       break;
2788     }
2789     case GST_MESSAGE_LATENCY:
2790     {
2791       gst_bin_recalculate_latency (GST_BIN_CAST (priv->pipeline));
2792       break;
2793     }
2794     case GST_MESSAGE_ERROR:
2795     {
2796       GError *gerror;
2797       gchar *debug;
2798
2799       gst_message_parse_error (message, &gerror, &debug);
2800       GST_WARNING ("%p: got error %s (%s)", media, gerror->message, debug);
2801       g_error_free (gerror);
2802       g_free (debug);
2803
2804       gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
2805       break;
2806     }
2807     case GST_MESSAGE_WARNING:
2808     {
2809       GError *gerror;
2810       gchar *debug;
2811
2812       gst_message_parse_warning (message, &gerror, &debug);
2813       GST_WARNING ("%p: got warning %s (%s)", media, gerror->message, debug);
2814       g_error_free (gerror);
2815       g_free (debug);
2816       break;
2817     }
2818     case GST_MESSAGE_ELEMENT:
2819     {
2820       const GstStructure *s;
2821
2822       s = gst_message_get_structure (message);
2823       if (gst_structure_has_name (s, "GstRTSPStreamBlocking")) {
2824         GST_DEBUG ("media received blocking message");
2825         if (priv->blocked && media_streams_blocking (media) &&
2826             priv->no_more_pads_pending == 0) {
2827           GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "media is blocking");
2828           collect_media_stats (media);
2829
2830           if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
2831             gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
2832         }
2833       }
2834       break;
2835     }
2836     case GST_MESSAGE_STREAM_STATUS:
2837       break;
2838     case GST_MESSAGE_ASYNC_DONE:
2839       if (priv->complete) {
2840         /* receive the final ASYNC_DONE, that is posted by the media pipeline
2841          * after all the transport parts have been successfully added to
2842          * the media streams. */
2843         GST_DEBUG_OBJECT (media, "got async-done");
2844         if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
2845           gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
2846       }
2847       break;
2848     case GST_MESSAGE_EOS:
2849       GST_INFO ("%p: got EOS", media);
2850
2851       if (priv->status == GST_RTSP_MEDIA_STATUS_UNPREPARING) {
2852         GST_DEBUG ("shutting down after EOS");
2853         finish_unprepare (media);
2854       }
2855       break;
2856     default:
2857       GST_INFO ("%p: got message type %d (%s)", media, type,
2858           gst_message_type_get_name (type));
2859       break;
2860   }
2861   return TRUE;
2862 }
2863
2864 static gboolean
2865 bus_message (GstBus * bus, GstMessage * message, GstRTSPMedia * media)
2866 {
2867   GstRTSPMediaPrivate *priv = media->priv;
2868   GstRTSPMediaClass *klass;
2869   gboolean ret;
2870
2871   klass = GST_RTSP_MEDIA_GET_CLASS (media);
2872
2873   g_rec_mutex_lock (&priv->state_lock);
2874   if (klass->handle_message)
2875     ret = klass->handle_message (media, message);
2876   else
2877     ret = FALSE;
2878   g_rec_mutex_unlock (&priv->state_lock);
2879
2880   return ret;
2881 }
2882
2883 static void
2884 watch_destroyed (GstRTSPMedia * media)
2885 {
2886   GST_DEBUG_OBJECT (media, "source destroyed");
2887   g_object_unref (media);
2888 }
2889
2890 static GstElement *
2891 find_payload_element (GstElement * payloader)
2892 {
2893   GstElement *pay = NULL;
2894
2895   if (GST_IS_BIN (payloader)) {
2896     GstIterator *iter;
2897     GValue item = { 0 };
2898
2899     iter = gst_bin_iterate_recurse (GST_BIN (payloader));
2900     while (gst_iterator_next (iter, &item) == GST_ITERATOR_OK) {
2901       GstElement *element = (GstElement *) g_value_get_object (&item);
2902       GstElementClass *eclass = GST_ELEMENT_GET_CLASS (element);
2903       const gchar *klass;
2904
2905       klass =
2906           gst_element_class_get_metadata (eclass, GST_ELEMENT_METADATA_KLASS);
2907       if (klass == NULL)
2908         continue;
2909
2910       if (strstr (klass, "Payloader") && strstr (klass, "RTP")) {
2911         pay = gst_object_ref (element);
2912         g_value_unset (&item);
2913         break;
2914       }
2915       g_value_unset (&item);
2916     }
2917     gst_iterator_free (iter);
2918   } else {
2919     pay = g_object_ref (payloader);
2920   }
2921
2922   return pay;
2923 }
2924
2925 /* called from streaming threads */
2926 static void
2927 pad_added_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media)
2928 {
2929   GstRTSPMediaPrivate *priv = media->priv;
2930   GstRTSPStream *stream;
2931   GstElement *pay;
2932
2933   /* find the real payload element */
2934   pay = find_payload_element (element);
2935   stream = gst_rtsp_media_create_stream (media, pay, pad);
2936   gst_object_unref (pay);
2937
2938   GST_INFO ("pad added %s:%s, stream %p", GST_DEBUG_PAD_NAME (pad), stream);
2939
2940   g_rec_mutex_lock (&priv->state_lock);
2941   if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARING)
2942     goto not_preparing;
2943
2944   g_object_set_data (G_OBJECT (pad), "gst-rtsp-dynpad-stream", stream);
2945
2946   /* join the element in the PAUSED state because this callback is
2947    * called from the streaming thread and it is PAUSED */
2948   if (!gst_rtsp_stream_join_bin (stream, GST_BIN (priv->pipeline),
2949           priv->rtpbin, GST_STATE_PAUSED)) {
2950     GST_WARNING ("failed to join bin element");
2951   }
2952
2953   if (priv->blocked)
2954     gst_rtsp_stream_set_blocked (stream, TRUE);
2955
2956   g_rec_mutex_unlock (&priv->state_lock);
2957
2958   return;
2959
2960   /* ERRORS */
2961 not_preparing:
2962   {
2963     gst_rtsp_media_remove_stream (media, stream);
2964     g_rec_mutex_unlock (&priv->state_lock);
2965     GST_INFO ("ignore pad because we are not preparing");
2966     return;
2967   }
2968 }
2969
2970 static void
2971 pad_removed_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media)
2972 {
2973   GstRTSPMediaPrivate *priv = media->priv;
2974   GstRTSPStream *stream;
2975
2976   stream = g_object_get_data (G_OBJECT (pad), "gst-rtsp-dynpad-stream");
2977   if (stream == NULL)
2978     return;
2979
2980   GST_INFO ("pad removed %s:%s, stream %p", GST_DEBUG_PAD_NAME (pad), stream);
2981
2982   g_rec_mutex_lock (&priv->state_lock);
2983   gst_rtsp_stream_leave_bin (stream, GST_BIN (priv->pipeline), priv->rtpbin);
2984   g_rec_mutex_unlock (&priv->state_lock);
2985
2986   gst_rtsp_media_remove_stream (media, stream);
2987 }
2988
2989 static void
2990 no_more_pads_cb (GstElement * element, GstRTSPMedia * media)
2991 {
2992   GstRTSPMediaPrivate *priv = media->priv;
2993
2994   GST_INFO_OBJECT (element, "no more pads");
2995   g_mutex_lock (&priv->lock);
2996   priv->no_more_pads_pending--;
2997   g_mutex_unlock (&priv->lock);
2998 }
2999
3000 typedef struct _DynPaySignalHandlers DynPaySignalHandlers;
3001
3002 struct _DynPaySignalHandlers
3003 {
3004   gulong pad_added_handler;
3005   gulong pad_removed_handler;
3006   gulong no_more_pads_handler;
3007 };
3008
3009 static gboolean
3010 start_preroll (GstRTSPMedia * media)
3011 {
3012   GstRTSPMediaPrivate *priv = media->priv;
3013   GstStateChangeReturn ret;
3014
3015   GST_INFO ("setting pipeline to PAUSED for media %p", media);
3016
3017   /* start blocked since it is possible that there are no sink elements yet */
3018   media_streams_set_blocked (media, TRUE);
3019   ret = set_target_state (media, GST_STATE_PAUSED, TRUE);
3020
3021   switch (ret) {
3022     case GST_STATE_CHANGE_SUCCESS:
3023       GST_INFO ("SUCCESS state change for media %p", media);
3024       break;
3025     case GST_STATE_CHANGE_ASYNC:
3026       GST_INFO ("ASYNC state change for media %p", media);
3027       break;
3028     case GST_STATE_CHANGE_NO_PREROLL:
3029       /* we need to go to PLAYING */
3030       GST_INFO ("NO_PREROLL state change: live media %p", media);
3031       /* FIXME we disable seeking for live streams for now. We should perform a
3032        * seeking query in preroll instead */
3033       priv->seekable = -1;
3034       priv->is_live = TRUE;
3035
3036       ret = set_state (media, GST_STATE_PLAYING);
3037       if (ret == GST_STATE_CHANGE_FAILURE)
3038         goto state_failed;
3039       break;
3040     case GST_STATE_CHANGE_FAILURE:
3041       goto state_failed;
3042   }
3043
3044   return TRUE;
3045
3046 state_failed:
3047   {
3048     GST_WARNING ("failed to preroll pipeline");
3049     return FALSE;
3050   }
3051 }
3052
3053 static gboolean
3054 wait_preroll (GstRTSPMedia * media)
3055 {
3056   GstRTSPMediaStatus status;
3057
3058   GST_DEBUG ("wait to preroll pipeline");
3059
3060   /* wait until pipeline is prerolled */
3061   status = gst_rtsp_media_get_status (media);
3062   if (status == GST_RTSP_MEDIA_STATUS_ERROR)
3063     goto preroll_failed;
3064
3065   return TRUE;
3066
3067 preroll_failed:
3068   {
3069     GST_WARNING ("failed to preroll pipeline");
3070     return FALSE;
3071   }
3072 }
3073
3074 static GstElement *
3075 request_aux_sender (GstElement * rtpbin, guint sessid, GstRTSPMedia * media)
3076 {
3077   GstRTSPMediaPrivate *priv = media->priv;
3078   GstRTSPStream *stream = NULL;
3079   guint i;
3080   GstElement *res = NULL;
3081
3082   g_mutex_lock (&priv->lock);
3083   for (i = 0; i < priv->streams->len; i++) {
3084     stream = g_ptr_array_index (priv->streams, i);
3085
3086     if (sessid == gst_rtsp_stream_get_index (stream))
3087       break;
3088
3089     stream = NULL;
3090   }
3091   g_mutex_unlock (&priv->lock);
3092
3093   if (stream)
3094     res = gst_rtsp_stream_request_aux_sender (stream, sessid);
3095
3096   return res;
3097 }
3098
3099 static GstElement *
3100 request_aux_receiver (GstElement * rtpbin, guint sessid, GstRTSPMedia * media)
3101 {
3102   GstRTSPMediaPrivate *priv = media->priv;
3103   GstRTSPStream *stream = NULL;
3104   guint i;
3105   GstElement *res = NULL;
3106
3107   g_mutex_lock (&priv->lock);
3108   for (i = 0; i < priv->streams->len; i++) {
3109     stream = g_ptr_array_index (priv->streams, i);
3110
3111     if (sessid == gst_rtsp_stream_get_index (stream))
3112       break;
3113
3114     stream = NULL;
3115   }
3116   g_mutex_unlock (&priv->lock);
3117
3118   if (stream)
3119     res = gst_rtsp_stream_request_aux_receiver (stream, sessid);
3120
3121   return res;
3122 }
3123
3124 static GstElement *
3125 request_fec_decoder (GstElement * rtpbin, guint sessid, GstRTSPMedia * media)
3126 {
3127   GstRTSPMediaPrivate *priv = media->priv;
3128   GstRTSPStream *stream = NULL;
3129   guint i;
3130   GstElement *res = NULL;
3131
3132   g_mutex_lock (&priv->lock);
3133   for (i = 0; i < priv->streams->len; i++) {
3134     stream = g_ptr_array_index (priv->streams, i);
3135
3136     if (sessid == gst_rtsp_stream_get_index (stream))
3137       break;
3138
3139     stream = NULL;
3140   }
3141   g_mutex_unlock (&priv->lock);
3142
3143   if (stream) {
3144     res = gst_rtsp_stream_request_ulpfec_decoder (stream, rtpbin, sessid);
3145   }
3146
3147   return res;
3148 }
3149
3150 static void
3151 new_storage_cb (GstElement * rtpbin, GObject * storage, guint sessid,
3152     GstRTSPMedia * media)
3153 {
3154   g_object_set (storage, "size-time", (media->priv->latency + 50) * GST_MSECOND,
3155       NULL);
3156 }
3157
3158 static gboolean
3159 start_prepare (GstRTSPMedia * media)
3160 {
3161   GstRTSPMediaPrivate *priv = media->priv;
3162   guint i;
3163   GList *walk;
3164
3165   g_rec_mutex_lock (&priv->state_lock);
3166   if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARING)
3167     goto no_longer_preparing;
3168
3169   g_signal_connect (priv->rtpbin, "new-storage", G_CALLBACK (new_storage_cb),
3170       media);
3171   g_signal_connect (priv->rtpbin, "request-fec-decoder",
3172       G_CALLBACK (request_fec_decoder), media);
3173
3174   /* link streams we already have, other streams might appear when we have
3175    * dynamic elements */
3176   for (i = 0; i < priv->streams->len; i++) {
3177     GstRTSPStream *stream;
3178
3179     stream = g_ptr_array_index (priv->streams, i);
3180
3181     if (priv->rtx_time > 0) {
3182       /* enable retransmission by setting rtprtxsend as the "aux" element of rtpbin */
3183       g_signal_connect (priv->rtpbin, "request-aux-sender",
3184           (GCallback) request_aux_sender, media);
3185     }
3186
3187     if (priv->do_retransmission) {
3188       g_signal_connect (priv->rtpbin, "request-aux-receiver",
3189           (GCallback) request_aux_receiver, media);
3190     }
3191
3192     if (!gst_rtsp_stream_join_bin (stream, GST_BIN (priv->pipeline),
3193             priv->rtpbin, GST_STATE_NULL)) {
3194       goto join_bin_failed;
3195     }
3196   }
3197
3198   if (priv->rtpbin)
3199     g_object_set (priv->rtpbin, "do-retransmission", priv->do_retransmission,
3200         "do-lost", TRUE, NULL);
3201
3202   for (walk = priv->dynamic; walk; walk = g_list_next (walk)) {
3203     GstElement *elem = walk->data;
3204     DynPaySignalHandlers *handlers = g_slice_new (DynPaySignalHandlers);
3205
3206     GST_INFO ("adding callbacks for dynamic element %p", elem);
3207
3208     handlers->pad_added_handler = g_signal_connect (elem, "pad-added",
3209         (GCallback) pad_added_cb, media);
3210     handlers->pad_removed_handler = g_signal_connect (elem, "pad-removed",
3211         (GCallback) pad_removed_cb, media);
3212     handlers->no_more_pads_handler = g_signal_connect (elem, "no-more-pads",
3213         (GCallback) no_more_pads_cb, media);
3214
3215     g_object_set_data (G_OBJECT (elem), "gst-rtsp-dynpay-handlers", handlers);
3216   }
3217
3218   if (priv->nb_dynamic_elements == 0 && is_receive_only (media)) {
3219     /* If we are receive_only (RECORD), do not try to preroll, to avoid
3220      * a second ASYNC state change failing */
3221     priv->is_live = TRUE;
3222     gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
3223   } else if (!start_preroll (media)) {
3224     goto preroll_failed;
3225   }
3226
3227   g_rec_mutex_unlock (&priv->state_lock);
3228
3229   return FALSE;
3230
3231 no_longer_preparing:
3232   {
3233     GST_INFO ("media is no longer preparing");
3234     g_rec_mutex_unlock (&priv->state_lock);
3235     return FALSE;
3236   }
3237 join_bin_failed:
3238   {
3239     GST_WARNING ("failed to join bin element");
3240     gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
3241     g_rec_mutex_unlock (&priv->state_lock);
3242     return FALSE;
3243   }
3244 preroll_failed:
3245   {
3246     GST_WARNING ("failed to preroll pipeline");
3247     gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
3248     g_rec_mutex_unlock (&priv->state_lock);
3249     return FALSE;
3250   }
3251 }
3252
3253 static gboolean
3254 default_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
3255 {
3256   GstRTSPMediaPrivate *priv;
3257   GstRTSPMediaClass *klass;
3258   GstBus *bus;
3259   GMainContext *context;
3260   GSource *source;
3261
3262   priv = media->priv;
3263
3264   klass = GST_RTSP_MEDIA_GET_CLASS (media);
3265
3266   if (!klass->create_rtpbin)
3267     goto no_create_rtpbin;
3268
3269   priv->rtpbin = klass->create_rtpbin (media);
3270   if (priv->rtpbin != NULL) {
3271     gboolean success = TRUE;
3272
3273     g_object_set (priv->rtpbin, "latency", priv->latency, NULL);
3274
3275     if (klass->setup_rtpbin)
3276       success = klass->setup_rtpbin (media, priv->rtpbin);
3277
3278     if (success == FALSE) {
3279       gst_object_unref (priv->rtpbin);
3280       priv->rtpbin = NULL;
3281     }
3282   }
3283   if (priv->rtpbin == NULL)
3284     goto no_rtpbin;
3285
3286   priv->thread = thread;
3287   context = (thread != NULL) ? (thread->context) : NULL;
3288
3289   bus = gst_pipeline_get_bus (GST_PIPELINE_CAST (priv->pipeline));
3290
3291   /* add the pipeline bus to our custom mainloop */
3292   priv->source = gst_bus_create_watch (bus);
3293   gst_object_unref (bus);
3294
3295   g_source_set_callback (priv->source, (GSourceFunc) bus_message,
3296       g_object_ref (media), (GDestroyNotify) watch_destroyed);
3297
3298   priv->id = g_source_attach (priv->source, context);
3299
3300   /* add stuff to the bin */
3301   gst_bin_add (GST_BIN (priv->pipeline), priv->rtpbin);
3302
3303   /* do remainder in context */
3304   source = g_idle_source_new ();
3305   g_source_set_callback (source, (GSourceFunc) start_prepare,
3306       g_object_ref (media), (GDestroyNotify) g_object_unref);
3307   g_source_attach (source, context);
3308   g_source_unref (source);
3309
3310   return TRUE;
3311
3312   /* ERRORS */
3313 no_create_rtpbin:
3314   {
3315     GST_ERROR ("no create_rtpbin function");
3316     g_critical ("no create_rtpbin vmethod function set");
3317     return FALSE;
3318   }
3319 no_rtpbin:
3320   {
3321     GST_WARNING ("no rtpbin element");
3322     g_warning ("failed to create element 'rtpbin', check your installation");
3323     return FALSE;
3324   }
3325 }
3326
3327 /**
3328  * gst_rtsp_media_prepare:
3329  * @media: a #GstRTSPMedia
3330  * @thread: (transfer full) (allow-none): a #GstRTSPThread to run the
3331  *   bus handler or %NULL
3332  *
3333  * Prepare @media for streaming. This function will create the objects
3334  * to manage the streaming. A pipeline must have been set on @media with
3335  * gst_rtsp_media_take_pipeline().
3336  *
3337  * It will preroll the pipeline and collect vital information about the streams
3338  * such as the duration.
3339  *
3340  * Returns: %TRUE on success.
3341  */
3342 gboolean
3343 gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
3344 {
3345   GstRTSPMediaPrivate *priv;
3346   GstRTSPMediaClass *klass;
3347
3348   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
3349
3350   priv = media->priv;
3351
3352   g_rec_mutex_lock (&priv->state_lock);
3353   priv->prepare_count++;
3354
3355   if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARED ||
3356       priv->status == GST_RTSP_MEDIA_STATUS_SUSPENDED)
3357     goto was_prepared;
3358
3359   if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
3360     goto is_preparing;
3361
3362   if (priv->status != GST_RTSP_MEDIA_STATUS_UNPREPARED)
3363     goto not_unprepared;
3364
3365   if (!priv->reusable && priv->reused)
3366     goto is_reused;
3367
3368   GST_INFO ("preparing media %p", media);
3369
3370   /* reset some variables */
3371   priv->is_live = FALSE;
3372   priv->seekable = -1;
3373   priv->buffering = FALSE;
3374   priv->no_more_pads_pending = priv->nb_dynamic_elements;
3375
3376   /* we're preparing now */
3377   gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
3378
3379   klass = GST_RTSP_MEDIA_GET_CLASS (media);
3380   if (klass->prepare) {
3381     if (!klass->prepare (media, thread))
3382       goto prepare_failed;
3383   }
3384
3385 wait_status:
3386   g_rec_mutex_unlock (&priv->state_lock);
3387
3388   /* now wait for all pads to be prerolled, FIXME, we should somehow be
3389    * able to do this async so that we don't block the server thread. */
3390   if (!wait_preroll (media))
3391     goto preroll_failed;
3392
3393   g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_PREPARED], 0, NULL);
3394
3395   GST_INFO ("object %p is prerolled", media);
3396
3397   return TRUE;
3398
3399   /* OK */
3400 is_preparing:
3401   {
3402     /* we are not going to use the giving thread, so stop it. */
3403     if (thread)
3404       gst_rtsp_thread_stop (thread);
3405     goto wait_status;
3406   }
3407 was_prepared:
3408   {
3409     GST_LOG ("media %p was prepared", media);
3410     /* we are not going to use the giving thread, so stop it. */
3411     if (thread)
3412       gst_rtsp_thread_stop (thread);
3413     g_rec_mutex_unlock (&priv->state_lock);
3414     return TRUE;
3415   }
3416   /* ERRORS */
3417 not_unprepared:
3418   {
3419     /* we are not going to use the giving thread, so stop it. */
3420     if (thread)
3421       gst_rtsp_thread_stop (thread);
3422     GST_WARNING ("media %p was not unprepared", media);
3423     priv->prepare_count--;
3424     g_rec_mutex_unlock (&priv->state_lock);
3425     return FALSE;
3426   }
3427 is_reused:
3428   {
3429     /* we are not going to use the giving thread, so stop it. */
3430     if (thread)
3431       gst_rtsp_thread_stop (thread);
3432     priv->prepare_count--;
3433     g_rec_mutex_unlock (&priv->state_lock);
3434     GST_WARNING ("can not reuse media %p", media);
3435     return FALSE;
3436   }
3437 prepare_failed:
3438   {
3439     /* we are not going to use the giving thread, so stop it. */
3440     if (thread)
3441       gst_rtsp_thread_stop (thread);
3442     priv->prepare_count--;
3443     g_rec_mutex_unlock (&priv->state_lock);
3444     GST_ERROR ("failed to prepare media");
3445     return FALSE;
3446   }
3447 preroll_failed:
3448   {
3449     GST_WARNING ("failed to preroll pipeline");
3450     gst_rtsp_media_unprepare (media);
3451     return FALSE;
3452   }
3453 }
3454
3455 /* must be called with state-lock */
3456 static void
3457 finish_unprepare (GstRTSPMedia * media)
3458 {
3459   GstRTSPMediaPrivate *priv = media->priv;
3460   gint i;
3461   GList *walk;
3462
3463   GST_DEBUG ("shutting down");
3464
3465   /* release the lock on shutdown, otherwise pad_added_cb might try to
3466    * acquire the lock and then we deadlock */
3467   g_rec_mutex_unlock (&priv->state_lock);
3468   set_state (media, GST_STATE_NULL);
3469   g_rec_mutex_lock (&priv->state_lock);
3470
3471   media_streams_set_blocked (media, FALSE);
3472
3473   if (priv->status != GST_RTSP_MEDIA_STATUS_UNPREPARING)
3474     return;
3475
3476   for (i = 0; i < priv->streams->len; i++) {
3477     GstRTSPStream *stream;
3478
3479     GST_INFO ("Removing elements of stream %d from pipeline", i);
3480
3481     stream = g_ptr_array_index (priv->streams, i);
3482
3483     gst_rtsp_stream_leave_bin (stream, GST_BIN (priv->pipeline), priv->rtpbin);
3484   }
3485
3486   /* remove the pad signal handlers */
3487   for (walk = priv->dynamic; walk; walk = g_list_next (walk)) {
3488     GstElement *elem = walk->data;
3489     DynPaySignalHandlers *handlers;
3490
3491     handlers =
3492         g_object_steal_data (G_OBJECT (elem), "gst-rtsp-dynpay-handlers");
3493     g_assert (handlers != NULL);
3494
3495     g_signal_handler_disconnect (G_OBJECT (elem), handlers->pad_added_handler);
3496     g_signal_handler_disconnect (G_OBJECT (elem),
3497         handlers->pad_removed_handler);
3498     g_signal_handler_disconnect (G_OBJECT (elem),
3499         handlers->no_more_pads_handler);
3500
3501     g_slice_free (DynPaySignalHandlers, handlers);
3502   }
3503
3504   gst_bin_remove (GST_BIN (priv->pipeline), priv->rtpbin);
3505   priv->rtpbin = NULL;
3506
3507   if (priv->nettime)
3508     gst_object_unref (priv->nettime);
3509   priv->nettime = NULL;
3510
3511   priv->reused = TRUE;
3512   gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_UNPREPARED);
3513
3514   /* when the media is not reusable, this will effectively unref the media and
3515    * recreate it */
3516   g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_UNPREPARED], 0, NULL);
3517
3518   /* the source has the last ref to the media */
3519   if (priv->source) {
3520     GST_DEBUG ("destroy source");
3521     g_source_destroy (priv->source);
3522     g_source_unref (priv->source);
3523   }
3524   if (priv->thread) {
3525     GST_DEBUG ("stop thread");
3526     gst_rtsp_thread_stop (priv->thread);
3527   }
3528 }
3529
3530 /* called with state-lock */
3531 static gboolean
3532 default_unprepare (GstRTSPMedia * media)
3533 {
3534   GstRTSPMediaPrivate *priv = media->priv;
3535
3536   gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_UNPREPARING);
3537
3538   if (priv->eos_shutdown) {
3539     GST_DEBUG ("sending EOS for shutdown");
3540     /* ref so that we don't disappear */
3541     gst_element_send_event (priv->pipeline, gst_event_new_eos ());
3542     /* we need to go to playing again for the EOS to propagate, normally in this
3543      * state, nothing is receiving data from us anymore so this is ok. */
3544     set_state (media, GST_STATE_PLAYING);
3545   } else {
3546     finish_unprepare (media);
3547   }
3548   return TRUE;
3549 }
3550
3551 /**
3552  * gst_rtsp_media_unprepare:
3553  * @media: a #GstRTSPMedia
3554  *
3555  * Unprepare @media. After this call, the media should be prepared again before
3556  * it can be used again. If the media is set to be non-reusable, a new instance
3557  * must be created.
3558  *
3559  * Returns: %TRUE on success.
3560  */
3561 gboolean
3562 gst_rtsp_media_unprepare (GstRTSPMedia * media)
3563 {
3564   GstRTSPMediaPrivate *priv;
3565   gboolean success;
3566
3567   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
3568
3569   priv = media->priv;
3570
3571   g_rec_mutex_lock (&priv->state_lock);
3572   if (priv->status == GST_RTSP_MEDIA_STATUS_UNPREPARED)
3573     goto was_unprepared;
3574
3575   priv->prepare_count--;
3576   if (priv->prepare_count > 0)
3577     goto is_busy;
3578
3579   GST_INFO ("unprepare media %p", media);
3580   set_target_state (media, GST_STATE_NULL, FALSE);
3581   success = TRUE;
3582
3583   if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARED) {
3584     GstRTSPMediaClass *klass;
3585
3586     klass = GST_RTSP_MEDIA_GET_CLASS (media);
3587     if (klass->unprepare)
3588       success = klass->unprepare (media);
3589   } else {
3590     gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_UNPREPARING);
3591     finish_unprepare (media);
3592   }
3593   g_rec_mutex_unlock (&priv->state_lock);
3594
3595   return success;
3596
3597 was_unprepared:
3598   {
3599     g_rec_mutex_unlock (&priv->state_lock);
3600     GST_INFO ("media %p was already unprepared", media);
3601     return TRUE;
3602   }
3603 is_busy:
3604   {
3605     GST_INFO ("media %p still prepared %d times", media, priv->prepare_count);
3606     g_rec_mutex_unlock (&priv->state_lock);
3607     return TRUE;
3608   }
3609 }
3610
3611 /* should be called with state-lock */
3612 static GstClock *
3613 get_clock_unlocked (GstRTSPMedia * media)
3614 {
3615   if (media->priv->status != GST_RTSP_MEDIA_STATUS_PREPARED) {
3616     GST_DEBUG_OBJECT (media, "media was not prepared");
3617     return NULL;
3618   }
3619   return gst_pipeline_get_clock (GST_PIPELINE_CAST (media->priv->pipeline));
3620 }
3621
3622 /**
3623  * gst_rtsp_media_get_clock:
3624  * @media: a #GstRTSPMedia
3625  *
3626  * Get the clock that is used by the pipeline in @media.
3627  *
3628  * @media must be prepared before this method returns a valid clock object.
3629  *
3630  * Returns: (transfer full) (nullable): the #GstClock used by @media. unref after usage.
3631  */
3632 GstClock *
3633 gst_rtsp_media_get_clock (GstRTSPMedia * media)
3634 {
3635   GstClock *clock;
3636   GstRTSPMediaPrivate *priv;
3637
3638   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
3639
3640   priv = media->priv;
3641
3642   g_rec_mutex_lock (&priv->state_lock);
3643   clock = get_clock_unlocked (media);
3644   g_rec_mutex_unlock (&priv->state_lock);
3645
3646   return clock;
3647 }
3648
3649 /**
3650  * gst_rtsp_media_get_base_time:
3651  * @media: a #GstRTSPMedia
3652  *
3653  * Get the base_time that is used by the pipeline in @media.
3654  *
3655  * @media must be prepared before this method returns a valid base_time.
3656  *
3657  * Returns: the base_time used by @media.
3658  */
3659 GstClockTime
3660 gst_rtsp_media_get_base_time (GstRTSPMedia * media)
3661 {
3662   GstClockTime result;
3663   GstRTSPMediaPrivate *priv;
3664
3665   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), GST_CLOCK_TIME_NONE);
3666
3667   priv = media->priv;
3668
3669   g_rec_mutex_lock (&priv->state_lock);
3670   if (media->priv->status != GST_RTSP_MEDIA_STATUS_PREPARED)
3671     goto not_prepared;
3672
3673   result = gst_element_get_base_time (media->priv->pipeline);
3674   g_rec_mutex_unlock (&priv->state_lock);
3675
3676   return result;
3677
3678   /* ERRORS */
3679 not_prepared:
3680   {
3681     g_rec_mutex_unlock (&priv->state_lock);
3682     GST_DEBUG_OBJECT (media, "media was not prepared");
3683     return GST_CLOCK_TIME_NONE;
3684   }
3685 }
3686
3687 /**
3688  * gst_rtsp_media_get_time_provider:
3689  * @media: a #GstRTSPMedia
3690  * @address: (allow-none): an address or %NULL
3691  * @port: a port or 0
3692  *
3693  * Get the #GstNetTimeProvider for the clock used by @media. The time provider
3694  * will listen on @address and @port for client time requests.
3695  *
3696  * Returns: (transfer full): the #GstNetTimeProvider of @media.
3697  */
3698 GstNetTimeProvider *
3699 gst_rtsp_media_get_time_provider (GstRTSPMedia * media, const gchar * address,
3700     guint16 port)
3701 {
3702   GstRTSPMediaPrivate *priv;
3703   GstNetTimeProvider *provider = NULL;
3704
3705   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
3706
3707   priv = media->priv;
3708
3709   g_rec_mutex_lock (&priv->state_lock);
3710   if (priv->time_provider) {
3711     if ((provider = priv->nettime) == NULL) {
3712       GstClock *clock;
3713
3714       if (priv->time_provider && (clock = get_clock_unlocked (media))) {
3715         provider = gst_net_time_provider_new (clock, address, port);
3716         gst_object_unref (clock);
3717
3718         priv->nettime = provider;
3719       }
3720     }
3721   }
3722   g_rec_mutex_unlock (&priv->state_lock);
3723
3724   if (provider)
3725     gst_object_ref (provider);
3726
3727   return provider;
3728 }
3729
3730 static gboolean
3731 default_setup_sdp (GstRTSPMedia * media, GstSDPMessage * sdp, GstSDPInfo * info)
3732 {
3733   return gst_rtsp_sdp_from_media (sdp, info, media);
3734 }
3735
3736 /**
3737  * gst_rtsp_media_setup_sdp:
3738  * @media: a #GstRTSPMedia
3739  * @sdp: (transfer none): a #GstSDPMessage
3740  * @info: (transfer none): a #GstSDPInfo
3741  *
3742  * Add @media specific info to @sdp. @info is used to configure the connection
3743  * information in the SDP.
3744  *
3745  * Returns: TRUE on success.
3746  */
3747 gboolean
3748 gst_rtsp_media_setup_sdp (GstRTSPMedia * media, GstSDPMessage * sdp,
3749     GstSDPInfo * info)
3750 {
3751   GstRTSPMediaPrivate *priv;
3752   GstRTSPMediaClass *klass;
3753   gboolean res;
3754
3755   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
3756   g_return_val_if_fail (sdp != NULL, FALSE);
3757   g_return_val_if_fail (info != NULL, FALSE);
3758
3759   priv = media->priv;
3760
3761   g_rec_mutex_lock (&priv->state_lock);
3762
3763   klass = GST_RTSP_MEDIA_GET_CLASS (media);
3764
3765   if (!klass->setup_sdp)
3766     goto no_setup_sdp;
3767
3768   res = klass->setup_sdp (media, sdp, info);
3769
3770   g_rec_mutex_unlock (&priv->state_lock);
3771
3772   return res;
3773
3774   /* ERRORS */
3775 no_setup_sdp:
3776   {
3777     g_rec_mutex_unlock (&priv->state_lock);
3778     GST_ERROR ("no setup_sdp function");
3779     g_critical ("no setup_sdp vmethod function set");
3780     return FALSE;
3781   }
3782 }
3783
3784 static gboolean
3785 default_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp)
3786 {
3787   GstRTSPMediaPrivate *priv = media->priv;
3788   gint i, medias_len;
3789
3790   medias_len = gst_sdp_message_medias_len (sdp);
3791   if (medias_len != priv->streams->len) {
3792     GST_ERROR ("%p: Media has more or less streams than SDP (%d /= %d)", media,
3793         priv->streams->len, medias_len);
3794     return FALSE;
3795   }
3796
3797   for (i = 0; i < medias_len; i++) {
3798     const gchar *proto;
3799     const GstSDPMedia *sdp_media = gst_sdp_message_get_media (sdp, i);
3800     GstRTSPStream *stream;
3801     gint j, formats_len;
3802     const gchar *control;
3803     GstRTSPProfile profile, profiles;
3804
3805     stream = g_ptr_array_index (priv->streams, i);
3806
3807     /* TODO: Should we do something with the other SDP information? */
3808
3809     /* get proto */
3810     proto = gst_sdp_media_get_proto (sdp_media);
3811     if (proto == NULL) {
3812       GST_ERROR ("%p: SDP media %d has no proto", media, i);
3813       return FALSE;
3814     }
3815
3816     if (g_str_equal (proto, "RTP/AVP")) {
3817       profile = GST_RTSP_PROFILE_AVP;
3818     } else if (g_str_equal (proto, "RTP/SAVP")) {
3819       profile = GST_RTSP_PROFILE_SAVP;
3820     } else if (g_str_equal (proto, "RTP/AVPF")) {
3821       profile = GST_RTSP_PROFILE_AVPF;
3822     } else if (g_str_equal (proto, "RTP/SAVPF")) {
3823       profile = GST_RTSP_PROFILE_SAVPF;
3824     } else {
3825       GST_ERROR ("%p: unsupported profile '%s' for stream %d", media, proto, i);
3826       return FALSE;
3827     }
3828
3829     profiles = gst_rtsp_stream_get_profiles (stream);
3830     if ((profiles & profile) == 0) {
3831       GST_ERROR ("%p: unsupported profile '%s' for stream %d", media, proto, i);
3832       return FALSE;
3833     }
3834
3835     formats_len = gst_sdp_media_formats_len (sdp_media);
3836     for (j = 0; j < formats_len; j++) {
3837       gint pt;
3838       GstCaps *caps;
3839       GstStructure *s;
3840
3841       pt = atoi (gst_sdp_media_get_format (sdp_media, j));
3842
3843       GST_DEBUG (" looking at %d pt: %d", j, pt);
3844
3845       /* convert caps */
3846       caps = gst_sdp_media_get_caps_from_media (sdp_media, pt);
3847       if (caps == NULL) {
3848         GST_WARNING (" skipping pt %d without caps", pt);
3849         continue;
3850       }
3851
3852       /* do some tweaks */
3853       GST_DEBUG ("mapping sdp session level attributes to caps");
3854       gst_sdp_message_attributes_to_caps (sdp, caps);
3855       GST_DEBUG ("mapping sdp media level attributes to caps");
3856       gst_sdp_media_attributes_to_caps (sdp_media, caps);
3857
3858       s = gst_caps_get_structure (caps, 0);
3859       gst_structure_set_name (s, "application/x-rtp");
3860
3861       if (!g_strcmp0 (gst_structure_get_string (s, "encoding-name"), "ULPFEC"))
3862         gst_structure_set (s, "is-fec", G_TYPE_BOOLEAN, TRUE, NULL);
3863
3864       gst_rtsp_stream_set_pt_map (stream, pt, caps);
3865       gst_caps_unref (caps);
3866     }
3867
3868     control = gst_sdp_media_get_attribute_val (sdp_media, "control");
3869     if (control)
3870       gst_rtsp_stream_set_control (stream, control);
3871
3872   }
3873
3874   return TRUE;
3875 }
3876
3877 /**
3878  * gst_rtsp_media_handle_sdp:
3879  * @media: a #GstRTSPMedia
3880  * @sdp: (transfer none): a #GstSDPMessage
3881  *
3882  * Configure an SDP on @media for receiving streams
3883  *
3884  * Returns: TRUE on success.
3885  */
3886 gboolean
3887 gst_rtsp_media_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp)
3888 {
3889   GstRTSPMediaPrivate *priv;
3890   GstRTSPMediaClass *klass;
3891   gboolean res;
3892
3893   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
3894   g_return_val_if_fail (sdp != NULL, FALSE);
3895
3896   priv = media->priv;
3897
3898   g_rec_mutex_lock (&priv->state_lock);
3899
3900   klass = GST_RTSP_MEDIA_GET_CLASS (media);
3901
3902   if (!klass->handle_sdp)
3903     goto no_handle_sdp;
3904
3905   res = klass->handle_sdp (media, sdp);
3906
3907   g_rec_mutex_unlock (&priv->state_lock);
3908
3909   return res;
3910
3911   /* ERRORS */
3912 no_handle_sdp:
3913   {
3914     g_rec_mutex_unlock (&priv->state_lock);
3915     GST_ERROR ("no handle_sdp function");
3916     g_critical ("no handle_sdp vmethod function set");
3917     return FALSE;
3918   }
3919 }
3920
3921 static void
3922 do_set_seqnum (GstRTSPStream * stream)
3923 {
3924   guint16 seq_num;
3925
3926   if (gst_rtsp_stream_is_sender (stream)) {
3927     seq_num = gst_rtsp_stream_get_current_seqnum (stream);
3928     gst_rtsp_stream_set_seqnum_offset (stream, seq_num + 1);
3929   }
3930 }
3931
3932 /* call with state_lock */
3933 static gboolean
3934 default_suspend (GstRTSPMedia * media)
3935 {
3936   GstRTSPMediaPrivate *priv = media->priv;
3937   GstStateChangeReturn ret;
3938
3939   switch (priv->suspend_mode) {
3940     case GST_RTSP_SUSPEND_MODE_NONE:
3941       GST_DEBUG ("media %p no suspend", media);
3942       break;
3943     case GST_RTSP_SUSPEND_MODE_PAUSE:
3944       GST_DEBUG ("media %p suspend to PAUSED", media);
3945       ret = set_target_state (media, GST_STATE_PAUSED, TRUE);
3946       if (ret == GST_STATE_CHANGE_FAILURE)
3947         goto state_failed;
3948       break;
3949     case GST_RTSP_SUSPEND_MODE_RESET:
3950       GST_DEBUG ("media %p suspend to NULL", media);
3951       ret = set_target_state (media, GST_STATE_NULL, TRUE);
3952       if (ret == GST_STATE_CHANGE_FAILURE)
3953         goto state_failed;
3954       /* Because payloader needs to set the sequence number as
3955        * monotonic, we need to preserve the sequence number
3956        * after pause. (otherwise going from pause to play,  which
3957        * is actually from NULL to PLAY will create a new sequence
3958        * number. */
3959       g_ptr_array_foreach (priv->streams, (GFunc) do_set_seqnum, NULL);
3960       break;
3961     default:
3962       break;
3963   }
3964
3965   return TRUE;
3966
3967   /* ERRORS */
3968 state_failed:
3969   {
3970     GST_WARNING ("failed changing pipeline's state for media %p", media);
3971     return FALSE;
3972   }
3973 }
3974
3975 /**
3976  * gst_rtsp_media_suspend:
3977  * @media: a #GstRTSPMedia
3978  *
3979  * Suspend @media. The state of the pipeline managed by @media is set to
3980  * GST_STATE_NULL but all streams are kept. @media can be prepared again
3981  * with gst_rtsp_media_unsuspend()
3982  *
3983  * @media must be prepared with gst_rtsp_media_prepare();
3984  *
3985  * Returns: %TRUE on success.
3986  */
3987 gboolean
3988 gst_rtsp_media_suspend (GstRTSPMedia * media)
3989 {
3990   GstRTSPMediaPrivate *priv = media->priv;
3991   GstRTSPMediaClass *klass;
3992
3993   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
3994
3995   GST_FIXME ("suspend for dynamic pipelines needs fixing");
3996
3997   g_rec_mutex_lock (&priv->state_lock);
3998   if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED)
3999     goto not_prepared;
4000
4001   /* don't attempt to suspend when something is busy */
4002   if (priv->n_active > 0)
4003     goto done;
4004
4005   klass = GST_RTSP_MEDIA_GET_CLASS (media);
4006   if (klass->suspend) {
4007     if (!klass->suspend (media))
4008       goto suspend_failed;
4009   }
4010
4011   gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_SUSPENDED);
4012 done:
4013   g_rec_mutex_unlock (&priv->state_lock);
4014
4015   return TRUE;
4016
4017   /* ERRORS */
4018 not_prepared:
4019   {
4020     g_rec_mutex_unlock (&priv->state_lock);
4021     GST_WARNING ("media %p was not prepared", media);
4022     return FALSE;
4023   }
4024 suspend_failed:
4025   {
4026     g_rec_mutex_unlock (&priv->state_lock);
4027     gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
4028     GST_WARNING ("failed to suspend media %p", media);
4029     return FALSE;
4030   }
4031 }
4032
4033 /* call with state_lock */
4034 static gboolean
4035 default_unsuspend (GstRTSPMedia * media)
4036 {
4037   GstRTSPMediaPrivate *priv = media->priv;
4038   gboolean preroll_ok;
4039
4040   switch (priv->suspend_mode) {
4041     case GST_RTSP_SUSPEND_MODE_NONE:
4042       if (is_receive_only (media))
4043         break;
4044       if (media_streams_blocking (media)) {
4045         gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
4046         /* at this point the media pipeline has been updated and contain all
4047          * specific transport parts: all active streams contain at least one sink
4048          * element and it's safe to unblock any blocked streams that are active */
4049         media_unblock_linked (media);
4050       } else {
4051         /* streams are not blocked and media is suspended from PAUSED */
4052         gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
4053       }
4054       g_rec_mutex_unlock (&priv->state_lock);
4055       if (gst_rtsp_media_get_status (media) == GST_RTSP_MEDIA_STATUS_ERROR) {
4056         g_rec_mutex_lock (&priv->state_lock);
4057         goto preroll_failed;
4058       }
4059       g_rec_mutex_lock (&priv->state_lock);
4060       break;
4061     case GST_RTSP_SUSPEND_MODE_PAUSE:
4062       gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
4063       break;
4064     case GST_RTSP_SUSPEND_MODE_RESET:
4065     {
4066       gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
4067       /* at this point the media pipeline has been updated and contain all
4068        * specific transport parts: all active streams contain at least one sink
4069        * element and it's safe to unblock any blocked streams that are active */
4070       media_unblock_linked (media);
4071       if (!start_preroll (media))
4072         goto start_failed;
4073
4074       g_rec_mutex_unlock (&priv->state_lock);
4075       preroll_ok = wait_preroll (media);
4076       g_rec_mutex_lock (&priv->state_lock);
4077
4078       if (!preroll_ok)
4079         goto preroll_failed;
4080     }
4081     default:
4082       break;
4083   }
4084
4085   return TRUE;
4086
4087   /* ERRORS */
4088 start_failed:
4089   {
4090     GST_WARNING ("failed to preroll pipeline");
4091     return FALSE;
4092   }
4093 preroll_failed:
4094   {
4095     GST_WARNING ("failed to preroll pipeline");
4096     return FALSE;
4097   }
4098 }
4099
4100 /**
4101  * gst_rtsp_media_unsuspend:
4102  * @media: a #GstRTSPMedia
4103  *
4104  * Unsuspend @media if it was in a suspended state. This method does nothing
4105  * when the media was not in the suspended state.
4106  *
4107  * Returns: %TRUE on success.
4108  */
4109 gboolean
4110 gst_rtsp_media_unsuspend (GstRTSPMedia * media)
4111 {
4112   GstRTSPMediaPrivate *priv = media->priv;
4113   GstRTSPMediaClass *klass;
4114
4115   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
4116
4117   g_rec_mutex_lock (&priv->state_lock);
4118   if (priv->status != GST_RTSP_MEDIA_STATUS_SUSPENDED)
4119     goto done;
4120
4121   klass = GST_RTSP_MEDIA_GET_CLASS (media);
4122   if (klass->unsuspend) {
4123     if (!klass->unsuspend (media))
4124       goto unsuspend_failed;
4125   }
4126
4127 done:
4128   g_rec_mutex_unlock (&priv->state_lock);
4129
4130   return TRUE;
4131
4132   /* ERRORS */
4133 unsuspend_failed:
4134   {
4135     g_rec_mutex_unlock (&priv->state_lock);
4136     GST_WARNING ("failed to unsuspend media %p", media);
4137     gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR);
4138     return FALSE;
4139   }
4140 }
4141
4142 /* must be called with state-lock */
4143 static void
4144 media_set_pipeline_state_locked (GstRTSPMedia * media, GstState state)
4145 {
4146   GstRTSPMediaPrivate *priv = media->priv;
4147
4148   if (state == GST_STATE_NULL) {
4149     gst_rtsp_media_unprepare (media);
4150   } else {
4151     GST_INFO ("state %s media %p", gst_element_state_get_name (state), media);
4152     set_target_state (media, state, FALSE);
4153     /* when we are buffering, don't update the state yet, this will be done
4154      * when buffering finishes */
4155     if (priv->buffering) {
4156       GST_INFO ("Buffering busy, delay state change");
4157     } else {
4158       if (state == GST_STATE_PLAYING)
4159         /* make sure pads are not blocking anymore when going to PLAYING */
4160         media_unblock_linked (media);
4161
4162       set_state (media, state);
4163
4164       /* and suspend after pause */
4165       if (state == GST_STATE_PAUSED)
4166         gst_rtsp_media_suspend (media);
4167     }
4168   }
4169 }
4170
4171 /**
4172  * gst_rtsp_media_set_pipeline_state:
4173  * @media: a #GstRTSPMedia
4174  * @state: the target state of the pipeline
4175  *
4176  * Set the state of the pipeline managed by @media to @state
4177  */
4178 void
4179 gst_rtsp_media_set_pipeline_state (GstRTSPMedia * media, GstState state)
4180 {
4181   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
4182
4183   g_rec_mutex_lock (&media->priv->state_lock);
4184   media_set_pipeline_state_locked (media, state);
4185   g_rec_mutex_unlock (&media->priv->state_lock);
4186 }
4187
4188 /**
4189  * gst_rtsp_media_set_state:
4190  * @media: a #GstRTSPMedia
4191  * @state: the target state of the media
4192  * @transports: (transfer none) (element-type GstRtspServer.RTSPStreamTransport):
4193  * a #GPtrArray of #GstRTSPStreamTransport pointers
4194  *
4195  * Set the state of @media to @state and for the transports in @transports.
4196  *
4197  * @media must be prepared with gst_rtsp_media_prepare();
4198  *
4199  * Returns: %TRUE on success.
4200  */
4201 gboolean
4202 gst_rtsp_media_set_state (GstRTSPMedia * media, GstState state,
4203     GPtrArray * transports)
4204 {
4205   GstRTSPMediaPrivate *priv;
4206   gint i;
4207   gboolean activate, deactivate, do_state;
4208   gint old_active;
4209
4210   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
4211   g_return_val_if_fail (transports != NULL, FALSE);
4212
4213   priv = media->priv;
4214
4215   g_rec_mutex_lock (&priv->state_lock);
4216   if (priv->status == GST_RTSP_MEDIA_STATUS_ERROR)
4217     goto error_status;
4218   if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED &&
4219       priv->status != GST_RTSP_MEDIA_STATUS_SUSPENDED)
4220     goto not_prepared;
4221
4222   /* NULL and READY are the same */
4223   if (state == GST_STATE_READY)
4224     state = GST_STATE_NULL;
4225
4226   activate = deactivate = FALSE;
4227
4228   GST_INFO ("going to state %s media %p, target state %s",
4229       gst_element_state_get_name (state), media,
4230       gst_element_state_get_name (priv->target_state));
4231
4232   switch (state) {
4233     case GST_STATE_NULL:
4234       /* we're going from PLAYING or PAUSED to READY or NULL, deactivate */
4235       if (priv->target_state >= GST_STATE_PAUSED)
4236         deactivate = TRUE;
4237       break;
4238     case GST_STATE_PAUSED:
4239       /* we're going from PLAYING to PAUSED, READY or NULL, deactivate */
4240       if (priv->target_state == GST_STATE_PLAYING)
4241         deactivate = TRUE;
4242       break;
4243     case GST_STATE_PLAYING:
4244       /* we're going to PLAYING, activate */
4245       activate = TRUE;
4246       break;
4247     default:
4248       break;
4249   }
4250   old_active = priv->n_active;
4251
4252   GST_DEBUG ("%d transports, activate %d, deactivate %d", transports->len,
4253       activate, deactivate);
4254   for (i = 0; i < transports->len; i++) {
4255     GstRTSPStreamTransport *trans;
4256
4257     /* we need a non-NULL entry in the array */
4258     trans = g_ptr_array_index (transports, i);
4259     if (trans == NULL)
4260       continue;
4261
4262     if (activate) {
4263       if (gst_rtsp_stream_transport_set_active (trans, TRUE))
4264         priv->n_active++;
4265     } else if (deactivate) {
4266       if (gst_rtsp_stream_transport_set_active (trans, FALSE))
4267         priv->n_active--;
4268     }
4269   }
4270
4271   /* we just activated the first media, do the playing state change */
4272   if (old_active == 0 && activate)
4273     do_state = TRUE;
4274   /* if we have no more active media, do the downward state changes */
4275   else if (priv->n_active == 0)
4276     do_state = TRUE;
4277   else
4278     do_state = FALSE;
4279
4280   GST_INFO ("state %d active %d media %p do_state %d", state, priv->n_active,
4281       media, do_state);
4282
4283   if (priv->target_state != state) {
4284     if (do_state) {
4285       media_set_pipeline_state_locked (media, state);
4286       g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_NEW_STATE], 0, state,
4287           NULL);
4288     }
4289   }
4290
4291   /* remember where we are */
4292   if (state != GST_STATE_NULL && (state == GST_STATE_PAUSED ||
4293           old_active != priv->n_active))
4294     collect_media_stats (media);
4295
4296   g_rec_mutex_unlock (&priv->state_lock);
4297
4298   return TRUE;
4299
4300   /* ERRORS */
4301 not_prepared:
4302   {
4303     GST_WARNING ("media %p was not prepared", media);
4304     g_rec_mutex_unlock (&priv->state_lock);
4305     return FALSE;
4306   }
4307 error_status:
4308   {
4309     GST_WARNING ("media %p in error status while changing to state %d",
4310         media, state);
4311     if (state == GST_STATE_NULL) {
4312       for (i = 0; i < transports->len; i++) {
4313         GstRTSPStreamTransport *trans;
4314
4315         /* we need a non-NULL entry in the array */
4316         trans = g_ptr_array_index (transports, i);
4317         if (trans == NULL)
4318           continue;
4319
4320         gst_rtsp_stream_transport_set_active (trans, FALSE);
4321       }
4322       priv->n_active = 0;
4323     }
4324     g_rec_mutex_unlock (&priv->state_lock);
4325     return FALSE;
4326   }
4327 }
4328
4329 /**
4330  * gst_rtsp_media_set_transport_mode:
4331  * @media: a #GstRTSPMedia
4332  * @mode: the new value
4333  *
4334  * Sets if the media pipeline can work in PLAY or RECORD mode
4335  */
4336 void
4337 gst_rtsp_media_set_transport_mode (GstRTSPMedia * media,
4338     GstRTSPTransportMode mode)
4339 {
4340   GstRTSPMediaPrivate *priv;
4341
4342   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
4343
4344   priv = media->priv;
4345
4346   g_mutex_lock (&priv->lock);
4347   priv->transport_mode = mode;
4348   g_mutex_unlock (&priv->lock);
4349 }
4350
4351 /**
4352  * gst_rtsp_media_get_transport_mode:
4353  * @media: a #GstRTSPMedia
4354  *
4355  * Check if the pipeline for @media can be used for PLAY or RECORD methods.
4356  *
4357  * Returns: The transport mode.
4358  */
4359 GstRTSPTransportMode
4360 gst_rtsp_media_get_transport_mode (GstRTSPMedia * media)
4361 {
4362   GstRTSPMediaPrivate *priv;
4363   GstRTSPTransportMode res;
4364
4365   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
4366
4367   priv = media->priv;
4368
4369   g_mutex_lock (&priv->lock);
4370   res = priv->transport_mode;
4371   g_mutex_unlock (&priv->lock);
4372
4373   return res;
4374 }
4375
4376 /**
4377  * gst_rtsp_media_get_seekable:
4378  * @media: a #GstRTSPMedia
4379  *
4380  * Check if the pipeline for @media seek and up to what point in time,
4381  * it can seek.
4382  *
4383  * Returns: -1 if the stream is not seekable, 0 if seekable only to the beginning
4384  * and > 0 to indicate the longest duration between any two random access points.
4385  * %G_MAXINT64 means any value is possible.
4386  */
4387 GstClockTimeDiff
4388 gst_rtsp_media_seekable (GstRTSPMedia * media)
4389 {
4390   GstRTSPMediaPrivate *priv;
4391   GstClockTimeDiff res;
4392
4393   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
4394
4395   priv = media->priv;
4396
4397   /* Currently we are not able to seek on live streams,
4398    * and no stream is seekable only to the beginning */
4399   g_mutex_lock (&priv->lock);
4400   res = priv->seekable;
4401   g_mutex_unlock (&priv->lock);
4402
4403   return res;
4404 }
4405
4406 /**
4407  * gst_rtsp_media_complete_pipeline:
4408  * @media: a #GstRTSPMedia
4409  * @transports: (element-type GstRTSPTransport): a list of #GstRTSPTransport
4410  *
4411  * Add a receiver and sender parts to the pipeline based on the transport from
4412  * SETUP.
4413  *
4414  * Returns: %TRUE if the media pipeline has been sucessfully updated.
4415  */
4416 gboolean
4417 gst_rtsp_media_complete_pipeline (GstRTSPMedia * media, GPtrArray * transports)
4418 {
4419   GstRTSPMediaPrivate *priv;
4420   guint i;
4421
4422   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
4423   g_return_val_if_fail (transports, FALSE);
4424
4425   GST_DEBUG_OBJECT (media, "complete pipeline");
4426
4427   priv = media->priv;
4428
4429   g_mutex_lock (&priv->lock);
4430   for (i = 0; i < priv->streams->len; i++) {
4431     GstRTSPStreamTransport *transport;
4432     GstRTSPStream *stream;
4433     const GstRTSPTransport *rtsp_transport;
4434
4435     transport = g_ptr_array_index (transports, i);
4436     if (!transport)
4437       continue;
4438
4439     stream = gst_rtsp_stream_transport_get_stream (transport);
4440     if (!stream)
4441       continue;
4442
4443     rtsp_transport = gst_rtsp_stream_transport_get_transport (transport);
4444
4445     if (!gst_rtsp_stream_complete_stream (stream, rtsp_transport)) {
4446       g_mutex_unlock (&priv->lock);
4447       return FALSE;
4448     }
4449   }
4450
4451   priv->complete = TRUE;
4452   g_mutex_unlock (&priv->lock);
4453
4454   return TRUE;
4455 }