~ubuntu-branches/ubuntu/feisty/gst-plugins-good0.10/feisty-security

« back to all changes in this revision

Viewing changes to gst/rtsp/gstrtspsrc.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-12-21 21:12:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20061221211215-3uukkusokhe0nk4f
Tags: 0.10.5-0ubuntu1
* Sync with pkg-gstreamer SVN:
  + debian/rules:
    - Use Ubuntu as distribution name and point to the proper Launchpad URL
  + debian/patches/01_esdsink-priority.patch:
    - Mark the esdsink with rank primary-2 to get
      pulse > alsadmix > esd > alsa > oss

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* GStreamer
2
 
 * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
 
2
 * Copyright (C) <2005,2006> Wim Taymans <wim at fluendo dot com>
 
3
 *               <2006> Lutz Mueller <lutz at topfrose dot de>
3
4
 *
4
5
 * This library is free software; you can redistribute it and/or
5
6
 * modify it under the terms of the GNU Library General Public
16
17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
18
 * Boston, MA 02111-1307, USA.
18
19
 */
 
20
/*
 
21
 * Unless otherwise indicated, Source Code is licensed under MIT license.
 
22
 * See further explanation attached in License Statement (distributed in the file
 
23
 * LICENSE).
 
24
 *
 
25
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 
26
 * this software and associated documentation files (the "Software"), to deal in
 
27
 * the Software without restriction, including without limitation the rights to
 
28
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 
29
 * of the Software, and to permit persons to whom the Software is furnished to do
 
30
 * so, subject to the following conditions:
 
31
 *
 
32
 * The above copyright notice and this permission notice shall be included in all
 
33
 * copies or substantial portions of the Software.
 
34
 *
 
35
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
36
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
37
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
38
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
39
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
40
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
41
 * SOFTWARE.
 
42
 */
19
43
/**
20
44
 * SECTION:element-rtspsrc
21
45
 *
35
59
 * rtspsrc currently understands SDP as the format of the session description.
36
60
 * For each stream listed in the SDP a new rtp_stream%d pad will be created
37
61
 * with caps derived from the SDP media description. This is a caps of mime type
38
 
 * "application/x-rtp" that can be connected to any available rtp depayloader
 
62
 * "application/x-rtp" that can be connected to any available RTP depayloader
39
63
 * element. 
40
64
 * </para>
41
65
 * <para>
53
77
 * <programlisting>
54
78
 * gst-launch rtspsrc location=rtsp://some.server/url ! fakesink
55
79
 * </programlisting>
56
 
 * Establish a connection to an RTSP server and send the stream to a fakesink.
 
80
 * Establish a connection to an RTSP server and send the raw RTP packets to a fakesink.
57
81
 * </para>
58
82
 * </refsect2>
59
83
 *
60
 
 * Last reviewed on 2006-06-20 (0.10.4)
 
84
 * Last reviewed on 2006-08-18 (0.10.5)
61
85
 */
62
86
 
63
87
#ifdef HAVE_CONFIG_H
65
89
#endif
66
90
 
67
91
#include <unistd.h>
 
92
#include <stdlib.h>
68
93
#include <string.h>
69
94
 
70
95
#include "gstrtspsrc.h"
71
96
#include "sdp.h"
72
97
 
 
98
#if 0
 
99
#define WITH_EXT_REAL
 
100
#endif
 
101
 
 
102
#include "rtspextwms.h"
 
103
#ifdef WITH_EXT_REAL
 
104
#include "rtspextreal.h"
 
105
#endif
 
106
 
73
107
GST_DEBUG_CATEGORY_STATIC (rtspsrc_debug);
74
108
#define GST_CAT_DEFAULT (rtspsrc_debug)
75
109
 
78
112
GST_ELEMENT_DETAILS ("RTSP packet receiver",
79
113
    "Source/Network",
80
114
    "Receive data over the network via RTSP (RFC 2326)",
81
 
    "Wim Taymans <wim@fluendo.com>");
82
 
 
83
 
static GstStaticPadTemplate rtptemplate =
84
 
GST_STATIC_PAD_TEMPLATE ("rtp_stream%d",
85
 
    GST_PAD_SRC,
86
 
    GST_PAD_SOMETIMES,
87
 
    GST_STATIC_CAPS_ANY);
88
 
 
89
 
static GstStaticPadTemplate rtcptemplate =
90
 
GST_STATIC_PAD_TEMPLATE ("rtcp_stream%d",
91
 
    GST_PAD_SRC,
92
 
    GST_PAD_SOMETIMES,
93
 
    GST_STATIC_CAPS_ANY);
 
115
    "Wim Taymans <wim@fluendo.com>\n"
 
116
    "Thijs Vermeir <thijs.vermeir@barco.com>\n"
 
117
    "Lutz Mueller <lutz@topfrose.de>");
 
118
 
 
119
static GstStaticPadTemplate rtptemplate = GST_STATIC_PAD_TEMPLATE ("stream%d",
 
120
    GST_PAD_SRC,
 
121
    GST_PAD_SOMETIMES,
 
122
    GST_STATIC_CAPS ("application/x-rtp; application/x-rdt"));
94
123
 
95
124
enum
96
125
{
99
128
};
100
129
 
101
130
#define DEFAULT_LOCATION        NULL
102
 
#define DEFAULT_PROTOCOLS       GST_RTSP_PROTO_UDP_UNICAST | GST_RTSP_PROTO_UDP_MULTICAST | GST_RTSP_PROTO_TCP
 
131
#define DEFAULT_PROTOCOLS       RTSP_LOWER_TRANS_UDP | RTSP_LOWER_TRANS_UDP_MCAST | RTSP_LOWER_TRANS_TCP
103
132
#define DEFAULT_DEBUG           FALSE
104
133
#define DEFAULT_RETRY           20
 
134
#define DEFAULT_TIMEOUT         5000000
105
135
 
106
136
enum
107
137
{
110
140
  PROP_PROTOCOLS,
111
141
  PROP_DEBUG,
112
142
  PROP_RETRY,
113
 
  /* FILL ME */
 
143
  PROP_TIMEOUT,
114
144
};
115
145
 
116
 
#define GST_TYPE_RTSP_PROTO (gst_rtsp_proto_get_type())
 
146
#define GST_TYPE_RTSP_LOWER_TRANS (gst_rtsp_lower_trans_get_type())
117
147
static GType
118
 
gst_rtsp_proto_get_type (void)
 
148
gst_rtsp_lower_trans_get_type (void)
119
149
{
120
 
  static GType rtsp_proto_type = 0;
121
 
  static const GFlagsValue rtsp_proto[] = {
122
 
    {GST_RTSP_PROTO_UDP_UNICAST, "UDP Unicast", "UDP unicast mode"},
123
 
    {GST_RTSP_PROTO_UDP_MULTICAST, "UDP Multicast", "UDP Multicast mode"},
124
 
    {GST_RTSP_PROTO_TCP, "TCP", "TCP interleaved mode"},
 
150
  static GType rtsp_lower_trans_type = 0;
 
151
  static const GFlagsValue rtsp_lower_trans[] = {
 
152
    {RTSP_LOWER_TRANS_UDP, "UDP Unicast Mode", "udp-unicast"},
 
153
    {RTSP_LOWER_TRANS_UDP_MCAST, "UDP Multicast Mode", "udp-multicast"},
 
154
    {RTSP_LOWER_TRANS_TCP, "TCP interleaved mode", "tcp"},
125
155
    {0, NULL, NULL},
126
156
  };
127
157
 
128
 
  if (!rtsp_proto_type) {
129
 
    rtsp_proto_type = g_flags_register_static ("GstRTSPProto", rtsp_proto);
 
158
  if (!rtsp_lower_trans_type) {
 
159
    rtsp_lower_trans_type =
 
160
        g_flags_register_static ("GstRTSPLowerTrans", rtsp_lower_trans);
130
161
  }
131
 
  return rtsp_proto_type;
 
162
  return rtsp_lower_trans_type;
132
163
}
133
164
 
134
 
 
135
165
static void gst_rtspsrc_base_init (gpointer g_class);
136
 
static void gst_rtspsrc_class_init (GstRTSPSrc * klass);
137
 
static void gst_rtspsrc_init (GstRTSPSrc * rtspsrc);
 
166
static void gst_rtspsrc_finalize (GObject * object);
138
167
 
139
168
static void gst_rtspsrc_uri_handler_init (gpointer g_iface,
140
169
    gpointer iface_data);
 
170
static GstCaps *gst_rtspsrc_media_to_caps (gint pt, SDPMedia * media);
141
171
 
142
172
static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element,
143
173
    GstStateChange transition);
 
174
static void gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message);
144
175
 
145
176
static void gst_rtspsrc_set_property (GObject * object, guint prop_id,
146
177
    const GValue * value, GParamSpec * pspec);
147
178
static void gst_rtspsrc_get_property (GObject * object, guint prop_id,
148
179
    GValue * value, GParamSpec * pspec);
149
180
 
 
181
static gboolean gst_rtspsrc_open (GstRTSPSrc * src);
 
182
static gboolean gst_rtspsrc_play (GstRTSPSrc * src);
 
183
static gboolean gst_rtspsrc_pause (GstRTSPSrc * src);
 
184
static gboolean gst_rtspsrc_close (GstRTSPSrc * src);
 
185
 
 
186
static gboolean gst_rtspsrc_uri_set_uri (GstURIHandler * handler,
 
187
    const gchar * uri);
 
188
 
150
189
static void gst_rtspsrc_loop (GstRTSPSrc * src);
151
190
 
152
 
static GstElementClass *parent_class = NULL;
 
191
/* commands we send to out loop to notify it of events */
 
192
#define CMD_WAIT        0
 
193
#define CMD_RECONNECT   1
 
194
#define CMD_STOP        2
153
195
 
154
196
/*static guint gst_rtspsrc_signals[LAST_SIGNAL] = { 0 }; */
155
197
 
156
 
GType
157
 
gst_rtspsrc_get_type (void)
 
198
static void
 
199
_do_init (GType rtspsrc_type)
158
200
{
159
 
  static GType rtspsrc_type = 0;
160
 
 
161
 
  if (!rtspsrc_type) {
162
 
    static const GTypeInfo rtspsrc_info = {
163
 
      sizeof (GstRTSPSrcClass),
164
 
      gst_rtspsrc_base_init,
165
 
      NULL,
166
 
      (GClassInitFunc) gst_rtspsrc_class_init,
167
 
      NULL,
168
 
      NULL,
169
 
      sizeof (GstRTSPSrc),
170
 
      0,
171
 
      (GInstanceInitFunc) gst_rtspsrc_init,
172
 
      NULL
173
 
    };
174
 
    static const GInterfaceInfo urihandler_info = {
175
 
      gst_rtspsrc_uri_handler_init,
176
 
      NULL,
177
 
      NULL
178
 
    };
179
 
 
180
 
    GST_DEBUG_CATEGORY_INIT (rtspsrc_debug, "rtspsrc", 0, "RTSP src");
181
 
 
182
 
    rtspsrc_type =
183
 
        g_type_register_static (GST_TYPE_ELEMENT, "GstRTSPSrc", &rtspsrc_info,
184
 
        0);
185
 
 
186
 
    g_type_add_interface_static (rtspsrc_type, GST_TYPE_URI_HANDLER,
187
 
        &urihandler_info);
188
 
  }
189
 
  return rtspsrc_type;
 
201
  static const GInterfaceInfo urihandler_info = {
 
202
    gst_rtspsrc_uri_handler_init,
 
203
    NULL,
 
204
    NULL
 
205
  };
 
206
 
 
207
  GST_DEBUG_CATEGORY_INIT (rtspsrc_debug, "rtspsrc", 0, "RTSP src");
 
208
 
 
209
  g_type_add_interface_static (rtspsrc_type, GST_TYPE_URI_HANDLER,
 
210
      &urihandler_info);
190
211
}
191
212
 
 
213
GST_BOILERPLATE_FULL (GstRTSPSrc, gst_rtspsrc, GstBin, GST_TYPE_BIN, _do_init);
 
214
 
192
215
static void
193
216
gst_rtspsrc_base_init (gpointer g_class)
194
217
{
196
219
 
197
220
  gst_element_class_add_pad_template (element_class,
198
221
      gst_static_pad_template_get (&rtptemplate));
199
 
  gst_element_class_add_pad_template (element_class,
200
 
      gst_static_pad_template_get (&rtcptemplate));
201
222
 
202
223
  gst_element_class_set_details (element_class, &gst_rtspsrc_details);
203
224
}
204
225
 
205
226
static void
206
 
gst_rtspsrc_class_init (GstRTSPSrc * klass)
 
