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
34
35 #if HAVE_POLL_H
36 #include <poll.h>
37 #endif
43
52
53 /* Timeout values for socket poll, in ms,
54 * and read_packet(), in seconds */
55 #define POLL_TIMEOUT_MS 100
56 #define READ_PACKET_TIMEOUT_S 10
57 #define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS
58 #define SDP_MAX_SIZE 16384
59 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
60 #define DEFAULT_REORDERING_DELAY 100000
61
62 #define OFFSET(x) offsetof(RTSPState, x)
63 #define DEC AV_OPT_FLAG_DECODING_PARAM
64 #define ENC AV_OPT_FLAG_ENCODING_PARAM
65
66 #define RTSP_FLAG_OPTS(name, longname) \
67 { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
68 { "filter_src", "only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
69
70 #define RTSP_MEDIATYPE_OPTS(name, longname) \
71 { name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { .i64 = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1 }, INT_MIN, INT_MAX, DEC, "allowed_media_types" }, \
72 { "video", "Video", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_VIDEO}, 0, 0, DEC, "allowed_media_types" }, \
73 { "audio", "Audio", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_AUDIO}, 0, 0, DEC, "allowed_media_types" }, \
74 { "data", "Data", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_DATA}, 0, 0, DEC, "allowed_media_types" }, \
75 { "subtitle", "Subtitle", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_SUBTITLE}, 0, 0, DEC, "allowed_media_types" }
76
77 #define RTSP_REORDERING_OPTS() \
78 { "reorder_queue_size", "set number of packets to buffer for handling of reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC }
79
81 {
"initial_pause",
"do not start playing the stream immediately",
OFFSET(initial_pause),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1,
DEC },
83 {
"rtsp_transport",
"set RTSP transport protocols",
OFFSET(lower_transport_mask),
AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX,
DEC|
ENC,
"rtsp_transport" }, \
90 {
"prefer_tcp",
"try RTP via TCP first, if available", 0,
AV_OPT_TYPE_CONST, {.i64 =
RTSP_FLAG_PREFER_TCP}, 0, 0,
DEC|
ENC,
"rtsp_flags" },
94 {
"timeout",
"set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen)",
OFFSET(initial_timeout),
AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX,
DEC },
95 {
"stimeout",
"set timeout (in microseconds) of socket TCP I/O operations",
OFFSET(stimeout),
AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX,
DEC },
99 };
100
108 };
109
114 };
115
117 const char *sep, const char **pp)
118 {
119 const char *p;
120 char *q;
121
122 p = *pp;
125 while (!strchr(sep, *p) && *p != '0円') {
126 if ((q - buf) < buf_size - 1)
127 *q++ = *p;
128 p++;
129 }
130 if (buf_size > 0)
131 *q = '0円';
132 *pp = p;
133 }
134
136 const char **pp)
137 {
138 if (**pp == '/') (*pp)++;
140 }
141
143 {
145 }
146
147 /** Parse a string p in the form of Range:npt=xx-xx, and determine the start
148 * and end time.
149 * Used for seeking in the rtp stream.
150 */
152 {
154
157 return;
158
161
164 if (*p == '-') {
165 p++;
168 }
169 }
170
172 {
176 return -1;
177 memcpy(sock, ai->ai_addr,
FFMIN(
sizeof(*sock), ai->ai_addrlen));
179 return 0;
180 }
181
182 #if CONFIG_RTPDEC
185 {
187 if (!handler)
188 return;
189 if (codec)
192 if (st)
198 }
199 }
200
203 {
207 if (ret < 0) {
213 }
216 }
217 }
218 }
219
220 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
223 int payload_type, const char *p)
224 {
227 int i;
229 const char *c_name;
230
231 /* See if we can handle this kind of payload.
232 * The space should normally not be there but some Real streams or
233 * particular servers ("RealServer Version 6.1.3.970", see issue 1658)
234 * have a trailing space. */
237 /* We are in a standard case
238 * (from http://www.iana.org/assignments/rtp-parameters). */
240 }
241
245 init_rtp_handler(handler, rtsp_st, st);
246 /* If no dynamic handler was found, check with the list of standard
247 * allocated types, if such a stream for some reason happens to
248 * use a private payload type. This isn't handled in rtpdec.c, since
249 * the format name from the rtpmap line never is passed into rtpdec. */
252 }
253
257 else
258 c_name = "(null)";
259
261 i = atoi(buf);
267 if (i > 0) {
271 i = atoi(buf);
272 if (i > 0)
274 }
279 break;
282 if (i > 0)
284 break;
285 default:
286 break;
287 }
288 finalize_rtp_handler_init(s, rtsp_st, st);
289 return 0;
290 }
291
292 /* parse the attribute line from the fmtp a line of an sdp response. This
293 * is broken out as a function because it is used in rtp_h264.c, which is
294 * forthcoming. */
296 char *
value,
int value_size)
297 {
299 if (**p) {
301 if (**p == '=')
302 (*p)++;
304 if (**p == ';')
305 (*p)++;
306 return 1;
307 }
308 return 0;
309 }
310
311 typedef struct SDPParseState {
312 /* SDP only */
314 int default_ttl;
315 int skip_media; ///< set if an unknown m= line occurs
316 int nb_default_include_source_addrs; /**< Number of source-specific multicast include source IP address (from SDP content) */
317 struct RTSPSource **default_include_source_addrs;
/**< Source-specific multicast include source IP address (from SDP content) */
318 int nb_default_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP address (from SDP content) */
319 struct RTSPSource **default_exclude_source_addrs;
/**< Source-specific multicast exclude source IP address (from SDP content) */
320 int seen_rtpmap;
321 int seen_fmtp;
322 char delayed_fmtp[2048];
323 } SDPParseState;
324
325 static void copy_default_source_addrs(
struct RTSPSource **addrs,
int count,
327 {
329 int i;
330 for (i = 0; i <
count; i++) {
331 rtsp_src = addrs[i];
332 rtsp_src2 =
av_malloc(
sizeof(*rtsp_src2));
333 if (!rtsp_src2)
334 continue;
335 memcpy(rtsp_src2, rtsp_src, sizeof(*rtsp_src));
337 }
338 }
339
341 int payload_type,
const char *
line)
342 {
343 int i;
344
352 }
353 }
354 }
355
357 int letter, const char *buf)
358 {
360 char buf1[64], st_type[64];
361 const char *p;
363 int payload_type;
368 int ttl;
369
370 av_dlog(s,
"sdp: %c='%s'\n", letter, buf);
371
373 if (s1->skip_media && letter != 'm')
374 return;
375 switch (letter) {
376 case 'c':
378 if (strcmp(buf1, "IN") != 0)
379 return;
381 if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
382 return;
385 return;
386 ttl = 16;
387 if (*p == '/') {
388 p++;
390 ttl = atoi(buf1);
391 }
393 s1->default_ip = sdp_ip;
394 s1->default_ttl = ttl;
395 } else {
399 }
400 break;
401 case 's':
403 break;
404 case 'i':
407 break;
408 }
409 break;
410 case 'm':
411 /* new stream */
412 s1->skip_media = 0;
413 s1->seen_fmtp = 0;
414 s1->seen_rtpmap = 0;
416 get_word(st_type,
sizeof(st_type), &p);
417 if (!strcmp(st_type, "audio")) {
419 } else if (!strcmp(st_type, "video")) {
421 } else if (!strcmp(st_type, "application")) {
423 } else if (!strcmp(st_type, "text")) {
425 }
427 s1->skip_media = 1;
428 return;
429 }
431 if (!rtsp_st)
432 return;
435
436 rtsp_st->
sdp_ip = s1->default_ip;
437 rtsp_st->
sdp_ttl = s1->default_ttl;
438
439 copy_default_source_addrs(s1->default_include_source_addrs,
440 s1->nb_default_include_source_addrs,
443 copy_default_source_addrs(s1->default_exclude_source_addrs,
444 s1->nb_default_exclude_source_addrs,
447
448 get_word(buf1,
sizeof(buf1), &p);
/* port */
450
451 get_word(buf1,
sizeof(buf1), &p);
/* protocol */
452 if (!strcmp(buf1, "udp"))
454 else if (strstr(buf1, "/AVPF") || strstr(buf1, "/SAVPF"))
456
457 /* XXX: handle list of formats */
458 get_word(buf1,
sizeof(buf1), &p);
/* format list */
460
462 /* no corresponding stream */
464 if (CONFIG_RTPDEC && !rt->
ts)
466 } else {
470 init_rtp_handler(handler, rtsp_st,
NULL);
471 finalize_rtp_handler_init(s, rtsp_st,
NULL);
472 }
475 /* RTX stream, a stream that carries all the other actual
476 * audio/video streams. Don't expose this to the callers. */
477 } else {
479 if (!st)
480 return;
486 /* if standard payload type, we can find the codec right now */
491 /* Even static payload types may need a custom depacketizer */
494 init_rtp_handler(handler, rtsp_st, st);
495 finalize_rtp_handler_init(s, rtsp_st, st);
496 }
499 }
500 /* put a default control url */
503 break;
504 case 'a':
507 if (!strncmp(p, "rtsp://", 7))
510 } else {
511 char proto[32];
512 /* get the control url */
514
515 /* XXX: may need to add full url resolution */
518 if (proto[0] == '0円') {
519 /* relative control URL */
525 } else
528 }
530 /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
532 payload_type = atoi(buf1);
536 sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p);
537 }
538 s1->seen_rtpmap = 1;
539 if (s1->seen_fmtp) {
540 parse_fmtp(s, rt, payload_type, s1->delayed_fmtp);
541 }
544 // let dynamic protocol handlers have a stab at the line.
546 payload_type = atoi(buf1);
547 if (s1->seen_rtpmap) {
549 } else {
550 s1->seen_fmtp = 1;
551 av_strlcpy(s1->delayed_fmtp, buf,
sizeof(s1->delayed_fmtp));
552 }
555
556 // this is so that seeking on a streamed file can work.
559 /* AV_NOPTS_VALUE means live broadcast (and can't seek) */
569 }
570 } else
572 }
else if (
av_strstart(p,
"IsRealDataType:integer;",&p)) {
573 if (atoi(p) == 1)
575 }
else if (
av_strstart(p,
"SampleRate:integer;", &p) &&
580 // RFC 4568
582 get_word(buf1,
sizeof(buf1), &p);
// ignore tag
588 int exclude = 0;
590 if (strcmp(buf1, "incl") && strcmp(buf1, "excl"))
591 return;
592 exclude = !strcmp(buf1, "excl");
593
595 if (strcmp(buf1, "IN") != 0)
596 return;
598 if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6") && strcmp(buf1, "*"))
599 return;
600 // not checking that the destination address actually matches or is wildcard
602
603 while (*p != '0円') {
605 if (!rtsp_src)
606 return;
608 if (exclude) {
610 dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
611 } else {
614 }
615 } else {
617 dynarray_add(&s1->default_include_source_addrs, &s1->nb_default_include_source_addrs, rtsp_src);
618 } else {
621 }
622 }
623 }
624 } else {
629
632
638 }
639 }
640 break;
641 }
642 }
643
645 {
647 const char *p;
648 int letter, i;
649 /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
650 * contain long SDP lines containing complete ASF Headers (several
651 * kB) or arrays of MDPR (RM stream descriptor) headers plus
652 * "rulebooks" describing their properties. Therefore, the SDP line
653 * buffer is large.
654 *
655 * The Vorbis FMTP line can be up to 16KB - see xiph_parse_sdp_line
656 * in rtpdec_xiph.c. */
657 char buf[16384], *q;
658 SDPParseState sdp_parse_state = { { 0 } }, *s1 = &sdp_parse_state;
659
660 p = content;
661 for (;;) {
663 letter = *p;
664 if (letter == '0円')
665 break;
666 p++;
667 if (*p != '=')
668 goto next_line;
669 p++;
670 /* get the content */
672 while (*p != '\n' && *p != '\r' && *p != '0円') {
673 if ((q - buf) < sizeof(buf) - 1)
674 *q++ = *p;
675 p++;
676 }
677 *q = '0円';
678 sdp_parse_line(s, s1, letter, buf);
679 next_line:
680 while (*p != '\n' && *p != '0円')
681 p++;
682 if (*p == '\n')
683 p++;
684 }
685
686 for (i = 0; i < s1->nb_default_include_source_addrs; i++)
687 av_freep(&s1->default_include_source_addrs[i]);
688 av_freep(&s1->default_include_source_addrs);
689 for (i = 0; i < s1->nb_default_exclude_source_addrs; i++)
690 av_freep(&s1->default_exclude_source_addrs[i]);
691 av_freep(&s1->default_exclude_source_addrs);
692
695 return 0;
696 }
697 #endif /* CONFIG_RTPDEC */
698
700 {
702 int i;
703
706 if (!rtsp_st)
707 continue;
713 if (CONFIG_RTSP_MUXER && rtpctx->
pb && send_packets)
716 } else {
718 }
724 }
729 }
730 }
731
732 /* close and free RTSP streams */
734 {
736 int i, j;
738
742 if (rtsp_st) {
748 }
755
757 }
758 }
762 }
763 if (CONFIG_RTPDEC && rt->
ts)
767 }
768
770 {
774 if (reordering_queue_size < 0) {
776 reordering_queue_size = 0;
777 else
779 }
780
781 /* open the RTP context */
784 if (!st)
786
787 if (CONFIG_RTSP_MUXER && s->
oformat) {
792 /* Ownership of rtp_handle is passed to the rtp mux context */
794 if (ret < 0)
798 return 0; // Don't need to open any parser here
803 else if (CONFIG_RTPDEC)
806 reordering_queue_size);
807
815 }
820 }
821
822 return 0;
823 }
824
825 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
826 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
827 {
828 const char *q;
829 char *p;
831
832 q = *pp;
834 v = strtol(q, &p, 10);
835 if (*p == '-') {
836 p++;
838 v = strtol(p, &p, 10);
840 } else {
843 }
844 *pp = p;
845 }
846
847 /* XXX: only one transport specification is parsed */
849 {
850 char transport_protocol[16];
852 char lower_transport[16];
853 char parameter[16];
855 char buf[256];
856
858
859 for (;;) {
861 if (*p == '0円')
862 break;
863
865
866 get_word_sep(transport_protocol,
sizeof(transport_protocol),
867 "/", &p);
870 lower_transport[0] = '0円';
871 /* rtp/avp/<protocol> */
872 if (*p == '/') {
874 ";,", &p);
875 }
877 }
else if (!
av_strcasecmp (transport_protocol,
"x-pn-tng") ||
879 /* x-pn-tng/<protocol> */
880 get_word_sep(lower_transport,
sizeof(lower_transport),
"/;,", &p);
881 profile[0] = '0円';
885 lower_transport[0] = '0円';
886 /* raw/raw/<protocol> */
887 if (*p == '/') {
889 ";,", &p);
890 }
892 }
895 else
897
898 if (*p == ';')
899 p++;
900 /* get each parameter */
901 while (*p != '0円' && *p != ',') {
903 if (!strcmp(parameter, "port")) {
904 if (*p == '=') {
905 p++;
907 }
908 } else if (!strcmp(parameter, "client_port")) {
909 if (*p == '=') {
910 p++;
913 }
914 } else if (!strcmp(parameter, "server_port")) {
915 if (*p == '=') {
916 p++;
919 }
920 } else if (!strcmp(parameter, "interleaved")) {
921 if (*p == '=') {
922 p++;
925 }
926 } else if (!strcmp(parameter, "multicast")) {
929 } else if (!strcmp(parameter, "ttl")) {
930 if (*p == '=') {
932 p++;
933 th->
ttl = strtol(p, &end, 10);
935 }
936 } else if (!strcmp(parameter, "destination")) {
937 if (*p == '=') {
938 p++;
941 }
942 } else if (!strcmp(parameter, "source")) {
943 if (*p == '=') {
944 p++;
947 }
948 } else if (!strcmp(parameter, "mode")) {
949 if (*p == '=') {
950 p++;
952 if (!strcmp(buf, "record") ||
953 !strcmp(buf, "receive"))
955 }
956 }
957
958 while (*p != ';' && *p != '0円' && *p != ',')
959 p++;
960 if (*p == ';')
961 p++;
962 }
963 if (*p == ',')
964 p++;
965
967 }
968 }
969
970 static void handle_rtp_info(
RTSPState *rt,
const char *url,
971 uint32_t seq, uint32_t rtptime)
972 {
973 int i;
974 if (!rtptime || !url[0])
975 return;
977 return;
981 if (!rtpctx)
982 continue;
985 break;
986 }
987 }
988 }
989
990 static void rtsp_parse_rtp_info(
RTSPState *rt,
const char *p)
991 {
992 int read = 0;
993 char key[20], value[1024], url[1024] = "";
994 uint32_t seq = 0, rtptime = 0;
995
996 for (;;) {
998 if (!*p)
999 break;
1001 if (*p != '=')
1002 break;
1003 p++;
1005 read++;
1006 if (!strcmp(key, "url"))
1008 else if (!strcmp(key, "seq"))
1009 seq = strtoul(value,
NULL, 10);
1010 else if (!strcmp(key, "rtptime"))
1011 rtptime = strtoul(value,
NULL, 10);
1012 if (*p == ',') {
1013 handle_rtp_info(rt, url, seq, rtptime);
1014 url[0] = '0円';
1015 seq = rtptime = 0;
1016 read = 0;
1017 }
1018 if (*p)
1019 p++;
1020 }
1021 if (read > 0)
1022 handle_rtp_info(rt, url, seq, rtptime);
1023 }
1024
1027 {
1028 const char *p;
1029
1030 /* NOTE: we do case independent match for broken servers */
1033 int t;
1036 (t = strtol(p,
NULL, 10)) > 0) {
1038 }
1042 rtsp_parse_transport(reply, p);
1044 reply->
seq = strtol(p,
NULL, 10);
1059 }
else if (
av_stristart(p,
"WWW-Authenticate:", &p) && rt) {
1062 }
else if (
av_stristart(p,
"Authentication-Info:", &p) && rt) {
1065 }
else if (
av_stristart(p,
"Content-Base:", &p) && rt) {
1067 if (method && !strcmp(method, "DESCRIBE"))
1071 if (method && !strcmp(method, "PLAY"))
1072 rtsp_parse_rtp_info(rt, p);
1074 if (strstr(p, "GET_PARAMETER") &&
1075 method && !strcmp(method, "OPTIONS"))
1077 }
else if (
av_stristart(p,
"x-Accept-Dynamic-Rate:", &p) && rt) {
1083 }
1084 }
1085
1086 /* skip a RTP/TCP interleaved packet */
1088 {
1092
1094 if (ret != 3)
1095 return;
1097
1098 av_dlog(s,
"skipping RTP packet len=%d\n", len);
1099
1100 /* skip payload */
1101 while (len > 0) {
1103 if (len1 > sizeof(buf))
1106 if (ret != len1)
1107 return;
1108 len -= len1;
1109 }
1110 }
1111
1113 unsigned char **content_ptr,
1114 int return_on_interleaved_data, const char *method)
1115 {
1117 char buf[4096], buf1[1024], *q;
1118 unsigned char ch;
1119 const char *p;
1120 int ret, content_length, line_count = 0, request = 0;
1121 unsigned char *content =
NULL;
1122
1124 line_count = 0;
1125 request = 0;
1127 memset(reply, 0, sizeof(*reply));
1128
1129 /* parse reply (XXX: use buffers) */
1131 for (;;) {
1133 for (;;) {
1135 av_dlog(s,
"ret=%d c=%02x [%c]\n", ret, ch, ch);
1136 if (ret != 1)
1138 if (ch == '\n')
1139 break;
1140 if (ch == '$') {
1141 /* XXX: only parse it if first char on line ? */
1142 if (return_on_interleaved_data) {
1143 return 1;
1144 } else
1146 } else if (ch != '\r') {
1147 if ((q - buf) < sizeof(buf) - 1)
1148 *q++ = ch;
1149 }
1150 }
1151 *q = '0円';
1152
1153 av_dlog(s,
"line='%s'\n", buf);
1154
1155 /* test if last line */
1156 if (buf[0] == '0円')
1157 break;
1159 if (line_count == 0) {
1160 /* get reply code */
1162 if (!strncmp(buf1, "RTSP/", 5)) {
1166 } else {
1168 get_word(buf1,
sizeof(buf1), &p);
// object
1169 request = 1;
1170 }
1171 } else {
1175 }
1176 line_count++;
1177 }
1178
1181
1183 if (content_length > 0) {
1184 /* leave some room for a trailing '0円' (useful for simple parsing) */
1185 content =
av_malloc(content_length + 1);
1186 if (!content)
1189 content[content_length] = '0円';
1190 }
1191 if (content_ptr)
1192 *content_ptr = content;
1193 else
1195
1196 if (request) {
1197 char buf[1024];
1199 const char* ptr =
buf;
1200
1201 if (!strcmp(reply->
reason,
"OPTIONS")) {
1202 snprintf(buf,
sizeof(buf),
"RTSP/1.0 200 OK\r\n");
1208 } else {
1209 snprintf(buf,
sizeof(buf),
"RTSP/1.0 501 Not Implemented\r\n");
1210 }
1212
1215 ptr = base64buf;
1216 }
1218
1220 /* Even if the request from the server had data, it is not the data
1221 * that the caller wants or expects. The memory could also be leaked
1222 * if the actual following reply has content data. */
1223 if (content_ptr)
1225 /* If method is set, this is called from ff_rtsp_send_cmd,
1226 * where a reply to exactly this request is awaited. For
1227 * callers from within packet receiving, we just want to
1228 * return to the caller and go back to receiving packets. */
1229 if (method)
1231 return 0;
1232 }
1233
1234 if (rt->
seq != reply->
seq) {
1237 }
1238
1239 /* EOS */
1240 if (reply->
notice == 2101
/* End-of-Stream Reached */ ||
1241 reply->
notice == 2104
/* Start-of-Stream Reached */ ||
1242 reply->
notice == 2306
/* Continuous Feed Terminated */) {
1244 }
else if (reply->
notice >= 4400 && reply->
notice < 5500) {
1245 return AVERROR(EIO);
/* data or server error */
1246 }
else if (reply->
notice == 2401
/* Ticket Expired */ ||
1247 (reply->
notice >= 5500 && reply->
notice < 5600)
/* end of term */ )
1249
1250 return 0;
1251 }
1252
1253 /**
1254 * Send a command to the RTSP server without waiting for the reply.
1255 *
1256 * @param s RTSP (de)muxer context
1257 * @param method the method for the request
1258 * @param url the target url for the request
1259 * @param headers extra header lines to include in the request
1260 * @param send_content if non-null, the data to send as request body content
1261 * @param send_content_length the length of the send_content data, or 0 if
1262 * send_content is null
1263 *
1264 * @return zero if success, nonzero otherwise
1265 */
1267 const char *method, const char *url,
1268 const char *headers,
1269 const unsigned char *send_content,
1270 int send_content_length)
1271 {
1273 char buf[4096], *out_buf;
1275
1276 /* Add in RTSP headers */
1279 snprintf(buf,
sizeof(buf),
"%s %s RTSP/1.0\r\n", method, url);
1280 if (headers)
1284 if (rt->
session_id[0] !=
'0円' && (!headers ||
1285 !strstr(headers, "\nIf-Match:"))) {
1287 }
1290 rt->
auth, url, method);
1291 if (str)
1294 }
1295 if (send_content_length > 0 && send_content)
1296 av_strlcatf(buf,
sizeof(buf),
"Content-Length: %d\r\n", send_content_length);
1298
1299 /* base64 encode rtsp if tunneling */
1302 out_buf = base64buf;
1303 }
1304
1305 av_dlog(s,
"Sending:\n%s--\n", buf);
1306
1308 if (send_content_length > 0 && send_content) {
1311 "with content data not supported\n");
1313 }
1315 }
1317
1318 return 0;
1319 }
1320
1322 const char *url, const char *headers)
1323 {
1324 return rtsp_send_cmd_with_content_async(s, method, url, headers,
NULL, 0);
1325 }
1326
1329 unsigned char **content_ptr)
1330 {
1332 content_ptr,
NULL, 0);
1333 }
1334
1336 const char *method, const char *url,
1339 unsigned char **content_ptr,
1340 const unsigned char *send_content,
1341 int send_content_length)
1342 {
1345 int ret, attempts = 0;
1346
1347 retry:
1349 if ((ret = rtsp_send_cmd_with_content_async(s, method, url, header,
1350 send_content,
1351 send_content_length)))
1353
1356 attempts++;
1357
1361 goto retry;
1362
1365 method,
1369 }
1370
1371 return 0;
1372 }
1373
1375 int lower_transport, const char *real_challenge)
1376 {
1378 int rtx = 0, j, i, err,
interleave = 0, port_off;
1381 char cmd[2048];
1382 const char *trans_pref;
1383
1385 trans_pref = "x-pn-tng";
1387 trans_pref = "RAW/RAW";
1388 else
1389 trans_pref = "RTP/AVP";
1390
1391 /* default timeout: 1 minute */
1393
1394 /* Choose a random starting offset within the first half of the
1395 * port range, to allow for a number of ports to try even if the offset
1396 * happens to be at the end of the random range. */
1398 /* even random offset */
1399 port_off -= port_off & 0x01;
1400
1401 for (j = rt->
rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) {
1402 char transport[2048];
1403
1404 /*
1405 * WMS serves all UDP data over a single connection, the RTX, which
1406 * isn't necessarily the first in the SDP but has to be the first
1407 * to be set up, else the second/third SETUP will fail with a 461.
1408 */
1411 if (i == 0) {
1412 /* rtx first */
1415 if (len >= 4 &&
1417 "/rtx"))
1418 break;
1419 }
1421 return -1; /* no RTX found */
1423 } else
1425 } else
1427
1428 /* RTP/UDP */
1430 char buf[256];
1431
1434 goto have_port;
1435 }
1436
1437 /* first try in specified port range */
1438 while (j <= rt->rtp_port_max) {
1440 "?localport=%d", j);
1441 /* we will use two ports per rtp stream (rtp and rtcp) */
1442 j += 2;
1445 goto rtp_opened;
1446 }
1449 goto fail;
1450
1451 rtp_opened:
1453 have_port:
1454 snprintf(transport,
sizeof(transport) - 1,
1455 "%s/UDP;", trans_pref);
1457 av_strlcat(transport,
"unicast;",
sizeof(transport));
1459 "client_port=%d", port);
1462 av_strlcatf(transport,
sizeof(transport),
"-%d", port + 1);
1463 }
1464
1465 /* RTP/TCP */
1467 /* For WMS streams, the application streams are only used for
1468 * UDP. When trying to set it up for TCP streams, the server
1469 * will return an error. Therefore, we skip those streams. */
1474 continue;
1475 snprintf(transport,
sizeof(transport) - 1,
1476 "%s/TCP;", trans_pref);
1478 av_strlcat(transport,
"unicast;",
sizeof(transport));
1480 "interleaved=%d-%d",
1481 interleave, interleave + 1);
1482 interleave += 2;
1483 }
1484
1486 snprintf(transport,
sizeof(transport) - 1,
1487 "%s/UDP;multicast", trans_pref);
1488 }
1490 av_strlcat(transport,
";mode=record",
sizeof(transport));
1493 av_strlcat(transport,
";mode=play",
sizeof(transport));
1495 "Transport: %s\r\n",
1496 transport);
1498 av_strlcat(cmd,
"x-Dynamic-Rate: 0\r\n",
sizeof(cmd));
1500 char real_res[41], real_csum[9];
1502 real_challenge);
1504 "If-Match: %s\r\n"
1505 "RealChallenge2: %s, sd=%s\r\n",
1507 }
1509 if (reply->
status_code == 461
/* Unsupported protocol */ && i == 0) {
1510 err = 1;
1511 goto fail;
1515 goto fail;
1516 }
1517
1518 /* XXX: same protocol for all streams is required */
1519 if (i > 0) {
1523 goto fail;
1524 }
1525 } else {
1528 }
1529
1530 /* Fail if the server responded with another lower transport mode
1531 * than what we requested. */
1535 goto fail;
1536 }
1537
1542 break;
1543
1545 char url[1024],
options[30] =
"";
1546 const char *peer = host;
1547
1549 av_strlcpy(options,
"?connect=1",
sizeof(options));
1550 /* Use source address if specified */
1558 goto fail;
1559 }
1560 break;
1561 }
1563 char url[1024], namebuf[50], optbuf[20] = "";
1565 int port, ttl;
1566
1571 } else {
1575 }
1576 if (ttl > 0)
1577 snprintf(optbuf,
sizeof(optbuf),
"?ttl=%d", ttl);
1578 getnameinfo((
struct sockaddr*) &addr,
sizeof(addr),
1581 port, "%s", optbuf);
1585 goto fail;
1586 }
1587 break;
1588 }
1589 }
1590
1592 goto fail;
1593 }
1594
1597
1600
1601 return 0;
1602
1603 fail:
1605 return err;
1606 }
1607
1609 {
1614 }
1615
1617 {
1619 char proto[128], host[1024], path[1024];
1620 char tcpname[1024], cmd[2048], auth[128];
1621 const char *lower_rtsp_proto = "tcp";
1622 int port, err, tcp_fd;
1624 int lower_transport_mask = 0;
1626 char real_challenge[64] = "";
1628 socklen_t peer_len = sizeof(peer);
1629
1635 }
1636
1639
1640 if (s->
max_delay < 0)
/* Not set by the caller */
1642
1647 }
1648 /* Only pass through valid flags from here */
1650
1651 redirect:
1652 /* extract hostname and port */
1654 host,
sizeof(host), &port, path,
sizeof(path), s->
filename);
1655
1656 if (!strcmp(proto, "rtsps")) {
1657 lower_rtsp_proto = "tls";
1660 }
1661
1662 if (*auth) {
1664 }
1665 if (port < 0)
1666 port = default_port;
1667
1669
1670 if (!lower_transport_mask)
1672
1674 /* Only UDP or TCP - UDP multicast isn't supported. */
1679 "only UDP and TCP are supported for output.\n");
1681 goto fail;
1682 }
1683 }
1684
1685 /* Construct the URI used in request; this is similar to s->filename,
1686 * but with authentication credentials removed and RTSP specific options
1687 * stripped out. */
1689 host, port, "%s", path);
1690
1692 /* set up initial handshake for tunneling */
1693 char httpname[1024];
1694 char sessioncookie[17];
1695 char headers[1024];
1696
1697 ff_url_join(httpname,
sizeof(httpname),
"http", auth, host, port,
"%s", path);
1698 snprintf(sessioncookie,
sizeof(sessioncookie),
"%08x%08x",
1700
1701 /* GET requests */
1705 goto fail;
1706 }
1707
1708 /* generate GET headers */
1710 "x-sessioncookie: %s\r\n"
1711 "Accept: application/x-rtsp-tunnelled\r\n"
1712 "Pragma: no-cache\r\n"
1713 "Cache-Control: no-cache\r\n",
1714 sessioncookie);
1716
1717 /* complete the connection */
1720 goto fail;
1721 }
1722
1723 /* POST requests */
1727 goto fail;
1728 }
1729
1730 /* generate POST headers */
1732 "x-sessioncookie: %s\r\n"
1733 "Content-Type: application/x-rtsp-tunnelled\r\n"
1734 "Pragma: no-cache\r\n"
1735 "Cache-Control: no-cache\r\n"
1736 "Content-Length: 32767\r\n"
1737 "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
1738 sessioncookie);
1741
1742 /* Initialize the authentication state for the POST session. The HTTP
1743 * protocol implementation doesn't properly handle multi-pass
1744 * authentication for POST requests, since it would require one of
1745 * the following:
1746 * - implementing Expect: 100-continue, which many HTTP servers
1747 * don't support anyway, even less the RTSP servers that do HTTP
1748 * tunneling
1749 * - sending the whole POST data until getting a 401 reply specifying
1750 * what authentication method to use, then resending all that data
1751 * - waiting for potential 401 replies directly after sending the
1752 * POST header (waiting for some unspecified time)
1753 * Therefore, we copy the full auth state, which works for both basic
1754 * and digest. (For digest, we would have to synchronize the nonce
1755 * count variable between the two sessions, if we'd do more requests
1756 * with the original session, though.)
1757 */
1759
1760 /* complete the connection */
1763 goto fail;
1764 }
1765 } else {
1767 /* open the tcp connection */
1769 host, port,
1774 goto fail;
1775 }
1777 }
1779
1781 if (tcp_fd < 0) {
1782 err = tcp_fd;
1783 goto fail;
1784 }
1785 if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
1786 getnameinfo((
struct sockaddr*) &peer, peer_len, host,
sizeof(host),
1788 }
1789
1790 /* request options supported by the server; this also detects server
1791 * type */
1793 cmd[0] = 0;
1796 /*
1797 * The following entries are required for proper
1798 * streaming from a Realmedia server. They are
1799 * interdependent in some way although we currently
1800 * don't quite understand how. Values were copied
1801 * from mplayer SVN r23589.
1802 * ClientChallenge is a 16-byte ID in hex
1803 * CompanyID is a 16-byte ID in base64
1804 */
1805 "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
1806 "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
1807 "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
1808 "GUID: 00000000-0000-0000-0000-000000000000\r\n",
1809 sizeof(cmd));
1813 goto fail;
1814 }
1815
1816 /* detect server type if not standard-compliant RTP */
1819 continue;
1824 break;
1825 }
1826
1827 if (CONFIG_RTSP_DEMUXER && s->
iformat)
1829 else if (CONFIG_RTSP_MUXER)
1831 else
1833 if (err)
1834 goto fail;
1835
1836 do {
1837 int lower_transport =
ff_log2_tab[lower_transport_mask &
1838 ~(lower_transport_mask - 1)];
1839
1843
1846 real_challenge :
NULL);
1847 if (err < 0)
1848 goto fail;
1849 lower_transport_mask &= ~(1 << lower_transport);
1850 if (lower_transport_mask == 0 && err == 1) {
1851 err =
AVERROR(EPROTONOSUPPORT);
1852 goto fail;
1853 }
1854 } while (err);
1855
1859 rt->
seek_timestamp = 0;
/* default is to start stream at position zero */
1860 return 0;
1861 fail:
1870 goto redirect;
1871 }
1873 return err;
1874 }
1875 #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
1876
1877 #if CONFIG_RTPDEC
1879 uint8_t *buf,
int buf_size, int64_t wait_end)
1880 {
1883 int n, i,
ret, tcp_fd, timeout_cnt = 0;
1884 int max_p = 0;
1885 struct pollfd *p = rt->
p;
1886 int *fds =
NULL, fdsnum, fdsidx;
1887
1888 for (;;) {
1893 max_p = 0;
1896 p[max_p].fd = tcp_fd;
1897 p[max_p++].events = POLLIN;
1898 } else {
1899 tcp_fd = -1;
1900 }
1905 &fds, &fdsnum)) {
1908 }
1909 if (fdsnum != 2) {
1911 "Number of fds %d not supported\n", fdsnum);
1913 }
1914 for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) {
1915 p[max_p].fd = fds[fdsidx];
1916 p[max_p++].events = POLLIN;
1917 }
1919 }
1920 }
1922 if (n > 0) {
1923 int j = 1 - (tcp_fd == -1);
1924 timeout_cnt = 0;
1928 if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
1930 if (ret > 0) {
1931 *prtsp_st = rtsp_st;
1933 }
1934 }
1935 j+=2;
1936 }
1937 }
1938 #if CONFIG_RTSP_DEMUXER
1939 if (tcp_fd != -1 && p[0].revents & POLLIN) {
1944 else
1946 "Unable to answer to TEARDOWN\n");
1947 } else
1948 return 0;
1949 } else {
1952 if (ret < 0)
1954 /* XXX: parse message */
1956 return 0;
1957 }
1958 }
1959 #endif
1962 } else if (n < 0 && errno != EINTR)
1964 }
1965 }
1966
1969 {
1971 int i;
1972 if (len < 0)
1977 }
1980 int no_ssrc = 0;
1983 if (!rtpctx)
1984 continue;
1988 }
1990 no_ssrc = 1;
1991 }
1992 if (no_ssrc) {
1994 "Unable to pick stream for packet - SSRC not known for "
1995 "all streams\n");
1997 }
1998 } else {
2003 }
2004 }
2005 }
2006 }
2009 }
2010
2012 {
2016 int64_t wait_end = 0;
2017
2020
2021 /* get next frames from the same RTP packet */
2027 }
else if (CONFIG_RTPDEC && rt->
ts) {
2029 if (ret >= 0) {
2032 }
2033 } else
2034 ret = -1;
2035 if (ret == 0) {
2037 return 0;
2038 } else if (ret == 1) {
2039 return 0;
2040 } else
2042 }
2043
2044 redo:
2046 int i;
2047 int64_t first_queue_time = 0;
2050 int64_t queue_time;
2051 if (!rtpctx)
2052 continue;
2054 if (queue_time && (queue_time - first_queue_time < 0 ||
2055 !first_queue_time)) {
2056 first_queue_time = queue_time;
2058 }
2059 }
2060 if (first_queue_time) {
2061 wait_end = first_queue_time + s->
max_delay;
2062 } else {
2063 wait_end = 0;
2064 first_queue_st =
NULL;
2065 }
2066 }
2067
2068 /* read next RTP packet */
2073 }
2074
2076 default:
2077 #if CONFIG_RTSP_DEMUXER
2080 break;
2081 #endif
2087 break;
2092 else
2094 len = pick_stream(s, &rtsp_st, rt->
recvbuf, len);
2097 break;
2098 }
2099 if (len ==
AVERROR(EAGAIN) && first_queue_st &&
2101 rtsp_st = first_queue_st;
2104 }
2105 if (len < 0)
2107 if (len == 0)
2118 }
2119 if (ret < 0) {
2120 /* Either bad packet, or a RTCP packet. Check if the
2121 * first_rtcp_ntp_time field was initialized. */
2124 /* first_rtcp_ntp_time has been initialized for this stream,
2125 * copy the same value to all other uninitialized streams,
2126 * in order to map their timestamp origin to the same ntp time
2127 * as this one. */
2128 int i;
2137 if (rtpctx2 && st && st2 &&
2143 }
2144 }
2145 // Make real NTP start time available in AVFormatContext
2153 }
2154 }
2155 }
2158
2161
2164 }
2165 }
2166 }
else if (CONFIG_RTPDEC && rt->
ts) {
2168 if (ret >= 0) {
2169 if (ret < len) {
2173 return 1;
2174 } else {
2175 ret = 0;
2176 }
2177 }
2178 } else {
2180 }
2182 if (ret < 0)
2183 goto redo;
2184 if (ret == 1)
2185 /* more packets may follow, so we save the RTP context */
2187
2189 }
2190 #endif /* CONFIG_RTPDEC */
2191
2192 #if CONFIG_SDP_DEMUXER
2194 {
2196
2197 /* we look for a line beginning "c=IN IP" */
2198 while (p < p_end && *p != '0円') {
2199 if (p + sizeof("c=IN IP") - 1 < p_end &&
2202
2203 while (p < p_end - 1 && *p != '\n') p++;
2204 if (++p >= p_end)
2205 break;
2206 if (*p == '\r')
2207 p++;
2208 }
2209 return 0;
2210 }
2211
2212 static void append_source_addrs(
char *buf,
int size,
const char *
name,
2214 {
2215 int i;
2216 if (!count)
2217 return;
2218 av_strlcatf(buf, size,
"&%s=%s", name, addrs[0]->addr);
2219 for (i = 1; i <
count; i++)
2221 }
2222
2224 {
2228 char *content;
2229 char url[1024];
2230
2233
2234 if (s->
max_delay < 0)
/* Not set by the caller */
2238
2239 /* read the whole sdp file */
2240 /* XXX: better loading */
2243 if (size <= 0) {
2246 }
2247 content[
size] =
'0円';
2248
2251 if (err) goto fail;
2252
2253 /* open each RTP stream */
2255 char namebuf[50];
2257
2263 "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
2267
2268 append_source_addrs(url, sizeof(url), "sources",
2271 append_source_addrs(url, sizeof(url), "block",
2277 goto fail;
2278 }
2279 }
2281 goto fail;
2282 }
2283 return 0;
2284 fail:
2287 return err;
2288 }
2289
2291 {
2294 return 0;
2295 }
2296
2297 static const AVClass sdp_demuxer_class = {
2302 };
2303
2312 .priv_class = &sdp_demuxer_class,
2313 };
2314 #endif /* CONFIG_SDP_DEMUXER */
2315
2316 #if CONFIG_RTP_DEMUXER
2318 {
2321 return 0;
2322 }
2323
2325 {
2327 char host[500], sdp[500];
2330 int payload_type;
2334 socklen_t addrlen = sizeof(addr);
2336
2339
2342 if (ret)
2343 goto fail;
2344
2345 while (1) {
2346 ret =
ffurl_read(in, recvbuf,
sizeof(recvbuf));
2348 continue;
2349 if (ret < 0)
2350 goto fail;
2351 if (ret < 12) {
2353 continue;
2354 }
2355
2356 if ((recvbuf[0] & 0xc0) != 0x80) {
2358 "received\n");
2359 continue;
2360 }
2361
2363 continue;
2364
2365 payload_type = recvbuf[1] & 0x7f;
2366 break;
2367 }
2371
2374 "without an SDP file describing it\n",
2375 payload_type);
2376 goto fail;
2377 }
2380 "properly you need an SDP file "
2381 "describing it\n");
2382 }
2383
2386
2388 "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
2389 addr.ss_family == AF_INET ? 4 : 6, host,
2392 port, payload_type);
2394
2397
2398 /* sdp_read_header initializes this again */
2400
2402
2403 ret = sdp_read_header(s);
2406
2407 fail:
2408 if (in)
2412 }
2413
2414 static const AVClass rtp_demuxer_class = {
2419 };
2420
2430 .priv_class = &rtp_demuxer_class,
2431 };
2432 #endif /* CONFIG_RTP_DEMUXER */