parser: mark av_parser_parse() for removal on next major bump
[ffmpeg.git] / libavformat / rtsp.c
1 /*
2  * RTSP/SDP client
3  * Copyright (c) 2002 Fabrice Bellard
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavutil/base64.h"
23 #include "libavutil/avstring.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/parseutils.h"
26 #include "libavutil/random_seed.h"
27 #include "avformat.h"
28 #include "avio_internal.h"
29
30 #include <sys/time.h>
31 #if HAVE_POLL_H
32 #include <poll.h>
33 #endif
34 #include <strings.h>
35 #include "internal.h"
36 #include "network.h"
37 #include "os_support.h"
38 #include "http.h"
39 #include "rtsp.h"
40
41 #include "rtpdec.h"
42 #include "rdt.h"
43 #include "rtpdec_formats.h"
44 #include "rtpenc_chain.h"
45
46 //#define DEBUG
47 //#define DEBUG_RTP_TCP
48
49 /* Timeout values for socket poll, in ms,
50  * and read_packet(), in seconds  */
51 #define POLL_TIMEOUT_MS 100
52 #define READ_PACKET_TIMEOUT_S 10
53 #define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS
54 #define SDP_MAX_SIZE 16384
55 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
56
57 static void get_word_until_chars(char *buf, int buf_size,
58                                  const char *sep, const char **pp)
59 {
60     const char *p;
61     char *q;
62
63     p = *pp;
64     p += strspn(p, SPACE_CHARS);
65     q = buf;
66     while (!strchr(sep, *p) && *p != '\0') {
67         if ((q - buf) < buf_size - 1)
68             *q++ = *p;
69         p++;
70     }
71     if (buf_size > 0)
72         *q = '\0';
73     *pp = p;
74 }
75
76 static void get_word_sep(char *buf, int buf_size, const char *sep,
77                          const char **pp)
78 {
79     if (**pp == '/') (*pp)++;
80     get_word_until_chars(buf, buf_size, sep, pp);
81 }
82
83 static void get_word(char *buf, int buf_size, const char **pp)
84 {
85     get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
86 }
87
88 /** Parse a string p in the form of Range:npt=xx-xx, and determine the start
89  *  and end time.
90  *  Used for seeking in the rtp stream.
91  */
92 static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
93 {
94     char buf[256];
95
96     p += strspn(p, SPACE_CHARS);
97     if (!av_stristart(p, "npt=", &p))
98         return;
99
100     *start = AV_NOPTS_VALUE;
101     *end = AV_NOPTS_VALUE;
102
103     get_word_sep(buf, sizeof(buf), "-", &p);
104     av_parse_time(start, buf, 1);
105     if (*p == '-') {
106         p++;
107         get_word_sep(buf, sizeof(buf), "-", &p);
108         av_parse_time(end, buf, 1);
109     }
110 //    av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
111 //    av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
112 }
113
114 static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
115 {
116     struct addrinfo hints, *ai = NULL;
117     memset(&hints, 0, sizeof(hints));
118     hints.ai_flags = AI_NUMERICHOST;
119     if (getaddrinfo(buf, NULL, &hints, &ai))
120         return -1;
121     memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
122     freeaddrinfo(ai);
123     return 0;
124 }
125
126 #if CONFIG_RTPDEC
127 static void init_rtp_handler(RTPDynamicProtocolHandler *handler,
128                              RTSPStream *rtsp_st, AVCodecContext *codec)
129 {
130     if (!handler)
131         return;
132     codec->codec_id          = handler->codec_id;
133     rtsp_st->dynamic_handler = handler;
134     if (handler->open)
135         rtsp_st->dynamic_protocol_context = handler->open();
136 }
137
138 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
139 static int sdp_parse_rtpmap(AVFormatContext *s,
140                             AVStream *st, RTSPStream *rtsp_st,
141                             int payload_type, const char *p)
142 {
143     AVCodecContext *codec = st->codec;
144     char buf[256];
145     int i;
146     AVCodec *c;
147     const char *c_name;
148
149     /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
150      * see if we can handle this kind of payload.
151      * The space should normally not be there but some Real streams or
152      * particular servers ("RealServer Version 6.1.3.970", see issue 1658)
153      * have a trailing space. */
154     get_word_sep(buf, sizeof(buf), "/ ", &p);
155     if (payload_type >= RTP_PT_PRIVATE) {
156         RTPDynamicProtocolHandler *handler =
157             ff_rtp_handler_find_by_name(buf, codec->codec_type);
158         init_rtp_handler(handler, rtsp_st, codec);
159         /* If no dynamic handler was found, check with the list of standard
160          * allocated types, if such a stream for some reason happens to
161          * use a private payload type. This isn't handled in rtpdec.c, since
162          * the format name from the rtpmap line never is passed into rtpdec. */
163         if (!rtsp_st->dynamic_handler)
164             codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
165     } else {
166         /* We are in a standard case
167          * (from http://www.iana.org/assignments/rtp-parameters). */
168         /* search into AVRtpPayloadTypes[] */
169         codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
170     }
171
172     c = avcodec_find_decoder(codec->codec_id);
173     if (c && c->name)
174         c_name = c->name;
175     else
176         c_name = "(null)";
177
178     get_word_sep(buf, sizeof(buf), "/", &p);
179     i = atoi(buf);
180     switch (codec->codec_type) {
181     case AVMEDIA_TYPE_AUDIO:
182         av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name);
183         codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE;
184         codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
185         if (i > 0) {
186             codec->sample_rate = i;
187             av_set_pts_info(st, 32, 1, codec->sample_rate);
188             get_word_sep(buf, sizeof(buf), "/", &p);
189             i = atoi(buf);
190             if (i > 0)
191                 codec->channels = i;
192             // TODO: there is a bug here; if it is a mono stream, and
193             // less than 22000Hz, faad upconverts to stereo and twice
194             // the frequency.  No problem, but the sample rate is being
195             // set here by the sdp line. Patch on its way. (rdm)
196         }
197         av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
198                codec->sample_rate);
199         av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n",
200                codec->channels);
201         break;
202     case AVMEDIA_TYPE_VIDEO:
203         av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
204         if (i > 0)
205             av_set_pts_info(st, 32, 1, i);
206         break;
207     default:
208         break;
209     }
210     return 0;
211 }
212
213 /* parse the attribute line from the fmtp a line of an sdp response. This
214  * is broken out as a function because it is used in rtp_h264.c, which is
215  * forthcoming. */
216 int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
217                                 char *value, int value_size)
218 {
219     *p += strspn(*p, SPACE_CHARS);
220     if (**p) {
221         get_word_sep(attr, attr_size, "=", p);
222         if (**p == '=')
223             (*p)++;
224         get_word_sep(value, value_size, ";", p);
225         if (**p == ';')
226             (*p)++;
227         return 1;
228     }
229     return 0;
230 }
231
232 typedef struct SDPParseState {
233     /* SDP only */
234     struct sockaddr_storage default_ip;
235     int            default_ttl;
236     int            skip_media;  ///< set if an unknown m= line occurs
237 } SDPParseState;
238
239 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
240                            int letter, const char *buf)
241 {
242     RTSPState *rt = s->priv_data;
243     char buf1[64], st_type[64];
244     const char *p;
245     enum AVMediaType codec_type;
246     int payload_type, i;
247     AVStream *st;
248     RTSPStream *rtsp_st;
249     struct sockaddr_storage sdp_ip;
250     int ttl;
251
252     av_dlog(s, "sdp: %c='%s'\n", letter, buf);
253
254     p = buf;
255     if (s1->skip_media && letter != 'm')
256         return;
257     switch (letter) {
258     case 'c':
259         get_word(buf1, sizeof(buf1), &p);
260         if (strcmp(buf1, "IN") != 0)
261             return;
262         get_word(buf1, sizeof(buf1), &p);
263         if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
264             return;
265         get_word_sep(buf1, sizeof(buf1), "/", &p);
266         if (get_sockaddr(buf1, &sdp_ip))
267             return;
268         ttl = 16;
269         if (*p == '/') {
270             p++;
271             get_word_sep(buf1, sizeof(buf1), "/", &p);
272             ttl = atoi(buf1);
273         }
274         if (s->nb_streams == 0) {
275             s1->default_ip = sdp_ip;
276             s1->default_ttl = ttl;
277         } else {
278             rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
279             rtsp_st->sdp_ip = sdp_ip;
280             rtsp_st->sdp_ttl = ttl;
281         }
282         break;
283     case 's':
284         av_metadata_set2(&s->metadata, "title", p, 0);
285         break;
286     case 'i':
287         if (s->nb_streams == 0) {
288             av_metadata_set2(&s->metadata, "comment", p, 0);
289             break;
290         }
291         break;
292     case 'm':
293         /* new stream */
294         s1->skip_media = 0;
295         get_word(st_type, sizeof(st_type), &p);
296         if (!strcmp(st_type, "audio")) {
297             codec_type = AVMEDIA_TYPE_AUDIO;
298         } else if (!strcmp(st_type, "video")) {
299             codec_type = AVMEDIA_TYPE_VIDEO;
300         } else if (!strcmp(st_type, "application")) {
301             codec_type = AVMEDIA_TYPE_DATA;
302         } else {
303             s1->skip_media = 1;
304             return;
305         }
306         rtsp_st = av_mallocz(sizeof(RTSPStream));
307         if (!rtsp_st)
308             return;
309         rtsp_st->stream_index = -1;
310         dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);
311
312         rtsp_st->sdp_ip = s1->default_ip;
313         rtsp_st->sdp_ttl = s1->default_ttl;
314
315         get_word(buf1, sizeof(buf1), &p); /* port */
316         rtsp_st->sdp_port = atoi(buf1);
317
318         get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */
319
320         /* XXX: handle list of formats */
321         get_word(buf1, sizeof(buf1), &p); /* format list */
322         rtsp_st->sdp_payload_type = atoi(buf1);
323
324         if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
325             /* no corresponding stream */
326         } else {
327             st = av_new_stream(s, rt->nb_rtsp_streams - 1);
328             if (!st)
329                 return;
330             rtsp_st->stream_index = st->index;
331             st->codec->codec_type = codec_type;
332             if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
333                 RTPDynamicProtocolHandler *handler;
334                 /* if standard payload type, we can find the codec right now */
335                 ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);
336                 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
337                     st->codec->sample_rate > 0)
338                     av_set_pts_info(st, 32, 1, st->codec->sample_rate);
339                 /* Even static payload types may need a custom depacketizer */
340                 handler = ff_rtp_handler_find_by_id(
341                               rtsp_st->sdp_payload_type, st->codec->codec_type);
342                 init_rtp_handler(handler, rtsp_st, st->codec);
343             }
344         }
345         /* put a default control url */
346         av_strlcpy(rtsp_st->control_url, rt->control_uri,
347                    sizeof(rtsp_st->control_url));
348         break;
349     case 'a':
350         if (av_strstart(p, "control:", &p)) {
351             if (s->nb_streams == 0) {
352                 if (!strncmp(p, "rtsp://", 7))
353                     av_strlcpy(rt->control_uri, p,
354                                sizeof(rt->control_uri));
355             } else {
356                 char proto[32];
357                 /* get the control url */
358                 rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
359
360                 /* XXX: may need to add full url resolution */
361                 av_url_split(proto, sizeof(proto), NULL, 0, NULL, 0,
362                              NULL, NULL, 0, p);
363                 if (proto[0] == '\0') {
364                     /* relative control URL */
365                     if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/')
366                     av_strlcat(rtsp_st->control_url, "/",
367                                sizeof(rtsp_st->control_url));
368                     av_strlcat(rtsp_st->control_url, p,
369                                sizeof(rtsp_st->control_url));
370                 } else
371                     av_strlcpy(rtsp_st->control_url, p,
372                                sizeof(rtsp_st->control_url));
373             }
374         } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
375             /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
376             get_word(buf1, sizeof(buf1), &p);
377             payload_type = atoi(buf1);
378             st = s->streams[s->nb_streams - 1];
379             rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
380             sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p);
381         } else if (av_strstart(p, "fmtp:", &p) ||
382                    av_strstart(p, "framesize:", &p)) {
383             /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
384             // let dynamic protocol handlers have a stab at the line.
385             get_word(buf1, sizeof(buf1), &p);
386             payload_type = atoi(buf1);
387             for (i = 0; i < rt->nb_rtsp_streams; i++) {
388                 rtsp_st = rt->rtsp_streams[i];
389                 if (rtsp_st->sdp_payload_type == payload_type &&
390                     rtsp_st->dynamic_handler &&
391                     rtsp_st->dynamic_handler->parse_sdp_a_line)
392                     rtsp_st->dynamic_handler->parse_sdp_a_line(s, i,
393                         rtsp_st->dynamic_protocol_context, buf);
394             }
395         } else if (av_strstart(p, "range:", &p)) {
396             int64_t start, end;
397
398             // this is so that seeking on a streamed file can work.
399             rtsp_parse_range_npt(p, &start, &end);
400             s->start_time = start;
401             /* AV_NOPTS_VALUE means live broadcast (and can't seek) */
402             s->duration   = (end == AV_NOPTS_VALUE) ?
403                             AV_NOPTS_VALUE : end - start;
404         } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
405             if (atoi(p) == 1)
406                 rt->transport = RTSP_TRANSPORT_RDT;
407         } else if (av_strstart(p, "SampleRate:integer;", &p) &&
408                    s->nb_streams > 0) {
409             st = s->streams[s->nb_streams - 1];
410             st->codec->sample_rate = atoi(p);
411         } else {
412             if (rt->server_type == RTSP_SERVER_WMS)
413                 ff_wms_parse_sdp_a_line(s, p);
414             if (s->nb_streams > 0) {
415                 if (rt->server_type == RTSP_SERVER_REAL)
416                     ff_real_parse_sdp_a_line(s, s->nb_streams - 1, p);
417
418                 rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
419                 if (rtsp_st->dynamic_handler &&
420                     rtsp_st->dynamic_handler->parse_sdp_a_line)
421                     rtsp_st->dynamic_handler->parse_sdp_a_line(s,
422                         s->nb_streams - 1,
423                         rtsp_st->dynamic_protocol_context, buf);
424             }
425         }
426         break;
427     }
428 }
429
430 /**
431  * Parse the sdp description and allocate the rtp streams and the
432  * pollfd array used for udp ones.
433  */
434
435 int ff_sdp_parse(AVFormatContext *s, const char *content)
436 {
437     RTSPState *rt = s->priv_data;
438     const char *p;
439     int letter;
440     /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
441      * contain long SDP lines containing complete ASF Headers (several
442      * kB) or arrays of MDPR (RM stream descriptor) headers plus
443      * "rulebooks" describing their properties. Therefore, the SDP line
444      * buffer is large.
445      *
446      * The Vorbis FMTP line can be up to 16KB - see xiph_parse_sdp_line
447      * in rtpdec_xiph.c. */
448     char buf[16384], *q;
449     SDPParseState sdp_parse_state, *s1 = &sdp_parse_state;
450
451     memset(s1, 0, sizeof(SDPParseState));
452     p = content;
453     for (;;) {
454         p += strspn(p, SPACE_CHARS);
455         letter = *p;
456         if (letter == '\0')
457             break;
458         p++;
459         if (*p != '=')
460             goto next_line;
461         p++;
462         /* get the content */
463         q = buf;
464         while (*p != '\n' && *p != '\r' && *p != '\0') {
465             if ((q - buf) < sizeof(buf) - 1)
466                 *q++ = *p;
467             p++;
468         }
469         *q = '\0';
470         sdp_parse_line(s, s1, letter, buf);
471     next_line:
472         while (*p != '\n' && *p != '\0')
473             p++;
474         if (*p == '\n')
475             p++;
476     }
477     rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
478     if (!rt->p) return AVERROR(ENOMEM);
479     return 0;
480 }
481 #endif /* CONFIG_RTPDEC */
482
483 void ff_rtsp_undo_setup(AVFormatContext *s)
484 {
485     RTSPState *rt = s->priv_data;
486     int i;
487
488     for (i = 0; i < rt->nb_rtsp_streams; i++) {
489         RTSPStream *rtsp_st = rt->rtsp_streams[i];
490         if (!rtsp_st)
491             continue;
492         if (rtsp_st->transport_priv) {
493             if (s->oformat) {
494                 AVFormatContext *rtpctx = rtsp_st->transport_priv;
495                 av_write_trailer(rtpctx);
496                 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
497                     uint8_t *ptr;
498                     url_close_dyn_buf(rtpctx->pb, &ptr);
499                     av_free(ptr);
500                 } else {
501                     avio_close(rtpctx->pb);
502                 }
503                 avformat_free_context(rtpctx);
504             } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
505                 ff_rdt_parse_close(rtsp_st->transport_priv);
506             else if (CONFIG_RTPDEC)
507                 rtp_parse_close(rtsp_st->transport_priv);
508         }
509         rtsp_st->transport_priv = NULL;
510         if (rtsp_st->rtp_handle)
511             url_close(rtsp_st->rtp_handle);
512         rtsp_st->rtp_handle = NULL;
513     }
514 }
515
516 /* close and free RTSP streams */
517 void ff_rtsp_close_streams(AVFormatContext *s)
518 {
519     RTSPState *rt = s->priv_data;
520     int i;
521     RTSPStream *rtsp_st;
522
523     ff_rtsp_undo_setup(s);
524     for (i = 0; i < rt->nb_rtsp_streams; i++) {
525         rtsp_st = rt->rtsp_streams[i];
526         if (rtsp_st) {
527             if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
528                 rtsp_st->dynamic_handler->close(
529                     rtsp_st->dynamic_protocol_context);
530             av_free(rtsp_st);
531         }
532     }
533     av_free(rt->rtsp_streams);
534     if (rt->asf_ctx) {
535         av_close_input_stream (rt->asf_ctx);
536         rt->asf_ctx = NULL;
537     }
538     av_free(rt->p);
539     av_free(rt->recvbuf);
540 }
541
542 static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
543 {
544     RTSPState *rt = s->priv_data;
545     AVStream *st = NULL;
546
547     /* open the RTP context */
548     if (rtsp_st->stream_index >= 0)
549         st = s->streams[rtsp_st->stream_index];
550     if (!st)
551         s->ctx_flags |= AVFMTCTX_NOHEADER;
552
553     if (s->oformat && CONFIG_RTSP_MUXER) {
554         rtsp_st->transport_priv = ff_rtp_chain_mux_open(s, st,
555                                       rtsp_st->rtp_handle,
556                                       RTSP_TCP_MAX_PACKET_SIZE);
557         /* Ownership of rtp_handle is passed to the rtp mux context */
558         rtsp_st->rtp_handle = NULL;
559     } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
560         rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
561                                             rtsp_st->dynamic_protocol_context,
562                                             rtsp_st->dynamic_handler);
563     else if (CONFIG_RTPDEC)
564         rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle,
565                                          rtsp_st->sdp_payload_type,
566             (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
567             ? 0 : RTP_REORDER_QUEUE_DEFAULT_SIZE);
568
569     if (!rtsp_st->transport_priv) {
570          return AVERROR(ENOMEM);
571     } else if (rt->transport != RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) {
572         if (rtsp_st->dynamic_handler) {
573             rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
574                                            rtsp_st->dynamic_protocol_context,
575                                            rtsp_st->dynamic_handler);
576         }
577     }
578
579     return 0;
580 }
581
582 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
583 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
584 {
585     const char *p;
586     int v;
587
588     p = *pp;
589     p += strspn(p, SPACE_CHARS);
590     v = strtol(p, (char **)&p, 10);
591     if (*p == '-') {
592         p++;
593         *min_ptr = v;
594         v = strtol(p, (char **)&p, 10);
595         *max_ptr = v;
596     } else {
597         *min_ptr = v;
598         *max_ptr = v;
599     }
600     *pp = p;
601 }
602
603 /* XXX: only one transport specification is parsed */
604 static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
605 {
606     char transport_protocol[16];
607     char profile[16];
608     char lower_transport[16];
609     char parameter[16];
610     RTSPTransportField *th;
611     char buf[256];
612
613     reply->nb_transports = 0;
614
615     for (;;) {
616         p += strspn(p, SPACE_CHARS);
617         if (*p == '\0')
618             break;
619
620         th = &reply->transports[reply->nb_transports];
621
622         get_word_sep(transport_protocol, sizeof(transport_protocol),
623                      "/", &p);
624         if (!strcasecmp (transport_protocol, "rtp")) {
625             get_word_sep(profile, sizeof(profile), "/;,", &p);
626             lower_transport[0] = '\0';
627             /* rtp/avp/<protocol> */
628             if (*p == '/') {
629                 get_word_sep(lower_transport, sizeof(lower_transport),
630                              ";,", &p);
631             }
632             th->transport = RTSP_TRANSPORT_RTP;
633         } else if (!strcasecmp (transport_protocol, "x-pn-tng") ||
634                    !strcasecmp (transport_protocol, "x-real-rdt")) {
635             /* x-pn-tng/<protocol> */
636             get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
637             profile[0] = '\0';
638             th->transport = RTSP_TRANSPORT_RDT;
639         }
640         if (!strcasecmp(lower_transport, "TCP"))
641             th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
642         else
643             th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;
644
645         if (*p == ';')
646             p++;
647         /* get each parameter */
648         while (*p != '\0' && *p != ',') {
649             get_word_sep(parameter, sizeof(parameter), "=;,", &p);
650             if (!strcmp(parameter, "port")) {
651                 if (*p == '=') {
652                     p++;
653                     rtsp_parse_range(&th->port_min, &th->port_max, &p);
654                 }
655             } else if (!strcmp(parameter, "client_port")) {
656                 if (*p == '=') {
657                     p++;
658                     rtsp_parse_range(&th->client_port_min,
659                                      &th->client_port_max, &p);
660                 }
661             } else if (!strcmp(parameter, "server_port")) {
662                 if (*p == '=') {
663                     p++;
664                     rtsp_parse_range(&th->server_port_min,
665                                      &th->server_port_max, &p);
666                 }
667             } else if (!strcmp(parameter, "interleaved")) {
668                 if (*p == '=') {
669                     p++;
670                     rtsp_parse_range(&th->interleaved_min,
671                                      &th->interleaved_max, &p);
672                 }
673             } else if (!strcmp(parameter, "multicast")) {
674                 if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP)
675                     th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
676             } else if (!strcmp(parameter, "ttl")) {
677                 if (*p == '=') {
678                     p++;
679                     th->ttl = strtol(p, (char **)&p, 10);
680                 }
681             } else if (!strcmp(parameter, "destination")) {
682                 if (*p == '=') {
683                     p++;
684                     get_word_sep(buf, sizeof(buf), ";,", &p);
685                     get_sockaddr(buf, &th->destination);
686                 }
687             } else if (!strcmp(parameter, "source")) {
688                 if (*p == '=') {
689                     p++;
690                     get_word_sep(buf, sizeof(buf), ";,", &p);
691                     av_strlcpy(th->source, buf, sizeof(th->source));
692                 }
693             }
694
695             while (*p != ';' && *p != '\0' && *p != ',')
696                 p++;
697             if (*p == ';')
698                 p++;
699         }
700         if (*p == ',')
701             p++;
702
703         reply->nb_transports++;
704     }
705 }
706
707 static void handle_rtp_info(RTSPState *rt, const char *url,
708                             uint32_t seq, uint32_t rtptime)
709 {
710     int i;
711     if (!rtptime || !url[0])
712         return;
713     if (rt->transport != RTSP_TRANSPORT_RTP)
714         return;
715     for (i = 0; i < rt->nb_rtsp_streams; i++) {
716         RTSPStream *rtsp_st = rt->rtsp_streams[i];
717         RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
718         if (!rtpctx)
719             continue;
720         if (!strcmp(rtsp_st->control_url, url)) {
721             rtpctx->base_timestamp = rtptime;
722             break;
723         }
724     }
725 }
726
727 static void rtsp_parse_rtp_info(RTSPState *rt, const char *p)
728 {
729     int read = 0;
730     char key[20], value[1024], url[1024] = "";
731     uint32_t seq = 0, rtptime = 0;
732
733     for (;;) {
734         p += strspn(p, SPACE_CHARS);
735         if (!*p)
736             break;
737         get_word_sep(key, sizeof(key), "=", &p);
738         if (*p != '=')
739             break;
740         p++;
741         get_word_sep(value, sizeof(value), ";, ", &p);
742         read++;
743         if (!strcmp(key, "url"))
744             av_strlcpy(url, value, sizeof(url));
745         else if (!strcmp(key, "seq"))
746             seq = strtol(value, NULL, 10);
747         else if (!strcmp(key, "rtptime"))
748             rtptime = strtol(value, NULL, 10);
749         if (*p == ',') {
750             handle_rtp_info(rt, url, seq, rtptime);
751             url[0] = '\0';
752             seq = rtptime = 0;
753             read = 0;
754         }
755         if (*p)
756             p++;
757     }
758     if (read > 0)
759         handle_rtp_info(rt, url, seq, rtptime);
760 }
761
762 void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
763                         RTSPState *rt, const char *method)
764 {
765     const char *p;
766
767     /* NOTE: we do case independent match for broken servers */
768     p = buf;
769     if (av_stristart(p, "Session:", &p)) {
770         int t;
771         get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
772         if (av_stristart(p, ";timeout=", &p) &&
773             (t = strtol(p, NULL, 10)) > 0) {
774             reply->timeout = t;
775         }
776     } else if (av_stristart(p, "Content-Length:", &p)) {
777         reply->content_length = strtol(p, NULL, 10);
778     } else if (av_stristart(p, "Transport:", &p)) {
779         rtsp_parse_transport(reply, p);
780     } else if (av_stristart(p, "CSeq:", &p)) {
781         reply->seq = strtol(p, NULL, 10);
782     } else if (av_stristart(p, "Range:", &p)) {
783         rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
784     } else if (av_stristart(p, "RealChallenge1:", &p)) {
785         p += strspn(p, SPACE_CHARS);
786         av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
787     } else if (av_stristart(p, "Server:", &p)) {
788         p += strspn(p, SPACE_CHARS);
789         av_strlcpy(reply->server, p, sizeof(reply->server));
790     } else if (av_stristart(p, "Notice:", &p) ||
791                av_stristart(p, "X-Notice:", &p)) {
792         reply->notice = strtol(p, NULL, 10);
793     } else if (av_stristart(p, "Location:", &p)) {
794         p += strspn(p, SPACE_CHARS);
795         av_strlcpy(reply->location, p , sizeof(reply->location));
796     } else if (av_stristart(p, "WWW-Authenticate:", &p) && rt) {
797         p += strspn(p, SPACE_CHARS);
798         ff_http_auth_handle_header(&rt->auth_state, "WWW-Authenticate", p);
799     } else if (av_stristart(p, "Authentication-Info:", &p) && rt) {
800         p += strspn(p, SPACE_CHARS);
801         ff_http_auth_handle_header(&rt->auth_state, "Authentication-Info", p);
802     } else if (av_stristart(p, "Content-Base:", &p) && rt) {
803         p += strspn(p, SPACE_CHARS);
804         if (method && !strcmp(method, "DESCRIBE"))
805             av_strlcpy(rt->control_uri, p , sizeof(rt->control_uri));
806     } else if (av_stristart(p, "RTP-Info:", &p) && rt) {
807         p += strspn(p, SPACE_CHARS);
808         if (method && !strcmp(method, "PLAY"))
809             rtsp_parse_rtp_info(rt, p);
810     }
811 }
812
813 /* skip a RTP/TCP interleaved packet */
814 void ff_rtsp_skip_packet(AVFormatContext *s)
815 {
816     RTSPState *rt = s->priv_data;
817     int ret, len, len1;
818     uint8_t buf[1024];
819
820     ret = url_read_complete(rt->rtsp_hd, buf, 3);
821     if (ret != 3)
822         return;
823     len = AV_RB16(buf + 1);
824
825     av_dlog(s, "skipping RTP packet len=%d\n", len);
826
827     /* skip payload */
828     while (len > 0) {
829         len1 = len;
830         if (len1 > sizeof(buf))
831             len1 = sizeof(buf);
832         ret = url_read_complete(rt->rtsp_hd, buf, len1);
833         if (ret != len1)
834             return;
835         len -= len1;
836     }
837 }
838
839 int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
840                        unsigned char **content_ptr,
841                        int return_on_interleaved_data, const char *method)
842 {
843     RTSPState *rt = s->priv_data;
844     char buf[4096], buf1[1024], *q;
845     unsigned char ch;
846     const char *p;
847     int ret, content_length, line_count = 0;
848     unsigned char *content = NULL;
849
850     memset(reply, 0, sizeof(*reply));
851
852     /* parse reply (XXX: use buffers) */
853     rt->last_reply[0] = '\0';
854     for (;;) {
855         q = buf;
856         for (;;) {
857             ret = url_read_complete(rt->rtsp_hd, &ch, 1);
858 #ifdef DEBUG_RTP_TCP
859             av_dlog(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
860 #endif
861             if (ret != 1)
862                 return AVERROR_EOF;
863             if (ch == '\n')
864                 break;
865             if (ch == '$') {
866                 /* XXX: only parse it if first char on line ? */
867                 if (return_on_interleaved_data) {
868                     return 1;
869                 } else
870                     ff_rtsp_skip_packet(s);
871             } else if (ch != '\r') {
872                 if ((q - buf) < sizeof(buf) - 1)
873                     *q++ = ch;
874             }
875         }
876         *q = '\0';
877
878         av_dlog(s, "line='%s'\n", buf);
879
880         /* test if last line */
881         if (buf[0] == '\0')
882             break;
883         p = buf;
884         if (line_count == 0) {
885             /* get reply code */
886             get_word(buf1, sizeof(buf1), &p);
887             get_word(buf1, sizeof(buf1), &p);
888             reply->status_code = atoi(buf1);
889             av_strlcpy(reply->reason, p, sizeof(reply->reason));
890         } else {
891             ff_rtsp_parse_line(reply, p, rt, method);
892             av_strlcat(rt->last_reply, p,    sizeof(rt->last_reply));
893             av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
894         }
895         line_count++;
896     }
897
898     if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0')
899         av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));
900
901     content_length = reply->content_length;
902     if (content_length > 0) {
903         /* leave some room for a trailing '\0' (useful for simple parsing) */
904         content = av_malloc(content_length + 1);
905         (void)url_read_complete(rt->rtsp_hd, content, content_length);
906         content[content_length] = '\0';
907     }
908     if (content_ptr)
909         *content_ptr = content;
910     else
911         av_free(content);
912
913     if (rt->seq != reply->seq) {
914         av_log(s, AV_LOG_WARNING, "CSeq %d expected, %d received.\n",
915             rt->seq, reply->seq);
916     }
917
918     /* EOS */
919     if (reply->notice == 2101 /* End-of-Stream Reached */      ||
920         reply->notice == 2104 /* Start-of-Stream Reached */    ||
921         reply->notice == 2306 /* Continuous Feed Terminated */) {
922         rt->state = RTSP_STATE_IDLE;
923     } else if (reply->notice >= 4400 && reply->notice < 5500) {
924         return AVERROR(EIO); /* data or server error */
925     } else if (reply->notice == 2401 /* Ticket Expired */ ||
926              (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
927         return AVERROR(EPERM);
928
929     return 0;
930 }
931
932 /**
933  * Send a command to the RTSP server without waiting for the reply.
934  *
935  * @param s RTSP (de)muxer context
936  * @param method the method for the request
937  * @param url the target url for the request
938  * @param headers extra header lines to include in the request
939  * @param send_content if non-null, the data to send as request body content
940  * @param send_content_length the length of the send_content data, or 0 if
941  *                            send_content is null
942  *
943  * @return zero if success, nonzero otherwise
944  */
945 static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
946                                                const char *method, const char *url,
947                                                const char *headers,
948                                                const unsigned char *send_content,
949                                                int send_content_length)
950 {
951     RTSPState *rt = s->priv_data;
952     char buf[4096], *out_buf;
953     char base64buf[AV_BASE64_SIZE(sizeof(buf))];
954
955     /* Add in RTSP headers */
956     out_buf = buf;
957     rt->seq++;
958     snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url);
959     if (headers)
960         av_strlcat(buf, headers, sizeof(buf));
961     av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
962     if (rt->session_id[0] != '\0' && (!headers ||
963         !strstr(headers, "\nIf-Match:"))) {
964         av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
965     }
966     if (rt->auth[0]) {
967         char *str = ff_http_auth_create_response(&rt->auth_state,
968                                                  rt->auth, url, method);
969         if (str)
970             av_strlcat(buf, str, sizeof(buf));
971         av_free(str);
972     }
973     if (send_content_length > 0 && send_content)
974         av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length);
975     av_strlcat(buf, "\r\n", sizeof(buf));
976
977     /* base64 encode rtsp if tunneling */
978     if (rt->control_transport == RTSP_MODE_TUNNEL) {
979         av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
980         out_buf = base64buf;
981     }
982
983     av_dlog(s, "Sending:\n%s--\n", buf);
984
985     url_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
986     if (send_content_length > 0 && send_content) {
987         if (rt->control_transport == RTSP_MODE_TUNNEL) {
988             av_log(s, AV_LOG_ERROR, "tunneling of RTSP requests "
989                                     "with content data not supported\n");
990             return AVERROR_PATCHWELCOME;
991         }
992         url_write(rt->rtsp_hd_out, send_content, send_content_length);
993     }
994     rt->last_cmd_time = av_gettime();
995
996     return 0;
997 }
998
999 int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
1000                            const char *url, const char *headers)
1001 {
1002     return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
1003 }
1004
1005 int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
1006                      const char *headers, RTSPMessageHeader *reply,
1007                      unsigned char **content_ptr)
1008 {
1009     return ff_rtsp_send_cmd_with_content(s, method, url, headers, reply,
1010                                          content_ptr, NULL, 0);
1011 }
1012
1013 int ff_rtsp_send_cmd_with_content(AVFormatContext *s,
1014                                   const char *method, const char *url,
1015                                   const char *header,
1016                                   RTSPMessageHeader *reply,
1017                                   unsigned char **content_ptr,
1018                                   const unsigned char *send_content,
1019                                   int send_content_length)
1020 {
1021     RTSPState *rt = s->priv_data;
1022     HTTPAuthType cur_auth_type;
1023     int ret;
1024
1025 retry:
1026     cur_auth_type = rt->auth_state.auth_type;
1027     if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
1028                                                    send_content,
1029                                                    send_content_length)))
1030         return ret;
1031
1032     if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
1033         return ret;
1034
1035     if (reply->status_code == 401 && cur_auth_type == HTTP_AUTH_NONE &&
1036         rt->auth_state.auth_type != HTTP_AUTH_NONE)
1037         goto retry;
1038
1039     if (reply->status_code > 400){
1040         av_log(s, AV_LOG_ERROR, "method %s failed: %d%s\n",
1041                method,
1042                reply->status_code,
1043                reply->reason);
1044         av_log(s, AV_LOG_DEBUG, "%s\n", rt->last_reply);
1045     }
1046
1047     return 0;
1048 }
1049
1050 /**
1051  * @return 0 on success, <0 on error, 1 if protocol is unavailable.
1052  */
1053 int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
1054                               int lower_transport, const char *real_challenge)
1055 {
1056     RTSPState *rt = s->priv_data;
1057     int rtx, j, i, err, interleave = 0;
1058     RTSPStream *rtsp_st;
1059     RTSPMessageHeader reply1, *reply = &reply1;
1060     char cmd[2048];
1061     const char *trans_pref;
1062
1063     if (rt->transport == RTSP_TRANSPORT_RDT)
1064         trans_pref = "x-pn-tng";
1065     else
1066         trans_pref = "RTP/AVP";
1067
1068     /* default timeout: 1 minute */
1069     rt->timeout = 60;
1070
1071     /* for each stream, make the setup request */
1072     /* XXX: we assume the same server is used for the control of each
1073      * RTSP stream */
1074
1075     for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
1076         char transport[2048];
1077
1078         /**
1079          * WMS serves all UDP data over a single connection, the RTX, which
1080          * isn't necessarily the first in the SDP but has to be the first
1081          * to be set up, else the second/third SETUP will fail with a 461.
1082          */
1083         if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
1084              rt->server_type == RTSP_SERVER_WMS) {
1085             if (i == 0) {
1086                 /* rtx first */
1087                 for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) {
1088                     int len = strlen(rt->rtsp_streams[rtx]->control_url);
1089                     if (len >= 4 &&
1090                         !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4,
1091                                 "/rtx"))
1092                         break;
1093                 }
1094                 if (rtx == rt->nb_rtsp_streams)
1095                     return -1; /* no RTX found */
1096                 rtsp_st = rt->rtsp_streams[rtx];
1097             } else
1098                 rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];
1099         } else
1100             rtsp_st = rt->rtsp_streams[i];
1101
1102         /* RTP/UDP */
1103         if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
1104             char buf[256];
1105
1106             if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
1107                 port = reply->transports[0].client_port_min;
1108                 goto have_port;
1109             }
1110
1111             /* first try in specified port range */
1112             if (RTSP_RTP_PORT_MIN != 0) {
1113                 while (j <= RTSP_RTP_PORT_MAX) {
1114                     ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,
1115                                 "?localport=%d", j);
1116                     /* we will use two ports per rtp stream (rtp and rtcp) */
1117                     j += 2;
1118                     if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0)
1119                         goto rtp_opened;
1120                 }
1121             }
1122
1123 #if 0
1124             /* then try on any port */
1125             if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
1126                 err = AVERROR_INVALIDDATA;
1127                 goto fail;
1128             }
1129 #else
1130             av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
1131             err = AVERROR(EIO);
1132             goto fail;
1133 #endif
1134
1135         rtp_opened:
1136             port = rtp_get_local_rtp_port(rtsp_st->rtp_handle);
1137         have_port:
1138             snprintf(transport, sizeof(transport) - 1,
1139                      "%s/UDP;", trans_pref);
1140             if (rt->server_type != RTSP_SERVER_REAL)
1141                 av_strlcat(transport, "unicast;", sizeof(transport));
1142             av_strlcatf(transport, sizeof(transport),
1143                      "client_port=%d", port);
1144             if (rt->transport == RTSP_TRANSPORT_RTP &&
1145                 !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1146                 av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
1147         }
1148
1149         /* RTP/TCP */
1150         else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1151             /** For WMS streams, the application streams are only used for
1152              * UDP. When trying to set it up for TCP streams, the server
1153              * will return an error. Therefore, we skip those streams. */
1154             if (rt->server_type == RTSP_SERVER_WMS &&
1155                 s->streams[rtsp_st->stream_index]->codec->codec_type ==
1156                     AVMEDIA_TYPE_DATA)
1157                 continue;
1158             snprintf(transport, sizeof(transport) - 1,
1159                      "%s/TCP;", trans_pref);
1160             if (rt->transport != RTSP_TRANSPORT_RDT)
1161                 av_strlcat(transport, "unicast;", sizeof(transport));
1162             av_strlcatf(transport, sizeof(transport),
1163                         "interleaved=%d-%d",
1164                         interleave, interleave + 1);
1165             interleave += 2;
1166         }
1167
1168         else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
1169             snprintf(transport, sizeof(transport) - 1,
1170                      "%s/UDP;multicast", trans_pref);
1171         }
1172         if (s->oformat) {
1173             av_strlcat(transport, ";mode=receive", sizeof(transport));
1174         } else if (rt->server_type == RTSP_SERVER_REAL ||
1175                    rt->server_type == RTSP_SERVER_WMS)
1176             av_strlcat(transport, ";mode=play", sizeof(transport));
1177         snprintf(cmd, sizeof(cmd),
1178                  "Transport: %s\r\n",
1179                  transport);
1180         if (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {
1181             char real_res[41], real_csum[9];
1182             ff_rdt_calc_response_and_checksum(real_res, real_csum,
1183                                               real_challenge);
1184             av_strlcatf(cmd, sizeof(cmd),
1185                         "If-Match: %s\r\n"
1186                         "RealChallenge2: %s, sd=%s\r\n",
1187                         rt->session_id, real_res, real_csum);
1188         }
1189         ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
1190         if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
1191             err = 1;
1192             goto fail;
1193         } else if (reply->status_code != RTSP_STATUS_OK ||
1194                    reply->nb_transports != 1) {
1195             err = AVERROR_INVALIDDATA;
1196             goto fail;
1197         }
1198
1199         /* XXX: same protocol for all streams is required */
1200         if (i > 0) {
1201             if (reply->transports[0].lower_transport != rt->lower_transport ||
1202                 reply->transports[0].transport != rt->transport) {
1203                 err = AVERROR_INVALIDDATA;
1204                 goto fail;
1205             }
1206         } else {
1207             rt->lower_transport = reply->transports[0].lower_transport;
1208             rt->transport = reply->transports[0].transport;
1209         }
1210
1211         /* Fail if the server responded with another lower transport mode
1212          * than what we requested. */
1213         if (reply->transports[0].lower_transport != lower_transport) {
1214             av_log(s, AV_LOG_ERROR, "Nonmatching transport in server reply\n");
1215             err = AVERROR_INVALIDDATA;
1216             goto fail;
1217         }
1218
1219         switch(reply->transports[0].lower_transport) {
1220         case RTSP_LOWER_TRANSPORT_TCP:
1221             rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
1222             rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
1223             break;
1224
1225         case RTSP_LOWER_TRANSPORT_UDP: {
1226             char url[1024], options[30] = "";
1227
1228             if (rt->filter_source)
1229                 av_strlcpy(options, "?connect=1", sizeof(options));
1230             /* Use source address if specified */
1231             if (reply->transports[0].source[0]) {
1232                 ff_url_join(url, sizeof(url), "rtp", NULL,
1233                             reply->transports[0].source,
1234                             reply->transports[0].server_port_min, options);
1235             } else {
1236                 ff_url_join(url, sizeof(url), "rtp", NULL, host,
1237                             reply->transports[0].server_port_min, options);
1238             }
1239             if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1240                 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
1241                 err = AVERROR_INVALIDDATA;
1242                 goto fail;
1243             }
1244             /* Try to initialize the connection state in a
1245              * potential NAT router by sending dummy packets.
1246              * RTP/RTCP dummy packets are used for RDT, too.
1247              */
1248             if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&
1249                 CONFIG_RTPDEC)
1250                 rtp_send_punch_packets(rtsp_st->rtp_handle);
1251             break;
1252         }
1253         case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
1254             char url[1024], namebuf[50];
1255             struct sockaddr_storage addr;
1256             int port, ttl;
1257
1258             if (reply->transports[0].destination.ss_family) {
1259                 addr      = reply->transports[0].destination;
1260                 port      = reply->transports[0].port_min;
1261                 ttl       = reply->transports[0].ttl;
1262             } else {
1263                 addr      = rtsp_st->sdp_ip;
1264                 port      = rtsp_st->sdp_port;
1265                 ttl       = rtsp_st->sdp_ttl;
1266             }
1267             getnameinfo((struct sockaddr*) &addr, sizeof(addr),
1268                         namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
1269             ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
1270                         port, "?ttl=%d", ttl);
1271             if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1272                 err = AVERROR_INVALIDDATA;
1273                 goto fail;
1274             }
1275             break;
1276         }
1277         }
1278
1279         if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1280             goto fail;
1281     }
1282
1283     if (reply->timeout > 0)
1284         rt->timeout = reply->timeout;
1285
1286     if (rt->server_type == RTSP_SERVER_REAL)
1287         rt->need_subscription = 1;
1288
1289     return 0;
1290
1291 fail:
1292     ff_rtsp_undo_setup(s);
1293     return err;
1294 }
1295
1296 void ff_rtsp_close_connections(AVFormatContext *s)
1297 {
1298     RTSPState *rt = s->priv_data;
1299     if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out);
1300     url_close(rt->rtsp_hd);
1301     rt->rtsp_hd = rt->rtsp_hd_out = NULL;
1302 }
1303
1304 int ff_rtsp_connect(AVFormatContext *s)
1305 {
1306     RTSPState *rt = s->priv_data;
1307     char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128];
1308     char *option_list, *option, *filename;
1309     int port, err, tcp_fd;
1310     RTSPMessageHeader reply1 = {0}, *reply = &reply1;
1311     int lower_transport_mask = 0;
1312     char real_challenge[64] = "";
1313     struct sockaddr_storage peer;
1314     socklen_t peer_len = sizeof(peer);
1315
1316     if (!ff_network_init())
1317         return AVERROR(EIO);
1318 redirect:
1319     rt->control_transport = RTSP_MODE_PLAIN;
1320     /* extract hostname and port */
1321     av_url_split(NULL, 0, auth, sizeof(auth),
1322                  host, sizeof(host), &port, path, sizeof(path), s->filename);
1323     if (*auth) {
1324         av_strlcpy(rt->auth, auth, sizeof(rt->auth));
1325     }
1326     if (port < 0)
1327         port = RTSP_DEFAULT_PORT;
1328
1329     /* search for options */
1330     option_list = strrchr(path, '?');
1331     if (option_list) {
1332         /* Strip out the RTSP specific options, write out the rest of
1333          * the options back into the same string. */
1334         filename = option_list;
1335         while (option_list) {
1336             /* move the option pointer */
1337             option = ++option_list;
1338             option_list = strchr(option_list, '&');
1339             if (option_list)
1340                 *option_list = 0;
1341
1342             /* handle the options */
1343             if (!strcmp(option, "udp")) {
1344                 lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_UDP);
1345             } else if (!strcmp(option, "multicast")) {
1346                 lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
1347             } else if (!strcmp(option, "tcp")) {
1348                 lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
1349             } else if(!strcmp(option, "http")) {
1350                 lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
1351                 rt->control_transport = RTSP_MODE_TUNNEL;
1352             } else if (!strcmp(option, "filter_src")) {
1353                 rt->filter_source = 1;
1354             } else {
1355                 /* Write options back into the buffer, using memmove instead
1356                  * of strcpy since the strings may overlap. */
1357                 int len = strlen(option);
1358                 memmove(++filename, option, len);
1359                 filename += len;
1360                 if (option_list) *filename = '&';
1361             }
1362         }
1363         *filename = 0;
1364     }
1365
1366     if (!lower_transport_mask)
1367         lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1368
1369     if (s->oformat) {
1370         /* Only UDP or TCP - UDP multicast isn't supported. */
1371         lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) |
1372                                 (1 << RTSP_LOWER_TRANSPORT_TCP);
1373         if (!lower_transport_mask || rt->control_transport == RTSP_MODE_TUNNEL) {
1374             av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
1375                                     "only UDP and TCP are supported for output.\n");
1376             err = AVERROR(EINVAL);
1377             goto fail;
1378         }
1379     }
1380
1381     /* Construct the URI used in request; this is similar to s->filename,
1382      * but with authentication credentials removed and RTSP specific options
1383      * stripped out. */
1384     ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL,
1385                 host, port, "%s", path);
1386
1387     if (rt->control_transport == RTSP_MODE_TUNNEL) {
1388         /* set up initial handshake for tunneling */
1389         char httpname[1024];
1390         char sessioncookie[17];
1391         char headers[1024];
1392
1393         ff_url_join(httpname, sizeof(httpname), "http", auth, host, port, "%s", path);
1394         snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
1395                  av_get_random_seed(), av_get_random_seed());
1396
1397         /* GET requests */
1398         if (url_alloc(&rt->rtsp_hd, httpname, URL_RDONLY) < 0) {
1399             err = AVERROR(EIO);
1400             goto fail;
1401         }
1402
1403         /* generate GET headers */
1404         snprintf(headers, sizeof(headers),
1405                  "x-sessioncookie: %s\r\n"
1406                  "Accept: application/x-rtsp-tunnelled\r\n"
1407                  "Pragma: no-cache\r\n"
1408                  "Cache-Control: no-cache\r\n",
1409                  sessioncookie);
1410         ff_http_set_headers(rt->rtsp_hd, headers);
1411
1412         /* complete the connection */
1413         if (url_connect(rt->rtsp_hd)) {
1414             err = AVERROR(EIO);
1415             goto fail;
1416         }
1417
1418         /* POST requests */
1419         if (url_alloc(&rt->rtsp_hd_out, httpname, URL_WRONLY) < 0 ) {
1420             err = AVERROR(EIO);
1421             goto fail;
1422         }
1423
1424         /* generate POST headers */
1425         snprintf(headers, sizeof(headers),
1426                  "x-sessioncookie: %s\r\n"
1427                  "Content-Type: application/x-rtsp-tunnelled\r\n"
1428                  "Pragma: no-cache\r\n"
1429                  "Cache-Control: no-cache\r\n"
1430                  "Content-Length: 32767\r\n"
1431                  "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
1432                  sessioncookie);
1433         ff_http_set_headers(rt->rtsp_hd_out, headers);
1434         ff_http_set_chunked_transfer_encoding(rt->rtsp_hd_out, 0);
1435
1436         /* Initialize the authentication state for the POST session. The HTTP
1437          * protocol implementation doesn't properly handle multi-pass
1438          * authentication for POST requests, since it would require one of
1439          * the following:
1440          * - implementing Expect: 100-continue, which many HTTP servers
1441          *   don't support anyway, even less the RTSP servers that do HTTP
1442          *   tunneling
1443          * - sending the whole POST data until getting a 401 reply specifying
1444          *   what authentication method to use, then resending all that data
1445          * - waiting for potential 401 replies directly after sending the
1446          *   POST header (waiting for some unspecified time)
1447          * Therefore, we copy the full auth state, which works for both basic
1448          * and digest. (For digest, we would have to synchronize the nonce
1449          * count variable between the two sessions, if we'd do more requests
1450          * with the original session, though.)
1451          */
1452         ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd);
1453
1454         /* complete the connection */
1455         if (url_connect(rt->rtsp_hd_out)) {
1456             err = AVERROR(EIO);
1457             goto fail;
1458         }
1459     } else {
1460         /* open the tcp connection */
1461         ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL);
1462         if (url_open(&rt->rtsp_hd, tcpname, URL_RDWR) < 0) {
1463             err = AVERROR(EIO);
1464             goto fail;
1465         }
1466         rt->rtsp_hd_out = rt->rtsp_hd;
1467     }
1468     rt->seq = 0;
1469
1470     tcp_fd = url_get_file_handle(rt->rtsp_hd);
1471     if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
1472         getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
1473                     NULL, 0, NI_NUMERICHOST);
1474     }
1475
1476     /* request options supported by the server; this also detects server
1477      * type */
1478     for (rt->server_type = RTSP_SERVER_RTP;;) {
1479         cmd[0] = 0;
1480         if (rt->server_type == RTSP_SERVER_REAL)
1481             av_strlcat(cmd,
1482                        /**
1483                         * The following entries are required for proper
1484                         * streaming from a Realmedia server. They are
1485                         * interdependent in some way although we currently
1486                         * don't quite understand how. Values were copied
1487                         * from mplayer SVN r23589.
1488                         * @param CompanyID is a 16-byte ID in base64
1489                         * @param ClientChallenge is a 16-byte ID in hex
1490                         */
1491                        "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
1492                        "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
1493                        "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
1494                        "GUID: 00000000-0000-0000-0000-000000000000\r\n",
1495                        sizeof(cmd));
1496         ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL);
1497         if (reply->status_code != RTSP_STATUS_OK) {
1498             err = AVERROR_INVALIDDATA;
1499             goto fail;
1500         }
1501
1502         /* detect server type if not standard-compliant RTP */
1503         if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
1504             rt->server_type = RTSP_SERVER_REAL;
1505             continue;
1506         } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
1507             rt->server_type = RTSP_SERVER_WMS;
1508         } else if (rt->server_type == RTSP_SERVER_REAL)
1509             strcpy(real_challenge, reply->real_challenge);
1510         break;
1511     }
1512
1513     if (s->iformat && CONFIG_RTSP_DEMUXER)
1514         err = ff_rtsp_setup_input_streams(s, reply);
1515     else if (CONFIG_RTSP_MUXER)
1516         err = ff_rtsp_setup_output_streams(s, host);
1517     if (err)
1518         goto fail;
1519
1520     do {
1521         int lower_transport = ff_log2_tab[lower_transport_mask &
1522                                   ~(lower_transport_mask - 1)];
1523
1524         err = ff_rtsp_make_setup_request(s, host, port, lower_transport,
1525                                  rt->server_type == RTSP_SERVER_REAL ?
1526                                      real_challenge : NULL);
1527         if (err < 0)
1528             goto fail;
1529         lower_transport_mask &= ~(1 << lower_transport);
1530         if (lower_transport_mask == 0 && err == 1) {
1531             err = AVERROR(EPROTONOSUPPORT);
1532             goto fail;
1533         }
1534     } while (err);
1535
1536     rt->lower_transport_mask = lower_transport_mask;
1537     av_strlcpy(rt->real_challenge, real_challenge, sizeof(rt->real_challenge));
1538     rt->state = RTSP_STATE_IDLE;
1539     rt->seek_timestamp = 0; /* default is to start stream at position zero */
1540     return 0;
1541  fail:
1542     ff_rtsp_close_streams(s);
1543     ff_rtsp_close_connections(s);
1544     if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
1545         av_strlcpy(s->filename, reply->location, sizeof(s->filename));
1546         av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
1547                reply->status_code,
1548                s->filename);
1549         goto redirect;
1550     }
1551     ff_network_close();
1552     return err;
1553 }
1554 #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
1555
1556 #if CONFIG_RTPDEC
1557 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1558                            uint8_t *buf, int buf_size, int64_t wait_end)
1559 {
1560     RTSPState *rt = s->priv_data;
1561     RTSPStream *rtsp_st;
1562     int n, i, ret, tcp_fd, timeout_cnt = 0;
1563     int max_p = 0;
1564     struct pollfd *p = rt->p;
1565
1566     for (;;) {
1567         if (url_interrupt_cb())
1568             return AVERROR_EXIT;
1569         if (wait_end && wait_end - av_gettime() < 0)
1570             return AVERROR(EAGAIN);
1571         max_p = 0;
1572         if (rt->rtsp_hd) {
1573             tcp_fd = url_get_file_handle(rt->rtsp_hd);
1574             p[max_p].fd = tcp_fd;
1575             p[max_p++].events = POLLIN;
1576         } else {
1577             tcp_fd = -1;
1578         }
1579         for (i = 0; i < rt->nb_rtsp_streams; i++) {
1580             rtsp_st = rt->rtsp_streams[i];
1581             if (rtsp_st->rtp_handle) {
1582                 p[max_p].fd = url_get_file_handle(rtsp_st->rtp_handle);
1583                 p[max_p++].events = POLLIN;
1584                 p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
1585                 p[max_p++].events = POLLIN;
1586             }
1587         }
1588         n = poll(p, max_p, POLL_TIMEOUT_MS);
1589         if (n > 0) {
1590             int j = 1 - (tcp_fd == -1);
1591             timeout_cnt = 0;
1592             for (i = 0; i < rt->nb_rtsp_streams; i++) {
1593                 rtsp_st = rt->rtsp_streams[i];
1594                 if (rtsp_st->rtp_handle) {
1595                     if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
1596                         ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
1597                         if (ret > 0) {
1598                             *prtsp_st = rtsp_st;
1599                             return ret;
1600                         }
1601                     }
1602                     j+=2;
1603                 }
1604             }
1605 #if CONFIG_RTSP_DEMUXER
1606             if (tcp_fd != -1 && p[0].revents & POLLIN) {
1607                 RTSPMessageHeader reply;
1608
1609                 ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
1610                 if (ret < 0)
1611                     return ret;
1612                 /* XXX: parse message */
1613                 if (rt->state != RTSP_STATE_STREAMING)
1614                     return 0;
1615             }
1616 #endif
1617         } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
1618             return AVERROR(ETIMEDOUT);
1619         } else if (n < 0 && errno != EINTR)
1620             return AVERROR(errno);
1621     }
1622 }
1623
1624 int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
1625 {
1626     RTSPState *rt = s->priv_data;
1627     int ret, len;
1628     RTSPStream *rtsp_st, *first_queue_st = NULL;
1629     int64_t wait_end = 0;
1630
1631     if (rt->nb_byes == rt->nb_rtsp_streams)
1632         return AVERROR_EOF;
1633
1634     /* get next frames from the same RTP packet */
1635     if (rt->cur_transport_priv) {
1636         if (rt->transport == RTSP_TRANSPORT_RDT) {
1637             ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1638         } else
1639             ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1640         if (ret == 0) {
1641             rt->cur_transport_priv = NULL;
1642             return 0;
1643         } else if (ret == 1) {
1644             return 0;
1645         } else
1646             rt->cur_transport_priv = NULL;
1647     }
1648
1649     if (rt->transport == RTSP_TRANSPORT_RTP) {
1650         int i;
1651         int64_t first_queue_time = 0;
1652         for (i = 0; i < rt->nb_rtsp_streams; i++) {
1653             RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
1654             int64_t queue_time;
1655             if (!rtpctx)
1656                 continue;
1657             queue_time = ff_rtp_queued_packet_time(rtpctx);
1658             if (queue_time && (queue_time - first_queue_time < 0 ||
1659                                !first_queue_time)) {
1660                 first_queue_time = queue_time;
1661                 first_queue_st   = rt->rtsp_streams[i];
1662             }
1663         }
1664         if (first_queue_time)
1665             wait_end = first_queue_time + s->max_delay;
1666     }
1667
1668     /* read next RTP packet */
1669  redo:
1670     if (!rt->recvbuf) {
1671         rt->recvbuf = av_malloc(RECVBUF_SIZE);
1672         if (!rt->recvbuf)
1673             return AVERROR(ENOMEM);
1674     }
1675
1676     switch(rt->lower_transport) {
1677     default:
1678 #if CONFIG_RTSP_DEMUXER
1679     case RTSP_LOWER_TRANSPORT_TCP:
1680         len = ff_rtsp_tcp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE);
1681         break;
1682 #endif
1683     case RTSP_LOWER_TRANSPORT_UDP:
1684     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
1685         len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
1686         if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
1687             rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
1688         break;
1689     }
1690     if (len == AVERROR(EAGAIN) && first_queue_st &&
1691         rt->transport == RTSP_TRANSPORT_RTP) {
1692         rtsp_st = first_queue_st;
1693         ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
1694         goto end;
1695     }
1696     if (len < 0)
1697         return len;
1698     if (len == 0)
1699         return AVERROR_EOF;
1700     if (rt->transport == RTSP_TRANSPORT_RDT) {
1701         ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
1702     } else {
1703         ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
1704         if (ret < 0) {
1705             /* Either bad packet, or a RTCP packet. Check if the
1706              * first_rtcp_ntp_time field was initialized. */
1707             RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
1708             if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
1709                 /* first_rtcp_ntp_time has been initialized for this stream,
1710                  * copy the same value to all other uninitialized streams,
1711                  * in order to map their timestamp origin to the same ntp time
1712                  * as this one. */
1713                 int i;
1714                 AVStream *st = NULL;
1715                 if (rtsp_st->stream_index >= 0)
1716                     st = s->streams[rtsp_st->stream_index];
1717                 for (i = 0; i < rt->nb_rtsp_streams; i++) {
1718                     RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
1719                     AVStream *st2 = NULL;
1720                     if (rt->rtsp_streams[i]->stream_index >= 0)
1721                         st2 = s->streams[rt->rtsp_streams[i]->stream_index];
1722                     if (rtpctx2 && st && st2 &&
1723                         rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
1724                         rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
1725                         rtpctx2->rtcp_ts_offset = av_rescale_q(
1726                             rtpctx->rtcp_ts_offset, st->time_base,
1727                             st2->time_base);
1728                     }
1729                 }
1730             }
1731             if (ret == -RTCP_BYE) {
1732                 rt->nb_byes++;
1733
1734                 av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
1735                        rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);
1736
1737                 if (rt->nb_byes == rt->nb_rtsp_streams)
1738                     return AVERROR_EOF;
1739             }
1740         }
1741     }
1742 end:
1743     if (ret < 0)
1744         goto redo;
1745     if (ret == 1)
1746         /* more packets may follow, so we save the RTP context */
1747         rt->cur_transport_priv = rtsp_st->transport_priv;
1748
1749     return ret;
1750 }
1751 #endif /* CONFIG_RTPDEC */
1752
1753 #if CONFIG_SDP_DEMUXER
1754 static int sdp_probe(AVProbeData *p1)
1755 {
1756     const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
1757
1758     /* we look for a line beginning "c=IN IP" */
1759     while (p < p_end && *p != '\0') {
1760         if (p + sizeof("c=IN IP") - 1 < p_end &&
1761             av_strstart(p, "c=IN IP", NULL))
1762             return AVPROBE_SCORE_MAX / 2;
1763
1764         while (p < p_end - 1 && *p != '\n') p++;
1765         if (++p >= p_end)
1766             break;
1767         if (*p == '\r')
1768             p++;
1769     }
1770     return 0;
1771 }
1772
1773 static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap)
1774 {
1775     RTSPState *rt = s->priv_data;
1776     RTSPStream *rtsp_st;
1777     int size, i, err;
1778     char *content;
1779     char url[1024];
1780
1781     if (!ff_network_init())
1782         return AVERROR(EIO);
1783
1784     /* read the whole sdp file */
1785     /* XXX: better loading */
1786     content = av_malloc(SDP_MAX_SIZE);
1787     size = avio_read(s->pb, content, SDP_MAX_SIZE - 1);
1788     if (size <= 0) {
1789         av_free(content);
1790         return AVERROR_INVALIDDATA;
1791     }
1792     content[size] ='\0';
1793
1794     err = ff_sdp_parse(s, content);
1795     av_free(content);
1796     if (err) goto fail;
1797
1798     /* open each RTP stream */
1799     for (i = 0; i < rt->nb_rtsp_streams; i++) {
1800         char namebuf[50];
1801         rtsp_st = rt->rtsp_streams[i];
1802
1803         getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip),
1804                     namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
1805         ff_url_join(url, sizeof(url), "rtp", NULL,
1806                     namebuf, rtsp_st->sdp_port,
1807                     "?localport=%d&ttl=%d", rtsp_st->sdp_port,
1808                     rtsp_st->sdp_ttl);
1809         if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1810             err = AVERROR_INVALIDDATA;
1811             goto fail;
1812         }
1813         if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1814             goto fail;
1815     }
1816     return 0;
1817 fail:
1818     ff_rtsp_close_streams(s);
1819     ff_network_close();
1820     return err;
1821 }
1822
1823 static int sdp_read_close(AVFormatContext *s)
1824 {
1825     ff_rtsp_close_streams(s);
1826     ff_network_close();
1827     return 0;
1828 }
1829
1830 AVInputFormat ff_sdp_demuxer = {
1831     "sdp",
1832     NULL_IF_CONFIG_SMALL("SDP"),
1833     sizeof(RTSPState),
1834     sdp_probe,
1835     sdp_read_header,
1836     ff_rtsp_fetch_packet,
1837     sdp_read_close,
1838 };
1839 #endif /* CONFIG_SDP_DEMUXER */
1840
1841 #if CONFIG_RTP_DEMUXER
1842 static int rtp_probe(AVProbeData *p)
1843 {
1844     if (av_strstart(p->filename, "rtp:", NULL))
1845         return AVPROBE_SCORE_MAX;
1846     return 0;
1847 }
1848
1849 static int rtp_read_header(AVFormatContext *s,
1850                            AVFormatParameters *ap)
1851 {
1852     uint8_t recvbuf[1500];
1853     char host[500], sdp[500];
1854     int ret, port;
1855     URLContext* in = NULL;
1856     int payload_type;
1857     AVCodecContext codec;
1858     struct sockaddr_storage addr;
1859     AVIOContext pb;
1860     socklen_t addrlen = sizeof(addr);
1861
1862     if (!ff_network_init())
1863         return AVERROR(EIO);
1864
1865     ret = url_open(&in, s->filename, URL_RDONLY);
1866     if (ret)
1867         goto fail;
1868
1869     while (1) {
1870         ret = url_read(in, recvbuf, sizeof(recvbuf));
1871         if (ret == AVERROR(EAGAIN))
1872             continue;
1873         if (ret < 0)
1874             goto fail;
1875         if (ret < 12) {
1876             av_log(s, AV_LOG_WARNING, "Received too short packet\n");
1877             continue;
1878         }
1879
1880         if ((recvbuf[0] & 0xc0) != 0x80) {
1881             av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet "
1882                                       "received\n");
1883             continue;
1884         }
1885
1886         payload_type = recvbuf[1] & 0x7f;
1887         break;
1888     }
1889     getsockname(url_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
1890     url_close(in);
1891     in = NULL;
1892
1893     memset(&codec, 0, sizeof(codec));
1894     if (ff_rtp_get_codec_info(&codec, payload_type)) {
1895         av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
1896                                 "without an SDP file describing it\n",
1897                                  payload_type);
1898         goto fail;
1899     }
1900     if (codec.codec_type != AVMEDIA_TYPE_DATA) {
1901         av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
1902                                   "properly you need an SDP file "
1903                                   "describing it\n");
1904     }
1905
1906     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
1907                  NULL, 0, s->filename);
1908
1909     snprintf(sdp, sizeof(sdp),
1910              "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
1911              addr.ss_family == AF_INET ? 4 : 6, host,
1912              codec.codec_type == AVMEDIA_TYPE_DATA  ? "application" :
1913              codec.codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
1914              port, payload_type);
1915     av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
1916
1917     ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
1918     s->pb = &pb;
1919
1920     /* sdp_read_header initializes this again */
1921     ff_network_close();
1922
1923     ret = sdp_read_header(s, ap);
1924     s->pb = NULL;
1925     return ret;
1926
1927 fail:
1928     if (in)
1929         url_close(in);
1930     ff_network_close();
1931     return ret;
1932 }
1933
1934 AVInputFormat ff_rtp_demuxer = {
1935     "rtp",
1936     NULL_IF_CONFIG_SMALL("RTP input format"),
1937     sizeof(RTSPState),
1938     rtp_probe,
1939     rtp_read_header,
1940     ff_rtsp_fetch_packet,
1941     sdp_read_close,
1942     .flags = AVFMT_NOFILE,
1943 };
1944 #endif /* CONFIG_RTP_DEMUXER */
1945