227
gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
207
228
{
208
229
  GObjectClass *gobject_class;
209
230
  GstElementClass *gstelement_class;
 
231
  GstBinClass *gstbin_class;
210
232
 
211
233
  gobject_class = (GObjectClass *) klass;
212
234
  gstelement_class = (GstElementClass *) klass;
213
 
 
214
 
  parent_class = g_type_class_peek_parent (klass);
 
235
  gstbin_class = (GstBinClass *) klass;
215
236
 
216
237
  gobject_class->set_property = gst_rtspsrc_set_property;
217
238
  gobject_class->get_property = gst_rtspsrc_get_property;
218
239
 
 
240
  gobject_class->finalize = gst_rtspsrc_finalize;
 
241
 
219
242
  g_object_class_install_property (gobject_class, PROP_LOCATION,
220
243
      g_param_spec_string ("location", "RTSP Location",
221
244
          "Location of the RTSP url to read",
222
 
          DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
245
          DEFAULT_LOCATION, G_PARAM_READWRITE));
223
246
 
224
247
  g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
225
 
      g_param_spec_flags ("protocols", "Protocols", "Allowed protocols",
226
 
          GST_TYPE_RTSP_PROTO, DEFAULT_PROTOCOLS,
227
 
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
248
      g_param_spec_flags ("protocols", "Protocols",
 
249
          "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
 
250
          DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
228
251
 
229
252
  g_object_class_install_property (gobject_class, PROP_DEBUG,
230
253
      g_param_spec_boolean ("debug", "Debug",
237
260
          0, G_MAXUINT16, DEFAULT_RETRY,
238
261
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
239
262
 
 
263
  g_object_class_install_property (gobject_class, PROP_TIMEOUT,
 
264
      g_param_spec_uint64 ("timeout", "Timeout",
 
265
          "Retry TCP transport after timeout microseconds (0 = disabled)",
 
266
          0, G_MAXUINT64, DEFAULT_TIMEOUT,
 
267
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
268
 
240
269
  gstelement_class->change_state = gst_rtspsrc_change_state;
241
 
}
242
 
 
243
 
static void
244
 
gst_rtspsrc_init (GstRTSPSrc * src)
245
 
{
 
270
 
 
271
  gstbin_class->handle_message = gst_rtspsrc_handle_message;
 
272
}
 
273
 
 
274
static void
 
275
gst_rtspsrc_init (GstRTSPSrc * src, GstRTSPSrcClass * g_class)
 
276
{
 
277
  src->stream_rec_lock = g_new (GStaticRecMutex, 1);
 
278
  g_static_rec_mutex_init (src->stream_rec_lock);
 
279
 
 
280
  src->loop_cond = g_cond_new ();
 
281
 
 
282
  src->location = g_strdup (DEFAULT_LOCATION);
 
283
  src->url = NULL;
 
284
 
 
285
  /* install WMS extension by default */
 
286
  src->extension = rtsp_ext_wms_get_context ();
 
287
#ifdef WITH_EXT_REAL
 
288
  src->extension = rtsp_ext_real_get_context ();
 
289
#endif
 
290
  src->extension->src = (gpointer) src;
 
291
}
 
292
 
 
293
static void
 
294
gst_rtspsrc_finalize (GObject * object)
 
295
{
 
296
  GstRTSPSrc *rtspsrc;
 
297
 
 
298
  rtspsrc = GST_RTSPSRC (object);
 
299
 
 
300
  g_static_rec_mutex_free (rtspsrc->stream_rec_lock);
 
301
  g_free (rtspsrc->stream_rec_lock);
 
302
  g_cond_free (rtspsrc->loop_cond);
 
303
  g_free (rtspsrc->location);
 
304
  g_free (rtspsrc->content_base);
 
305
  rtsp_url_free (rtspsrc->url);
 
306
 
 
307
  G_OBJECT_CLASS (parent_class)->finalize (object);
246
308
}
247
309
 
248
310
static void
255
317
 
256
318
  switch (prop_id) {
257
319
    case PROP_LOCATION:
258
 
      g_free (rtspsrc->location);
259
 
      rtspsrc->location = g_value_dup_string (value);
 
320
      gst_rtspsrc_uri_set_uri (GST_URI_HANDLER (rtspsrc),
 
321
          g_value_get_string (value));
260
322
      break;
261
323
    case PROP_PROTOCOLS:
262
324
      rtspsrc->protocols = g_value_get_flags (value);
267
329
    case PROP_RETRY:
268
330
      rtspsrc->retry = g_value_get_uint (value);
269
331
      break;
 
332
    case PROP_TIMEOUT:
 
333
      rtspsrc->timeout = g_value_get_uint64 (value);
 
334
      break;
270
335
    default:
271
336
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
272
337
      break;
294
359
    case PROP_RETRY:
295
360
      g_value_set_uint (value, rtspsrc->retry);
296
361
      break;
 
362
    case PROP_TIMEOUT:
 
363
      g_value_set_uint64 (value, rtspsrc->timeout);
 
364
      break;
297
365
    default:
298
366
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
299
367
      break;
300
368
  }
301
369
}
302
370
 
 
371
static gint
 
372
find_stream_by_pt (GstRTSPStream * stream, gconstpointer a)
 
373
{
 
374
  gint pt = GPOINTER_TO_INT (a);
 
375
 
 
376
  if (stream->pt == pt)
 
377
    return 0;
 
378
 
 
379
  return -1;
 
380
}
 
381
 
303
382
static GstRTSPStream *
304
 
gst_rtspsrc_create_stream (GstRTSPSrc * src)
305
 
{
306
 
  GstRTSPStream *s;
307
 
 
308
 
  s = g_new0 (GstRTSPStream, 1);
309
 
  s->parent = src;
310
 
  s->id = src->numstreams++;
311
 
 
312
 
  src->streams = g_list_append (src->streams, s);
313
 
 
314
 
  return s;
315
 
}
316
 
 
317
 
static gboolean
318
 
gst_rtspsrc_add_element (GstRTSPSrc * src, GstElement * element)
319
 
{
320
 
  gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (src));
321
 
 
322
 
  return TRUE;
323
 
}
324
 
 
325
 
static GstStateChangeReturn
326
 
gst_rtspsrc_set_state (GstRTSPSrc * src, GstState state)
327
 
{
328
 
  GstStateChangeReturn ret;
329
 
  GList *streams;
330
 
 
331
 
  ret = GST_STATE_CHANGE_SUCCESS;
332
 
 
333
 
  /* for all streams */
334
 
  for (streams = src->streams; streams; streams = g_list_next (streams)) {
335
 
    GstRTSPStream *stream;
336
 
 
337
 
    stream = (GstRTSPStream *) streams->data;
338
 
 
339
 
    /* first our rtp session manager */
340
 
    if (stream->rtpdec) {
341
 
      if ((ret =
342
 
              gst_element_set_state (stream->rtpdec,
343
 
                  state)) == GST_STATE_CHANGE_FAILURE)
344
 
        goto done;
345
 
    }
346
 
 
347
 
    /* then our sources */
348
 
    if (stream->rtpsrc) {
349
 
      if ((ret =
350
 
              gst_element_set_state (stream->rtpsrc,
351
 
                  state)) == GST_STATE_CHANGE_FAILURE)
352
 
        goto done;
353
 
    }
354
 
 
355
 
    if (stream->rtcpsrc) {
356
 
      if ((ret =
357
 
              gst_element_set_state (stream->rtcpsrc,
358
 
                  state)) == GST_STATE_CHANGE_FAILURE)
359
 
        goto done;
360
 
    }
361
 
  }
362
 
 
363
 
done:
364
 
  return ret;
365
 
}
 
383
gst_rtspsrc_create_stream (GstRTSPSrc * src, SDPMessage * sdp, gint idx)
 
384
{
 
385
  GstRTSPStream *stream;
 
386
  gchar *control_url;
 
387
  gchar *payload;
 
388
  SDPMedia *media;
 
389
 
 
390
  /* get media, should not return NULL */
 
391
  media = sdp_message_get_media (sdp, idx);
 
392
  if (media == NULL)
 
393
    return NULL;
 
394
 
 
395
  stream = g_new0 (GstRTSPStream, 1);
 
396
  stream->parent = src;
 
397
  /* we mark the pad as not linked, we will mark it as OK when we add the pad to
 
398
   * the element. */
 
399
  stream->last_ret = GST_FLOW_NOT_LINKED;
 
400
  stream->id = src->numstreams++;
 
401
 
 
402
  /* we must have a payload. No payload means we cannot create caps */
 
403
  /* FIXME, handle multiple formats. */
 
404
  if ((payload = sdp_media_get_format (media, 0))) {
 
405
    stream->pt = atoi (payload);
 
406
    /* convert caps */
 
407
    stream->caps = gst_rtspsrc_media_to_caps (stream->pt, media);
 
408
 
 
409
    if (stream->pt >= 96) {
 
410
      /* If we have a dynamic payload type, see if we have a stream with the
 
411
       * same payload number. If there is one, they are part of the same
 
412
       * container and we only need to add one pad. */
 
413
      if (g_list_find_custom (src->streams, GINT_TO_POINTER (stream->pt),
 
414
              (GCompareFunc) find_stream_by_pt)) {
 
415
        stream->container = TRUE;
 
416
      }
 
417
    }
 
418
  }
 
419
 
 
420
  /* get control url to construct the setup url. The setup url is used to
 
421
   * configure the transport of the stream and is used to identity the stream in
 
422
   * the RTP-Info header field returned from PLAY. */
 
423
  control_url = sdp_media_get_attribute_val (media, "control");
 
424
 
 
425
  GST_DEBUG_OBJECT (src, "stream %d", stream->id);
 
426
  GST_DEBUG_OBJECT (src, " pt: %d", stream->pt);
 
427
  GST_DEBUG_OBJECT (src, " container: %d", stream->container);
 
428
  GST_DEBUG_OBJECT (src, " caps: %" GST_PTR_FORMAT, stream->caps);
 
429
  GST_DEBUG_OBJECT (src, " control: %s", GST_STR_NULL (control_url));
 
430
 
 
431
  if (control_url != NULL) {
 
432
    /* If the control_url starts with a '/' or a non rtsp: protocol we will most
 
433
     * likely build a URL that the server will fail to understand, this is ok,
 
434
     * we will fail then. */
 
435
    if (g_str_has_prefix (control_url, "rtsp://"))
 
436
      stream->setup_url = g_strdup (control_url);
 
437
    else if (src->content_base)
 
438
      stream->setup_url =
 
439
          g_strdup_printf ("%s%s", src->content_base, control_url);
 
440
    else
 
441
      stream->setup_url = g_strdup_printf ("%s/%s", src->location, control_url);
 
442
  }
 
443
  GST_DEBUG_OBJECT (src, " setup: %s", GST_STR_NULL (stream->setup_url));
 
444
 
 
445
  /* we keep track of all streams */
 
446
  src->streams = g_list_append (src->streams, stream);
 
447
 
 
448
  return stream;
 
449
}
 
450
 
 
451
#if 0
 
452
static void
 
453
gst_rtspsrc_free_stream (GstRTSPSrc * src, GstRTSPStream * stream)
 
454
{
 
455
  if (stream->caps) {
 
456
    gst_caps_unref (stream->caps);
 
457
  }
 
458
  g_free (stream->setup_url);
 
459
 
 
460
  src->streams = g_list_remove (src->streams, stream);
 
461
  src->numstreams--;
 
462
 
 
463
  g_free (stream);
 
464
}
 
465
#endif
366
466
 
367
467
#define PARSE_INT(p, del, res)          \
368
468
G_STMT_START {                          \
394
494
  while (*p && g_ascii_isspace (*p))    \
395
495
    p++;
396
496
 
 
497
/* rtpmap contains:
 
498
 *
 
499
 *  <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
 
500
 */
397
501
static gboolean
398
502
gst_rtspsrc_parse_rtpmap (gchar * rtpmap, gint * payload, gchar ** name,
399
503
    gint * rate, gchar ** params)
411
515
    return FALSE;
412
516
 
413
517
  PARSE_STRING (p, "/", *name);
414
 
  if (*name == NULL)
415
 
    return FALSE;
 
518
  if (*name == NULL) {
 
519
    /* no rate, assume 0 then */
 
520
    *name = p;
 
521
    *rate = -1;
 
522
    return TRUE;
 
523
  }
416
524
 
417
525
  t = p;
418
526
  p = strstr (p, "/");
435
543
/*
436
544
 *  Mapping of caps to and from SDP fields:
437
545
 *
438
 
 *   m=<media> <udp port> RTP/AVP <payload> 
 
546
 *   m=<media> <UDP port> RTP/AVP <payload> 
439
547
 *   a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
440
 
 *   a=fmtp:<payload> <param>=<value>;...
 
548
 *   a=fmtp:<payload> <param>[=<value>];...
441
549
 */
442
550
static GstCaps *
443
 
gst_rtspsrc_media_to_caps (SDPMedia * media)
 
551
gst_rtspsrc_media_to_caps (gint pt, SDPMedia * media)
444
552
{
445
553
  GstCaps *caps;
446
 
  gchar *payload;
447
554
  gchar *rtpmap;
448
555
  gchar *fmtp;
449
 
  gint pt;
450
556
  gchar *name = NULL;
451
557
  gint rate = -1;
452
558
  gchar *params = NULL;
453
559
  GstStructure *s;
454
560
 
455
 
  payload = sdp_media_get_format (media, 0);
456
 
  if (payload == NULL) {
457
 
    g_warning ("payload type not given");
458
 
    return NULL;
459
 
  }
460
 
  pt = atoi (payload);
461
 
 
 
561
  /* dynamic payloads need rtpmap */
462
562
  if (pt >= 96) {
463
563
    gint payload = 0;
464
564
    gboolean ret;
465
565
 
466
566
    if ((rtpmap = sdp_media_get_attribute_val (media, "rtpmap"))) {
467
 
      if ((ret =
468
 
              gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate,
469
 
                  &params))) {
 
567
      ret = gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate, &params);
 
568
      if (ret) {
470
569
        if (payload != pt) {
 
570
          /* FIXME, not fatal? */
471
571
          g_warning ("rtpmap of wrong payload type");
472
572
          name = NULL;
473
573
          rate = -1;
474
574
          params = NULL;
475
575
        }
476
576
      } else {
 
577
        /* FIXME, not fatal? */
477
578
        g_warning ("error parsing rtpmap");
478
579
      }
479
 
    } else {
480
 
      g_warning ("rtpmap type not given fot dynamic payload %d", pt);
481
 
      return NULL;
482
 
    }
 
580
    } else
 
581
      goto no_rtpmap;
483
582
  }
484
583
 
485
 
  caps = gst_caps_new_simple ("application/x-rtp",
 
584
  caps = gst_caps_new_simple ("application/x-unknown",
486
585
      "media", G_TYPE_STRING, media->media, "payload", G_TYPE_INT, pt, NULL);
487
586
  s = gst_caps_get_structure (caps, 0);
488
587
 
502
601
 
503
602
    p = fmtp;
504
603
 
 
604
    /* p is now of the format <payload> <param>[=<value>];... */
505
605
    PARSE_INT (p, " ", payload);
506
606
    if (payload != -1 && payload == pt) {
507
607
      gchar **pairs;
508
608
      gint i;
509
609
 
 
610
      /* <param>[=<value>] are separated with ';' */
510
611
      pairs = g_strsplit (p, ";", 0);
511
612
      for (i = 0; pairs[i]; i++) {
512
 
        gchar **keyval;
513
 
 
514
 
        keyval = g_strsplit (pairs[i], "=", 0);
515
 
        if (keyval[0]) {
516
 
          gchar *val, *key;
517
 
 
518
 
          if (keyval[1])
519
 
            val = g_strstrip (keyval[1]);
520
 
          else
521
 
            val = "1";
522
 
 
523
 
          key = g_strstrip (keyval[0]);
524
 
 
525
 
          gst_structure_set (s, key, G_TYPE_STRING, val, NULL);
 
613
        gchar *valpos;
 
614
        gchar *val, *key;
 
615
 
 
616
        /* the key may not have a '=', the value can have other '='s */
 
617
        valpos = strstr (pairs[i], "=");
 
618
        if (valpos) {
 
619
          /* we have a '=' and thus a value, remove the '=' with \0 */
 
620
          *valpos = '\0';
 
621
          /* value is everything between '=' and ';'. FIXME, strip? */
 
622
          val = g_strstrip (valpos + 1);
 
623
        } else {
 
624
          /* simple <param>;.. is translated into <param>=1;... */
 
625
          val = "1";
526
626
        }
527
 
        g_strfreev (keyval);
 
627
        /* strip the key of spaces */
 
628
        key = g_strstrip (pairs[i]);
 
629
 
 
630
        gst_structure_set (s, key, G_TYPE_STRING, val, NULL);
528
631
      }
529
632
      g_strfreev (pairs);
530
633
    }
531
634
  }
532
 
 
533
635
  return caps;
 
636
 
 
637
  /* ERRORS */
 
638
no_rtpmap:
 
639
  {
 
640
    g_warning ("rtpmap type not given for dynamic payload %d", pt);
 
641
    return NULL;
 
642
  }
534
643
}
535
644
 
536
645
static gboolean
537
 
gst_rtspsrc_stream_setup_rtp (GstRTSPStream * stream, SDPMedia * media,
 
646
gst_rtspsrc_alloc_udp_ports (GstRTSPStream * stream,
538
647
    gint * rtpport, gint * rtcpport)
539
648
{
 
649
  GstRTSPSrc *src;
540
650
  GstStateChangeReturn ret;
541
 
  GstRTSPSrc *src;
542
 
  GstCaps *caps;
543
 
  GstElement *tmp, *rtp, *rtcp;
 
651
  GstElement *tmp, *udpsrc0, *udpsrc1;
544
652
  gint tmp_rtp, tmp_rtcp;
545
653
  guint count;
546
654
 
547
655
  src = stream->parent;
548
656
 
549
657
  tmp = NULL;
550
 
  rtp = NULL;
551
 
  rtcp = NULL;
 
658
  udpsrc0 = NULL;
 
659
  udpsrc1 = NULL;
552
660
  count = 0;
553
661
 
554
 
  /* try to allocate 2 udp ports, the RTP port should be an even
 
662
  /* try to allocate 2 UDP ports, the RTP port should be an even
555
663
   * number and the RTCP port should be the next (uneven) port */
556
664
again:
557
 
  rtp = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0:0", NULL);
558
 
  if (rtp == NULL)
559
 
    goto no_udp_rtp_protocol;
 
665
  udpsrc0 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0:0", NULL);
 
666
  if (udpsrc0 == NULL)
 
667
    goto no_udp_protocol;
560
668
 
561
 
  ret = gst_element_set_state (rtp, GST_STATE_PAUSED);
 
669
  ret = gst_element_set_state (udpsrc0, GST_STATE_PAUSED);
562
670
  if (ret == GST_STATE_CHANGE_FAILURE)
563
 
    goto start_rtp_failure;
 
671
    goto start_udp_failure;
564
672
 
565
 
  g_object_get (G_OBJECT (rtp), "port", &tmp_rtp, NULL);
 
673
  g_object_get (G_OBJECT (udpsrc0), "port", &tmp_rtp, NULL);
566
674
  GST_DEBUG_OBJECT (src, "got RTP port %d", tmp_rtp);
567
675
 
568
676
  /* check if port is even */
579
687
      gst_element_set_state (tmp, GST_STATE_NULL);
580
688
      gst_object_unref (tmp);
581
689
    }
582
 
    tmp = rtp;
 
690
    tmp = udpsrc0;
583
691
    GST_DEBUG_OBJECT (src, "retry %d", count);
584
692
    goto again;
585
693
  }
591
699
  }
592
700
 
593
701
  /* allocate port+1 for RTCP now */
594
 
  rtcp = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL);
595
 
  if (rtcp == NULL)
 
702
  udpsrc1 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL);
 
703
  if (udpsrc1 == NULL)
596
704
    goto no_udp_rtcp_protocol;
597
705
 
598
706
  /* set port */
599
707
  tmp_rtcp = tmp_rtp + 1;
600
 
  g_object_set (G_OBJECT (rtcp), "port", tmp_rtcp, NULL);
 
708
  g_object_set (G_OBJECT (udpsrc1), "port", tmp_rtcp, NULL);
601
709
 
602
710
  GST_DEBUG_OBJECT (src, "starting RTCP on port %d", tmp_rtcp);
603
 
  ret = gst_element_set_state (rtcp, GST_STATE_PAUSED);
 
711
  ret = gst_element_set_state (udpsrc1, GST_STATE_PAUSED);
604
712
  /* FIXME, this could fail if the next port is not free, we
605
713
   * should retry with another port then */
606
714
  if (ret == GST_STATE_CHANGE_FAILURE)
607
715
    goto start_rtcp_failure;
608
716
 
609
717
  /* all fine, do port check */
610
 
  g_object_get (G_OBJECT (rtp), "port", rtpport, NULL);
611
 
  g_object_get (G_OBJECT (rtcp), "port", rtcpport, NULL);
 
718
  g_object_get (G_OBJECT (udpsrc0), "port", rtpport, NULL);
 
719
  g_object_get (G_OBJECT (udpsrc1), "port", rtcpport, NULL);
612
720
 
613
721
  /* this should not happen */
614
722
  if (*rtpport != tmp_rtp || *rtcpport != tmp_rtcp)
615
723
    goto port_error;
616
724
 
617
 
  /* we manage these elements */
618
 
  stream->rtpsrc = rtp;
619
 
  gst_rtspsrc_add_element (src, stream->rtpsrc);
620
 
  stream->rtcpsrc = rtcp;
621
 
  gst_rtspsrc_add_element (src, stream->rtcpsrc);
622
 
 
623
 
  caps = gst_rtspsrc_media_to_caps (media);
624
 
 
625
 
  /* set caps */
626
 
  g_object_set (G_OBJECT (stream->rtpsrc), "caps", caps, NULL);
 
725
  /* we keep these elements, we configure all in configure_transport when the
 
726
   * server told us to really use the UDP ports. */
 
727
  stream->udpsrc[0] = udpsrc0;
 
728
  stream->udpsrc[1] = udpsrc1;
627
729
 
628
730
  return TRUE;
629
731
 
630
732
  /* ERRORS */
631
 
no_udp_rtp_protocol:
 
733
no_udp_protocol:
632
734
  {
633
 
    GST_DEBUG ("could not get UDP source for RTP");
 
735
    GST_DEBUG_OBJECT (src, "could not get UDP source");
634
736
    goto cleanup;
635
737
  }
636
 
start_rtp_failure:
 
738
start_udp_failure:
637
739
  {
638
 
    GST_DEBUG ("could not start UDP source for RTP");
 
740
    GST_DEBUG_OBJECT (src, "could not start UDP source");
639
741
    goto cleanup;
640
742
  }
641
743
no_ports:
642
744
  {
643
 
    GST_DEBUG ("could not allocate UDP port pair after %d retries", count);
 
745
    GST_DEBUG_OBJECT (src, "could not allocate UDP port pair after %d retries",
 
746
        count);
644
747
    goto cleanup;
645
748
  }
646
749
no_udp_rtcp_protocol:
647
750
  {
648
 
    GST_DEBUG ("could not get UDP source for RTCP");
 
751
    GST_DEBUG_OBJECT (src, "could not get UDP source for RTCP");
649
752
    goto cleanup;
650
753
  }
651
754
start_rtcp_failure:
652
755
  {
653
 
    GST_DEBUG ("could not start UDP source for RTCP");
 
756
    GST_DEBUG_OBJECT (src, "could not start UDP source for RTCP");
654
757
    goto cleanup;
655
758
  }
656
759
port_error:
657
760
  {
658
 
    GST_DEBUG ("ports don't match rtp: %d<->%d, rtcp: %d<->%d",
 
761
    GST_DEBUG_OBJECT (src, "ports don't match rtp: %d<->%d, rtcp: %d<->%d",
659
762
        tmp_rtp, *rtpport, tmp_rtcp, *rtcpport);
660
763
    goto cleanup;
661
764
  }
665
768
      gst_element_set_state (tmp, GST_STATE_NULL);
666
769
      gst_object_unref (tmp);
667
770
    }
668
 
    if (rtp) {
669
 
      gst_element_set_state (rtp, GST_STATE_NULL);
670
 
      gst_object_unref (rtp);
 
771
    if (udpsrc0) {
 
772
      gst_element_set_state (udpsrc0, GST_STATE_NULL);
 
773
      gst_object_unref (udpsrc0);
671
774
    }
672
 
    if (rtcp) {
673
 
      gst_element_set_state (rtcp, GST_STATE_NULL);
674
 
      gst_object_unref (rtcp);
 
775
    if (udpsrc1) {
 
776
      gst_element_set_state (udpsrc1, GST_STATE_NULL);
 
777
      gst_object_unref (udpsrc1);
675
778
    }
676
779
    return FALSE;
677
780
  }
682
785
    RTSPTransport * transport)
683
786
{
684
787
  GstRTSPSrc *src;
685
 
  GstPad *pad;
 
788
  GstPad *outpad = NULL;
 
789
  GstPadTemplate *template;
686
790
  GstStateChangeReturn ret;
687
791
  gchar *name;
 
792
  GstStructure *s;
 
793
  const gchar *mime, *manager;
 
794
  RTSPResult res;
688
795
 
689
796
  src = stream->parent;
690
797
 
691
 
  if (!(stream->rtpdec = gst_element_factory_make ("rtpdec", NULL)))
692
 
    goto no_element;
693
 
 
694
 
  /* we manage this element */
695
 
  gst_rtspsrc_add_element (src, stream->rtpdec);
696
 
 
697
 
  if ((ret =
698
 
          gst_element_set_state (stream->rtpdec,
699
 
              GST_STATE_PAUSED)) != GST_STATE_CHANGE_SUCCESS)
700
 
    goto start_rtpdec_failure;
701
 
 
702
 
  stream->rtpdecrtp = gst_element_get_pad (stream->rtpdec, "sinkrtp");
703
 
  stream->rtpdecrtcp = gst_element_get_pad (stream->rtpdec, "sinkrtcp");
 
798
  GST_DEBUG_OBJECT (src, "configuring transport for stream %p", stream);
 
799
 
 
800
  s = gst_caps_get_structure (stream->caps, 0);
 
801
 
 
802
  if ((res = rtsp_transport_get_mime (transport->trans, &mime)) < 0)
 
803
    goto no_mime;
 
804
  if (!mime)
 
805
    goto no_mime;
 
806
 
 
807
  GST_DEBUG_OBJECT (src, "setting mime to %s", mime);
 
808
  /* configure the final mime type */
 
809
  gst_structure_set_name (s, mime);
 
810
 
 
811
  if ((res = rtsp_transport_get_manager (transport->trans, &manager)) < 0)
 
812
    goto no_manager;
 
813
 
 
814
  if (manager) {
 
815
    GST_DEBUG_OBJECT (src, "using manager %s", manager);
 
816
    /* FIXME, the session manager needs to be shared with all the streams */
 
817
    if (!(stream->sess = gst_element_factory_make (manager, NULL)))
 
818
      goto no_element;
 
819
 
 
820
    /* we manage this element */
 
821
    gst_bin_add (GST_BIN_CAST (src), stream->sess);
 
822
 
 
823
    ret = gst_element_set_state (stream->sess, GST_STATE_PAUSED);
 
824
    if (ret != GST_STATE_CHANGE_SUCCESS)
 
825
      goto start_session_failure;
 
826
 
 
827
    stream->channelpad[0] = gst_element_get_pad (stream->sess, "sinkrtp");
 
828
    stream->channelpad[1] = gst_element_get_pad (stream->sess, "sinkrtcp");
 
829
  }
704
830
 
705
831
  if (transport->lower_transport == RTSP_LOWER_TRANS_TCP) {
 
832
    gint i;
 
833
 
706
834
    /* configure for interleaved delivery, nothing needs to be done
707
835
     * here, the loop function will call the chain functions of the
708
 
     * rtp session manager. */
 
836
     * session manager. */
 
837
    stream->channel[0] = transport->interleaved.min;
 
838
    stream->channel[1] = transport->interleaved.max;
 
839
    GST_DEBUG_OBJECT (src, "stream %p on channels %d-%d", stream,
 
840
        stream->channel[0], stream->channel[1]);
 
841
 
 
842
    /* we can remove the allocated UDP ports now */
 
843
    for (i = 0; i < 2; i++) {
 
844
      if (stream->udpsrc[i]) {
 
845
        gst_element_set_state (stream->udpsrc[i], GST_STATE_NULL);
 
846
        gst_object_unref (stream->udpsrc[i]);
 
847
        stream->udpsrc[i] = NULL;
 
848
      }
 
849
    }
 
850
    /* no session manager, send data to srcpad directly */
 
851
    if (!stream->channelpad[0]) {
 
852
      GST_DEBUG_OBJECT (src, "no manager, creating pad");
 
853
 
 
854
      name = g_strdup_printf ("stream%d", stream->id);
 
855
      template = gst_static_pad_template_get (&rtptemplate);
 
856
      stream->srcpad = gst_pad_new_from_template (template, name);
 
857
      gst_object_unref (template);
 
858
      g_free (name);
 
859
 
 
860
      gst_pad_use_fixed_caps (stream->srcpad);
 
861
      gst_pad_set_caps (stream->srcpad, stream->caps);
 
862
 
 
863
      stream->channelpad[0] = gst_object_ref (stream->srcpad);
 
864
      gst_pad_set_active (stream->srcpad, TRUE);
 
865
      gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad);
 
866
    } else {
 
867
      GST_DEBUG_OBJECT (src, "using manager source pad");
 
868
      outpad = gst_element_get_pad (stream->sess, "srcrtp");
 
869
    }
709
870
  } else {
710
 
    /* configure for UDP delivery, we need to connect the udp pads to
711
 
     * the rtp session plugin. */
712
 
    pad = gst_element_get_pad (stream->rtpsrc, "src");
713
 
    gst_pad_link (pad, stream->rtpdecrtp);
714
 
    gst_object_unref (pad);
715
 
 
716
 
    pad = gst_element_get_pad (stream->rtcpsrc, "src");
717
 
    gst_pad_link (pad, stream->rtpdecrtcp);
718
 
    gst_object_unref (pad);
719
 
  }
720
 
 
721
 
  pad = gst_element_get_pad (stream->rtpdec, "srcrtp");
722
 
  name = g_strdup_printf ("rtp_stream%d", stream->id);
723
 
  gst_element_add_pad (GST_ELEMENT_CAST (src), gst_ghost_pad_new (name, pad));
724
 
  g_free (name);
725
 
  gst_object_unref (pad);
 
871
    /* multicast was selected, create UDP sources and join the multicast
 
872
     * group. */
 
873
    if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST) {
 
874
      gchar *uri;
 
875
 
 
876
      GST_DEBUG_OBJECT (src, "creating UDP sources for multicast");
 
877
 
 
878
      /* creating UDP source */
 
879
      if (transport->port.min != -1) {
 
880
        uri = g_strdup_printf ("udp://%s:%d", transport->destination,
 
881
            transport->port.min);
 
882
        stream->udpsrc[0] = gst_element_make_from_uri (GST_URI_SRC, uri, NULL);
 
883
        g_free (uri);
 
884
        if (stream->udpsrc[0] == NULL)
 
885
          goto no_element;
 
886
 
 
887
        /* change state */
 
888
        gst_element_set_state (stream->udpsrc[0], GST_STATE_PAUSED);
 
889
      }
 
890
 
 
891
      /* creating another UDP source */
 
892
      if (transport->port.max != -1) {
 
893
        uri = g_strdup_printf ("udp://%s:%d", transport->destination,
 
894
            transport->port.max);
 
895
        stream->udpsrc[1] = gst_element_make_from_uri (GST_URI_SRC, uri, NULL);
 
896
        g_free (uri);
 
897
        if (stream->udpsrc[1] == NULL)
 
898
          goto no_element;
 
899
 
 
900
        gst_element_set_state (stream->udpsrc[1], GST_STATE_PAUSED);
 
901
      }
 
902
    }
 
