]> git.sesse.net Git - ffmpeg/blob - libavformat/rtsp.c
Remove slash-skipping code because the function called right after that
[ffmpeg] / libavformat / rtsp.c
1 /*
2  * RTSP/SDP client
3  * Copyright (c) 2002 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /* needed by inet_aton() */
23 #define _SVID_SOURCE
24
25 #include "libavutil/avstring.h"
26 #include "libavutil/intreadwrite.h"
27 #include "avformat.h"
28
29 #include <sys/time.h>
30 #if HAVE_SYS_SELECT_H
31 #include <sys/select.h>
32 #endif
33 #include <strings.h>
34 #include "network.h"
35 #include "rtsp.h"
36
37 #include "rtpdec.h"
38 #include "rdt.h"
39 #include "rtp_asf.h"
40
41 //#define DEBUG
42 //#define DEBUG_RTP_TCP
43
44 static int rtsp_read_play(AVFormatContext *s);
45
46 #if LIBAVFORMAT_VERSION_INT < (53 << 16)
47 int rtsp_default_protocols = (1 << RTSP_LOWER_TRANSPORT_UDP);
48 #endif
49
50 static int rtsp_probe(AVProbeData *p)
51 {
52     if (av_strstart(p->filename, "rtsp:", NULL))
53         return AVPROBE_SCORE_MAX;
54     return 0;
55 }
56
57 #define SPACE_CHARS " \t\r\n"
58 #define redir_isspace(c) strchr(SPACE_CHARS, c)
59 static void skip_spaces(const char **pp)
60 {
61     const char *p;
62     p = *pp;
63     while (redir_isspace(*p))
64         p++;
65     *pp = p;
66 }
67
68 static void get_word_until_chars(char *buf, int buf_size,
69                                  const char *sep, const char **pp)
70 {
71     const char *p;
72     char *q;
73
74     p = *pp;
75     skip_spaces(&p);
76     q = buf;
77     while (!strchr(sep, *p) && *p != '\0') {
78         if ((q - buf) < buf_size - 1)
79             *q++ = *p;
80         p++;
81     }
82     if (buf_size > 0)
83         *q = '\0';
84     *pp = p;
85 }
86
87 static void get_word_sep(char *buf, int buf_size, const char *sep,
88                          const char **pp)
89 {
90     if (**pp == '/') (*pp)++;
91     get_word_until_chars(buf, buf_size, sep, pp);
92 }
93
94 static void get_word(char *buf, int buf_size, const char **pp)
95 {
96     get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
97 }
98
99 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other
100    params>] */
101 static int sdp_parse_rtpmap(AVCodecContext *codec, RTSPStream *rtsp_st, int payload_type, const char *p)
102 {
103     char buf[256];
104     int i;
105     AVCodec *c;
106     const char *c_name;
107
108     /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
109        see if we can handle this kind of payload */
110     get_word_sep(buf, sizeof(buf), "/", &p);
111     if (payload_type >= RTP_PT_PRIVATE) {
112         RTPDynamicProtocolHandler *handler= RTPFirstDynamicPayloadHandler;
113         while(handler) {
114             if (!strcasecmp(buf, handler->enc_name) && (codec->codec_type == handler->codec_type)) {
115                 codec->codec_id = handler->codec_id;
116                 rtsp_st->dynamic_handler= handler;
117                 if(handler->open) {
118                     rtsp_st->dynamic_protocol_context= handler->open();
119                 }
120                 break;
121             }
122             handler= handler->next;
123         }
124     } else {
125         /* We are in a standard case ( from http://www.iana.org/assignments/rtp-parameters) */
126         /* search into AVRtpPayloadTypes[] */
127         codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
128     }
129
130     c = avcodec_find_decoder(codec->codec_id);
131     if (c && c->name)
132         c_name = c->name;
133     else
134         c_name = (char *)NULL;
135
136     if (c_name) {
137         get_word_sep(buf, sizeof(buf), "/", &p);
138         i = atoi(buf);
139         switch (codec->codec_type) {
140             case CODEC_TYPE_AUDIO:
141                 av_log(codec, AV_LOG_DEBUG, " audio codec set to : %s\n", c_name);
142                 codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE;
143                 codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
144                 if (i > 0) {
145                     codec->sample_rate = i;
146                     get_word_sep(buf, sizeof(buf), "/", &p);
147                     i = atoi(buf);
148                     if (i > 0)
149                         codec->channels = i;
150                     // TODO: there is a bug here; if it is a mono stream, and less than 22000Hz, faad upconverts to stereo and twice the
151                     //  frequency.  No problem, but the sample rate is being set here by the sdp line.  Upcoming patch forthcoming. (rdm)
152                 }
153                 av_log(codec, AV_LOG_DEBUG, " audio samplerate set to : %i\n", codec->sample_rate);
154                 av_log(codec, AV_LOG_DEBUG, " audio channels set to : %i\n", codec->channels);
155                 break;
156             case CODEC_TYPE_VIDEO:
157                 av_log(codec, AV_LOG_DEBUG, " video codec set to : %s\n", c_name);
158                 break;
159             default:
160                 break;
161         }
162         return 0;
163     }
164
165     return -1;
166 }
167
168 /* return the length and optionnaly the data */
169 static int hex_to_data(uint8_t *data, const char *p)
170 {
171     int c, len, v;
172
173     len = 0;
174     v = 1;
175     for(;;) {
176         skip_spaces(&p);
177         if (*p == '\0')
178             break;
179         c = toupper((unsigned char)*p++);
180         if (c >= '0' && c <= '9')
181             c = c - '0';
182         else if (c >= 'A' && c <= 'F')
183             c = c - 'A' + 10;
184         else
185             break;
186         v = (v << 4) | c;
187         if (v & 0x100) {
188             if (data)
189                 data[len] = v;
190             len++;
191             v = 1;
192         }
193     }
194     return len;
195 }
196
197 static void sdp_parse_fmtp_config(AVCodecContext *codec, char *attr, char *value)
198 {
199     switch (codec->codec_id) {
200         case CODEC_ID_MPEG4:
201         case CODEC_ID_AAC:
202             if (!strcmp(attr, "config")) {
203                 /* decode the hexa encoded parameter */
204                 int len = hex_to_data(NULL, value);
205                 if (codec->extradata)
206                     av_free(codec->extradata);
207                 codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
208                 if (!codec->extradata)
209                     return;
210                 codec->extradata_size = len;
211                 hex_to_data(codec->extradata, value);
212             }
213             break;
214         default:
215             break;
216     }
217     return;
218 }
219
220 typedef struct {
221     const char *str;
222     uint16_t type;
223     uint32_t offset;
224 } AttrNameMap;
225
226 /* All known fmtp parmeters and the corresping RTPAttrTypeEnum */
227 #define ATTR_NAME_TYPE_INT 0
228 #define ATTR_NAME_TYPE_STR 1
229 static const AttrNameMap attr_names[]=
230 {
231     {"SizeLength",       ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, sizelength)},
232     {"IndexLength",      ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, indexlength)},
233     {"IndexDeltaLength", ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, indexdeltalength)},
234     {"profile-level-id", ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, profile_level_id)},
235     {"StreamType",       ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, streamtype)},
236     {"mode",             ATTR_NAME_TYPE_STR, offsetof(RTPPayloadData, mode)},
237     {NULL, -1, -1},
238 };
239
240 /** parse the attribute line from the fmtp a line of an sdp resonse.  This is broken out as a function
241 * because it is used in rtp_h264.c, which is forthcoming.
242 */
243 int rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size)
244 {
245     skip_spaces(p);
246     if(**p) {
247         get_word_sep(attr, attr_size, "=", p);
248         if (**p == '=')
249             (*p)++;
250         get_word_sep(value, value_size, ";", p);
251         if (**p == ';')
252             (*p)++;
253         return 1;
254     }
255     return 0;
256 }
257
258 /* parse a SDP line and save stream attributes */
259 static void sdp_parse_fmtp(AVStream *st, const char *p)
260 {
261     char attr[256];
262     char value[4096];
263     int i;
264
265     RTSPStream *rtsp_st = st->priv_data;
266     AVCodecContext *codec = st->codec;
267     RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data;
268
269     /* loop on each attribute */
270     while(rtsp_next_attr_and_value(&p, attr, sizeof(attr), value, sizeof(value)))
271     {
272         /* grab the codec extra_data from the config parameter of the fmtp line */
273         sdp_parse_fmtp_config(codec, attr, value);
274         /* Looking for a known attribute */
275         for (i = 0; attr_names[i].str; ++i) {
276             if (!strcasecmp(attr, attr_names[i].str)) {
277                 if (attr_names[i].type == ATTR_NAME_TYPE_INT)
278                     *(int *)((char *)rtp_payload_data + attr_names[i].offset) = atoi(value);
279                 else if (attr_names[i].type == ATTR_NAME_TYPE_STR)
280                     *(char **)((char *)rtp_payload_data + attr_names[i].offset) = av_strdup(value);
281             }
282         }
283     }
284 }
285
286 /** Parse a string \p in the form of Range:npt=xx-xx, and determine the start
287  *  and end time.
288  *  Used for seeking in the rtp stream.
289  */
290 static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
291 {
292     char buf[256];
293
294     skip_spaces(&p);
295     if (!av_stristart(p, "npt=", &p))
296         return;
297
298     *start = AV_NOPTS_VALUE;
299     *end = AV_NOPTS_VALUE;
300
301     get_word_sep(buf, sizeof(buf), "-", &p);
302     *start = parse_date(buf, 1);
303     if (*p == '-') {
304         p++;
305         get_word_sep(buf, sizeof(buf), "-", &p);
306         *end = parse_date(buf, 1);
307     }
308 //    av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
309 //    av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
310 }
311
312 typedef struct SDPParseState {
313     /* SDP only */
314     struct in_addr default_ip;
315     int default_ttl;
316     int skip_media; ///< set if an unknown m= line occurs
317 } SDPParseState;
318
319 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
320                            int letter, const char *buf)
321 {
322     RTSPState *rt = s->priv_data;
323     char buf1[64], st_type[64];
324     const char *p;
325     enum CodecType codec_type;
326     int payload_type, i;
327     AVStream *st;
328     RTSPStream *rtsp_st;
329     struct in_addr sdp_ip;
330     int ttl;
331
332 #ifdef DEBUG
333     printf("sdp: %c='%s'\n", letter, buf);
334 #endif
335
336     p = buf;
337     if (s1->skip_media && letter != 'm')
338         return;
339     switch(letter) {
340     case 'c':
341         get_word(buf1, sizeof(buf1), &p);
342         if (strcmp(buf1, "IN") != 0)
343             return;
344         get_word(buf1, sizeof(buf1), &p);
345         if (strcmp(buf1, "IP4") != 0)
346             return;
347         get_word_sep(buf1, sizeof(buf1), "/", &p);
348         if (inet_aton(buf1, &sdp_ip) == 0)
349             return;
350         ttl = 16;
351         if (*p == '/') {
352             p++;
353             get_word_sep(buf1, sizeof(buf1), "/", &p);
354             ttl = atoi(buf1);
355         }
356         if (s->nb_streams == 0) {
357             s1->default_ip = sdp_ip;
358             s1->default_ttl = ttl;
359         } else {
360             st = s->streams[s->nb_streams - 1];
361             rtsp_st = st->priv_data;
362             rtsp_st->sdp_ip = sdp_ip;
363             rtsp_st->sdp_ttl = ttl;
364         }
365         break;
366     case 's':
367         av_metadata_set(&s->metadata, "title", p);
368         break;
369     case 'i':
370         if (s->nb_streams == 0) {
371             av_metadata_set(&s->metadata, "comment", p);
372             break;
373         }
374         break;
375     case 'm':
376         /* new stream */
377         s1->skip_media = 0;
378         get_word(st_type, sizeof(st_type), &p);
379         if (!strcmp(st_type, "audio")) {
380             codec_type = CODEC_TYPE_AUDIO;
381         } else if (!strcmp(st_type, "video")) {
382             codec_type = CODEC_TYPE_VIDEO;
383         } else if (!strcmp(st_type, "application")) {
384             codec_type = CODEC_TYPE_DATA;
385         } else {
386             s1->skip_media = 1;
387             return;
388         }
389         rtsp_st = av_mallocz(sizeof(RTSPStream));
390         if (!rtsp_st)
391             return;
392         rtsp_st->stream_index = -1;
393         dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);
394
395         rtsp_st->sdp_ip = s1->default_ip;
396         rtsp_st->sdp_ttl = s1->default_ttl;
397
398         get_word(buf1, sizeof(buf1), &p); /* port */
399         rtsp_st->sdp_port = atoi(buf1);
400
401         get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */
402
403         /* XXX: handle list of formats */
404         get_word(buf1, sizeof(buf1), &p); /* format list */
405         rtsp_st->sdp_payload_type = atoi(buf1);
406
407         if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
408             /* no corresponding stream */
409         } else {
410             st = av_new_stream(s, 0);
411             if (!st)
412                 return;
413             st->priv_data = rtsp_st;
414             rtsp_st->stream_index = st->index;
415             st->codec->codec_type = codec_type;
416             if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
417                 /* if standard payload type, we can find the codec right now */
418                 ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);
419             }
420         }
421         /* put a default control url */
422         av_strlcpy(rtsp_st->control_url, s->filename, sizeof(rtsp_st->control_url));
423         break;
424     case 'a':
425         if (av_strstart(p, "control:", &p) && s->nb_streams > 0) {
426             char proto[32];
427             /* get the control url */
428             st = s->streams[s->nb_streams - 1];
429             rtsp_st = st->priv_data;
430
431             /* XXX: may need to add full url resolution */
432             url_split(proto, sizeof(proto), NULL, 0, NULL, 0, NULL, NULL, 0, p);
433             if (proto[0] == '\0') {
434                 /* relative control URL */
435                 av_strlcat(rtsp_st->control_url, "/", sizeof(rtsp_st->control_url));
436                 av_strlcat(rtsp_st->control_url, p,   sizeof(rtsp_st->control_url));
437             } else {
438                 av_strlcpy(rtsp_st->control_url, p,   sizeof(rtsp_st->control_url));
439             }
440         } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
441             /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
442             get_word(buf1, sizeof(buf1), &p);
443             payload_type = atoi(buf1);
444             st = s->streams[s->nb_streams - 1];
445             rtsp_st = st->priv_data;
446             sdp_parse_rtpmap(st->codec, rtsp_st, payload_type, p);
447         } else if (av_strstart(p, "fmtp:", &p)) {
448             /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
449             get_word(buf1, sizeof(buf1), &p);
450             payload_type = atoi(buf1);
451             for(i = 0; i < s->nb_streams;i++) {
452                 st = s->streams[i];
453                 rtsp_st = st->priv_data;
454                 if (rtsp_st->sdp_payload_type == payload_type) {
455                     if(rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) {
456                         if(!rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, rtsp_st->dynamic_protocol_context, buf)) {
457                             sdp_parse_fmtp(st, p);
458                         }
459                     } else {
460                         sdp_parse_fmtp(st, p);
461                     }
462                 }
463             }
464         } else if(av_strstart(p, "framesize:", &p)) {
465             // let dynamic protocol handlers have a stab at the line.
466             get_word(buf1, sizeof(buf1), &p);
467             payload_type = atoi(buf1);
468             for(i = 0; i < s->nb_streams;i++) {
469                 st = s->streams[i];
470                 rtsp_st = st->priv_data;
471                 if (rtsp_st->sdp_payload_type == payload_type) {
472                     if(rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) {
473                         rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, rtsp_st->dynamic_protocol_context, buf);
474                     }
475                 }
476             }
477         } else if(av_strstart(p, "range:", &p)) {
478             int64_t start, end;
479
480             // this is so that seeking on a streamed file can work.
481             rtsp_parse_range_npt(p, &start, &end);
482             s->start_time= start;
483             s->duration= (end==AV_NOPTS_VALUE)?AV_NOPTS_VALUE:end-start; // AV_NOPTS_VALUE means live broadcast (and can't seek)
484         } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
485             if (atoi(p) == 1)
486                 rt->transport = RTSP_TRANSPORT_RDT;
487         } else {
488             if (rt->server_type == RTSP_SERVER_WMS)
489                 ff_wms_parse_sdp_a_line(s, p);
490             if (s->nb_streams > 0) {
491                 if (rt->server_type == RTSP_SERVER_REAL)
492                     ff_real_parse_sdp_a_line(s, s->nb_streams - 1, p);
493
494                 rtsp_st = s->streams[s->nb_streams - 1]->priv_data;
495                 if (rtsp_st->dynamic_handler &&
496                     rtsp_st->dynamic_handler->parse_sdp_a_line)
497                     rtsp_st->dynamic_handler->parse_sdp_a_line(s, s->nb_streams - 1,
498                         rtsp_st->dynamic_protocol_context, buf);
499             }
500         }
501         break;
502     }
503 }
504
505 static int sdp_parse(AVFormatContext *s, const char *content)
506 {
507     const char *p;
508     int letter;
509     /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
510      * contain long SDP lines containing complete ASF Headers (several
511      * kB) or arrays of MDPR (RM stream descriptor) headers plus
512      * "rulebooks" describing their properties. Therefore, the SDP line
513      * buffer is large. */
514     char buf[8192], *q;
515     SDPParseState sdp_parse_state, *s1 = &sdp_parse_state;
516
517     memset(s1, 0, sizeof(SDPParseState));
518     p = content;
519     for(;;) {
520         skip_spaces(&p);
521         letter = *p;
522         if (letter == '\0')
523             break;
524         p++;
525         if (*p != '=')
526             goto next_line;
527         p++;
528         /* get the content */
529         q = buf;
530         while (*p != '\n' && *p != '\r' && *p != '\0') {
531             if ((q - buf) < sizeof(buf) - 1)
532                 *q++ = *p;
533             p++;
534         }
535         *q = '\0';
536         sdp_parse_line(s, s1, letter, buf);
537     next_line:
538         while (*p != '\n' && *p != '\0')
539             p++;
540         if (*p == '\n')
541             p++;
542     }
543     return 0;
544 }
545
546 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
547 {
548     const char *p;
549     int v;
550
551     p = *pp;
552     skip_spaces(&p);
553     v = strtol(p, (char **)&p, 10);
554     if (*p == '-') {
555         p++;
556         *min_ptr = v;
557         v = strtol(p, (char **)&p, 10);
558         *max_ptr = v;
559     } else {
560         *min_ptr = v;
561         *max_ptr = v;
562     }
563     *pp = p;
564 }
565
566 /* XXX: only one transport specification is parsed */
567 static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
568 {
569     char transport_protocol[16];
570     char profile[16];
571     char lower_transport[16];
572     char parameter[16];
573     RTSPTransportField *th;
574     char buf[256];
575
576     reply->nb_transports = 0;
577
578     for(;;) {
579         skip_spaces(&p);
580         if (*p == '\0')
581             break;
582
583         th = &reply->transports[reply->nb_transports];
584
585         get_word_sep(transport_protocol, sizeof(transport_protocol),
586                      "/", &p);
587         if (!strcasecmp (transport_protocol, "rtp")) {
588             get_word_sep(profile, sizeof(profile), "/;,", &p);
589             lower_transport[0] = '\0';
590             /* rtp/avp/<protocol> */
591             if (*p == '/') {
592                 get_word_sep(lower_transport, sizeof(lower_transport),
593                              ";,", &p);
594             }
595             th->transport = RTSP_TRANSPORT_RTP;
596         } else if (!strcasecmp (transport_protocol, "x-pn-tng") ||
597                    !strcasecmp (transport_protocol, "x-real-rdt")) {
598             /* x-pn-tng/<protocol> */
599             get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
600             profile[0] = '\0';
601             th->transport = RTSP_TRANSPORT_RDT;
602         }
603         if (!strcasecmp(lower_transport, "TCP"))
604             th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
605         else
606             th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;
607
608         if (*p == ';')
609             p++;
610         /* get each parameter */
611         while (*p != '\0' && *p != ',') {
612             get_word_sep(parameter, sizeof(parameter), "=;,", &p);
613             if (!strcmp(parameter, "port")) {
614                 if (*p == '=') {
615                     p++;
616                     rtsp_parse_range(&th->port_min, &th->port_max, &p);
617                 }
618             } else if (!strcmp(parameter, "client_port")) {
619                 if (*p == '=') {
620                     p++;
621                     rtsp_parse_range(&th->client_port_min,
622                                      &th->client_port_max, &p);
623                 }
624             } else if (!strcmp(parameter, "server_port")) {
625                 if (*p == '=') {
626                     p++;
627                     rtsp_parse_range(&th->server_port_min,
628                                      &th->server_port_max, &p);
629                 }
630             } else if (!strcmp(parameter, "interleaved")) {
631                 if (*p == '=') {
632                     p++;
633                     rtsp_parse_range(&th->interleaved_min,
634                                      &th->interleaved_max, &p);
635                 }
636             } else if (!strcmp(parameter, "multicast")) {
637                 if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP)
638                     th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
639             } else if (!strcmp(parameter, "ttl")) {
640                 if (*p == '=') {
641                     p++;
642                     th->ttl = strtol(p, (char **)&p, 10);
643                 }
644             } else if (!strcmp(parameter, "destination")) {
645                 struct in_addr ipaddr;
646
647                 if (*p == '=') {
648                     p++;
649                     get_word_sep(buf, sizeof(buf), ";,", &p);
650                     if (inet_aton(buf, &ipaddr))
651                         th->destination = ntohl(ipaddr.s_addr);
652                 }
653             }
654             while (*p != ';' && *p != '\0' && *p != ',')
655                 p++;
656             if (*p == ';')
657                 p++;
658         }
659         if (*p == ',')
660             p++;
661
662         reply->nb_transports++;
663     }
664 }
665
666 void rtsp_parse_line(RTSPMessageHeader *reply, const char *buf)
667 {
668     const char *p;
669
670     /* NOTE: we do case independent match for broken servers */
671     p = buf;
672     if (av_stristart(p, "Session:", &p)) {
673         get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
674     } else if (av_stristart(p, "Content-Length:", &p)) {
675         reply->content_length = strtol(p, NULL, 10);
676     } else if (av_stristart(p, "Transport:", &p)) {
677         rtsp_parse_transport(reply, p);
678     } else if (av_stristart(p, "CSeq:", &p)) {
679         reply->seq = strtol(p, NULL, 10);
680     } else if (av_stristart(p, "Range:", &p)) {
681         rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
682     } else if (av_stristart(p, "RealChallenge1:", &p)) {
683         skip_spaces(&p);
684         av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
685     } else if (av_stristart(p, "Server:", &p)) {
686         skip_spaces(&p);
687         av_strlcpy(reply->server, p, sizeof(reply->server));
688     }
689 }
690
691 static int url_readbuf(URLContext *h, unsigned char *buf, int size)
692 {
693     int ret, len;
694
695     len = 0;
696     while (len < size) {
697         ret = url_read(h, buf+len, size-len);
698         if (ret < 1)
699             return ret;
700         len += ret;
701     }
702     return len;
703 }
704
705 /* skip a RTP/TCP interleaved packet */
706 static void rtsp_skip_packet(AVFormatContext *s)
707 {
708     RTSPState *rt = s->priv_data;
709     int ret, len, len1;
710     uint8_t buf[1024];
711
712     ret = url_readbuf(rt->rtsp_hd, buf, 3);
713     if (ret != 3)
714         return;
715     len = AV_RB16(buf + 1);
716 #ifdef DEBUG
717     printf("skipping RTP packet len=%d\n", len);
718 #endif
719     /* skip payload */
720     while (len > 0) {
721         len1 = len;
722         if (len1 > sizeof(buf))
723             len1 = sizeof(buf);
724         ret = url_readbuf(rt->rtsp_hd, buf, len1);
725         if (ret != len1)
726             return;
727         len -= len1;
728     }
729 }
730
731 /**
732  * Read a RTSP message from the server, or prepare to read data
733  * packets if we're reading data interleaved over the TCP/RTSP
734  * connection as well.
735  *
736  * @param s RTSP demuxer context
737  * @param reply pointer where the RTSP message header will be stored
738  * @param content_ptr pointer where the RTSP message body, if any, will
739  *                    be stored (length is in \p reply)
740  * @param return_on_interleaved_data whether the function may return if we
741  *                   encounter a data marker ('$'), which precedes data
742  *                   packets over interleaved TCP/RTSP connections. If this
743  *                   is set, this function will return 1 after encountering
744  *                   a '$'. If it is not set, the function will skip any
745  *                   data packets (if they are encountered), until a reply
746  *                   has been fully parsed. If no more data is available
747  *                   without parsing a reply, it will return an error.
748  *
749  * @returns 1 if a data packets is ready to be received, -1 on error,
750  *          and 0 on success.
751  */
752 static int
753 rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
754                  unsigned char **content_ptr, int return_on_interleaved_data)
755 {
756     RTSPState *rt = s->priv_data;
757     char buf[4096], buf1[1024], *q;
758     unsigned char ch;
759     const char *p;
760     int ret, content_length, line_count = 0;
761     unsigned char *content = NULL;
762
763     memset(reply, 0, sizeof(*reply));
764
765     /* parse reply (XXX: use buffers) */
766     rt->last_reply[0] = '\0';
767     for(;;) {
768         q = buf;
769         for(;;) {
770             ret = url_readbuf(rt->rtsp_hd, &ch, 1);
771 #ifdef DEBUG_RTP_TCP
772             printf("ret=%d c=%02x [%c]\n", ret, ch, ch);
773 #endif
774             if (ret != 1)
775                 return -1;
776             if (ch == '\n')
777                 break;
778             if (ch == '$') {
779                 /* XXX: only parse it if first char on line ? */
780                 if (return_on_interleaved_data) {
781                     return 1;
782                 } else
783                 rtsp_skip_packet(s);
784             } else if (ch != '\r') {
785                 if ((q - buf) < sizeof(buf) - 1)
786                     *q++ = ch;
787             }
788         }
789         *q = '\0';
790 #ifdef DEBUG
791         printf("line='%s'\n", buf);
792 #endif
793         /* test if last line */
794         if (buf[0] == '\0')
795             break;
796         p = buf;
797         if (line_count == 0) {
798             /* get reply code */
799             get_word(buf1, sizeof(buf1), &p);
800             get_word(buf1, sizeof(buf1), &p);
801             reply->status_code = atoi(buf1);
802         } else {
803             rtsp_parse_line(reply, p);
804             av_strlcat(rt->last_reply, p,    sizeof(rt->last_reply));
805             av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
806         }
807         line_count++;
808     }
809
810     if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0')
811         av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));
812
813     content_length = reply->content_length;
814     if (content_length > 0) {
815         /* leave some room for a trailing '\0' (useful for simple parsing) */
816         content = av_malloc(content_length + 1);
817         (void)url_readbuf(rt->rtsp_hd, content, content_length);
818         content[content_length] = '\0';
819     }
820     if (content_ptr)
821         *content_ptr = content;
822     else
823         av_free(content);
824
825     return 0;
826 }
827
828 static void rtsp_send_cmd(AVFormatContext *s,
829                           const char *cmd, RTSPMessageHeader *reply,
830                           unsigned char **content_ptr)
831 {
832     RTSPState *rt = s->priv_data;
833     char buf[4096], buf1[1024];
834
835     rt->seq++;
836     av_strlcpy(buf, cmd, sizeof(buf));
837     snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq);
838     av_strlcat(buf, buf1, sizeof(buf));
839     if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) {
840         snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id);
841         av_strlcat(buf, buf1, sizeof(buf));
842     }
843     av_strlcat(buf, "\r\n", sizeof(buf));
844 #ifdef DEBUG
845     printf("Sending:\n%s--\n", buf);
846 #endif
847     url_write(rt->rtsp_hd, buf, strlen(buf));
848
849     rtsp_read_reply(s, reply, content_ptr, 0);
850 }
851
852
853 /* close and free RTSP streams */
854 static void rtsp_close_streams(RTSPState *rt)
855 {
856     int i;
857     RTSPStream *rtsp_st;
858
859     for(i=0;i<rt->nb_rtsp_streams;i++) {
860         rtsp_st = rt->rtsp_streams[i];
861         if (rtsp_st) {
862             if (rtsp_st->transport_priv) {
863                 if (rt->transport == RTSP_TRANSPORT_RDT)
864                     ff_rdt_parse_close(rtsp_st->transport_priv);
865                 else
866                     rtp_parse_close(rtsp_st->transport_priv);
867             }
868             if (rtsp_st->rtp_handle)
869                 url_close(rtsp_st->rtp_handle);
870             if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
871                 rtsp_st->dynamic_handler->close(rtsp_st->dynamic_protocol_context);
872         }
873     }
874     av_free(rt->rtsp_streams);
875     if (rt->asf_ctx) {
876         av_close_input_stream (rt->asf_ctx);
877         rt->asf_ctx = NULL;
878     }
879 }
880
881 static int
882 rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
883 {
884     RTSPState *rt = s->priv_data;
885     AVStream *st = NULL;
886
887     /* open the RTP context */
888     if (rtsp_st->stream_index >= 0)
889         st = s->streams[rtsp_st->stream_index];
890     if (!st)
891         s->ctx_flags |= AVFMTCTX_NOHEADER;
892
893     if (rt->transport == RTSP_TRANSPORT_RDT)
894         rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
895                                             rtsp_st->dynamic_protocol_context,
896                                             rtsp_st->dynamic_handler);
897     else
898         rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle,
899                                          rtsp_st->sdp_payload_type,
900                                          &rtsp_st->rtp_payload_data);
901
902     if (!rtsp_st->transport_priv) {
903          return AVERROR(ENOMEM);
904     } else if (rt->transport != RTSP_TRANSPORT_RDT) {
905         if(rtsp_st->dynamic_handler) {
906             rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
907                                            rtsp_st->dynamic_protocol_context,
908                                            rtsp_st->dynamic_handler);
909         }
910     }
911
912     return 0;
913 }
914
915 /**
916  * @returns 0 on success, <0 on error, 1 if protocol is unavailable.
917  */
918 static int
919 make_setup_request (AVFormatContext *s, const char *host, int port,
920                     int lower_transport, const char *real_challenge)
921 {
922     RTSPState *rt = s->priv_data;
923     int rtx, j, i, err, interleave = 0;
924     RTSPStream *rtsp_st;
925     RTSPMessageHeader reply1, *reply = &reply1;
926     char cmd[2048];
927     const char *trans_pref;
928
929     if (rt->transport == RTSP_TRANSPORT_RDT)
930         trans_pref = "x-pn-tng";
931     else
932         trans_pref = "RTP/AVP";
933
934     /* for each stream, make the setup request */
935     /* XXX: we assume the same server is used for the control of each
936        RTSP stream */
937
938     for(j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
939         char transport[2048];
940
941         /**
942          * WMS serves all UDP data over a single connection, the RTX, which
943          * isn't necessarily the first in the SDP but has to be the first
944          * to be set up, else the second/third SETUP will fail with a 461.
945          */
946         if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
947              rt->server_type == RTSP_SERVER_WMS) {
948             if (i == 0) {
949                 /* rtx first */
950                 for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) {
951                     int len = strlen(rt->rtsp_streams[rtx]->control_url);
952                     if (len >= 4 &&
953                         !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4, "/rtx"))
954                         break;
955                 }
956                 if (rtx == rt->nb_rtsp_streams)
957                     return -1; /* no RTX found */
958                 rtsp_st = rt->rtsp_streams[rtx];
959             } else
960                 rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];
961         } else
962             rtsp_st = rt->rtsp_streams[i];
963
964         /* RTP/UDP */
965         if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
966             char buf[256];
967
968             if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
969                 port = reply->transports[0].client_port_min;
970                 goto have_port;
971             }
972
973             /* first try in specified port range */
974             if (RTSP_RTP_PORT_MIN != 0) {
975                 while(j <= RTSP_RTP_PORT_MAX) {
976                     snprintf(buf, sizeof(buf), "rtp://%s?localport=%d", host, j);
977                     j += 2; /* we will use two port by rtp stream (rtp and rtcp) */
978                     if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) {
979                         goto rtp_opened;
980                     }
981                 }
982             }
983
984 /*            then try on any port
985 **            if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
986 **                err = AVERROR_INVALIDDATA;
987 **                goto fail;
988 **            }
989 */
990
991         rtp_opened:
992             port = rtp_get_local_port(rtsp_st->rtp_handle);
993         have_port:
994             snprintf(transport, sizeof(transport) - 1,
995                      "%s/UDP;", trans_pref);
996             if (rt->server_type != RTSP_SERVER_REAL)
997                 av_strlcat(transport, "unicast;", sizeof(transport));
998             av_strlcatf(transport, sizeof(transport),
999                      "client_port=%d", port);
1000             if (rt->transport == RTSP_TRANSPORT_RTP &&
1001                 !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1002                 av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
1003         }
1004
1005         /* RTP/TCP */
1006         else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1007             /** For WMS streams, the application streams are only used for
1008              * UDP. When trying to set it up for TCP streams, the server
1009              * will return an error. Therefore, we skip those streams. */
1010             if (rt->server_type == RTSP_SERVER_WMS &&
1011                 s->streams[rtsp_st->stream_index]->codec->codec_type == CODEC_TYPE_DATA)
1012                 continue;
1013             snprintf(transport, sizeof(transport) - 1,
1014                      "%s/TCP;", trans_pref);
1015             if (rt->server_type == RTSP_SERVER_WMS)
1016                 av_strlcat(transport, "unicast;", sizeof(transport));
1017             av_strlcatf(transport, sizeof(transport),
1018                         "interleaved=%d-%d",
1019                         interleave, interleave + 1);
1020             interleave += 2;
1021         }
1022
1023         else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
1024             snprintf(transport, sizeof(transport) - 1,
1025                      "%s/UDP;multicast", trans_pref);
1026         }
1027         if (rt->server_type == RTSP_SERVER_REAL ||
1028             rt->server_type == RTSP_SERVER_WMS)
1029             av_strlcat(transport, ";mode=play", sizeof(transport));
1030         snprintf(cmd, sizeof(cmd),
1031                  "SETUP %s RTSP/1.0\r\n"
1032                  "Transport: %s\r\n",
1033                  rtsp_st->control_url, transport);
1034         if (i == 0 && rt->server_type == RTSP_SERVER_REAL) {
1035             char real_res[41], real_csum[9];
1036             ff_rdt_calc_response_and_checksum(real_res, real_csum,
1037                                               real_challenge);
1038             av_strlcatf(cmd, sizeof(cmd),
1039                         "If-Match: %s\r\n"
1040                         "RealChallenge2: %s, sd=%s\r\n",
1041                         rt->session_id, real_res, real_csum);
1042         }
1043         rtsp_send_cmd(s, cmd, reply, NULL);
1044         if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
1045             err = 1;
1046             goto fail;
1047         } else if (reply->status_code != RTSP_STATUS_OK ||
1048                    reply->nb_transports != 1) {
1049             err = AVERROR_INVALIDDATA;
1050             goto fail;
1051         }
1052
1053         /* XXX: same protocol for all streams is required */
1054         if (i > 0) {
1055             if (reply->transports[0].lower_transport != rt->lower_transport ||
1056                 reply->transports[0].transport != rt->transport) {
1057                 err = AVERROR_INVALIDDATA;
1058                 goto fail;
1059             }
1060         } else {
1061             rt->lower_transport = reply->transports[0].lower_transport;
1062             rt->transport = reply->transports[0].transport;
1063         }
1064
1065         /* close RTP connection if not choosen */
1066         if (reply->transports[0].lower_transport != RTSP_LOWER_TRANSPORT_UDP &&
1067             (lower_transport == RTSP_LOWER_TRANSPORT_UDP)) {
1068             url_close(rtsp_st->rtp_handle);
1069             rtsp_st->rtp_handle = NULL;
1070         }
1071
1072         switch(reply->transports[0].lower_transport) {
1073         case RTSP_LOWER_TRANSPORT_TCP:
1074             rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
1075             rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
1076             break;
1077
1078         case RTSP_LOWER_TRANSPORT_UDP:
1079             {
1080                 char url[1024];
1081
1082                 /* XXX: also use address if specified */
1083                 snprintf(url, sizeof(url), "rtp://%s:%d",
1084                          host, reply->transports[0].server_port_min);
1085                 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1086                     rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
1087                     err = AVERROR_INVALIDDATA;
1088                     goto fail;
1089                 }
1090             }
1091             break;
1092         case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
1093             {
1094                 char url[1024];
1095                 struct in_addr in;
1096
1097                 in.s_addr = htonl(reply->transports[0].destination);
1098                 snprintf(url, sizeof(url), "rtp://%s:%d?ttl=%d",
1099                          inet_ntoa(in),
1100                          reply->transports[0].port_min,
1101                          reply->transports[0].ttl);
1102                 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1103                     err = AVERROR_INVALIDDATA;
1104                     goto fail;
1105                 }
1106             }
1107             break;
1108         }
1109
1110         if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1111             goto fail;
1112     }
1113
1114     if (rt->server_type == RTSP_SERVER_REAL)
1115         rt->need_subscription = 1;
1116
1117     return 0;
1118
1119 fail:
1120     for (i=0; i<rt->nb_rtsp_streams; i++) {
1121         if (rt->rtsp_streams[i]->rtp_handle) {
1122             url_close(rt->rtsp_streams[i]->rtp_handle);
1123             rt->rtsp_streams[i]->rtp_handle = NULL;
1124         }
1125     }
1126     return err;
1127 }
1128
1129 static int rtsp_read_header(AVFormatContext *s,
1130                             AVFormatParameters *ap)
1131 {
1132     RTSPState *rt = s->priv_data;
1133     char host[1024], path[1024], tcpname[1024], cmd[2048], *option_list, *option;
1134     URLContext *rtsp_hd;
1135     int port, ret, err;
1136     RTSPMessageHeader reply1, *reply = &reply1;
1137     unsigned char *content = NULL;
1138     int lower_transport_mask = 0;
1139     char real_challenge[64];
1140
1141     /* extract hostname and port */
1142     url_split(NULL, 0, NULL, 0,
1143               host, sizeof(host), &port, path, sizeof(path), s->filename);
1144     if (port < 0)
1145         port = RTSP_DEFAULT_PORT;
1146
1147     /* search for options */
1148     option_list = strchr(path, '?');
1149     if (option_list) {
1150         /* remove the options from the path */
1151         *option_list++ = 0;
1152         while(option_list) {
1153             /* move the option pointer */
1154             option = option_list;
1155             option_list = strchr(option_list, '&');
1156             if (option_list)
1157                 *(option_list++) = 0;
1158             /* handle the options */
1159             if (strcmp(option, "udp") == 0)
1160                 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP);
1161             else if (strcmp(option, "multicast") == 0)
1162                 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
1163             else if (strcmp(option, "tcp") == 0)
1164                 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_TCP);
1165         }
1166     }
1167
1168     if (!lower_transport_mask)
1169         lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1170
1171     /* open the tcp connexion */
1172     snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port);
1173     if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0)
1174         return AVERROR(EIO);
1175     rt->rtsp_hd = rtsp_hd;
1176     rt->seq = 0;
1177
1178     /* request options supported by the server; this also detects server type */
1179     for (rt->server_type = RTSP_SERVER_RTP;;) {
1180         snprintf(cmd, sizeof(cmd),
1181                  "OPTIONS %s RTSP/1.0\r\n", s->filename);
1182         if (rt->server_type == RTSP_SERVER_REAL)
1183             av_strlcat(cmd,
1184                        /**
1185                         * The following entries are required for proper
1186                         * streaming from a Realmedia server. They are
1187                         * interdependent in some way although we currently
1188                         * don't quite understand how. Values were copied
1189                         * from mplayer SVN r23589.
1190                         * @param CompanyID is a 16-byte ID in base64
1191                         * @param ClientChallenge is a 16-byte ID in hex
1192                         */
1193                        "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
1194                        "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
1195                        "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
1196                        "GUID: 00000000-0000-0000-0000-000000000000\r\n",
1197                        sizeof(cmd));
1198         rtsp_send_cmd(s, cmd, reply, NULL);
1199         if (reply->status_code != RTSP_STATUS_OK) {
1200             err = AVERROR_INVALIDDATA;
1201             goto fail;
1202         }
1203
1204         /* detect server type if not standard-compliant RTP */
1205         if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
1206             rt->server_type = RTSP_SERVER_REAL;
1207             continue;
1208         } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
1209             rt->server_type = RTSP_SERVER_WMS;
1210         } else if (rt->server_type == RTSP_SERVER_REAL) {
1211             strcpy(real_challenge, reply->real_challenge);
1212         }
1213         break;
1214     }
1215
1216     /* describe the stream */
1217     snprintf(cmd, sizeof(cmd),
1218              "DESCRIBE %s RTSP/1.0\r\n"
1219              "Accept: application/sdp\r\n",
1220              s->filename);
1221     if (rt->server_type == RTSP_SERVER_REAL) {
1222         /**
1223          * The Require: attribute is needed for proper streaming from
1224          * Realmedia servers.
1225          */
1226         av_strlcat(cmd,
1227                    "Require: com.real.retain-entity-for-setup\r\n",
1228                    sizeof(cmd));
1229     }
1230     rtsp_send_cmd(s, cmd, reply, &content);
1231     if (!content) {
1232         err = AVERROR_INVALIDDATA;
1233         goto fail;
1234     }
1235     if (reply->status_code != RTSP_STATUS_OK) {
1236         err = AVERROR_INVALIDDATA;
1237         goto fail;
1238     }
1239
1240     /* now we got the SDP description, we parse it */
1241     ret = sdp_parse(s, (const char *)content);
1242     av_freep(&content);
1243     if (ret < 0) {
1244         err = AVERROR_INVALIDDATA;
1245         goto fail;
1246     }
1247
1248     do {
1249         int lower_transport = ff_log2_tab[lower_transport_mask & ~(lower_transport_mask - 1)];
1250
1251         err = make_setup_request(s, host, port, lower_transport,
1252                                  rt->server_type == RTSP_SERVER_REAL ?
1253                                      real_challenge : NULL);
1254         if (err < 0)
1255             goto fail;
1256         lower_transport_mask &= ~(1 << lower_transport);
1257         if (lower_transport_mask == 0 && err == 1) {
1258             err = AVERROR(FF_NETERROR(EPROTONOSUPPORT));
1259             goto fail;
1260         }
1261     } while (err);
1262
1263     rt->state = RTSP_STATE_IDLE;
1264     rt->seek_timestamp = 0; /* default is to start stream at position
1265                                zero */
1266     if (ap->initial_pause) {
1267         /* do not start immediately */
1268     } else {
1269         if (rtsp_read_play(s) < 0) {
1270             err = AVERROR_INVALIDDATA;
1271             goto fail;
1272         }
1273     }
1274     return 0;
1275  fail:
1276     rtsp_close_streams(rt);
1277     av_freep(&content);
1278     url_close(rt->rtsp_hd);
1279     return err;
1280 }
1281
1282 static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1283                            uint8_t *buf, int buf_size)
1284 {
1285     RTSPState *rt = s->priv_data;
1286     int id, len, i, ret;
1287     RTSPStream *rtsp_st;
1288
1289 #ifdef DEBUG_RTP_TCP
1290     printf("tcp_read_packet:\n");
1291 #endif
1292  redo:
1293     for(;;) {
1294         RTSPMessageHeader reply;
1295
1296         ret = rtsp_read_reply(s, &reply, NULL, 1);
1297         if (ret == -1)
1298             return -1;
1299         if (ret == 1) /* received '$' */
1300             break;
1301         /* XXX: parse message */
1302     }
1303     ret = url_readbuf(rt->rtsp_hd, buf, 3);
1304     if (ret != 3)
1305         return -1;
1306     id = buf[0];
1307     len = AV_RB16(buf + 1);
1308 #ifdef DEBUG_RTP_TCP
1309     printf("id=%d len=%d\n", id, len);
1310 #endif
1311     if (len > buf_size || len < 12)
1312         goto redo;
1313     /* get the data */
1314     ret = url_readbuf(rt->rtsp_hd, buf, len);
1315     if (ret != len)
1316         return -1;
1317     if (rt->transport == RTSP_TRANSPORT_RDT &&
1318         ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
1319         return -1;
1320
1321     /* find the matching stream */
1322     for(i = 0; i < rt->nb_rtsp_streams; i++) {
1323         rtsp_st = rt->rtsp_streams[i];
1324         if (id >= rtsp_st->interleaved_min &&
1325             id <= rtsp_st->interleaved_max)
1326             goto found;
1327     }
1328     goto redo;
1329  found:
1330     *prtsp_st = rtsp_st;
1331     return len;
1332 }
1333
1334 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1335                            uint8_t *buf, int buf_size)
1336 {
1337     RTSPState *rt = s->priv_data;
1338     RTSPStream *rtsp_st;
1339     fd_set rfds;
1340     int fd, fd_max, n, i, ret, tcp_fd;
1341     struct timeval tv;
1342
1343     for(;;) {
1344         if (url_interrupt_cb())
1345             return AVERROR(EINTR);
1346         FD_ZERO(&rfds);
1347         tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
1348         FD_SET(tcp_fd, &rfds);
1349         for(i = 0; i < rt->nb_rtsp_streams; i++) {
1350             rtsp_st = rt->rtsp_streams[i];
1351             if (rtsp_st->rtp_handle) {
1352                 /* currently, we cannot probe RTCP handle because of
1353                  * blocking restrictions */
1354                 fd = url_get_file_handle(rtsp_st->rtp_handle);
1355                 if (fd > fd_max)
1356                     fd_max = fd;
1357                 FD_SET(fd, &rfds);
1358             }
1359         }
1360         tv.tv_sec = 0;
1361         tv.tv_usec = 100 * 1000;
1362         n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
1363         if (n > 0) {
1364             for(i = 0; i < rt->nb_rtsp_streams; i++) {
1365                 rtsp_st = rt->rtsp_streams[i];
1366                 if (rtsp_st->rtp_handle) {
1367                     fd = url_get_file_handle(rtsp_st->rtp_handle);
1368                     if (FD_ISSET(fd, &rfds)) {
1369                         ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
1370                         if (ret > 0) {
1371                             *prtsp_st = rtsp_st;
1372                             return ret;
1373                         }
1374                     }
1375                 }
1376             }
1377             if (FD_ISSET(tcp_fd, &rfds)) {
1378                 RTSPMessageHeader reply;
1379
1380                 rtsp_read_reply(s, &reply, NULL, 0);
1381                 /* XXX: parse message */
1382             }
1383         }
1384     }
1385 }
1386
1387 static int rtsp_read_packet(AVFormatContext *s,
1388                             AVPacket *pkt)
1389 {
1390     RTSPState *rt = s->priv_data;
1391     RTSPStream *rtsp_st;
1392     int ret, len;
1393     uint8_t buf[10 * RTP_MAX_PACKET_LENGTH];
1394
1395     if (rt->server_type == RTSP_SERVER_REAL) {
1396         int i;
1397         RTSPMessageHeader reply1, *reply = &reply1;
1398         enum AVDiscard cache[MAX_STREAMS];
1399         char cmd[1024];
1400
1401         for (i = 0; i < s->nb_streams; i++)
1402             cache[i] = s->streams[i]->discard;
1403
1404         if (!rt->need_subscription) {
1405             if (memcmp (cache, rt->real_setup_cache,
1406                         sizeof(enum AVDiscard) * s->nb_streams)) {
1407                 av_strlcatf(cmd, sizeof(cmd),
1408                             "SET_PARAMETER %s RTSP/1.0\r\n"
1409                             "Unsubscribe: %s\r\n",
1410                             s->filename, rt->last_subscription);
1411                 rtsp_send_cmd(s, cmd, reply, NULL);
1412                 if (reply->status_code != RTSP_STATUS_OK)
1413                     return AVERROR_INVALIDDATA;
1414                 rt->need_subscription = 1;
1415             }
1416         }
1417
1418         if (rt->need_subscription) {
1419             int r, rule_nr, first = 1;
1420
1421             memcpy(rt->real_setup_cache, cache,
1422                    sizeof(enum AVDiscard) * s->nb_streams);
1423             rt->last_subscription[0] = 0;
1424
1425             snprintf(cmd, sizeof(cmd),
1426                      "SET_PARAMETER %s RTSP/1.0\r\n"
1427                      "Subscribe: ",
1428                      s->filename);
1429             for (i = 0; i < rt->nb_rtsp_streams; i++) {
1430                 rule_nr = 0;
1431                 for (r = 0; r < s->nb_streams; r++) {
1432                     if (s->streams[r]->priv_data == rt->rtsp_streams[i]) {
1433                         if (s->streams[r]->discard != AVDISCARD_ALL) {
1434                             if (!first)
1435                                 av_strlcat(rt->last_subscription, ",",
1436                                            sizeof(rt->last_subscription));
1437                             ff_rdt_subscribe_rule(
1438                                 rt->last_subscription,
1439                                 sizeof(rt->last_subscription), i, rule_nr);
1440                             first = 0;
1441                         }
1442                         rule_nr++;
1443                     }
1444                 }
1445             }
1446             av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
1447             rtsp_send_cmd(s, cmd, reply, NULL);
1448             if (reply->status_code != RTSP_STATUS_OK)
1449                 return AVERROR_INVALIDDATA;
1450             rt->need_subscription = 0;
1451
1452             if (rt->state == RTSP_STATE_PLAYING)
1453                 rtsp_read_play (s);
1454         }
1455     }
1456
1457     /* get next frames from the same RTP packet */
1458     if (rt->cur_transport_priv) {
1459         if (rt->transport == RTSP_TRANSPORT_RDT)
1460             ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1461         else
1462             ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1463         if (ret == 0) {
1464             rt->cur_transport_priv = NULL;
1465             return 0;
1466         } else if (ret == 1) {
1467             return 0;
1468         } else {
1469             rt->cur_transport_priv = NULL;
1470         }
1471     }
1472
1473     /* read next RTP packet */
1474  redo:
1475     switch(rt->lower_transport) {
1476     default:
1477     case RTSP_LOWER_TRANSPORT_TCP:
1478         len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf));
1479         break;
1480     case RTSP_LOWER_TRANSPORT_UDP:
1481     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
1482         len = udp_read_packet(s, &rtsp_st, buf, sizeof(buf));
1483         if (len >=0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
1484             rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
1485         break;
1486     }
1487     if (len < 0)
1488         return len;
1489     if (rt->transport == RTSP_TRANSPORT_RDT)
1490         ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
1491     else
1492         ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
1493     if (ret < 0)
1494         goto redo;
1495     if (ret == 1) {
1496         /* more packets may follow, so we save the RTP context */
1497         rt->cur_transport_priv = rtsp_st->transport_priv;
1498     }
1499     return 0;
1500 }
1501
1502 static int rtsp_read_play(AVFormatContext *s)
1503 {
1504     RTSPState *rt = s->priv_data;
1505     RTSPMessageHeader reply1, *reply = &reply1;
1506     char cmd[1024];
1507
1508     av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
1509
1510     if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
1511         if (rt->state == RTSP_STATE_PAUSED) {
1512             snprintf(cmd, sizeof(cmd),
1513                      "PLAY %s RTSP/1.0\r\n",
1514                      s->filename);
1515         } else {
1516             snprintf(cmd, sizeof(cmd),
1517                      "PLAY %s RTSP/1.0\r\n"
1518                      "Range: npt=%0.3f-\r\n",
1519                      s->filename,
1520                      (double)rt->seek_timestamp / AV_TIME_BASE);
1521         }
1522         rtsp_send_cmd(s, cmd, reply, NULL);
1523         if (reply->status_code != RTSP_STATUS_OK) {
1524             return -1;
1525         }
1526     }
1527     rt->state = RTSP_STATE_PLAYING;
1528     return 0;
1529 }
1530
1531 /* pause the stream */
1532 static int rtsp_read_pause(AVFormatContext *s)
1533 {
1534     RTSPState *rt = s->priv_data;
1535     RTSPMessageHeader reply1, *reply = &reply1;
1536     char cmd[1024];
1537
1538     rt = s->priv_data;
1539
1540     if (rt->state != RTSP_STATE_PLAYING)
1541         return 0;
1542     else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
1543         snprintf(cmd, sizeof(cmd),
1544                  "PAUSE %s RTSP/1.0\r\n",
1545                  s->filename);
1546         rtsp_send_cmd(s, cmd, reply, NULL);
1547         if (reply->status_code != RTSP_STATUS_OK) {
1548             return -1;
1549         }
1550     }
1551     rt->state = RTSP_STATE_PAUSED;
1552     return 0;
1553 }
1554
1555 static int rtsp_read_seek(AVFormatContext *s, int stream_index,
1556                           int64_t timestamp, int flags)
1557 {
1558     RTSPState *rt = s->priv_data;
1559
1560     rt->seek_timestamp = av_rescale_q(timestamp, s->streams[stream_index]->time_base, AV_TIME_BASE_Q);
1561     switch(rt->state) {
1562     default:
1563     case RTSP_STATE_IDLE:
1564         break;
1565     case RTSP_STATE_PLAYING:
1566         if (rtsp_read_play(s) != 0)
1567             return -1;
1568         break;
1569     case RTSP_STATE_PAUSED:
1570         rt->state = RTSP_STATE_IDLE;
1571         break;
1572     }
1573     return 0;
1574 }
1575
1576 static int rtsp_read_close(AVFormatContext *s)
1577 {
1578     RTSPState *rt = s->priv_data;
1579     RTSPMessageHeader reply1, *reply = &reply1;
1580     char cmd[1024];
1581
1582 #if 0
1583     /* NOTE: it is valid to flush the buffer here */
1584     if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1585         url_fclose(&rt->rtsp_gb);
1586     }
1587 #endif
1588     snprintf(cmd, sizeof(cmd),
1589              "TEARDOWN %s RTSP/1.0\r\n",
1590              s->filename);
1591     rtsp_send_cmd(s, cmd, reply, NULL);
1592
1593     rtsp_close_streams(rt);
1594     url_close(rt->rtsp_hd);
1595     return 0;
1596 }
1597
1598 #if CONFIG_RTSP_DEMUXER
1599 AVInputFormat rtsp_demuxer = {
1600     "rtsp",
1601     NULL_IF_CONFIG_SMALL("RTSP input format"),
1602     sizeof(RTSPState),
1603     rtsp_probe,
1604     rtsp_read_header,
1605     rtsp_read_packet,
1606     rtsp_read_close,
1607     rtsp_read_seek,
1608     .flags = AVFMT_NOFILE,
1609     .read_play = rtsp_read_play,
1610     .read_pause = rtsp_read_pause,
1611 };
1612 #endif
1613
1614 static int sdp_probe(AVProbeData *p1)
1615 {
1616     const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
1617
1618     /* we look for a line beginning "c=IN IP4" */
1619     while (p < p_end && *p != '\0') {
1620         if (p + sizeof("c=IN IP4") - 1 < p_end && av_strstart(p, "c=IN IP4", NULL))
1621             return AVPROBE_SCORE_MAX / 2;
1622
1623         while(p < p_end - 1 && *p != '\n') p++;
1624         if (++p >= p_end)
1625             break;
1626         if (*p == '\r')
1627             p++;
1628     }
1629     return 0;
1630 }
1631
1632 #define SDP_MAX_SIZE 8192
1633
1634 static int sdp_read_header(AVFormatContext *s,
1635                            AVFormatParameters *ap)
1636 {
1637     RTSPState *rt = s->priv_data;
1638     RTSPStream *rtsp_st;
1639     int size, i, err;
1640     char *content;
1641     char url[1024];
1642
1643     /* read the whole sdp file */
1644     /* XXX: better loading */
1645     content = av_malloc(SDP_MAX_SIZE);
1646     size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1);
1647     if (size <= 0) {
1648         av_free(content);
1649         return AVERROR_INVALIDDATA;
1650     }
1651     content[size] ='\0';
1652
1653     sdp_parse(s, content);
1654     av_free(content);
1655
1656     /* open each RTP stream */
1657     for(i=0;i<rt->nb_rtsp_streams;i++) {
1658         rtsp_st = rt->rtsp_streams[i];
1659
1660         snprintf(url, sizeof(url), "rtp://%s:%d?localport=%d&ttl=%d",
1661                  inet_ntoa(rtsp_st->sdp_ip),
1662                  rtsp_st->sdp_port,
1663                  rtsp_st->sdp_port,
1664                  rtsp_st->sdp_ttl);
1665         if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1666             err = AVERROR_INVALIDDATA;
1667             goto fail;
1668         }
1669         if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1670             goto fail;
1671     }
1672     return 0;
1673  fail:
1674     rtsp_close_streams(rt);
1675     return err;
1676 }
1677
1678 static int sdp_read_packet(AVFormatContext *s,
1679                             AVPacket *pkt)
1680 {
1681     return rtsp_read_packet(s, pkt);
1682 }
1683
1684 static int sdp_read_close(AVFormatContext *s)
1685 {
1686     RTSPState *rt = s->priv_data;
1687     rtsp_close_streams(rt);
1688     return 0;
1689 }
1690
1691 #if CONFIG_SDP_DEMUXER
1692 AVInputFormat sdp_demuxer = {
1693     "sdp",
1694     NULL_IF_CONFIG_SMALL("SDP"),
1695     sizeof(RTSPState),
1696     sdp_probe,
1697     sdp_read_header,
1698     sdp_read_packet,
1699     sdp_read_close,
1700 };
1701 #endif
1702
1703 #if CONFIG_REDIR_DEMUXER
1704 /* dummy redirector format (used directly in av_open_input_file now) */
1705 static int redir_probe(AVProbeData *pd)
1706 {
1707     const char *p;
1708     p = pd->buf;
1709     skip_spaces(&p);
1710     if (av_strstart(p, "http://", NULL) ||
1711         av_strstart(p, "rtsp://", NULL))
1712         return AVPROBE_SCORE_MAX;
1713     return 0;
1714 }
1715
1716 static int redir_read_header(AVFormatContext *s, AVFormatParameters *ap)
1717 {
1718     char buf[4096], *q;
1719     int c;
1720     AVFormatContext *ic = NULL;
1721     ByteIOContext *f = s->pb;
1722
1723     /* parse each URL and try to open it */
1724     c = url_fgetc(f);
1725     while (c != URL_EOF) {
1726         /* skip spaces */
1727         for(;;) {
1728             if (!redir_isspace(c))
1729                 break;
1730             c = url_fgetc(f);
1731         }
1732         if (c == URL_EOF)
1733             break;
1734         /* record url */
1735         q = buf;
1736         for(;;) {
1737             if (c == URL_EOF || redir_isspace(c))
1738                 break;
1739             if ((q - buf) < sizeof(buf) - 1)
1740                 *q++ = c;
1741             c = url_fgetc(f);
1742         }
1743         *q = '\0';
1744         //printf("URL='%s'\n", buf);
1745         /* try to open the media file */
1746         if (av_open_input_file(&ic, buf, NULL, 0, NULL) == 0)
1747             break;
1748     }
1749     if (!ic)
1750         return AVERROR(EIO);
1751
1752     *s = *ic;
1753     url_fclose(f);
1754
1755     return 0;
1756 }
1757
1758 AVInputFormat redir_demuxer = {
1759     "redir",
1760     NULL_IF_CONFIG_SMALL("Redirector format"),
1761     0,
1762     redir_probe,
1763     redir_read_header,
1764     NULL,
1765     NULL,
1766 };
1767 #endif