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