903
 
 
904
    /* we manage the UDP elements now. For unicast, the UDP sources where
 
905
     * allocated in the stream when we suggested a transport. */
 
906
    if (stream->udpsrc[0]) {
 
907
      GstPad *pad;
 
908
 
 
909
      gst_bin_add (GST_BIN_CAST (src), stream->udpsrc[0]);
 
910
 
 
911
      GST_DEBUG_OBJECT (src, "setting up UDP source");
 
912
 
 
913
      /* set caps */
 
914
      g_object_set (G_OBJECT (stream->udpsrc[0]), "caps", stream->caps, NULL);
 
915
 
 
916
      /* configure a timeout on the UDP port */
 
917
      g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout", src->timeout,
 
918
          NULL);
 
919
 
 
920
      if (stream->channelpad[0]) {
 
921
        GST_DEBUG_OBJECT (src, "connecting UDP source 0 to manager");
 
922
        /* configure for UDP delivery, we need to connect the UDP pads to
 
923
         * the session plugin. */
 
924
        pad = gst_element_get_pad (stream->udpsrc[0], "src");
 
925
        gst_pad_link (pad, stream->channelpad[0]);
 
926
        gst_object_unref (pad);
 
927
 
 
928
        outpad = gst_element_get_pad (stream->sess, "srcrtp");
 
929
      } else {
 
930
        GST_DEBUG_OBJECT (src, "using UDP src pad as output");
 
931
        outpad = gst_element_get_pad (stream->udpsrc[0], "src");
 
932
      }
 
