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