2 * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 * SECTION:element-rtspsrc
24 * Makes a connection to an RTSP server and read the data.
25 * rtspsrc strictly follows RFC 2326 and therefore does not (yet) support
26 * RealMedia/Quicktime/Microsoft extensions.
29 * RTSP supports transport over TCP or UDP in unicast or multicast mode. By
30 * default rtspsrc will negotiate a connection in the following order:
31 * UDP unicast/UDP multicast/TCP. The order cannot be changed but the allowed
32 * protocols can be controlled with the "protocols" property.
35 * rtspsrc currently understands SDP as the format of the session description.
36 * For each stream listed in the SDP a new rtp_stream%d pad will be created
37 * 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
42 * rtspsrc will internally instantiate an RTP session manager element
43 * that will handle the RTCP messages to and from the server, jitter removal,
44 * packet reordering along with providing a clock for the pipeline.
45 * This feature is however currently not yet implemented.
48 * rtspsrc acts like a live source and will therefore only generate data in the
51 * <title>Example launch line</title>
54 * gst-launch rtspsrc location=rtsp://some.server/url ! fakesink
56 * Establish a connection to an RTSP server and send the stream to a fakesink.
60 * Last reviewed on 2006-06-20 (0.10.4)
70 #include "gstrtspsrc.h"
73 GST_DEBUG_CATEGORY_STATIC (rtspsrc_debug);
74 #define GST_CAT_DEFAULT (rtspsrc_debug)
76 /* elementfactory information */
77 static const GstElementDetails gst_rtspsrc_details =
78 GST_ELEMENT_DETAILS ("RTSP packet receiver",
80 "Receive data over the network via RTSP (RFC 2326)",
81 "Wim Taymans <wim@fluendo.com>");
83 static GstStaticPadTemplate rtptemplate =
84 GST_STATIC_PAD_TEMPLATE ("rtp_stream%d",
89 static GstStaticPadTemplate rtcptemplate =
90 GST_STATIC_PAD_TEMPLATE ("rtcp_stream%d",
101 #define DEFAULT_LOCATION NULL
102 #define DEFAULT_PROTOCOLS GST_RTSP_PROTO_UDP_UNICAST | GST_RTSP_PROTO_UDP_MULTICAST | GST_RTSP_PROTO_TCP
103 #define DEFAULT_DEBUG FALSE
104 #define DEFAULT_RETRY 20
116 #define GST_TYPE_RTSP_PROTO (gst_rtsp_proto_get_type())
118 gst_rtsp_proto_get_type (void)
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"},
128 if (!rtsp_proto_type) {
129 rtsp_proto_type = g_flags_register_static ("GstRTSPProto", rtsp_proto);
131 return rtsp_proto_type;
135 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);
138 static void gst_rtspsrc_finalize (GObject * object);
140 static void gst_rtspsrc_uri_handler_init (gpointer g_iface,
141 gpointer iface_data);
143 static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element,
144 GstStateChange transition);
146 static void gst_rtspsrc_set_property (GObject * object, guint prop_id,
147 const GValue * value, GParamSpec * pspec);
148 static void gst_rtspsrc_get_property (GObject * object, guint prop_id,
149 GValue * value, GParamSpec * pspec);
151 static void gst_rtspsrc_loop (GstRTSPSrc * src);
153 static GstElementClass *parent_class = NULL;
155 /*static guint gst_rtspsrc_signals[LAST_SIGNAL] = { 0 }; */
158 gst_rtspsrc_get_type (void)
160 static GType rtspsrc_type = 0;
163 static const GTypeInfo rtspsrc_info = {
164 sizeof (GstRTSPSrcClass),
165 gst_rtspsrc_base_init,
167 (GClassInitFunc) gst_rtspsrc_class_init,
172 (GInstanceInitFunc) gst_rtspsrc_init,
175 static const GInterfaceInfo urihandler_info = {
176 gst_rtspsrc_uri_handler_init,
181 GST_DEBUG_CATEGORY_INIT (rtspsrc_debug, "rtspsrc", 0, "RTSP src");
184 g_type_register_static (GST_TYPE_ELEMENT, "GstRTSPSrc", &rtspsrc_info,
187 g_type_add_interface_static (rtspsrc_type, GST_TYPE_URI_HANDLER,
194 gst_rtspsrc_base_init (gpointer g_class)
196 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
198 gst_element_class_add_pad_template (element_class,
199 gst_static_pad_template_get (&rtptemplate));
200 gst_element_class_add_pad_template (element_class,
201 gst_static_pad_template_get (&rtcptemplate));
203 gst_element_class_set_details (element_class, &gst_rtspsrc_details);
207 gst_rtspsrc_class_init (GstRTSPSrc * klass)
209 GObjectClass *gobject_class;
210 GstElementClass *gstelement_class;
212 gobject_class = (GObjectClass *) klass;
213 gstelement_class = (GstElementClass *) klass;
215 parent_class = g_type_class_peek_parent (klass);
217 gobject_class->set_property = gst_rtspsrc_set_property;
218 gobject_class->get_property = gst_rtspsrc_get_property;
220 gobject_class->finalize = gst_rtspsrc_finalize;
222 g_object_class_install_property (gobject_class, PROP_LOCATION,
223 g_param_spec_string ("location", "RTSP Location",
224 "Location of the RTSP url to read",
225 DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
227 g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
228 g_param_spec_flags ("protocols", "Protocols", "Allowed protocols",
229 GST_TYPE_RTSP_PROTO, DEFAULT_PROTOCOLS,
230 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
232 g_object_class_install_property (gobject_class, PROP_DEBUG,
233 g_param_spec_boolean ("debug", "Debug",
234 "Dump request and response messages to stdout",
235 DEFAULT_DEBUG, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
237 g_object_class_install_property (gobject_class, PROP_RETRY,
238 g_param_spec_uint ("retry", "Retry",
239 "Max number of retries when allocating RTP ports.",
240 0, G_MAXUINT16, DEFAULT_RETRY,
241 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
243 gstelement_class->change_state = gst_rtspsrc_change_state;
247 gst_rtspsrc_init (GstRTSPSrc * src)
249 src->stream_rec_lock = g_new (GStaticRecMutex, 1);
250 g_static_rec_mutex_init (src->stream_rec_lock);
254 gst_rtspsrc_finalize (GObject * object)
258 rtspsrc = GST_RTSPSRC (object);
260 g_static_rec_mutex_free (rtspsrc->stream_rec_lock);
261 g_free (rtspsrc->stream_rec_lock);
263 G_OBJECT_CLASS (parent_class)->finalize (object);
267 gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
272 rtspsrc = GST_RTSPSRC (object);
276 g_free (rtspsrc->location);
277 rtspsrc->location = g_value_dup_string (value);
280 rtspsrc->protocols = g_value_get_flags (value);
283 rtspsrc->debug = g_value_get_boolean (value);
286 rtspsrc->retry = g_value_get_uint (value);
289 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
295 gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
300 rtspsrc = GST_RTSPSRC (object);
304 g_value_set_string (value, rtspsrc->location);
307 g_value_set_flags (value, rtspsrc->protocols);
310 g_value_set_boolean (value, rtspsrc->debug);
313 g_value_set_uint (value, rtspsrc->retry);
316 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
321 static GstRTSPStream *
322 gst_rtspsrc_create_stream (GstRTSPSrc * src)
326 s = g_new0 (GstRTSPStream, 1);
328 s->id = src->numstreams++;
330 src->streams = g_list_append (src->streams, s);
337 gst_rtspsrc_free_stream (GstRTSPSrc * src, GstRTSPStream * stream)
340 gst_caps_unref (stream->caps);
344 src->streams = g_list_remove (src->streams, stream);
352 gst_rtspsrc_add_element (GstRTSPSrc * src, GstElement * element)
354 gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (src));
359 static GstStateChangeReturn
360 gst_rtspsrc_set_state (GstRTSPSrc * src, GstState state)
362 GstStateChangeReturn ret;
365 ret = GST_STATE_CHANGE_SUCCESS;
367 /* for all streams */
368 for (streams = src->streams; streams; streams = g_list_next (streams)) {
369 GstRTSPStream *stream;
371 stream = (GstRTSPStream *) streams->data;
373 /* first our rtp session manager */
374 if (stream->rtpdec) {
376 gst_element_set_state (stream->rtpdec,
377 state)) == GST_STATE_CHANGE_FAILURE)
381 /* then our sources */
382 if (stream->rtpsrc) {
384 gst_element_set_state (stream->rtpsrc,
385 state)) == GST_STATE_CHANGE_FAILURE)
389 if (stream->rtcpsrc) {
391 gst_element_set_state (stream->rtcpsrc,
392 state)) == GST_STATE_CHANGE_FAILURE)
401 #define PARSE_INT(p, del, res) \
404 p = strstr (p, del); \
414 #define PARSE_STRING(p, del, res) \
417 p = strstr (p, del); \
427 #define SKIP_SPACES(p) \
428 while (*p && g_ascii_isspace (*p)) \
432 gst_rtspsrc_parse_rtpmap (gchar * rtpmap, gint * payload, gchar ** name,
433 gint * rate, gchar ** params)
439 PARSE_INT (p, " ", *payload);
447 PARSE_STRING (p, "/", *name);
470 * Mapping of caps to and from SDP fields:
472 * m=<media> <udp port> RTP/AVP <payload>
473 * a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
474 * a=fmtp:<payload> <param>[=<value>];...
477 gst_rtspsrc_media_to_caps (SDPMedia * media)
486 gchar *params = NULL;
489 payload = sdp_media_get_format (media, 0);
490 if (payload == NULL) {
491 g_warning ("payload type not given");
500 if ((rtpmap = sdp_media_get_attribute_val (media, "rtpmap"))) {
502 gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate,
505 g_warning ("rtpmap of wrong payload type");
511 g_warning ("error parsing rtpmap");
514 g_warning ("rtpmap type not given fot dynamic payload %d", pt);
519 caps = gst_caps_new_simple ("application/x-rtp",
520 "media", G_TYPE_STRING, media->media, "payload", G_TYPE_INT, pt, NULL);
521 s = gst_caps_get_structure (caps, 0);
524 gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);
527 gst_structure_set (s, "encoding-name", G_TYPE_STRING, name, NULL);
530 gst_structure_set (s, "encoding-params", G_TYPE_STRING, params, NULL);
532 /* parse optional fmtp: field */
533 if ((fmtp = sdp_media_get_attribute_val (media, "fmtp"))) {
539 /* p is now of the format <payload> <param>[=<value>];... */
540 PARSE_INT (p, " ", payload);
541 if (payload != -1 && payload == pt) {
545 /* <param>[=<value>] are separated with ';' */
546 pairs = g_strsplit (p, ";", 0);
547 for (i = 0; pairs[i]; i++) {
551 /* the key may not have a '=', the value can have other '='s */
552 valpos = strstr (pairs[i], "=");
554 /* we have a '=' and thus a value, remove the '=' with \0 */
556 /* value is everything between '=' and ';' */
557 val = g_strstrip (valpos + 1);
559 /* simple <param>;.. is translated into <param>=1;... */
562 /* strip the key of spaces */
563 key = g_strstrip (pairs[i]);
565 gst_structure_set (s, key, G_TYPE_STRING, val, NULL);
574 gst_rtspsrc_stream_setup_rtp (GstRTSPStream * stream, SDPMedia * media,
575 gint * rtpport, gint * rtcpport)
577 GstStateChangeReturn ret;
580 GstElement *tmp, *rtp, *rtcp;
581 gint tmp_rtp, tmp_rtcp;
584 src = stream->parent;
591 /* try to allocate 2 udp ports, the RTP port should be an even
592 * number and the RTCP port should be the next (uneven) port */
594 rtp = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0:0", NULL);
596 goto no_udp_rtp_protocol;
598 ret = gst_element_set_state (rtp, GST_STATE_PAUSED);
599 if (ret == GST_STATE_CHANGE_FAILURE)
600 goto start_rtp_failure;
602 g_object_get (G_OBJECT (rtp), "port", &tmp_rtp, NULL);
603 GST_DEBUG_OBJECT (src, "got RTP port %d", tmp_rtp);
605 /* check if port is even */
606 if ((tmp_rtp & 0x01) != 0) {
607 /* port not even, close and allocate another */
609 if (count > src->retry)
612 GST_DEBUG_OBJECT (src, "RTP port not even, retry %d", count);
613 /* have to keep port allocated so we can get a new one */
615 GST_DEBUG_OBJECT (src, "free temp");
616 gst_element_set_state (tmp, GST_STATE_NULL);
617 gst_object_unref (tmp);
620 GST_DEBUG_OBJECT (src, "retry %d", count);
623 /* free leftover temp element/port */
625 gst_element_set_state (tmp, GST_STATE_NULL);
626 gst_object_unref (tmp);
630 /* allocate port+1 for RTCP now */
631 rtcp = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL);
633 goto no_udp_rtcp_protocol;
636 tmp_rtcp = tmp_rtp + 1;
637 g_object_set (G_OBJECT (rtcp), "port", tmp_rtcp, NULL);
639 GST_DEBUG_OBJECT (src, "starting RTCP on port %d", tmp_rtcp);
640 ret = gst_element_set_state (rtcp, GST_STATE_PAUSED);
641 /* FIXME, this could fail if the next port is not free, we
642 * should retry with another port then */
643 if (ret == GST_STATE_CHANGE_FAILURE)
644 goto start_rtcp_failure;
646 /* all fine, do port check */
647 g_object_get (G_OBJECT (rtp), "port", rtpport, NULL);
648 g_object_get (G_OBJECT (rtcp), "port", rtcpport, NULL);
650 /* this should not happen */
651 if (*rtpport != tmp_rtp || *rtcpport != tmp_rtcp)
654 /* we manage these elements */
655 stream->rtpsrc = rtp;
656 gst_rtspsrc_add_element (src, stream->rtpsrc);
657 stream->rtcpsrc = rtcp;
658 gst_rtspsrc_add_element (src, stream->rtcpsrc);
660 caps = gst_rtspsrc_media_to_caps (media);
663 g_object_set (G_OBJECT (stream->rtpsrc), "caps", caps, NULL);
670 GST_DEBUG_OBJECT (src, "could not get UDP source for RTP");
675 GST_DEBUG_OBJECT (src, "could not start UDP source for RTP");
680 GST_DEBUG_OBJECT (src, "could not allocate UDP port pair after %d retries",
684 no_udp_rtcp_protocol:
686 GST_DEBUG_OBJECT (src, "could not get UDP source for RTCP");
691 GST_DEBUG_OBJECT (src, "could not start UDP source for RTCP");
696 GST_DEBUG_OBJECT (src, "ports don't match rtp: %d<->%d, rtcp: %d<->%d",
697 tmp_rtp, *rtpport, tmp_rtcp, *rtcpport);
703 gst_element_set_state (tmp, GST_STATE_NULL);
704 gst_object_unref (tmp);
707 gst_element_set_state (rtp, GST_STATE_NULL);
708 gst_object_unref (rtp);
711 gst_element_set_state (rtcp, GST_STATE_NULL);
712 gst_object_unref (rtcp);
719 gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream,
720 SDPMedia * media, RTSPTransport * transport)
724 GstStateChangeReturn ret;
727 src = stream->parent;
729 GST_DEBUG ("configuring RTP transport for stream %p", stream);
731 if (!(stream->rtpdec = gst_element_factory_make ("rtpdec", NULL)))
734 /* we manage this element */
735 gst_rtspsrc_add_element (src, stream->rtpdec);
738 gst_element_set_state (stream->rtpdec,
739 GST_STATE_PAUSED)) != GST_STATE_CHANGE_SUCCESS)
740 goto start_rtpdec_failure;
742 stream->rtpdecrtp = gst_element_get_pad (stream->rtpdec, "sinkrtp");
743 stream->rtpdecrtcp = gst_element_get_pad (stream->rtpdec, "sinkrtcp");
745 if (transport->lower_transport == RTSP_LOWER_TRANS_TCP) {
746 /* configure for interleaved delivery, nothing needs to be done
747 * here, the loop function will call the chain functions of the
748 * rtp session manager. */
749 stream->rtpchannel = transport->interleaved.min;
750 stream->rtcpchannel = transport->interleaved.max;
751 GST_DEBUG ("stream %p on channels %d-%d", stream,
752 stream->rtpchannel, stream->rtcpchannel);
754 /* also store the caps in the stream */
755 stream->caps = gst_rtspsrc_media_to_caps (media);
757 /* configure for UDP delivery, we need to connect the udp pads to
758 * the rtp session plugin. */
759 pad = gst_element_get_pad (stream->rtpsrc, "src");
760 gst_pad_link (pad, stream->rtpdecrtp);
761 gst_object_unref (pad);
763 pad = gst_element_get_pad (stream->rtcpsrc, "src");
764 gst_pad_link (pad, stream->rtpdecrtcp);
765 gst_object_unref (pad);
768 pad = gst_element_get_pad (stream->rtpdec, "srcrtp");
770 gst_pad_use_fixed_caps (pad);
771 gst_pad_set_caps (pad, stream->caps);
773 name = g_strdup_printf ("rtp_stream%d", stream->id);
774 gst_element_add_pad (GST_ELEMENT_CAST (src), gst_ghost_pad_new (name, pad));
776 gst_object_unref (pad);
783 GST_DEBUG_OBJECT (src, "no rtpdec element found");
786 start_rtpdec_failure:
788 GST_DEBUG_OBJECT (src, "could not start RTP session");
794 find_stream (GstRTSPStream * stream, gconstpointer a)
796 gint channel = GPOINTER_TO_INT (a);
798 if (stream->rtpchannel == channel || stream->rtcpchannel == channel)
805 gst_rtspsrc_combine_flows (GstRTSPSrc * src, GstRTSPStream * stream,
810 /* store the value */
811 stream->last_ret = ret;
813 /* if it's success we can return the value right away */
814 if (GST_FLOW_IS_SUCCESS (ret))
817 /* any other error that is not-linked can be returned right
819 if (ret != GST_FLOW_NOT_LINKED)
822 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
823 for (streams = src->streams; streams; streams = g_list_next (streams)) {
824 GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
826 ret = ostream->last_ret;
827 /* some other return value (must be SUCCESS but we can return
828 * other values as well) */
829 if (ret != GST_FLOW_NOT_LINKED)
832 /* if we get here, all other pads were unlinked and we return
839 gst_rtspsrc_loop (GstRTSPSrc * src)
841 RTSPMessage response = { 0 };
845 GstRTSPStream *stream;
846 GstPad *outpad = NULL;
849 GstFlowReturn ret = GST_FLOW_OK;
850 GstCaps *caps = NULL;
853 GST_DEBUG_OBJECT (src, "doing receive");
854 if ((res = rtsp_connection_receive (src->connection, &response)) < 0)
856 GST_DEBUG_OBJECT (src, "got packet type %d", response.type);
858 while (response.type != RTSP_MESSAGE_DATA);
860 channel = response.type_data.data.channel;
862 lstream = g_list_find_custom (src->streams, GINT_TO_POINTER (channel),
863 (GCompareFunc) find_stream);
867 stream = (GstRTSPStream *) lstream->data;
868 if (channel == stream->rtpchannel) {
869 outpad = stream->rtpdecrtp;
871 } else if (channel == stream->rtcpchannel) {
872 outpad = stream->rtpdecrtcp;
875 rtsp_message_get_body (&response, &data, &size);
877 /* channels are not correct on some servers, do extra check */
878 if (data[1] >= 200 && data[1] <= 204) {
879 /* hmm RTCP message */
880 outpad = stream->rtpdecrtcp;
883 /* we have no clue what this is, just ignore then. */
887 /* and chain buffer to internal element */
891 /* strip the trailing \0 */
894 buf = gst_buffer_new_and_alloc (size);
895 memcpy (GST_BUFFER_DATA (buf), data, size);
898 gst_buffer_set_caps (buf, caps);
900 GST_DEBUG_OBJECT (src, "pushing data of size %d on channel %d", size,
903 /* chain to the peer pad */
904 ret = gst_pad_chain (outpad, buf);
906 /* combine all streams */
907 ret = gst_rtspsrc_combine_flows (src, stream, ret);
908 if (ret != GST_FLOW_OK)
916 GST_DEBUG_OBJECT (src, "unknown stream on channel %d, ignored", channel);
921 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
922 ("Could not receive message."), (NULL));
923 ret = GST_FLOW_UNEXPECTED;
925 gst_pad_push_event (src->srcpad, gst_event_new (GST_EVENT_EOS));
931 GST_DEBUG_OBJECT (src, "pausing task, reason %d (%s)", ret,
932 gst_flow_get_name (ret));
933 gst_task_pause (src->task);
939 gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
940 RTSPMessage * response, RTSPStatusCode * code)
945 rtsp_message_dump (request);
947 if ((res = rtsp_connection_send (src->connection, request)) < 0)
950 if ((res = rtsp_connection_receive (src->connection, response)) < 0)
954 *code = response->type_data.response.code;
958 rtsp_message_dump (response);
960 if (response->type_data.response.code != RTSP_STS_OK)
967 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
968 ("Could not send message."), (NULL));
973 GST_ELEMENT_ERROR (src, RESOURCE, READ,
974 ("Could not receive message."), (NULL));
979 GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Got error response: %d (%s).",
980 response->type_data.response.code,
981 response->type_data.response.reason), (NULL));
987 gst_rtspsrc_open (GstRTSPSrc * src)
991 RTSPMessage request = { 0 };
992 RTSPMessage response = { 0 };
995 SDPMessage sdp = { 0 };
996 GstRTSPProto protocols;
999 GST_DEBUG_OBJECT (src, "parsing url...");
1000 if ((res = rtsp_url_parse (src->location, &url)) < 0)
1003 /* open connection */
1004 GST_DEBUG_OBJECT (src, "opening connection...");
1005 if ((res = rtsp_connection_open (url, &src->connection)) < 0)
1006 goto could_not_open;
1008 /* create OPTIONS */
1009 GST_DEBUG_OBJECT (src, "create options...");
1011 rtsp_message_init_request (RTSP_OPTIONS, src->location,
1013 goto create_request_failed;
1016 GST_DEBUG_OBJECT (src, "send options...");
1017 if (!gst_rtspsrc_send (src, &request, &response, NULL))
1021 gchar *respoptions = NULL;
1025 /* Try Allow Header first */
1026 rtsp_message_get_header (&response, RTSP_HDR_ALLOW, &respoptions);
1028 /* Then maybe Public Header... */
1029 rtsp_message_get_header (&response, RTSP_HDR_PUBLIC, &respoptions);
1031 /* this field is not required, assume the server supports
1032 * DESCRIBE and SETUP*/
1033 GST_DEBUG_OBJECT (src, "could not get OPTIONS");
1034 src->options = RTSP_DESCRIBE | RTSP_SETUP;
1040 options = g_strsplit (respoptions, ",", 0);
1043 while (options[i]) {
1047 stripped = g_strdup (options[i]);
1048 stripped = g_strstrip (stripped);
1049 method = rtsp_find_method (stripped);
1052 /* keep bitfield of supported methods */
1054 src->options |= method;
1057 g_strfreev (options);
1060 /* we need describe and setup */
1061 if (!(src->options & RTSP_DESCRIBE))
1063 if (!(src->options & RTSP_SETUP))
1067 /* create DESCRIBE */
1068 GST_DEBUG_OBJECT (src, "create describe...");
1070 rtsp_message_init_request (RTSP_DESCRIBE, src->location,
1072 goto create_request_failed;
1073 /* we accept SDP for now */
1074 rtsp_message_add_header (&request, RTSP_HDR_ACCEPT, "application/sdp");
1077 GST_DEBUG_OBJECT (src, "send describe...");
1078 if (!gst_rtspsrc_send (src, &request, &response, NULL))
1081 /* check if reply is SDP */
1083 gchar *respcont = NULL;
1085 rtsp_message_get_header (&response, RTSP_HDR_CONTENT_TYPE, &respcont);
1086 /* could not be set but since the request returned OK, we assume it
1087 * was SDP, else check it. */
1089 if (!g_ascii_strcasecmp (respcont, "application/sdp") == 0)
1090 goto wrong_content_type;
1095 rtsp_message_get_body (&response, &data, &size);
1097 GST_DEBUG_OBJECT (src, "parse sdp...");
1098 sdp_message_init (&sdp);
1099 sdp_message_parse_buffer (data, size, &sdp);
1102 sdp_message_dump (&sdp);
1104 /* we allow all configured protocols */
1105 protocols = src->protocols;
1110 for (i = 0; i < sdp_message_medias_len (&sdp); i++) {
1115 GstRTSPStream *stream;
1117 media = sdp_message_get_media (&sdp, i);
1119 stream = gst_rtspsrc_create_stream (src);
1121 GST_DEBUG_OBJECT (src, "setup media %d", i);
1122 control_url = sdp_media_get_attribute_val (media, "control");
1123 if (control_url == NULL) {
1124 GST_DEBUG_OBJECT (src, "no control url found, skipping stream");
1128 /* check absolute/relative URL */
1129 /* FIXME, what if the control_url starts with a '/' or a non rtsp: protocol? */
1130 if (g_str_has_prefix (control_url, "rtsp://")) {
1131 setup_url = g_strdup (control_url);
1133 setup_url = g_strdup_printf ("%s/%s", src->location, control_url);
1136 GST_DEBUG_OBJECT (src, "setup %s", setup_url);
1137 /* create SETUP request */
1139 rtsp_message_init_request (RTSP_SETUP, setup_url,
1142 goto create_request_failed;
1146 transports = g_strdup ("");
1147 if (protocols & GST_RTSP_PROTO_UDP_UNICAST) {
1149 gint rtpport, rtcpport;
1152 /* allocate two udp ports */
1153 if (!gst_rtspsrc_stream_setup_rtp (stream, media, &rtpport, &rtcpport))
1154 goto setup_rtp_failed;
1156 GST_DEBUG_OBJECT (src, "setting up RTP ports %d-%d", rtpport, rtcpport);
1158 trxparams = g_strdup_printf ("client_port=%d-%d", rtpport, rtcpport);
1159 new = g_strconcat (transports, "RTP/AVP/UDP;unicast;", trxparams, NULL);
1161 g_free (transports);
1164 if (protocols & GST_RTSP_PROTO_UDP_MULTICAST) {
1167 GST_DEBUG_OBJECT (src, "setting up MULTICAST");
1170 g_strconcat (transports, transports[0] ? "," : "",
1171 "RTP/AVP/UDP;multicast", NULL);
1172 g_free (transports);
1175 if (protocols & GST_RTSP_PROTO_TCP) {
1178 GST_DEBUG_OBJECT (src, "setting up TCP");
1181 g_strconcat (transports, transports[0] ? "," : "", "RTP/AVP/TCP",
1183 g_free (transports);
1187 /* select transport, copy is made when adding to header */
1188 rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT, transports);
1189 g_free (transports);
1191 if (!gst_rtspsrc_send (src, &request, &response, NULL))
1194 /* parse response transport */
1196 gchar *resptrans = NULL;
1197 RTSPTransport transport = { 0 };
1199 rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans);
1203 /* parse transport */
1204 rtsp_transport_parse (resptrans, &transport);
1205 /* update allowed transports for other streams */
1206 if (transport.lower_transport == RTSP_LOWER_TRANS_TCP) {
1207 GST_DEBUG_OBJECT (src, "stream %d as TCP", i);
1208 protocols = GST_RTSP_PROTO_TCP;
1209 src->interleaved = TRUE;
1211 if (transport.multicast) {
1212 /* disable unicast */
1213 GST_DEBUG_OBJECT (src, "stream %d as MULTICAST", i);
1214 protocols = GST_RTSP_PROTO_UDP_MULTICAST;
1216 /* disable multicast */
1217 GST_DEBUG_OBJECT (src, "stream %d as UNICAST", i);
1218 protocols = GST_RTSP_PROTO_UDP_UNICAST;
1221 /* now configure the stream with the transport */
1222 if (!gst_rtspsrc_stream_configure_transport (stream, media, &transport)) {
1223 GST_DEBUG_OBJECT (src,
1224 "could not configure stream transport, skipping stream");
1226 /* clean up our transport struct */
1227 rtsp_transport_init (&transport);
1236 GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
1237 ("Not a valid RTSP url."), (NULL));
1242 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE,
1243 ("Could not open connection."), (NULL));
1246 create_request_failed:
1248 GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1249 ("Could not create request."), (NULL));
1254 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1255 ("Could not send message."), (NULL));
1260 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1261 ("Server does not support DESCRIBE."), (NULL));
1266 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1267 ("Server does not support SETUP."), (NULL));
1272 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1273 ("Server does not support SDP."), (NULL));
1278 GST_ELEMENT_ERROR (src, RESOURCE, WRITE, ("Could not setup rtp."), (NULL));
1283 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1284 ("Server did not select transport."), (NULL));
1290 gst_rtspsrc_close (GstRTSPSrc * src)
1292 RTSPMessage request = { 0 };
1293 RTSPMessage response = { 0 };
1296 GST_DEBUG_OBJECT (src, "TEARDOWN...");
1298 /* stop task if any */
1300 gst_task_stop (src->task);
1302 /* make sure it is not running */
1303 g_static_rec_mutex_lock (src->stream_rec_lock);
1304 g_static_rec_mutex_unlock (src->stream_rec_lock);
1306 /* no wait for the task to finish */
1307 gst_task_join (src->task);
1309 /* and free the task */
1310 gst_object_unref (GST_OBJECT (src->task));
1314 if (src->options & RTSP_PLAY) {
1317 rtsp_message_init_request (RTSP_TEARDOWN, src->location,
1319 goto create_request_failed;
1321 if (!gst_rtspsrc_send (src, &request, &response, NULL))
1325 /* close connection */
1326 GST_DEBUG_OBJECT (src, "closing connection...");
1327 if ((res = rtsp_connection_close (src->connection)) < 0)
1332 create_request_failed:
1334 GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1335 ("Could not create request."), (NULL));
1340 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1341 ("Could not send message."), (NULL));
1346 GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, ("Close failed."), (NULL));
1352 gst_rtspsrc_play (GstRTSPSrc * src)
1354 RTSPMessage request = { 0 };
1355 RTSPMessage response = { 0 };
1358 if (!(src->options & RTSP_PLAY))
1361 GST_DEBUG_OBJECT (src, "PLAY...");
1365 rtsp_message_init_request (RTSP_PLAY, src->location, &request)) < 0)
1366 goto create_request_failed;
1368 if (!gst_rtspsrc_send (src, &request, &response, NULL))
1371 if (src->interleaved) {
1372 src->task = gst_task_create ((GstTaskFunction) gst_rtspsrc_loop, src);
1374 gst_task_set_lock (src->task, src->stream_rec_lock);
1375 gst_task_start (src->task);
1380 create_request_failed:
1382 GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1383 ("Could not create request."), (NULL));
1388 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1389 ("Could not send message."), (NULL));
1395 gst_rtspsrc_pause (GstRTSPSrc * src)
1397 RTSPMessage request = { 0 };
1398 RTSPMessage response = { 0 };
1401 if (!(src->options & RTSP_PAUSE))
1404 GST_DEBUG_OBJECT (src, "PAUSE...");
1407 rtsp_message_init_request (RTSP_PAUSE, src->location, &request)) < 0)
1408 goto create_request_failed;
1410 if (!gst_rtspsrc_send (src, &request, &response, NULL))
1415 create_request_failed:
1417 GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1418 ("Could not create request."), (NULL));
1423 GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1424 ("Could not send message."), (NULL));
1429 static GstStateChangeReturn
1430 gst_rtspsrc_change_state (GstElement * element, GstStateChange transition)
1432 GstRTSPSrc *rtspsrc;
1433 GstStateChangeReturn ret;
1435 rtspsrc = GST_RTSPSRC (element);
1438 switch (transition) {
1439 case GST_STATE_CHANGE_NULL_TO_READY:
1441 case GST_STATE_CHANGE_READY_TO_PAUSED:
1442 rtspsrc->interleaved = FALSE;
1443 rtspsrc->options = 0;
1444 if (!gst_rtspsrc_open (rtspsrc))
1447 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1448 gst_rtspsrc_play (rtspsrc);
1454 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1455 if (ret == GST_STATE_CHANGE_FAILURE)
1458 ret = gst_rtspsrc_set_state (rtspsrc, GST_STATE_PENDING (rtspsrc));
1459 if (ret == GST_STATE_CHANGE_FAILURE)
1462 switch (transition) {
1463 case GST_STATE_CHANGE_READY_TO_PAUSED:
1464 ret = GST_STATE_CHANGE_NO_PREROLL;
1466 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1467 gst_rtspsrc_pause (rtspsrc);
1469 case GST_STATE_CHANGE_PAUSED_TO_READY:
1470 gst_rtspsrc_close (rtspsrc);
1472 case GST_STATE_CHANGE_READY_TO_NULL:
1483 return GST_STATE_CHANGE_FAILURE;
1487 /*** GSTURIHANDLER INTERFACE *************************************************/
1490 gst_rtspsrc_uri_get_type (void)
1495 gst_rtspsrc_uri_get_protocols (void)
1497 static gchar *protocols[] = { "rtsp", NULL };
1502 static const gchar *
1503 gst_rtspsrc_uri_get_uri (GstURIHandler * handler)
1505 GstRTSPSrc *src = GST_RTSPSRC (handler);
1507 return g_strdup (src->location);
1511 gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
1513 GstRTSPSrc *src = GST_RTSPSRC (handler);
1515 g_free (src->location);
1516 src->location = g_strdup (uri);
1522 gst_rtspsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
1524 GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
1526 iface->get_type = gst_rtspsrc_uri_get_type;
1527 iface->get_protocols = gst_rtspsrc_uri_get_protocols;
1528 iface->get_uri = gst_rtspsrc_uri_get_uri;
1529 iface->set_uri = gst_rtspsrc_uri_set_uri;