933
    }
 
934
 
 
935
    if (stream->udpsrc[1]) {
 
936
      gst_bin_add (GST_BIN_CAST (src), stream->udpsrc[1]);
 
937
 
 
938
      if (stream->channelpad[1]) {
 
939
        GstPad *pad;
 
940
 
 
941
        GST_DEBUG_OBJECT (src, "connecting UDP source 1 to manager");
 
942
 
 
943
        pad = gst_element_get_pad (stream->udpsrc[1], "src");
 
944
        gst_pad_link (pad, stream->channelpad[1]);
 
945
        gst_object_unref (pad);
 
946
      }
 
947
    }
 
948
  }
 
949
 
 
950
  if (outpad && !stream->srcpad) {
 
951
    GST_DEBUG_OBJECT (src, "creating ghostpad");
 
952
 
 
953
    gst_pad_use_fixed_caps (outpad);
 
954
    gst_pad_set_caps (outpad, stream->caps);
 
955
 
 
956
    /* create ghostpad */
 
957
    name = g_strdup_printf ("stream%d", stream->id);
 
958
    template = gst_static_pad_template_get (&rtptemplate);
 
959
    stream->srcpad = gst_ghost_pad_new_from_template (name, outpad, template);
 
960
    gst_object_unref (template);
 
961
    g_free (name);
 
962
 
 
963
    gst_object_unref (outpad);
 
964
 
 
965
    /* and add */
 
966
    gst_pad_set_active (stream->srcpad, TRUE);
 
967
    gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad);
 
968
  }
 
969
  /* mark pad as ok */
 
970
  stream->last_ret = GST_FLOW_OK;
726
971
 
727
972
  return TRUE;
728
973
 
 
974
  /* ERRORS */
 
975
no_mime:
 
976
  {
 
977
    GST_DEBUG_OBJECT (src, "unknown transport");
 
978
    return FALSE;
 
979
  }
 
980
no_manager:
 
981
  {
 
982
    GST_DEBUG_OBJECT (src, "cannot get a session manager");
 
983
    return FALSE;
 
984
  }
729
985
no_element:
730
986
  {
731
 
    GST_DEBUG ("no rtpdec element found");
 
987
    GST_DEBUG_OBJECT (src, "no rtpdec element found");
732
988
    return FALSE;
733
989
  }
734
 
start_rtpdec_failure:
 
990
start_session_failure:
735
991
  {
736
 
    GST_DEBUG ("could not start RTP session");
 
992
    GST_DEBUG_OBJECT (src, "could not start session");
737
993
    return FALSE;
738
994
  }
739
995
}
740
996
 
741
997
static gint
742
 
find_stream (GstRTSPStream * stream, gconstpointer a)
 
998
find_stream_by_channel (GstRTSPStream * stream, gconstpointer a)
743
999
{
744
1000
  gint channel = GPOINTER_TO_INT (a);
745
1001
 
746
 
  if (stream->rtpchannel == channel || stream->rtcpchannel == channel)
 
1002
  if (stream->channel[0] == channel || stream->channel[1] == channel)
747
1003
    return 0;
748
1004
 
749
1005
  return -1;
750
1006
}
751
1007
 
752
 
static void
753
 
gst_rtspsrc_loop (GstRTSPSrc * src)
 
1008
static GstFlowReturn
 
1009
gst_rtspsrc_combine_flows (GstRTSPSrc * src, GstRTSPStream * stream,
 
1010
    GstFlowReturn ret)
 
1011
{
 
1012
  GList *streams;
 
1013
 
 
1014
  /* store the value */
 
1015
  stream->last_ret = ret;
 
1016
 
 
1017
  /* if it's success we can return the value right away */
 
1018
  if (GST_FLOW_IS_SUCCESS (ret))
 
1019
    goto done;
 
1020
 
 
1021
  /* any other error that is not-linked can be returned right
 
1022
   * away */
 
1023
  if (ret != GST_FLOW_NOT_LINKED)
 
1024
    goto done;
 
1025
 
 
1026
  /* only return NOT_LINKED if all other pads returned NOT_LINKED */
 
1027
  for (streams = src->streams; streams; streams = g_list_next (streams)) {
 
1028
    GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
 
1029
 
 
1030
    ret = ostream->last_ret;
 
1031
    /* some other return value (must be SUCCESS but we can return
 
1032
     * other values as well) */
 
1033
    if (ret != GST_FLOW_NOT_LINKED)
 
1034
      goto done;
 
1035
  }
 
1036
  /* if we get here, all other pads were unlinked and we return
 
1037
   * NOT_LINKED then */
 
1038
done:
 
1039
  return ret;
 
1040
}
 
1041
 
 
1042
static void
 
1043
gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event)
 
1044
{
 
1045
  GList *streams;
 
1046
 
 
1047
  for (streams = src->streams; streams; streams = g_list_next (streams)) {
 
1048
    GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
 
1049
 
 
1050
    /* only pads that have a connection to the outside world */
 
1051
    if (ostream->srcpad == NULL)
 
1052
      continue;
 
1053
 
 
1054
    if (ostream->channelpad[0]) {
 
1055
      gst_event_ref (event);
 
1056
      if (GST_PAD_IS_SRC (ostream->channelpad[0]))
 
1057
        gst_pad_push_event (ostream->channelpad[0], event);
 
1058
      else
 
1059
        gst_pad_send_event (ostream->channelpad[0], event);
 
1060
    }
 
1061
 
 
1062
    if (ostream->channelpad[1]) {
 
1063
      gst_event_ref (event);
 
1064
      if (GST_PAD_IS_SRC (ostream->channelpad[1]))
 
1065
        gst_pad_push_event (ostream->channelpad[1], event);
 
1066
      else
 
1067
        gst_pad_send_event (ostream->channelpad[1], event);
 
1068
    }
 
1069
  }
 
1070
  gst_event_unref (event);
 
1071
}
 
1072
 
 
1073
static void
 
1074
gst_rtspsrc_loop_interleaved (GstRTSPSrc * src)
754
1075
{
755
1076
  RTSPMessage response = { 0 };
756
1077
  RTSPResult res;
760
1081
  GstPad *outpad = NULL;
761
1082
  guint8 *data;
762
1083
  guint size;
 
1084
  GstFlowReturn ret = GST_FLOW_OK;
 
1085
  GstCaps *caps = NULL;
 
1086
  GstBuffer *buf;
763
1087
 
764
1088
  do {
765
 
    GST_DEBUG ("doing reveive");
 
1089
    GST_DEBUG_OBJECT (src, "doing receive");
766
1090
    if ((res = rtsp_connection_receive (src->connection, &response)) < 0)
767
1091
      goto receive_error;
768
 
    GST_DEBUG ("got packet");
 
1092
 
 
1093
    GST_DEBUG_OBJECT (src, "got packet type %d", response.type);
769
1094
  }
770
1095
  while (response.type != RTSP_MESSAGE_DATA);
771
1096
 
772
1097
  channel = response.type_data.data.channel;
773
1098
 
774
1099
  lstream = g_list_find_custom (src->streams, GINT_TO_POINTER (channel),
775
 
      (GCompareFunc) find_stream);
 
1100
      (GCompareFunc) find_stream_by_channel);
776
1101
  if (!lstream)
777
1102
    goto unknown_stream;
778
1103
 
779
1104
  stream = (GstRTSPStream *) lstream->data;
780
 
  if (channel == stream->rtpchannel)
781
 
    outpad = stream->rtpdecrtp;
782
 
  else if (channel == stream->rtcpchannel)
783
 
    outpad = stream->rtpdecrtcp;
 
1105
  if (channel == stream->channel[0]) {
 
1106
    outpad = stream->channelpad[0];
 
1107
    caps = stream->caps;
 
1108
  } else if (channel == stream->channel[1]) {
 
1109
    outpad = stream->channelpad[1];
 
1110
  }
784
1111
 
 
1112
  /* take a look at the body to figure out what we have */
785
1113
  rtsp_message_get_body (&response, &data, &size);
 
1114
  if (size < 2)
 
1115
    goto invalid_length;
786
1116
 
787
1117
  /* channels are not correct on some servers, do extra check */
788
1118
  if (data[1] >= 200 && data[1] <= 204) {
789
 
    /* hmm RTCP message */
790
 
    outpad = stream->rtpdecrtcp;
 
1119
    /* hmm RTCP message switch to the RTCP pad of the same stream. */
 
1120
    outpad = stream->channelpad[1];
791
1121
  }
792
1122
 
793
1123
  /* we have no clue what this is, just ignore then. */
795
1125
    goto unknown_stream;
796
1126
 
797
1127
  /* and chain buffer to internal element */
798
 
  {
799
 
    GstBuffer *buf;
800
 
 
801
 
    buf = gst_buffer_new_and_alloc (size);
802
 
    memcpy (GST_BUFFER_DATA (buf), data, size);
803
 
 
804
 
    if (gst_pad_chain (outpad, buf) != GST_FLOW_OK)
805
 
      goto need_pause;
806
 
  }
807
 
 
 
1128
  rtsp_message_steal_body (&response, &data, &size);
 
1129
 
 
1130
  /* strip the trailing \0 */
 
1131
  size -= 1;
 
1132
 
 
1133
  buf = gst_buffer_new ();
 
1134
  GST_BUFFER_DATA (buf) = data;
 
1135
  GST_BUFFER_MALLOCDATA (buf) = data;
 
1136
  GST_BUFFER_SIZE (buf) = size;
 
1137
 
 
1138
  /* don't need message anymore */
 
1139
  rtsp_message_unset (&response);
 
1140
 
 
1141
  if (caps)
 
1142
    gst_buffer_set_caps (buf, caps);
 
1143
 
 
1144
  GST_DEBUG_OBJECT (src, "pushing data of size %d on channel %d", size,
 
1145
      channel);
 
1146
 
 
1147
  /* chain to the peer pad */
 
1148
  if (GST_PAD_IS_SINK (outpad))
 
1149
    ret = gst_pad_chain (outpad, buf);
 
1150
  else
 
1151
    ret = gst_pad_push (outpad, buf);
 
1152
 
 
1153
  /* combine all stream flows */
 
1154
  ret = gst_rtspsrc_combine_flows (src, stream, ret);
 
1155
  if (ret != GST_FLOW_OK)
 
1156
    goto need_pause;
 
1157
 
 
1158
  return;
 
1159
 
 
1160
  /* ERRORS */
808
1161
unknown_stream:
809
 
 
810
 
  return;
811
 
 
 
1162
  {
 
1163
    GST_DEBUG_OBJECT (src, "unknown stream on channel %d, ignored", channel);
 
1164
    rtsp_message_unset (&response);
 
1165
    return;
 
1166
  }
812
1167
receive_error:
813
1168
  {
814
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
815
 
        ("Could not receive message."), (NULL));
816
 
    /*
817
 
       gst_pad_push_event (src->srcpad, gst_event_new (GST_EVENT_EOS));
818
 
     */
 
1169
    gchar *str = rtsp_strresult (res);
 
1170
 
 
1171
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
 
1172
        ("Could not receive message. (%s)", str));
 
1173
    g_free (str);
 
1174
 
 
1175
    if (src->debug)
 
1176
      rtsp_message_dump (&response);
 
1177
 
 
1178
    rtsp_message_unset (&response);
 
1179
    ret = GST_FLOW_UNEXPECTED;
819
1180
    goto need_pause;
820
1181
  }
 
1182
invalid_length:
 
1183
  {
 
1184
    GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
 
1185
        ("Short message received."));
 
1186
    rtsp_message_unset (&response);
 
1187
    return;
 
1188
  }
821
1189
need_pause:
822
1190
  {
823
 
    gst_task_pause (src->task);
824
 
    return;
825
 
  }
826
 
}
827
 
 
828
 
static gboolean
 
1191
    const gchar *reason = gst_flow_get_name (ret);
 
1192
 
 
1193
    GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
 
1194
    src->running = FALSE;
 
1195
    gst_task_pause (src->task);
 
1196
    if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
 
1197
      if (ret == GST_FLOW_UNEXPECTED) {
 
1198
        /* perform EOS logic */
 
1199
        if (src->segment.flags & GST_SEEK_FLAG_SEGMENT) {
 
1200
          gst_element_post_message (GST_ELEMENT_CAST (src),
 
1201
              gst_message_new_segment_done (GST_OBJECT_CAST (src),
 
1202
                  src->segment.format, src->segment.last_stop));
 
1203
        } else {
 
1204
          gst_rtspsrc_push_event (src, gst_event_new_eos ());
 
1205
        }
 
1206
      } else {
 
1207
        /* for fatal errors we post an error message, post the error
 
1208
         * first so the app knows about the error first. */
 
1209
        GST_ELEMENT_ERROR (src, STREAM, FAILED,
 
1210
            ("Internal data flow error."),
 
1211
            ("streaming task paused, reason %s (%d)", reason, ret));
 
1212
        gst_rtspsrc_push_event (src, gst_event_new_eos ());
 
1213
      }
 
1214
    }
 
1215
    return;
 
1216
  }
 
1217
}
 
1218
 
 
1219
static void
 
1220
gst_rtspsrc_loop_udp (GstRTSPSrc * src)
 
1221
{
 
1222
  gboolean restart = FALSE;
 
1223
 
 
1224
  GST_OBJECT_LOCK (src);
 
1225
  if (src->loop_cmd == CMD_STOP)
 
1226
    goto stopping;
 
1227
 
 
1228
  while (src->loop_cmd == CMD_WAIT) {
 
1229
    GST_DEBUG_OBJECT (src, "waiting");
 
1230
    GST_RTSP_LOOP_WAIT (src);
 
1231
    GST_DEBUG_OBJECT (src, "waiting done");
 
1232
    if (src->loop_cmd == CMD_STOP)
 
1233
      goto stopping;
 
1234
  }
 
1235
  if (src->loop_cmd == CMD_RECONNECT) {
 
1236
    /* FIXME, when we get here we have to reconnect using tcp */
 
1237
    src->loop_cmd = CMD_WAIT;
 
1238
    restart = TRUE;
 
1239
  }
 
1240
  GST_OBJECT_UNLOCK (src);
 
1241
 
 
1242
  if (restart) {
 
1243
    gst_rtspsrc_pause (src);
 
1244
 
 
1245
    if (src->task) {
 
1246
      /* stop task, we cannot join as this would deadlock */
 
1247
      gst_task_stop (src->task);
 
1248
      /* and free the task so that _close will not stop/join it again. */
 
1249
      gst_object_unref (GST_OBJECT (src->task));
 
1250
      src->task = NULL;
 
1251
    }
 
1252
    gst_rtspsrc_close (src);
 
1253
 
 
1254
    /* see if we have TCP left to try */
 
1255
    if (src->cur_protocols & RTSP_LOWER_TRANS_TCP) {
 
1256
      gchar *url, *pos;
 
1257
 
 
1258
      /* We post a warning message now to inform the user
 
1259
       * that nothing happened. It's most likely a firewall thing. */
 
1260
      GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
 
1261
          ("Could not receive any UDP packets for %.4f seconds, maybe your "
 
1262
              "firewall is blocking it. Retrying using a TCP connection.",
 
1263
              (gdouble) src->timeout / 1000000));
 
1264
      /* we can try only TCP now */
 
1265
      src->cur_protocols = RTSP_LOWER_TRANS_TCP;
 
1266
 
 
1267
      pos = strstr (src->location, "://");
 
1268
      if (!pos)
 
1269
        goto weird_url;
 
1270
 
 
1271
      url = g_strdup_printf ("rtspt://%s", pos + 3);
 
1272
 
 
1273
      gst_element_post_message (GST_ELEMENT_CAST (src),
 
1274
          gst_message_new_element (GST_OBJECT_CAST (src),
 
1275
              gst_structure_new ("redirect",
 
1276
                  "new-location", G_TYPE_STRING, url, NULL)));
 
1277
      g_free (url);
 
1278
    } else {
 
1279
      src->cur_protocols = 0;
 
1280
      /* no transport possible, post an error and stop */
 
1281
      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
 
1282
          ("Could not connect to server, no protocols left"));
 
1283
    }
 
1284
  }
 
1285
  return;
 
1286
 
 
1287
  /* ERRORS */
 
1288
stopping:
 
1289
  {
 
1290
    GST_OBJECT_UNLOCK (src);
 
1291
    src->running = FALSE;
 
1292
    gst_task_pause (src->task);
 
1293
    return;
 
1294
  }
 
1295
weird_url:
 
1296
  {
 
1297
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
 
1298
        ("Could not redirect, location %s is invalid", src->location));
 
1299
    return;
 
1300
  }
 
1301
}
 
1302
 
 
1303
static void
 
1304
gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd)
 
1305
{
 
1306
  GST_OBJECT_LOCK (src);
 
1307
  src->loop_cmd = cmd;
 
1308
  GST_RTSP_LOOP_SIGNAL (src);
 
1309
  GST_OBJECT_UNLOCK (src);
 
1310
}
 
1311
 
 
1312
static void
 
1313
gst_rtspsrc_loop (GstRTSPSrc * src)
 
1314
{
 
1315
  if (src->interleaved)
 
1316
    gst_rtspsrc_loop_interleaved (src);
 
1317
  else
 
1318
    gst_rtspsrc_loop_udp (src);
 
1319
}
 
1320
 
 
1321
static RTSPResult
 
1322
gst_rtspsrc_handle_request (GstRTSPSrc * src, RTSPMessage * request)
 
1323
{
 
1324
  RTSPMessage response = { 0 };
 
1325
  RTSPResult res;
 
1326
 
 
1327
  res = rtsp_message_init_response (&response, RTSP_STS_OK, "OK", request);
 
1328
  if (res < 0)
 
1329
    goto send_error;
 
1330
 
 
1331
  if (src->debug)
 
1332
    rtsp_message_dump (&response);
 
1333
 
 
1334
  if ((res = rtsp_connection_send (src->connection, &response)) < 0)
 
1335
    goto send_error;
 
1336
 
 
1337
  return RTSP_OK;
 
1338
 
 
1339
  /* ERRORS */
 
1340
send_error:
 
1341
  {
 
1342
    gchar *str = rtsp_strresult (res);
 
1343
 
 
1344
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
 
1345
        ("Could not send message. (%s)", str));
 
1346
    g_free (str);
 
1347
    return res;
 
1348
  }
 
1349
}
 
1350
 
 
1351
/**
 
1352
 * gst_rtspsrc_send:
 
1353
 * @src: the rtsp source
 
1354
 * @request: must point to a valid request
 
1355
 * @response: must point to an empty #RTSPMessage
 
1356
 *
 
1357
 * send @request and retrieve the response in @response. optionally @code can be
 
1358
 * non-NULL in which case it will contain the status code of the response.
 
1359
 *
 
1360
 * If This function returns TRUE, @response will contain a valid response
 
1361
 * message that should be cleaned with rtsp_message_unset() after usage. 
 
1362
 *
 
1363
 * If @code is NULL, this function will return FALSE (with an invalid @response
 
1364
 * message) if the response code was not 200 (OK).
 
1365
 *
 
1366
 * Returns: TRUE if the processing was successful.
 
1367
 */
 
1368
gboolean
829
1369
gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
830
1370
    RTSPMessage * response, RTSPStatusCode * code)
831
1371
{
832
1372
  RTSPResult res;
833
 
 
834
 
  if (src->debug) {
 
1373
  RTSPStatusCode thecode;
 
1374
  gchar *content_base = NULL;
 
1375
 
 
1376
  if (src->extension && src->extension->before_send)
 
1377
    src->extension->before_send (src->extension, request);
 
1378
 
 
1379
  if (src->debug)
835
1380
    rtsp_message_dump (request);
836
 
  }
 
1381
 
837
1382
  if ((res = rtsp_connection_send (src->connection, request)) < 0)
838
1383
    goto send_error;
839
1384
 
 
1385
next:
840
1386
  if ((res = rtsp_connection_receive (src->connection, response)) < 0)
841
1387
    goto receive_error;
842
1388
 
843
 
  if (code) {
844
 
    *code = response->type_data.response.code;
845
 
  }
846
 
 
847
 
  if (src->debug) {
 
1389
  if (src->debug)
848
1390
    rtsp_message_dump (response);
 
1391
 
 
1392
  switch (response->type) {
 
1393
    case RTSP_MESSAGE_REQUEST:
 
1394
      /* FIXME, handle server request, reply with OK, for now */
 
1395
      if ((res = gst_rtspsrc_handle_request (src, response)) < 0)
 
1396
        goto handle_request_failed;
 
1397
      goto next;
 
1398
    case RTSP_MESSAGE_RESPONSE:
 
1399
      /* ok, a response is good */
 
1400
      break;
 
1401
    default:
 
1402
    case RTSP_MESSAGE_DATA:
 
1403
      /* get next response */
 
1404
      goto next;
849
1405
  }
850
 
  if (response->type_data.response.code != RTSP_STS_OK)
 
1406
 
 
1407
  thecode = response->type_data.response.code;
 
1408
  /* if the caller wanted the result code, we store it. Else we check if it's
 
1409
   * OK. */
 
1410
  if (code)
 
1411
    *code = thecode;
 
1412
  else if (thecode != RTSP_STS_OK)
851
1413
    goto error_response;
852
1414
 
 
1415
  /* store new content base if any */
 
1416
  rtsp_message_get_header (response, RTSP_HDR_CONTENT_BASE, &content_base);
 
1417
  if (content_base) {
 
1418
    g_free (src->content_base);
 
1419
    src->content_base = g_strdup (content_base);
 
1420
  }
 
1421
 
 
1422
  if (src->extension && src->extension->after_send)
 
1423
    src->extension->after_send (src->extension, request, response);
 
1424
 
853
1425
  return TRUE;
854
1426
 
 
1427
  /* ERRORS */
855
1428
send_error:
856
1429
  {
857
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
858
 
        ("Could not send message."), (NULL));
 
1430
    gchar *str = rtsp_strresult (res);
 
1431
 
 
1432
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
 
1433
        ("Could not send message. (%s)", str));
 
1434
    g_free (str);
859
1435
    return FALSE;
860
1436
  }
861
1437
receive_error:
862
1438
  {
863
 
    GST_ELEMENT_ERROR (src, RESOURCE, READ,
864
 
        ("Could not receive message."), (NULL));
 
1439
    gchar *str = rtsp_strresult (res);
 
1440
 
 
1441
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
 
1442
        ("Could not receive message. (%s)", str));
 
1443
    g_free (str);
 
1444
    return FALSE;
 
1445
  }
 
1446
handle_request_failed:
 
1447
  {
 
1448
    /* ERROR was posted */
865
1449
    return FALSE;
866
1450
  }
867
1451
error_response:
868
1452
  {
869
 
    GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Got error response: %d (%s).",
870
 
            response->type_data.response.code,
871
 
            response->type_data.response.reason), (NULL));
872
 
    return FALSE;
 
1453
    switch (response->type_data.response.code) {
 
1454
      case RTSP_STS_NOT_FOUND:
 
1455
        GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("%s",
 
1456
                response->type_data.response.reason));
 
1457
        break;
 
1458
      default:
 
1459
        GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
 
1460
            ("Got error response: %d (%s).", response->type_data.response.code,
 
1461
                response->type_data.response.reason));
 
1462
        break;
 
1463
    }
 
1464
    /* we return FALSE so we should unset the response ourselves */
 
1465
    rtsp_message_unset (response);
 
1466
    return FALSE;
 
1467
  }
 
1468
}
 
1469
 
 
1470
/* parse the response and collect all the supported methods. We need this
 
1471
 * information so that we don't try to send an unsupported request to the
 
1472
 * server.
 
1473
 */
 
1474
static gboolean
 
1475
gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response)
 
1476
{
 
1477
  gchar *respoptions = NULL;
 
1478
  gchar **options;
 
1479
  gint i;
 
1480
 
 
1481
  /* clear supported methods */
 
1482
  src->methods = 0;
 
1483
 
 
1484
  /* Try Allow Header first */
 
1485
  rtsp_message_get_header (response, RTSP_HDR_ALLOW, &respoptions);
 
1486
  if (!respoptions)
 
1487
    /* Then maybe Public Header... */
 
1488
    rtsp_message_get_header (response, RTSP_HDR_PUBLIC, &respoptions);
 
1489
  if (!respoptions) {
 
1490
    /* this field is not required, assume the server supports
 
1491
     * DESCRIBE, SETUP and PLAY */
 
1492
    GST_DEBUG_OBJECT (src, "could not get OPTIONS");
 
1493
    src->methods = RTSP_DESCRIBE | RTSP_SETUP | RTSP_PLAY | RTSP_PAUSE;
 
1494
    goto done;
 
1495
  }
 
1496
 
 
1497
  /* If we get here, the server gave a list of supported methods, parse
 
1498
   * them here. The string is like: 
 
1499
   *
 
1500
   * OPTIONS, DESCRIBE, ANNOUNCE, PLAY, SETUP, ...
 
1501
   */
 
1502
  options = g_strsplit (respoptions, ",", 0);
 
1503
 
 
1504
  for (i = 0; options[i]; i++) {
 
1505
    gchar *stripped;
 
1506
    gint method;
 
1507
 
 
1508
    stripped = g_strstrip (options[i]);
 
1509
    method = rtsp_find_method (stripped);
 
1510
 
 
1511
    /* keep bitfield of supported methods */
 
1512
    if (method != -1)
 
1513
      src->methods |= method;
 
1514
  }
 
1515
  g_strfreev (options);
 
1516
 
 
1517
  /* we need describe and setup */
 
1518
  if (!(src->methods & RTSP_DESCRIBE))
 
1519
    goto no_describe;
 
1520
  if (!(src->methods & RTSP_SETUP))
 
1521
    goto no_setup;
 
1522
 
 
1523
done:
 
1524
  return TRUE;
 
1525
 
 
1526
  /* ERRORS */
 
1527
no_describe:
 
1528
  {
 
1529
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
 
1530
        ("Server does not support DESCRIBE."));
 
1531
    return FALSE;
 
1532
  }
 
1533
no_setup:
 
1534
  {
 
1535
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
 
1536
        ("Server does not support SETUP."));
 
1537
    return FALSE;
 
1538
  }
 
1539
}
 
1540
 
 
1541
static RTSPResult
 
1542
gst_rtspsrc_create_transports_string (GstRTSPSrc * src,
 
1543
    RTSPLowerTrans protocols, gchar ** transports)
 
1544
{
 
1545
  gchar *result;
 
1546
  RTSPResult res;
 
1547
 
 
1548
  *transports = NULL;
 
1549
  if (src->extension && src->extension->get_transports)
 
1550
    if ((res =
 
1551
            src->extension->get_transports (src->extension, protocols,
 
1552
                transports)) < 0)
 
1553
      goto failed;
 
1554
 
 
1555
  /* extension listed transports, use those */
 
1556
  if (*transports != NULL)
 
1557
    return RTSP_OK;
 
1558
 
 
1559
  result = g_strdup ("");
 
1560
  if (protocols & RTSP_LOWER_TRANS_UDP) {
 
1561
    gchar *new;
 
1562
 
 
1563
    GST_DEBUG_OBJECT (src, "adding UDP unicast");
 
1564
 
 
1565
    new =
 
1566
        g_strconcat (result, "RTP/AVP/UDP;unicast;client_port=%%u1-%%u2", NULL);
 
1567
    g_free (result);
 
1568
    result = new;
 
1569
  }
 
1570
  if (protocols & RTSP_LOWER_TRANS_UDP_MCAST) {
 
1571
    gchar *new;
 
1572
 
 
1573
    GST_DEBUG_OBJECT (src, "adding UDP multicast");
 
1574
 
 
1575
    /* we don't have to allocate any UDP ports yet, if the selected transport
 
1576
     * turns out to be multicast we can create them and join the multicast
 
1577
     * group indicated in the transport reply */
 
1578
    new = g_strconcat (result, result[0] ? "," : "",
 
1579
        "RTP/AVP/UDP;multicast", NULL);
 
1580
    g_free (result);
 
1581
    result = new;
 
1582
  }
 
1583
  if (protocols & RTSP_LOWER_TRANS_TCP) {
 
1584
    gchar *new;
 
1585
 
 
1586
    GST_DEBUG_OBJECT (src, "adding TCP");
 
1587
 
 
1588
    new = g_strconcat (result, result[0] ? "," : "",
 
1589
        "RTP/AVP/TCP;unicast;interleaved=%%i1-%%i2", NULL);
 
1590
    g_free (result);
 
1591
    result = new;
 
1592
  }
 
1593
  *transports = result;
 
1594
 
 
1595
  return RTSP_OK;
 
1596
 
 
1597
  /* ERRORS */
 
1598
failed:
 
1599
  {
 
1600
    return res;
 
1601
  }
 
1602
}
 
1603
 
 
1604
static RTSPResult
 
1605
gst_rtspsrc_configure_transports (GstRTSPStream * stream, gchar ** transports)
 
1606
{
 
1607
  GstRTSPSrc *src;
 
1608
  gint nr_udp, nr_int;
 
1609
  gchar *next, *p;
 
1610
  gint rtpport = 0, rtcpport = 0;
 
1611
  GString *str;
 
1612
 
 
1613
  src = stream->parent;
 
1614
 
 
1615
  /* find number of placeholders first */
 
1616
  if (strstr (*transports, "%%i2"))
 
1617
    nr_int = 2;
 
1618
  else if (strstr (*transports, "%%i1"))
 
1619
    nr_int = 1;
 
1620
  else
 
1621
    nr_int = 0;
 
1622
 
 
1623
  if (strstr (*transports, "%%u2"))
 
1624
    nr_udp = 2;
 
1625
  else if (strstr (*transports, "%%u1"))
 
1626
    nr_udp = 1;
 
1627
  else
 
1628
    nr_udp = 0;
 
1629
 
 
1630
  if (nr_udp == 0 && nr_int == 0)
 
1631
    goto done;
 
1632
 
 
1633
  if (nr_udp > 0) {
 
1634
    if (!gst_rtspsrc_alloc_udp_ports (stream, &rtpport, &rtcpport))
 
1635
      goto failed;
 
1636
  }
 
1637
 
 
1638
  str = g_string_new ("");
 
1639
  p = *transports;
 
1640
  while ((next = strstr (p, "%%"))) {
 
1641
    g_string_append_len (str, p, next - p);
 
1642
    if (next[2] == 'u') {
 
1643
      if (next[3] == '1')
 
1644
        g_string_append_printf (str, "%d", rtpport);
 
1645
      else if (next[3] == '2')
 
1646
        g_string_append_printf (str, "%d", rtcpport);
 
1647
    }
 
1648
    if (next[2] == 'i') {
 
1649
      if (next[3] == '1')
 
1650
        g_string_append_printf (str, "%d", src->free_channel);
 
1651
      else if (next[3] == '2')
 
1652
        g_string_append_printf (str, "%d", src->free_channel + 1);
 
1653
    }
 
1654
 
 
1655
    p = next + 4;
 
1656
  }
 
1657
 
 
1658
  g_free (*transports);
 
1659
  *transports = g_string_free (str, FALSE);
 
1660
 
 
1661
done:
 
1662
  return RTSP_OK;
 
1663
 
 
1664
  /* ERRORS */
 
1665
failed:
 
1666
  {
 
1667
    return RTSP_ERROR;
873
1668
  }
874
1669
}
875
1670
 
876
1671
static gboolean
877
1672
gst_rtspsrc_open (GstRTSPSrc * src)
878
1673
{
879
 
  RTSPUrl *url;
880
1674
  RTSPResult res;
881
1675
  RTSPMessage request = { 0 };
882
1676
  RTSPMessage response = { 0 };
883
1677
  guint8 *data;
884
1678
  guint size;
 
1679
  gint i, n_streams;
885
1680
  SDPMessage sdp = { 0 };
886
 
  GstRTSPProto protocols;
887
 
 
888
 
  /* parse url */
889
 
  GST_DEBUG ("parsing url...");
890
 
  if ((res = rtsp_url_parse (src->location, &url)) < 0)
891
 
    goto invalid_url;
892
 
 
893
 
  /* open connection */
894
 
  GST_DEBUG ("opening connection...");
895
 
  if ((res = rtsp_connection_open (url, &src->connection)) < 0)
896
 
    goto could_not_open;
 
1681
  RTSPLowerTrans protocols;
 
1682
  GstRTSPStream *stream = NULL;
 
1683
  gchar *respcont = NULL;
 
1684
 
 
1685
  /* reset our state */
 
1686
  src->free_channel = 0;
 
1687
  src->interleaved = FALSE;
 
1688
  gst_segment_init (&src->segment, GST_FORMAT_TIME);
 
1689
 
 
1690
  /* can't continue without a valid url */
 
1691
  if (G_UNLIKELY (src->url == NULL))
 
1692
    goto no_url;
 
1693
 
 
1694
  /* create connection */
 
1695
  GST_DEBUG_OBJECT (src, "creating connection (%s)...", src->location);
 
1696
  if ((res = rtsp_connection_create (src->url, &src->connection)) < 0)
 
1697
    goto could_not_create;
 
1698
 
 
1699
  /* connect */
 
1700
  GST_DEBUG_OBJECT (src, "connecting (%s)...", src->location);
 
1701
  if ((res = rtsp_connection_connect (src->connection)) < 0)
 
1702
    goto could_not_connect;
897
1703
 
898
1704
  /* create OPTIONS */
899
 
  GST_DEBUG ("create options...");
900
 
  if ((res =
901
 
          rtsp_message_init_request (RTSP_OPTIONS, src->location,
902
 
              &request)) < 0)
 
1705
  GST_DEBUG_OBJECT (src, "create options...");
 
1706
  res = rtsp_message_init_request (&request, RTSP_OPTIONS, src->location);
 
1707
  if (res < 0)
903
1708
    goto create_request_failed;
904
1709
 
905
1710
  /* send OPTIONS */
906
 
  GST_DEBUG ("send options...");
 
1711
  GST_DEBUG_OBJECT (src, "send options...");
907
1712
  if (!gst_rtspsrc_send (src, &request, &response, NULL))
908
1713
    goto send_error;
909
1714
 
910
 
  {
911
 
    gchar *respoptions = NULL;
912
 
    gchar **options;
913
 
    gint i;
914
 
 
915
 
    /* Try Allow Header first */
916
 
    rtsp_message_get_header (&response, RTSP_HDR_ALLOW, &respoptions);
917
 
    if (!respoptions) {
918
 
      /* Then maybe Public Header... */
919
 
      rtsp_message_get_header (&response, RTSP_HDR_PUBLIC, &respoptions);
920
 
      if (!respoptions) {
921
 
        /* this field is not required, assume the server supports
922
 
         * DESCRIBE and SETUP*/
923
 
        GST_DEBUG_OBJECT (src, "could not get OPTIONS");
924
 
        src->options = RTSP_DESCRIBE | RTSP_SETUP;
925
 
        goto no_options;
926
 
      }
927
 
    }
928
 
 
929
 
    /* parse options */
930
 
    options = g_strsplit (respoptions, ",", 0);
931
 
 
932
 
    i = 0;
933
 
    while (options[i]) {
934
 
      gchar *stripped;
935
 
      gint method;
936
 
 
937
 
      stripped = g_strdup (options[i]);
938
 
      stripped = g_strstrip (stripped);
939
 
      method = rtsp_find_method (stripped);
940
 
      g_free (stripped);
941
 
 
942
 
      /* keep bitfield of supported methods */
943
 
      if (method != -1)
944
 
        src->options |= method;
945
 
      i++;
946
 
    }
947
 
    g_strfreev (options);
948
 
 
949
 
  no_options:
950
 
    /* we need describe and setup */
951
 
    if (!(src->options & RTSP_DESCRIBE))
952
 
      goto no_describe;
953
 
    if (!(src->options & RTSP_SETUP))
954
 
      goto no_setup;
955
 
  }
 
1715
  /* parse OPTIONS */
 
1716
  if (!gst_rtspsrc_parse_methods (src, &response))
 
1717
    goto methods_error;
956
1718
 
957
1719
  /* create DESCRIBE */
958
 
  GST_DEBUG ("create describe...");
959
 
  if ((res =
960
 
          rtsp_message_init_request (RTSP_DESCRIBE, src->location,
961
 
              &request)) < 0)
 
1720
  GST_DEBUG_OBJECT (src, "create describe...");
 
1721
  res = rtsp_message_init_request (&request, RTSP_DESCRIBE, src->location);
 
1722
  if (res < 0)
962
1723
    goto create_request_failed;
963
 
  /* we accept SDP for now */
 
1724
 
 
1725
  /* we only accept SDP for now */
964
1726
  rtsp_message_add_header (&request, RTSP_HDR_ACCEPT, "application/sdp");
965
1727
 
 
1728
  /* prepare global stream caps properties */
 
1729
  if (src->props)
 
1730
    gst_structure_remove_all_fields (src->props);
 
1731
  else
 
1732
    src->props = gst_structure_empty_new ("RTSP Properties");
 
1733
 
966
1734
  /* send DESCRIBE */
967
 
  GST_DEBUG ("send describe...");
 
1735
  GST_DEBUG_OBJECT (src, "send describe...");
968
1736
  if (!gst_rtspsrc_send (src, &request, &response, NULL))
969
1737
    goto send_error;
970
1738
 
971
1739
  /* check if reply is SDP */
972
 
  {
973
 
    gchar *respcont = NULL;
974
 
 
975
 
    rtsp_message_get_header (&response, RTSP_HDR_CONTENT_TYPE, &respcont);
976
 
    /* could not be set but since the request returned OK, we assume it
977
 
     * was SDP, else check it. */
978
 
    if (respcont) {
979
 
      if (!g_ascii_strcasecmp (respcont, "application/sdp") == 0)
980
 
        goto wrong_content_type;
981
 
    }
 
1740
  rtsp_message_get_header (&response, RTSP_HDR_CONTENT_TYPE, &respcont);
 
1741
  /* could not be set but since the request returned OK, we assume it
 
1742
   * was SDP, else check it. */
 
1743
  if (respcont) {
 
1744
    if (!g_ascii_strcasecmp (respcont, "application/sdp") == 0)
 
1745
      goto wrong_content_type;
982
1746
  }
983
1747
 
984
 
  /* parse SDP */
 
1748
  /* get message body and parse as SDP */
985
1749
  rtsp_message_get_body (&response, &data, &size);
986
1750
 
987
 
  GST_DEBUG ("parse sdp...");
 
1751
  GST_DEBUG_OBJECT (src, "parse SDP...");
988
1752
  sdp_message_init (&sdp);
989
1753
  sdp_message_parse_buffer (data, size, &sdp);
990
1754
 
991
1755
  if (src->debug)
992
1756
    sdp_message_dump (&sdp);
993
1757
 
994
 
  /* we allow all configured protocols */
995
 
  protocols = src->protocols;
 
1758
  if (src->extension && src->extension->parse_sdp)
 
1759
    src->extension->parse_sdp (src->extension, &sdp);
 
1760
 
 
1761
  /* we initially allow all configured lower transports. based on the URL
 
1762
   * transports and the replies from the server we narrow them down. */
 
1763
  protocols = src->url->transports & src->cur_protocols;
 
1764
 
996
1765
  /* setup streams */
997
 
  {
998
 
    gint i;
999
 
 
1000
 
    for (i = 0; i < sdp_message_medias_len (&sdp); i++) {
1001
 
      SDPMedia *media;
1002
 
      gchar *setup_url;
1003
 
      gchar *control_url;
1004
 
      gchar *transports;
1005
 
      GstRTSPStream *stream;
1006
 
 
1007
 
      media = sdp_message_get_media (&sdp, i);
1008
 
 
1009
 
      stream = gst_rtspsrc_create_stream (src);
1010
 
 
1011
 
      GST_DEBUG ("setup media %d", i);
1012
 
      control_url = sdp_media_get_attribute_val (media, "control");
1013
 
      if (control_url == NULL) {
1014
 
        GST_DEBUG ("no control url found, skipping stream");
1015
 
        continue;
1016
 
      }
1017
 
 
1018
 
      /* check absolute/relative URL */
1019
 
      /* FIXME, what if the control_url starts with a '/' or a non rtsp: protocol? */
1020
 
      if (g_str_has_prefix (control_url, "rtsp://")) {
1021
 
        setup_url = g_strdup (control_url);
1022
 
      } else {
1023
 
        setup_url = g_strdup_printf ("%s/%s", src->location, control_url);
1024
 
      }
1025
 
 
1026
 
      GST_DEBUG ("setup %s", setup_url);
1027
 
      /* create SETUP request */
1028
 
      if ((res =
1029
 
              rtsp_message_init_request (RTSP_SETUP, setup_url,
1030
 
                  &request)) < 0) {
1031
 
        g_free (setup_url);
1032
 
        goto create_request_failed;
1033
 
      }
1034
 
      g_free (setup_url);
1035
 
 
1036
 
      transports = g_strdup ("");
1037
 
      if (protocols & GST_RTSP_PROTO_UDP_UNICAST) {
1038
 
        gchar *new;
1039
 
        gint rtpport, rtcpport;
1040
 
        gchar *trxparams;
1041
 
 
1042
 
        /* allocate two udp ports */
1043
 
        if (!gst_rtspsrc_stream_setup_rtp (stream, media, &rtpport, &rtcpport))
1044
 
          goto setup_rtp_failed;
1045
 
 
1046
 
        trxparams = g_strdup_printf ("client_port=%d-%d", rtpport, rtcpport);
1047
 
        new = g_strconcat (transports, "RTP/AVP/UDP;unicast;", trxparams, NULL);
1048
 
        g_free (trxparams);
1049
 
        g_free (transports);
1050
 
        transports = new;
1051
 
      }
1052
 
      if (protocols & GST_RTSP_PROTO_UDP_MULTICAST) {
1053
 
        gchar *new;
1054
 
 
1055
 
        new =
1056
 
            g_strconcat (transports, transports[0] ? "," : "",
1057
 
            "RTP/AVP/UDP;multicast", NULL);
1058
 
        g_free (transports);
1059
 
        transports = new;
1060
 
      }
1061
 
      if (protocols & GST_RTSP_PROTO_TCP) {
1062
 
        gchar *new;
1063
 
 
1064
 
        new =
1065
 
            g_strconcat (transports, transports[0] ? "," : "", "RTP/AVP/TCP",
1066
 
            NULL);
1067
 
        g_free (transports);
1068
 
        transports = new;
1069
 
      }
1070
 
 
1071
 
      /* select transport, copy is made when adding to header */
1072
 
      rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT, transports);
1073
 
      g_free (transports);
1074
 
 
1075
 
      if (!gst_rtspsrc_send (src, &request, &response, NULL))
1076
 
        goto send_error;
1077
 
 
1078
 
      /* parse response transport */
1079
 
      {
1080
 
        gchar *resptrans = NULL;
1081
 
        RTSPTransport transport = { 0 };
1082
 
 
1083
 
        rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans);
1084
 
        if (!resptrans)
1085
 
          goto no_transport;
1086
 
 
1087
 
        /* parse transport */
1088
 
        rtsp_transport_parse (resptrans, &transport);
1089
 
        /* update allowed transports for other streams */
1090
 
        if (transport.lower_transport == RTSP_LOWER_TRANS_TCP) {
1091
 
          protocols = GST_RTSP_PROTO_TCP;
 
1766
  n_streams = sdp_message_medias_len (&sdp);
 
1767
  for (i = 0; i < n_streams; i++) {
 
1768
    gchar *transports;
 
1769
 
 
1770
    /* create stream from the media, can never return NULL */
 
1771
    stream = gst_rtspsrc_create_stream (src, &sdp, i);
 
1772
 
 
1773
    /* see if we need to configure this stream */
 
1774
    if (src->extension && src->extension->configure_stream) {
 
1775
      if (!src->extension->configure_stream (src->extension, stream)) {
 
1776
        GST_DEBUG_OBJECT (src, "skipping stream %d, disabled by extension", i);
 
1777
        continue;
 
1778
      }
 
1779
    }
 
1780
 
 
1781
    /* merge/overwrite global caps */
 
1782
    if (stream->caps) {
 
1783
      guint j, num;
 
1784
      GstStructure *s;
 
1785
 
 
1786
      s = gst_caps_get_structure (stream->caps, 0);
 
1787
 
 
1788
      num = gst_structure_n_fields (src->props);
 
1789
      for (j = 0; j < num; j++) {
 
1790
        const gchar *name;
 
1791
        const GValue *val;
 
1792
 
 
1793
        name = gst_structure_nth_field_name (src->props, j);
 
1794
        val = gst_structure_get_value (src->props, name);
 
1795
        gst_structure_set_value (s, name, val);
 
1796
 
 
1797
        GST_DEBUG_OBJECT (src, "copied %s", name);
 
1798
      }
 
1799
    }
 
1800
 
 
1801
    /* skip setup if we have no URL for it */
 
1802
    if (stream->setup_url == NULL) {
 
1803
      GST_DEBUG_OBJECT (src, "skipping stream %d, no setup", i);
 
1804
      continue;
 
1805
    }
 
1806
 
 
1807
    GST_DEBUG_OBJECT (src, "doing setup of stream %d with %s", i,
 
1808
        stream->setup_url);
 
1809
 
 
1810
    /* create SETUP request */
 
1811
    res = rtsp_message_init_request (&request, RTSP_SETUP, stream->setup_url);
 
1812
    if (res < 0)
 
1813
      goto create_request_failed;
 
1814
 
 
1815
    /* create a string with all the transports */
 
1816
    res = gst_rtspsrc_create_transports_string (src, protocols, &transports);
 
1817
    if (res < 0)
 
1818
      goto setup_transport_failed;
 
1819
 
 
1820
    /* replace placeholders with real values */
 
1821
    res = gst_rtspsrc_configure_transports (stream, &transports);
 
1822
    if (res < 0)
 
1823
      goto setup_transport_failed;
 
1824
 
 
1825
    /* select transport, copy is made when adding to header */
 
1826
    rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT, transports);
 
1827
    g_free (transports);
 
1828
 
 
1829
    if (!gst_rtspsrc_send (src, &request, &response, NULL))
 
1830
      goto send_error;
 
1831
 
 
1832
    /* parse response transport */
 
1833
    {
 
1834
      gchar *resptrans = NULL;
 
1835
      RTSPTransport transport = { 0 };
 
1836
 
 
1837
      rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans);
 
1838
      if (!resptrans)
 
1839
        goto no_transport;
 
1840
 
 
1841
      /* parse transport */
 
1842
      if (rtsp_transport_parse (resptrans, &transport) != RTSP_OK)
 
1843
        continue;
 
1844
 
 
1845
      /* update allowed transports for other streams. once the transport of
 
1846
       * one stream has been determined, we make sure that all other streams
 
1847
       * are configured in the same way */
 
1848
      switch (transport.lower_transport) {
 
1849
        case RTSP_LOWER_TRANS_TCP:
 
1850
          GST_DEBUG_OBJECT (src, "stream %d as TCP interleaved", i);
 
1851
          protocols = RTSP_LOWER_TRANS_TCP;
1092
1852
          src->interleaved = TRUE;
1093
 
        } else {
1094
 
          if (transport.multicast) {
1095
 
            /* disable unicast */
1096
 
            protocols = GST_RTSP_PROTO_UDP_MULTICAST;
1097
 
          } else {
1098
 
            /* disable multicast */
1099
 
            protocols = GST_RTSP_PROTO_UDP_UNICAST;
1100
 
          }
1101
 
        }
 
1853
          /* update free channels */
 
1854
          src->free_channel =
 
1855
              MAX (transport.interleaved.min, src->free_channel);
 
1856
          src->free_channel =
 
1857
              MAX (transport.interleaved.max, src->free_channel);
 
1858
          src->free_channel++;
 
1859
          break;
 
1860
        case RTSP_LOWER_TRANS_UDP_MCAST:
 
1861
          /* only allow multicast for other streams */
 
1862
          GST_DEBUG_OBJECT (src, "stream %d as UDP multicast", i);
 
1863
          protocols = RTSP_LOWER_TRANS_UDP_MCAST;
 
1864
          break;
 
1865
        case RTSP_LOWER_TRANS_UDP:
 
1866
          /* only allow unicast for other streams */
 
1867
          GST_DEBUG_OBJECT (src, "stream %d as UDP unicast", i);
 
1868
          protocols = RTSP_LOWER_TRANS_UDP;
 
1869
          break;
 
1870
        default:
 
1871
          GST_DEBUG_OBJECT (src, "stream %d unknown transport %d", i,
 
1872
              transport.lower_transport);
 
1873
          break;
 
1874
      }
 
1875
 
 
1876
      if (!stream->container || !src->interleaved) {
1102
1877
        /* now configure the stream with the transport */
1103
1878
        if (!gst_rtspsrc_stream_configure_transport (stream, &transport)) {
1104
 
          GST_DEBUG ("could not configure stream transport, skipping stream");
 
1879
          GST_DEBUG_OBJECT (src,
 
1880
              "could not configure stream %d transport, skipping stream", i);
1105
1881
        }
1106
 
        /* clean up our transport struct */
1107
 
        rtsp_transport_init (&transport);
1108
1882
      }
 
1883
 
 
1884
      /* clean up our transport struct */
 
1885
      rtsp_transport_init (&transport);
1109
1886
    }
1110
1887
  }
 
1888
  if (src->extension && src->extension->stream_select)
 
1889
    src->extension->stream_select (src->extension);
 
1890
 
 
1891
  /* if we got here all was configured. We have dynamic pads so we notify that
 
1892
   * we are done */
 
1893
  gst_element_no_more_pads (GST_ELEMENT_CAST (src));
 
1894
 
 
1895
  /* clean up any messages */
 
1896
  rtsp_message_unset (&request);
 
1897
  rtsp_message_unset (&response);
 
1898
 
1111
1899
  return TRUE;
1112
1900
 
1113
1901
  /* ERRORS */
1114
 
invalid_url:
1115
 
  {
1116
 
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
1117
 
        ("Not a valid RTSP url."), (NULL));
1118
 
    return FALSE;
1119
 
  }
1120
 
could_not_open:
1121
 
  {
1122
 
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE,
1123
 
        ("Could not open connection."), (NULL));
1124
 
    return FALSE;
 
1902
no_url:
 
1903
  {
 
1904
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
 
1905
        ("No valid RTSP URL was provided"));
 
1906
    goto cleanup_error;
 
1907
  }
 
1908
could_not_create:
 
1909
  {
 
1910
    gchar *str = rtsp_strresult (res);
 
1911
 
 
1912
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
 
1913
        ("Could not create connection. (%s)", str));
 
1914
    g_free (str);
 
1915
    goto cleanup_error;
 
1916
  }
 
1917
could_not_connect:
 
1918
  {
 
1919
    gchar *str = rtsp_strresult (res);
 
1920
 
 
1921
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
 
1922
        ("Could not connect to server. (%s)", str));
 
1923
    g_free (str);
 
1924
    goto cleanup_error;
1125
1925
  }
1126
1926
create_request_failed:
1127
1927
  {
1128
 
    GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1129
 
        ("Could not create request."), (NULL));
1130
 
    return FALSE;
 
1928
    gchar *str = rtsp_strresult (res);
 
1929
 
 
1930
    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
 
1931
        ("Could not create request. (%s)", str));
 
1932
    g_free (str);
 
1933
    goto cleanup_error;
1131
1934
  }
1132
1935
send_error:
1133
1936
  {
1134
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1135
 
        ("Could not send message."), (NULL));
1136
 
    return FALSE;
1137
 
  }
1138
 
no_describe:
1139
 
  {
1140
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1141
 
        ("Server does not support DESCRIBE."), (NULL));
1142
 
    return FALSE;
1143
 
  }
1144
 
no_setup:
1145
 
  {
1146
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1147
 
        ("Server does not support SETUP."), (NULL));
1148
 
    return FALSE;
 
1937
    gchar *str = rtsp_strresult (res);
 
1938
 
 
1939
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
 
1940
        ("Could not send message. (%s)", str));
 
1941
    g_free (str);
 
1942
    goto cleanup_error;
 
1943
  }
 
1944
methods_error:
 
1945
  {
 
1946
    /* error was posted */
 
1947
    goto cleanup_error;
1149
1948
  }
1150
1949
wrong_content_type:
1151
1950
  {
1152
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1153
 
        ("Server does not support SDP."), (NULL));
1154
 
    return FALSE;
 
1951
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
 
1952
        ("Server does not support SDP, got %s.", respcont));
 
1953
    goto cleanup_error;
1155
1954
  }
1156
 
setup_rtp_failed:
 
1955
setup_transport_failed:
1157
1956
  {
1158
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, ("Could not setup rtp."), (NULL));
1159
 
    return FALSE;
 
1957
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
 
1958
        ("Could not setup transport."));
 
1959
    goto cleanup_error;
1160
1960
  }
1161
1961
no_transport:
1162
1962
  {
1163
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1164
 
        ("Server did not select transport."), (NULL));
 
1963
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
 
1964
        ("Server did not select transport."));
 
1965
    goto cleanup_error;
 
1966
  }
 
1967
cleanup_error:
 
1968
  {
 
1969
    rtsp_message_unset (&request);
 
1970
    rtsp_message_unset (&response);
1165
1971
    return FALSE;
1166
1972
  }
1167
1973
}
1173
1979
  RTSPMessage response = { 0 };
1174
1980
  RTSPResult res;
1175
1981
 
1176
 
  GST_DEBUG ("TEARDOWN...");
 
1982
  GST_DEBUG_OBJECT (src, "TEARDOWN...");
 
1983
 
 
1984
  gst_rtspsrc_loop_send_cmd (src, CMD_STOP);
1177
1985
 
1178
1986
  /* stop task if any */
1179
1987
  if (src->task) {
1180
1988
    gst_task_stop (src->task);
 
1989
 
 
1990
    /* make sure it is not running */
 
1991
    g_static_rec_mutex_lock (src->stream_rec_lock);
 
1992
    g_static_rec_mutex_unlock (src->stream_rec_lock);
 
1993
 
 
1994
    /* no wait for the task to finish */
 
1995
    gst_task_join (src->task);
 
1996
 
 
1997
    /* and free the task */
1181
1998
    gst_object_unref (GST_OBJECT (src->task));
1182
1999
    src->task = NULL;
1183
2000
  }
1184
2001
 
1185
 
  if (src->options & RTSP_PLAY) {
 
2002
  if (src->methods & RTSP_PLAY) {
1186
2003
    /* do TEARDOWN */
1187
 
    if ((res =
1188
 
            rtsp_message_init_request (RTSP_TEARDOWN, src->location,
1189
 
                &request)) < 0)
 
2004
    res = rtsp_message_init_request (&request, RTSP_TEARDOWN, src->location);
 
2005
    if (res < 0)
1190
2006
      goto create_request_failed;
1191
2007
 
1192
2008
    if (!gst_rtspsrc_send (src, &request, &response, NULL))
1193
2009
      goto send_error;
 
2010
 
 
2011
    /* FIXME, parse result? */
 
2012
    rtsp_message_unset (&request);
 
2013
    rtsp_message_unset (&response);
1194
2014
  }
1195
2015
 
1196
2016
  /* close connection */
1197
 
  GST_DEBUG ("closing connection...");
 
2017
  GST_DEBUG_OBJECT (src, "closing connection...");
1198
2018
  if ((res = rtsp_connection_close (src->connection)) < 0)
1199
2019
    goto close_failed;
1200
2020
 
1201
2021
  return TRUE;
1202
2022
 
 
2023
  /* ERRORS */
1203
2024
create_request_failed:
1204
2025
  {
1205
 
    GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1206
 
        ("Could not create request."), (NULL));
 
2026
    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
 
2027
        ("Could not create request."));
1207
2028
    return FALSE;
1208
2029
  }
1209
2030
send_error:
1210
2031
  {
1211
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1212
 
        ("Could not send message."), (NULL));
 
2032
    rtsp_message_unset (&request);
 
2033
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
 
2034
        ("Could not send message."));
1213
2035
    return FALSE;
1214
2036
  }
1215
2037
close_failed:
1216
2038
  {
1217
 
    GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, ("Close failed."), (NULL));
 
2039
    GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL), ("Close failed."));
1218
2040
    return FALSE;
1219
2041
  }
1220
2042
}
1221
2043
 
 
2044
/* RTP-Info is of the format:
 
2045
 *
 
2046
 * url=<URL>;[seq=<seqbase>;rtptime=<timebase>] [, url=...]
 
2047
 */
 
2048
static gboolean
 
2049
gst_rtspsrc_parse_rtpinfo (GstRTSPSrc * src, gchar * rtpinfo)
 
2050
{
 
2051
  gchar **infos;
 
2052
  gint i;
 
2053
 
 
2054
  infos = g_strsplit (rtpinfo, ",", 0);
 
2055
  for (i = 0; infos[i]; i++) {
 
2056
    /* FIXME, do something here:
 
2057
     * parse url, find stream for url.
 
2058
     * parse seq and rtptime. The seq number should be configured in the rtp
 
2059
     * depayloader or session manager to detect gaps. Same for the rtptime, it
 
2060
     * should be used to create an initial time newsegment.
 
2061
     */
 
2062
  }
 
2063
  g_strfreev (infos);
 
2064
 
 
2065
  return TRUE;
 
2066
}
 
2067
 
1222
2068
static gboolean
1223
2069
gst_rtspsrc_play (GstRTSPSrc * src)
1224
2070
{
1225
2071
  RTSPMessage request = { 0 };
1226
2072
  RTSPMessage response = { 0 };
1227
2073
  RTSPResult res;
 
2074
  gchar *rtpinfo;
1228
2075
 
1229
 
  if (!(src->options & RTSP_PLAY))
 
2076
  if (!(src->methods & RTSP_PLAY))
1230
2077
    return TRUE;
1231
2078
 
1232
 
  GST_DEBUG ("PLAY...");
 
2079
  GST_DEBUG_OBJECT (src, "PLAY...");
1233
2080
 
1234
2081
  /* do play */
1235
 
  if ((res =
1236
 
          rtsp_message_init_request (RTSP_PLAY, src->location, &request)) < 0)
 
2082
  res = rtsp_message_init_request (&request, RTSP_PLAY, src->location);
 
2083
  if (res < 0)
1237
2084
    goto create_request_failed;
1238
2085
 
 
2086
  rtsp_message_add_header (&request, RTSP_HDR_RANGE, "npt=0-");
 
2087
 
1239
2088
  if (!gst_rtspsrc_send (src, &request, &response, NULL))
1240
2089
    goto send_error;
1241
2090
 
1242
 
  if (src->interleaved) {
 
2091
  rtsp_message_unset (&request);
 
2092
 
 
2093
  /* parse the RTP-Info header field (if ANY) to get the base seqnum and timestamp
 
2094
   * for the RTP packets. If this is not present, we assume all starts from 0... 
 
2095
   * FIXME, this is info for the RTP session manager ideally. */
 
2096
  rtsp_message_get_header (&response, RTSP_HDR_RTP_INFO, &rtpinfo);
 
2097
  if (rtpinfo)
 
2098
    gst_rtspsrc_parse_rtpinfo (src, rtpinfo);
 
2099
 
 
2100
  rtsp_message_unset (&response);
 
2101
 
 
2102
  /* for interleaved transport, we receive the data on the RTSP connection
 
2103
   * instead of UDP. We start a task to select and read from that connection.
 
2104
   * For UDP we start the task as well to look for server info and UDP timeouts. */
 
2105
  if (src->task == NULL) {
1243
2106
    src->task = gst_task_create ((GstTaskFunction) gst_rtspsrc_loop, src);
1244
 
 
1245
 
    gst_task_start (src->task);
 
2107
    gst_task_set_lock (src->task, src->stream_rec_lock);
1246
2108
  }
 
2109
  src->running = TRUE;
 
2110
  gst_rtspsrc_loop_send_cmd (src, CMD_WAIT);
 
2111
  gst_task_start (src->task);
1247
2112
 
1248
2113
  return TRUE;
1249
2114
 
 
2115
  /* ERRORS */
1250
2116
create_request_failed:
1251
2117
  {
1252
 
    GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1253
 
        ("Could not create request."), (NULL));
 
2118
    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
 
2119
        ("Could not create request."));
1254
2120
    return FALSE;
1255
2121
  }
1256
2122
send_error:
1257
2123
  {
1258
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1259
 
        ("Could not send message."), (NULL));
 
2124
    rtsp_message_unset (&request);
 
2125
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
 
2126
        ("Could not send message."));
1260
2127
    return FALSE;
1261
2128
  }
1262
2129
}
1268
2135
  RTSPMessage response = { 0 };
1269
2136
  RTSPResult res;
1270
2137
 
1271
 
  if (!(src->options & RTSP_PAUSE))
 
2138
  if (!(src->methods & RTSP_PAUSE))
1272
2139
    return TRUE;
1273
2140
 
1274
 
  GST_DEBUG ("PAUSE...");
 
2141
  GST_DEBUG_OBJECT (src, "PAUSE...");
1275
2142
  /* do pause */
1276
 
  if ((res =
1277
 
          rtsp_message_init_request (RTSP_PAUSE, src->location, &request)) < 0)
 
2143
  res = rtsp_message_init_request (&request, RTSP_PAUSE, src->location);
 
2144
  if (res < 0)
1278
2145
    goto create_request_failed;
1279
2146
 
1280
2147
  if (!gst_rtspsrc_send (src, &request, &response, NULL))
1281
2148
    goto send_error;
1282
2149
 
 
2150
  rtsp_message_unset (&request);
 
2151
  rtsp_message_unset (&response);
 
2152
 
1283
2153
  return TRUE;
1284
2154
 
 
2155
  /* ERRORS */
1285
2156
create_request_failed:
1286
2157
  {
1287
 
    GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1288
 
        ("Could not create request."), (NULL));
 
2158
    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
 
2159
        ("Could not create request."));
1289
2160
    return FALSE;
1290
2161
  }
1291
2162
send_error:
1292
2163
  {
1293
 
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1294
 
        ("Could not send message."), (NULL));
 
2164
    rtsp_message_unset (&request);
 
2165
    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
 
2166
        ("Could not send message."));
1295
2167
    return FALSE;
1296
2168
  }
1297
2169
}
1298
2170
 
 
2171
static void
 
2172
gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message)
 
2173
{
 
2174
  switch (GST_MESSAGE_TYPE (message)) {
 
2175
    case GST_MESSAGE_ELEMENT:
 
2176
    {
 
2177
      GstRTSPSrc *rtspsrc;
 
2178
      const GstStructure *s = gst_message_get_structure (message);
 
2179
 
 
2180
      rtspsrc = GST_RTSPSRC (bin);
 
2181
 
 
2182
      if (gst_structure_has_name (s, "GstUDPSrcTimeout")) {
 
2183
        GST_DEBUG_OBJECT (bin, "timeout on UDP port");
 
2184
        gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_RECONNECT);
 
2185
        return;
 
2186
      }
 
2187
    }
 
2188
      /* Fallthrough */
 
2189
    default:
 
2190
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
 
2191
      break;
 
2192
  }
 
2193
}
 
2194
 
1299
2195
static GstStateChangeReturn
1300
2196
gst_rtspsrc_change_state (GstElement * element, GstStateChange transition)
1301
2197
{
1304
2200
 
1305
2201
  rtspsrc = GST_RTSPSRC (element);
1306
2202
 
1307
 
 
1308
2203
  switch (transition) {
1309
2204
    case GST_STATE_CHANGE_NULL_TO_READY:
1310
2205
      break;
1311
2206
    case GST_STATE_CHANGE_READY_TO_PAUSED:
1312
 
      rtspsrc->interleaved = FALSE;
1313
 
      rtspsrc->options = 0;
 
2207
      rtspsrc->cur_protocols = rtspsrc->protocols;
1314
2208
      if (!gst_rtspsrc_open (rtspsrc))
1315
2209
        goto open_failed;
1316
2210
      break;
1317
2211
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
 
2212
      rtsp_connection_flush (rtspsrc->connection, FALSE);
 
2213
      /* copy configuerd protocols */
1318
2214
      gst_rtspsrc_play (rtspsrc);
1319
2215
      break;
 
2216
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
 
2217
    case GST_STATE_CHANGE_PAUSED_TO_READY:
 
2218
      rtsp_connection_flush (rtspsrc->connection, TRUE);
 
2219
      break;
1320
2220
    default:
1321
2221
      break;
1322
2222
  }
1325
2225
  if (ret == GST_STATE_CHANGE_FAILURE)
1326
2226
    goto done;
1327
2227
 
1328
 
  ret = gst_rtspsrc_set_state (rtspsrc, GST_STATE_PENDING (rtspsrc));
1329
 
  if (ret == GST_STATE_CHANGE_FAILURE)
1330
 
    goto done;
1331
 
 
1332
2228
  switch (transition) {
1333
2229
    case GST_STATE_CHANGE_READY_TO_PAUSED:
1334
2230
      ret = GST_STATE_CHANGE_NO_PREROLL;
1356
2252
 
1357
2253
/*** GSTURIHANDLER INTERFACE *************************************************/
1358
2254
 
1359
 
static guint
 
2255
static GstURIType
1360
2256
gst_rtspsrc_uri_get_type (void)
1361
2257
{
1362
2258
  return GST_URI_SRC;
1364
2260
static gchar **
1365
2261
gst_rtspsrc_uri_get_protocols (void)
1366
2262
{
1367
 
  static gchar *protocols[] = { "rtsp", NULL };
 
2263
  static gchar *protocols[] = { "rtsp", "rtspu", "rtspt", NULL };
1368
2264
 
1369
2265
  return protocols;
1370
2266
}
1374
2270
{
1375
2271
  GstRTSPSrc *src = GST_RTSPSRC (handler);
1376
2272
 
1377
 
  return g_strdup (src->location);
 
2273
  /* should not dup */
 
2274
  return src->location;
1378
2275
}
1379
2276
 
1380
2277
static gboolean
1381
2278
gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
1382
2279
{
1383
 
  GstRTSPSrc *src = GST_RTSPSRC (handler);
1384
 
 
 
2280
  GstRTSPSrc *src;
 
2281
  RTSPResult res;
 
2282
  RTSPUrl *newurl;
 
2283
 
 
2284
  src = GST_RTSPSRC (handler);
 
2285
 
 
2286
  /* same URI, we're fine */
 
2287
  if (src->location && uri && !strcmp (uri, src->location))
 
2288
    goto was_ok;
 
2289
 
 
2290
  /* try to parse */
 
2291
  if ((res = rtsp_url_parse (uri, &newurl)) < 0)
 
2292
    goto parse_error;
 
2293
 
 
2294
  /* if worked, free previous and store new url object along with the original
 
2295
   * location. */
 
2296
  rtsp_url_free (src->url);
 
2297
  src->url = newurl;
1385
2298
  g_free (src->location);
1386
2299
  src->location = g_strdup (uri);
 
2300
  if (!g_str_has_prefix (src->location, "rtsp://"))
 
2301
    memmove (src->location + 4, src->location + 5, strlen (src->location) - 4);
 
2302
 
 
2303
  GST_DEBUG_OBJECT (src, "set uri: %s", GST_STR_NULL (uri));
1387
2304
 
1388
2305
  return TRUE;
 
2306
 
 
2307
  /* Special cases */
 
2308
was_ok:
 
2309
  {
 
2310
    GST_DEBUG_OBJECT (src, "URI was ok: '%s'", GST_STR_NULL (uri));
 
2311
    return TRUE;
 
2312
  }
 
2313
parse_error:
 
2314
  {
 
2315
    GST_ERROR_OBJECT (src, "Not a valid RTSP url '%s' (%d)",
 
2316
        GST_STR_NULL (uri), res);
 
2317
    return FALSE;
 
2318
  }
1389
2319
}
1390
2320
 
1391
2321
static void