You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1188 lines
33KB

  1. /*
  2. * RTSP/SDP client
  3. * Copyright (c) 2002 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "avformat.h"
  20. #include <sys/time.h>
  21. #include <netinet/in.h>
  22. #include <sys/socket.h>
  23. #include <ctype.h>
  24. #ifndef __BEOS__
  25. # include <arpa/inet.h>
  26. #else
  27. # include "barpainet.h"
  28. #endif
  29. //#define DEBUG
  30. //#define DEBUG_RTP_TCP
  31. typedef struct RTSPState {
  32. URLContext *rtsp_hd; /* RTSP TCP connexion handle */
  33. /* XXX: currently we use unbuffered input */
  34. // ByteIOContext rtsp_gb;
  35. int seq; /* RTSP command sequence number */
  36. char session_id[512];
  37. enum RTSPProtocol protocol;
  38. char last_reply[2048]; /* XXX: allocate ? */
  39. } RTSPState;
  40. typedef struct RTSPStream {
  41. AVFormatContext *ic;
  42. int interleaved_min, interleaved_max; /* interleave ids, if TCP transport */
  43. char control_url[1024]; /* url for this stream (from SDP) */
  44. int sdp_port; /* port (from SDP content - not used in RTSP) */
  45. struct in_addr sdp_ip; /* IP address (from SDP content - not used in RTSP) */
  46. int sdp_ttl; /* IP TTL (from SDP content - not used in RTSP) */
  47. int sdp_payload_type; /* payload type - only used in SDP */
  48. } RTSPStream;
  49. /* suppress this hack */
  50. int rtsp_abort_req = 0;
  51. /* XXX: currently, the only way to change the protocols consists in
  52. changing this variable */
  53. #if 1
  54. int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP) | (1 << RTSP_PROTOCOL_RTP_UDP) | (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST);
  55. #else
  56. /* try it if a proxy is used */
  57. int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
  58. #endif
  59. /* if non zero, then set a range for RTP ports */
  60. int rtsp_rtp_port_min = 0;
  61. int rtsp_rtp_port_max = 0;
  62. FFRTSPCallback *ff_rtsp_callback = NULL;
  63. static int rtsp_probe(AVProbeData *p)
  64. {
  65. if (strstart(p->filename, "rtsp:", NULL))
  66. return AVPROBE_SCORE_MAX;
  67. return 0;
  68. }
  69. static int redir_isspace(int c)
  70. {
  71. return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
  72. }
  73. static void skip_spaces(const char **pp)
  74. {
  75. const char *p;
  76. p = *pp;
  77. while (redir_isspace(*p))
  78. p++;
  79. *pp = p;
  80. }
  81. static void get_word_sep(char *buf, int buf_size, const char *sep,
  82. const char **pp)
  83. {
  84. const char *p;
  85. char *q;
  86. p = *pp;
  87. skip_spaces(&p);
  88. q = buf;
  89. while (!strchr(sep, *p) && *p != '\0') {
  90. if ((q - buf) < buf_size - 1)
  91. *q++ = *p;
  92. p++;
  93. }
  94. if (buf_size > 0)
  95. *q = '\0';
  96. *pp = p;
  97. }
  98. static void get_word(char *buf, int buf_size, const char **pp)
  99. {
  100. const char *p;
  101. char *q;
  102. p = *pp;
  103. skip_spaces(&p);
  104. q = buf;
  105. while (!redir_isspace(*p) && *p != '\0') {
  106. if ((q - buf) < buf_size - 1)
  107. *q++ = *p;
  108. p++;
  109. }
  110. if (buf_size > 0)
  111. *q = '\0';
  112. *pp = p;
  113. }
  114. /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other
  115. params>] */
  116. static int sdp_parse_rtpmap(AVCodecContext *codec, const char *p)
  117. {
  118. char buf[256];
  119. /* codec name */
  120. get_word_sep(buf, sizeof(buf), "/", &p);
  121. if (!strcmp(buf, "MP4V-ES")) {
  122. codec->codec_id = CODEC_ID_MPEG4;
  123. return 0;
  124. } else {
  125. return -1;
  126. }
  127. }
  128. /* return the length and optionnaly the data */
  129. static int hex_to_data(uint8_t *data, const char *p)
  130. {
  131. int c, len, v;
  132. len = 0;
  133. v = 1;
  134. for(;;) {
  135. skip_spaces(&p);
  136. if (p == '\0')
  137. break;
  138. c = toupper((unsigned char)*p++);
  139. if (c >= '0' && c <= '9')
  140. c = c - '0';
  141. else if (c >= 'A' && c <= 'F')
  142. c = c - 'A' + 10;
  143. else
  144. break;
  145. v = (v << 4) | c;
  146. if (v & 0x100) {
  147. if (data)
  148. data[len] = v;
  149. len++;
  150. v = 1;
  151. }
  152. }
  153. return len;
  154. }
  155. static void sdp_parse_fmtp(AVCodecContext *codec, const char *p)
  156. {
  157. char attr[256];
  158. char value[4096];
  159. int len;
  160. /* loop on each attribute */
  161. for(;;) {
  162. skip_spaces(&p);
  163. if (*p == '\0')
  164. break;
  165. get_word_sep(attr, sizeof(attr), "=", &p);
  166. if (*p == '=')
  167. p++;
  168. get_word_sep(value, sizeof(value), ";", &p);
  169. if (*p == ';')
  170. p++;
  171. /* handle MPEG4 video */
  172. switch(codec->codec_id) {
  173. case CODEC_ID_MPEG4:
  174. if (!strcmp(attr, "config")) {
  175. /* decode the hexa encoded parameter */
  176. len = hex_to_data(NULL, value);
  177. codec->extradata = av_mallocz(len);
  178. if (!codec->extradata)
  179. goto fail;
  180. codec->extradata_size = len;
  181. hex_to_data(codec->extradata, value);
  182. }
  183. break;
  184. default:
  185. /* ignore data for other codecs */
  186. break;
  187. }
  188. fail: ;
  189. // printf("'%s' = '%s'\n", attr, value);
  190. }
  191. }
  192. typedef struct SDPParseState {
  193. /* SDP only */
  194. struct in_addr default_ip;
  195. int default_ttl;
  196. } SDPParseState;
  197. static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
  198. int letter, const char *buf)
  199. {
  200. char buf1[64], st_type[64];
  201. const char *p;
  202. int codec_type, payload_type, i;
  203. AVStream *st;
  204. RTSPStream *rtsp_st;
  205. struct in_addr sdp_ip;
  206. int ttl;
  207. #ifdef DEBUG
  208. printf("sdp: %c='%s'\n", letter, buf);
  209. #endif
  210. p = buf;
  211. switch(letter) {
  212. case 'c':
  213. get_word(buf1, sizeof(buf1), &p);
  214. if (strcmp(buf1, "IN") != 0)
  215. return;
  216. get_word(buf1, sizeof(buf1), &p);
  217. if (strcmp(buf1, "IP4") != 0)
  218. return;
  219. get_word_sep(buf1, sizeof(buf1), "/", &p);
  220. if (inet_aton(buf1, &sdp_ip) == 0)
  221. return;
  222. ttl = 16;
  223. if (*p == '/') {
  224. p++;
  225. get_word_sep(buf1, sizeof(buf1), "/", &p);
  226. ttl = atoi(buf1);
  227. }
  228. if (s->nb_streams == 0) {
  229. s1->default_ip = sdp_ip;
  230. s1->default_ttl = ttl;
  231. } else {
  232. st = s->streams[s->nb_streams - 1];
  233. rtsp_st = st->priv_data;
  234. rtsp_st->sdp_ip = sdp_ip;
  235. rtsp_st->sdp_ttl = ttl;
  236. }
  237. break;
  238. case 's':
  239. pstrcpy(s->title, sizeof(s->title), p);
  240. break;
  241. case 'i':
  242. if (s->nb_streams == 0) {
  243. pstrcpy(s->comment, sizeof(s->comment), p);
  244. break;
  245. }
  246. break;
  247. case 'm':
  248. /* new stream */
  249. get_word(st_type, sizeof(st_type), &p);
  250. if (!strcmp(st_type, "audio")) {
  251. codec_type = CODEC_TYPE_AUDIO;
  252. } else if (!strcmp(st_type, "video")) {
  253. codec_type = CODEC_TYPE_VIDEO;
  254. } else {
  255. return;
  256. }
  257. rtsp_st = av_mallocz(sizeof(RTSPStream));
  258. if (!rtsp_st)
  259. return;
  260. st = av_new_stream(s, s->nb_streams);
  261. if (!st)
  262. return;
  263. st->priv_data = rtsp_st;
  264. rtsp_st->sdp_ip = s1->default_ip;
  265. rtsp_st->sdp_ttl = s1->default_ttl;
  266. st->codec.codec_type = codec_type;
  267. get_word(buf1, sizeof(buf1), &p); /* port */
  268. rtsp_st->sdp_port = atoi(buf1);
  269. get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */
  270. /* XXX: handle list of formats */
  271. get_word(buf1, sizeof(buf1), &p); /* format list */
  272. rtsp_st->sdp_payload_type = atoi(buf1);
  273. if (rtsp_st->sdp_payload_type < 96) {
  274. /* if standard payload type, we can find the codec right now */
  275. rtp_get_codec_info(&st->codec, rtsp_st->sdp_payload_type);
  276. }
  277. /* put a default control url */
  278. pstrcpy(rtsp_st->control_url, sizeof(rtsp_st->control_url), s->filename);
  279. break;
  280. case 'a':
  281. if (strstart(p, "control:", &p) && s->nb_streams > 0) {
  282. char proto[32];
  283. /* get the control url */
  284. st = s->streams[s->nb_streams - 1];
  285. rtsp_st = st->priv_data;
  286. /* XXX: may need to add full url resolution */
  287. url_split(proto, sizeof(proto), NULL, 0, NULL, NULL, 0, p);
  288. if (proto[0] == '\0') {
  289. /* relative control URL */
  290. pstrcat(rtsp_st->control_url, sizeof(rtsp_st->control_url), "/");
  291. pstrcat(rtsp_st->control_url, sizeof(rtsp_st->control_url), p);
  292. } else {
  293. pstrcpy(rtsp_st->control_url, sizeof(rtsp_st->control_url), p);
  294. }
  295. } else if (strstart(p, "rtpmap:", &p)) {
  296. /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
  297. get_word(buf1, sizeof(buf1), &p);
  298. payload_type = atoi(buf1);
  299. for(i = 0; i < s->nb_streams;i++) {
  300. st = s->streams[i];
  301. rtsp_st = st->priv_data;
  302. if (rtsp_st->sdp_payload_type == payload_type) {
  303. sdp_parse_rtpmap(&st->codec, p);
  304. }
  305. }
  306. } else if (strstart(p, "fmtp:", &p)) {
  307. /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
  308. get_word(buf1, sizeof(buf1), &p);
  309. payload_type = atoi(buf1);
  310. for(i = 0; i < s->nb_streams;i++) {
  311. st = s->streams[i];
  312. rtsp_st = st->priv_data;
  313. if (rtsp_st->sdp_payload_type == payload_type) {
  314. sdp_parse_fmtp(&st->codec, p);
  315. }
  316. }
  317. }
  318. break;
  319. }
  320. }
  321. static int sdp_parse(AVFormatContext *s, const char *content)
  322. {
  323. const char *p;
  324. int letter;
  325. char buf[1024], *q;
  326. SDPParseState sdp_parse_state, *s1 = &sdp_parse_state;
  327. memset(s1, 0, sizeof(SDPParseState));
  328. p = content;
  329. for(;;) {
  330. skip_spaces(&p);
  331. letter = *p;
  332. if (letter == '\0')
  333. break;
  334. p++;
  335. if (*p != '=')
  336. goto next_line;
  337. p++;
  338. /* get the content */
  339. q = buf;
  340. while (*p != '\n' && *p != '\r' && *p != '\0') {
  341. if ((q - buf) < sizeof(buf) - 1)
  342. *q++ = *p;
  343. p++;
  344. }
  345. *q = '\0';
  346. sdp_parse_line(s, s1, letter, buf);
  347. next_line:
  348. while (*p != '\n' && *p != '\0')
  349. p++;
  350. if (*p == '\n')
  351. p++;
  352. }
  353. return 0;
  354. }
  355. static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
  356. {
  357. const char *p;
  358. int v;
  359. p = *pp;
  360. skip_spaces(&p);
  361. v = strtol(p, (char **)&p, 10);
  362. if (*p == '-') {
  363. p++;
  364. *min_ptr = v;
  365. v = strtol(p, (char **)&p, 10);
  366. *max_ptr = v;
  367. } else {
  368. *min_ptr = v;
  369. *max_ptr = v;
  370. }
  371. *pp = p;
  372. }
  373. /* XXX: only one transport specification is parsed */
  374. static void rtsp_parse_transport(RTSPHeader *reply, const char *p)
  375. {
  376. char transport_protocol[16];
  377. char profile[16];
  378. char lower_transport[16];
  379. char parameter[16];
  380. RTSPTransportField *th;
  381. char buf[256];
  382. reply->nb_transports = 0;
  383. for(;;) {
  384. skip_spaces(&p);
  385. if (*p == '\0')
  386. break;
  387. th = &reply->transports[reply->nb_transports];
  388. get_word_sep(transport_protocol, sizeof(transport_protocol),
  389. "/", &p);
  390. if (*p == '/')
  391. p++;
  392. get_word_sep(profile, sizeof(profile), "/;,", &p);
  393. lower_transport[0] = '\0';
  394. if (*p == '/') {
  395. p++;
  396. get_word_sep(lower_transport, sizeof(lower_transport),
  397. ";,", &p);
  398. }
  399. if (!strcasecmp(lower_transport, "TCP"))
  400. th->protocol = RTSP_PROTOCOL_RTP_TCP;
  401. else
  402. th->protocol = RTSP_PROTOCOL_RTP_UDP;
  403. if (*p == ';')
  404. p++;
  405. /* get each parameter */
  406. while (*p != '\0' && *p != ',') {
  407. get_word_sep(parameter, sizeof(parameter), "=;,", &p);
  408. if (!strcmp(parameter, "port")) {
  409. if (*p == '=') {
  410. p++;
  411. rtsp_parse_range(&th->port_min, &th->port_max, &p);
  412. }
  413. } else if (!strcmp(parameter, "client_port")) {
  414. if (*p == '=') {
  415. p++;
  416. rtsp_parse_range(&th->client_port_min,
  417. &th->client_port_max, &p);
  418. }
  419. } else if (!strcmp(parameter, "server_port")) {
  420. if (*p == '=') {
  421. p++;
  422. rtsp_parse_range(&th->server_port_min,
  423. &th->server_port_max, &p);
  424. }
  425. } else if (!strcmp(parameter, "interleaved")) {
  426. if (*p == '=') {
  427. p++;
  428. rtsp_parse_range(&th->interleaved_min,
  429. &th->interleaved_max, &p);
  430. }
  431. } else if (!strcmp(parameter, "multicast")) {
  432. if (th->protocol == RTSP_PROTOCOL_RTP_UDP)
  433. th->protocol = RTSP_PROTOCOL_RTP_UDP_MULTICAST;
  434. } else if (!strcmp(parameter, "ttl")) {
  435. if (*p == '=') {
  436. p++;
  437. th->ttl = strtol(p, (char **)&p, 10);
  438. }
  439. } else if (!strcmp(parameter, "destination")) {
  440. struct in_addr ipaddr;
  441. if (*p == '=') {
  442. p++;
  443. get_word_sep(buf, sizeof(buf), ";,", &p);
  444. if (inet_aton(buf, &ipaddr))
  445. th->destination = ntohl(ipaddr.s_addr);
  446. }
  447. }
  448. while (*p != ';' && *p != '\0' && *p != ',')
  449. p++;
  450. if (*p == ';')
  451. p++;
  452. }
  453. if (*p == ',')
  454. p++;
  455. reply->nb_transports++;
  456. }
  457. }
  458. void rtsp_parse_line(RTSPHeader *reply, const char *buf)
  459. {
  460. const char *p;
  461. /* NOTE: we do case independent match for broken servers */
  462. p = buf;
  463. if (stristart(p, "Session:", &p)) {
  464. get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
  465. } else if (stristart(p, "Content-Length:", &p)) {
  466. reply->content_length = strtol(p, NULL, 10);
  467. } else if (stristart(p, "Transport:", &p)) {
  468. rtsp_parse_transport(reply, p);
  469. } else if (stristart(p, "CSeq:", &p)) {
  470. reply->seq = strtol(p, NULL, 10);
  471. }
  472. }
  473. static void rtsp_send_cmd(AVFormatContext *s,
  474. const char *cmd, RTSPHeader *reply,
  475. unsigned char **content_ptr)
  476. {
  477. RTSPState *rt = s->priv_data;
  478. char buf[4096], buf1[1024], *q;
  479. unsigned char ch;
  480. const char *p;
  481. int content_length, line_count;
  482. unsigned char *content = NULL;
  483. memset(reply, 0, sizeof(RTSPHeader));
  484. rt->seq++;
  485. pstrcpy(buf, sizeof(buf), cmd);
  486. snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq);
  487. pstrcat(buf, sizeof(buf), buf1);
  488. if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) {
  489. snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id);
  490. pstrcat(buf, sizeof(buf), buf1);
  491. }
  492. pstrcat(buf, sizeof(buf), "\r\n");
  493. #ifdef DEBUG
  494. printf("Sending:\n%s--\n", buf);
  495. #endif
  496. url_write(rt->rtsp_hd, buf, strlen(buf));
  497. /* parse reply (XXX: use buffers) */
  498. line_count = 0;
  499. rt->last_reply[0] = '\0';
  500. for(;;) {
  501. q = buf;
  502. for(;;) {
  503. if (url_read(rt->rtsp_hd, &ch, 1) == 0)
  504. break;
  505. if (ch == '\n')
  506. break;
  507. if (ch != '\r') {
  508. if ((q - buf) < sizeof(buf) - 1)
  509. *q++ = ch;
  510. }
  511. }
  512. *q = '\0';
  513. #ifdef DEBUG
  514. printf("line='%s'\n", buf);
  515. #endif
  516. /* test if last line */
  517. if (buf[0] == '\0')
  518. break;
  519. p = buf;
  520. if (line_count == 0) {
  521. /* get reply code */
  522. get_word(buf1, sizeof(buf1), &p);
  523. get_word(buf1, sizeof(buf1), &p);
  524. reply->status_code = atoi(buf1);
  525. } else {
  526. rtsp_parse_line(reply, p);
  527. pstrcat(rt->last_reply, sizeof(rt->last_reply), p);
  528. pstrcat(rt->last_reply, sizeof(rt->last_reply), "\n");
  529. }
  530. line_count++;
  531. }
  532. if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0')
  533. pstrcpy(rt->session_id, sizeof(rt->session_id), reply->session_id);
  534. content_length = reply->content_length;
  535. if (content_length > 0) {
  536. /* leave some room for a trailing '\0' (useful for simple parsing) */
  537. content = av_malloc(content_length + 1);
  538. url_read(rt->rtsp_hd, content, content_length);
  539. content[content_length] = '\0';
  540. }
  541. if (content_ptr)
  542. *content_ptr = content;
  543. }
  544. /* useful for modules: set RTSP callback function */
  545. void rtsp_set_callback(FFRTSPCallback *rtsp_cb)
  546. {
  547. ff_rtsp_callback = rtsp_cb;
  548. }
  549. static int rtsp_read_header(AVFormatContext *s,
  550. AVFormatParameters *ap)
  551. {
  552. RTSPState *rt = s->priv_data;
  553. char host[1024], path[1024], tcpname[1024], cmd[2048];
  554. URLContext *rtsp_hd;
  555. int port, i, ret, err;
  556. RTSPHeader reply1, *reply = &reply1;
  557. unsigned char *content = NULL;
  558. AVStream *st;
  559. RTSPStream *rtsp_st;
  560. int protocol_mask;
  561. rtsp_abort_req = 0;
  562. /* extract hostname and port */
  563. url_split(NULL, 0,
  564. host, sizeof(host), &port, path, sizeof(path), s->filename);
  565. if (port < 0)
  566. port = RTSP_DEFAULT_PORT;
  567. /* open the tcp connexion */
  568. snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port);
  569. if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0)
  570. return AVERROR_IO;
  571. rt->rtsp_hd = rtsp_hd;
  572. rt->seq = 0;
  573. /* describe the stream */
  574. snprintf(cmd, sizeof(cmd),
  575. "DESCRIBE %s RTSP/1.0\r\n"
  576. "Accept: application/sdp\r\n",
  577. s->filename);
  578. rtsp_send_cmd(s, cmd, reply, &content);
  579. if (!content) {
  580. err = AVERROR_INVALIDDATA;
  581. goto fail;
  582. }
  583. if (reply->status_code != RTSP_STATUS_OK) {
  584. err = AVERROR_INVALIDDATA;
  585. goto fail;
  586. }
  587. /* now we got the SDP description, we parse it */
  588. ret = sdp_parse(s, (const char *)content);
  589. av_freep(&content);
  590. if (ret < 0) {
  591. err = AVERROR_INVALIDDATA;
  592. goto fail;
  593. }
  594. protocol_mask = rtsp_default_protocols;
  595. /* for each stream, make the setup request */
  596. /* XXX: we assume the same server is used for the control of each
  597. RTSP stream */
  598. for(i=0;i<s->nb_streams;i++) {
  599. char transport[2048];
  600. AVInputFormat *fmt;
  601. st = s->streams[i];
  602. rtsp_st = st->priv_data;
  603. /* compute available transports */
  604. transport[0] = '\0';
  605. /* RTP/UDP */
  606. if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP)) {
  607. char buf[256];
  608. int j;
  609. /* first try in specified port range */
  610. if (rtsp_rtp_port_min != 0) {
  611. for(j=rtsp_rtp_port_min;j<=rtsp_rtp_port_max;j++) {
  612. snprintf(buf, sizeof(buf), "rtp://?localport=%d", j);
  613. if (!av_open_input_file(&rtsp_st->ic, buf,
  614. &rtp_demux, 0, NULL))
  615. goto rtp_opened;
  616. }
  617. }
  618. /* then try on any port */
  619. if (av_open_input_file(&rtsp_st->ic, "rtp://",
  620. &rtp_demux, 0, NULL) < 0) {
  621. err = AVERROR_INVALIDDATA;
  622. goto fail;
  623. }
  624. rtp_opened:
  625. port = rtp_get_local_port(url_fileno(&rtsp_st->ic->pb));
  626. if (transport[0] != '\0')
  627. pstrcat(transport, sizeof(transport), ",");
  628. snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1,
  629. "RTP/AVP/UDP;unicast;client_port=%d-%d",
  630. port, port + 1);
  631. }
  632. /* RTP/TCP */
  633. if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_TCP)) {
  634. if (transport[0] != '\0')
  635. pstrcat(transport, sizeof(transport), ",");
  636. snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1,
  637. "RTP/AVP/TCP");
  638. }
  639. if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST)) {
  640. if (transport[0] != '\0')
  641. pstrcat(transport, sizeof(transport), ",");
  642. snprintf(transport + strlen(transport),
  643. sizeof(transport) - strlen(transport) - 1,
  644. "RTP/AVP/UDP;multicast");
  645. }
  646. snprintf(cmd, sizeof(cmd),
  647. "SETUP %s RTSP/1.0\r\n"
  648. "Transport: %s\r\n",
  649. rtsp_st->control_url, transport);
  650. rtsp_send_cmd(s, cmd, reply, NULL);
  651. if (reply->status_code != RTSP_STATUS_OK ||
  652. reply->nb_transports != 1) {
  653. err = AVERROR_INVALIDDATA;
  654. goto fail;
  655. }
  656. /* XXX: same protocol for all streams is required */
  657. if (i > 0) {
  658. if (reply->transports[0].protocol != rt->protocol) {
  659. err = AVERROR_INVALIDDATA;
  660. goto fail;
  661. }
  662. } else {
  663. rt->protocol = reply->transports[0].protocol;
  664. }
  665. /* close RTP connection if not choosen */
  666. if (reply->transports[0].protocol != RTSP_PROTOCOL_RTP_UDP &&
  667. (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP))) {
  668. av_close_input_file(rtsp_st->ic);
  669. rtsp_st->ic = NULL;
  670. }
  671. switch(reply->transports[0].protocol) {
  672. case RTSP_PROTOCOL_RTP_TCP:
  673. fmt = &rtp_demux;
  674. if (av_open_input_file(&rtsp_st->ic, "null", fmt, 0, NULL) < 0) {
  675. err = AVERROR_INVALIDDATA;
  676. goto fail;
  677. }
  678. rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
  679. rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
  680. break;
  681. case RTSP_PROTOCOL_RTP_UDP:
  682. {
  683. char url[1024];
  684. /* XXX: also use address if specified */
  685. snprintf(url, sizeof(url), "rtp://%s:%d",
  686. host, reply->transports[0].server_port_min);
  687. if (rtp_set_remote_url(url_fileno(&rtsp_st->ic->pb), url) < 0) {
  688. err = AVERROR_INVALIDDATA;
  689. goto fail;
  690. }
  691. }
  692. break;
  693. case RTSP_PROTOCOL_RTP_UDP_MULTICAST:
  694. {
  695. char url[1024];
  696. int ttl;
  697. fmt = &rtp_demux;
  698. ttl = reply->transports[0].ttl;
  699. if (!ttl)
  700. ttl = 16;
  701. snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d",
  702. host,
  703. reply->transports[0].server_port_min,
  704. ttl);
  705. if (av_open_input_file(&rtsp_st->ic, url, fmt, 0, NULL) < 0) {
  706. err = AVERROR_INVALIDDATA;
  707. goto fail;
  708. }
  709. }
  710. break;
  711. }
  712. }
  713. /* use callback if available to extend setup */
  714. if (ff_rtsp_callback) {
  715. if (ff_rtsp_callback(RTSP_ACTION_CLIENT_SETUP, rt->session_id,
  716. NULL, 0, rt->last_reply) < 0) {
  717. err = AVERROR_INVALIDDATA;
  718. goto fail;
  719. }
  720. }
  721. /* start playing */
  722. snprintf(cmd, sizeof(cmd),
  723. "PLAY %s RTSP/1.0\r\n"
  724. "Range: npt=0-\r\n",
  725. s->filename);
  726. rtsp_send_cmd(s, cmd, reply, NULL);
  727. if (reply->status_code != RTSP_STATUS_OK) {
  728. err = AVERROR_INVALIDDATA;
  729. goto fail;
  730. }
  731. #if 0
  732. /* open TCP with bufferized input */
  733. if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {
  734. if (url_fdopen(&rt->rtsp_gb, rt->rtsp_hd) < 0) {
  735. err = AVERROR_NOMEM;
  736. goto fail;
  737. }
  738. }
  739. #endif
  740. return 0;
  741. fail:
  742. for(i=0;i<s->nb_streams;i++) {
  743. st = s->streams[i];
  744. rtsp_st = st->priv_data;
  745. if (rtsp_st) {
  746. if (rtsp_st->ic)
  747. av_close_input_file(rtsp_st->ic);
  748. }
  749. av_free(rtsp_st);
  750. }
  751. av_freep(&content);
  752. url_close(rt->rtsp_hd);
  753. return err;
  754. }
  755. static int tcp_read_packet(AVFormatContext *s,
  756. AVPacket *pkt)
  757. {
  758. RTSPState *rt = s->priv_data;
  759. int id, len, i, ret;
  760. AVStream *st;
  761. RTSPStream *rtsp_st;
  762. uint8_t buf[RTP_MAX_PACKET_LENGTH];
  763. #ifdef DEBUG_RTP_TCP
  764. printf("tcp_read_packet:\n");
  765. #endif
  766. redo:
  767. for(;;) {
  768. ret = url_read(rt->rtsp_hd, buf, 1);
  769. #ifdef DEBUG_RTP_TCP
  770. printf("ret=%d c=%02x [%c]\n", ret, buf[0], buf[0]);
  771. #endif
  772. if (ret != 1)
  773. return AVERROR_IO;
  774. if (buf[0] == '$')
  775. break;
  776. }
  777. ret = url_read(rt->rtsp_hd, buf, 3);
  778. if (ret != 3)
  779. return AVERROR_IO;
  780. id = buf[0];
  781. len = (buf[1] << 8) | buf[2];
  782. #ifdef DEBUG_RTP_TCP
  783. printf("id=%d len=%d\n", id, len);
  784. #endif
  785. if (len > RTP_MAX_PACKET_LENGTH || len < 12)
  786. goto redo;
  787. /* get the data */
  788. ret = url_read(rt->rtsp_hd, buf, len);
  789. if (ret != len)
  790. return AVERROR_IO;
  791. /* find the matching stream */
  792. for(i = 0; i < s->nb_streams; i++) {
  793. st = s->streams[i];
  794. rtsp_st = st->priv_data;
  795. if (id >= rtsp_st->interleaved_min &&
  796. id <= rtsp_st->interleaved_max)
  797. goto found;
  798. }
  799. goto redo;
  800. found:
  801. ret = rtp_parse_packet(rtsp_st->ic, pkt, buf, len);
  802. if (ret < 0)
  803. goto redo;
  804. pkt->stream_index = i;
  805. return ret;
  806. }
  807. /* NOTE: output one packet at a time. May need to add a small fifo */
  808. static int udp_read_packet(AVFormatContext *s,
  809. AVPacket *pkt)
  810. {
  811. AVFormatContext *ic;
  812. AVStream *st;
  813. RTSPStream *rtsp_st;
  814. fd_set rfds;
  815. int fd1, fd2, fd_max, n, i, ret;
  816. char buf[RTP_MAX_PACKET_LENGTH];
  817. struct timeval tv;
  818. for(;;) {
  819. if (rtsp_abort_req)
  820. return -EIO;
  821. FD_ZERO(&rfds);
  822. fd_max = -1;
  823. for(i = 0; i < s->nb_streams; i++) {
  824. st = s->streams[i];
  825. rtsp_st = st->priv_data;
  826. ic = rtsp_st->ic;
  827. /* currently, we cannot probe RTCP handle because of blocking restrictions */
  828. rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2);
  829. if (fd1 > fd_max)
  830. fd_max = fd1;
  831. FD_SET(fd1, &rfds);
  832. }
  833. /* XXX: also add proper API to abort */
  834. tv.tv_sec = 0;
  835. tv.tv_usec = 500000;
  836. n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
  837. if (n > 0) {
  838. for(i = 0; i < s->nb_streams; i++) {
  839. st = s->streams[i];
  840. rtsp_st = st->priv_data;
  841. ic = rtsp_st->ic;
  842. rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2);
  843. if (FD_ISSET(fd1, &rfds)) {
  844. ret = url_read(url_fileno(&ic->pb), buf, sizeof(buf));
  845. if (ret >= 0 &&
  846. rtp_parse_packet(ic, pkt, buf, ret) == 0) {
  847. pkt->stream_index = i;
  848. return ret;
  849. }
  850. }
  851. }
  852. }
  853. }
  854. }
  855. static int rtsp_read_packet(AVFormatContext *s,
  856. AVPacket *pkt)
  857. {
  858. RTSPState *rt = s->priv_data;
  859. int ret;
  860. switch(rt->protocol) {
  861. default:
  862. case RTSP_PROTOCOL_RTP_TCP:
  863. ret = tcp_read_packet(s, pkt);
  864. break;
  865. case RTSP_PROTOCOL_RTP_UDP:
  866. ret = udp_read_packet(s, pkt);
  867. break;
  868. }
  869. return ret;
  870. }
  871. static int rtsp_read_close(AVFormatContext *s)
  872. {
  873. RTSPState *rt = s->priv_data;
  874. AVStream *st;
  875. RTSPStream *rtsp_st;
  876. RTSPHeader reply1, *reply = &reply1;
  877. int i;
  878. char cmd[1024];
  879. #if 0
  880. /* NOTE: it is valid to flush the buffer here */
  881. if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {
  882. url_fclose(&rt->rtsp_gb);
  883. }
  884. #endif
  885. snprintf(cmd, sizeof(cmd),
  886. "TEARDOWN %s RTSP/1.0\r\n",
  887. s->filename);
  888. rtsp_send_cmd(s, cmd, reply, NULL);
  889. if (ff_rtsp_callback) {
  890. ff_rtsp_callback(RTSP_ACTION_CLIENT_TEARDOWN, rt->session_id,
  891. NULL, 0, NULL);
  892. }
  893. for(i=0;i<s->nb_streams;i++) {
  894. st = s->streams[i];
  895. rtsp_st = st->priv_data;
  896. if (rtsp_st) {
  897. if (rtsp_st->ic)
  898. av_close_input_file(rtsp_st->ic);
  899. }
  900. av_free(rtsp_st);
  901. }
  902. url_close(rt->rtsp_hd);
  903. return 0;
  904. }
  905. static AVInputFormat rtsp_demux = {
  906. "rtsp",
  907. "RTSP input format",
  908. sizeof(RTSPState),
  909. rtsp_probe,
  910. rtsp_read_header,
  911. rtsp_read_packet,
  912. rtsp_read_close,
  913. .flags = AVFMT_NOFILE,
  914. };
  915. static int sdp_probe(AVProbeData *p1)
  916. {
  917. const char *p;
  918. /* we look for a line beginning "c=IN IP4" */
  919. p = p1->buf;
  920. while (*p != '\0') {
  921. if (strstart(p, "c=IN IP4", NULL))
  922. return AVPROBE_SCORE_MAX / 2;
  923. p = strchr(p, '\n');
  924. if (!p)
  925. break;
  926. p++;
  927. if (*p == '\r')
  928. p++;
  929. }
  930. return 0;
  931. }
  932. #define SDP_MAX_SIZE 8192
  933. static int sdp_read_header(AVFormatContext *s,
  934. AVFormatParameters *ap)
  935. {
  936. AVStream *st;
  937. RTSPStream *rtsp_st;
  938. int size, i, err;
  939. char *content;
  940. char url[1024];
  941. /* read the whole sdp file */
  942. /* XXX: better loading */
  943. content = av_malloc(SDP_MAX_SIZE);
  944. size = get_buffer(&s->pb, content, SDP_MAX_SIZE - 1);
  945. if (size <= 0) {
  946. av_free(content);
  947. return AVERROR_INVALIDDATA;
  948. }
  949. content[size] ='\0';
  950. sdp_parse(s, content);
  951. av_free(content);
  952. /* open each RTP stream */
  953. for(i=0;i<s->nb_streams;i++) {
  954. st = s->streams[i];
  955. rtsp_st = st->priv_data;
  956. snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d",
  957. inet_ntoa(rtsp_st->sdp_ip),
  958. rtsp_st->sdp_port,
  959. rtsp_st->sdp_ttl);
  960. if (av_open_input_file(&rtsp_st->ic, url, &rtp_demux, 0, NULL) < 0) {
  961. err = AVERROR_INVALIDDATA;
  962. goto fail;
  963. }
  964. }
  965. return 0;
  966. fail:
  967. for(i=0;i<s->nb_streams;i++) {
  968. st = s->streams[i];
  969. rtsp_st = st->priv_data;
  970. if (rtsp_st) {
  971. if (rtsp_st->ic)
  972. av_close_input_file(rtsp_st->ic);
  973. }
  974. av_free(rtsp_st);
  975. }
  976. return err;
  977. }
  978. static int sdp_read_packet(AVFormatContext *s,
  979. AVPacket *pkt)
  980. {
  981. return udp_read_packet(s, pkt);
  982. }
  983. static int sdp_read_close(AVFormatContext *s)
  984. {
  985. AVStream *st;
  986. RTSPStream *rtsp_st;
  987. int i;
  988. for(i=0;i<s->nb_streams;i++) {
  989. st = s->streams[i];
  990. rtsp_st = st->priv_data;
  991. if (rtsp_st) {
  992. if (rtsp_st->ic)
  993. av_close_input_file(rtsp_st->ic);
  994. }
  995. av_free(rtsp_st);
  996. }
  997. return 0;
  998. }
  999. static AVInputFormat sdp_demux = {
  1000. "sdp",
  1001. "SDP",
  1002. sizeof(RTSPState),
  1003. sdp_probe,
  1004. sdp_read_header,
  1005. sdp_read_packet,
  1006. sdp_read_close,
  1007. };
  1008. /* dummy redirector format (used directly in av_open_input_file now) */
  1009. static int redir_probe(AVProbeData *pd)
  1010. {
  1011. const char *p;
  1012. p = pd->buf;
  1013. while (redir_isspace(*p))
  1014. p++;
  1015. if (strstart(p, "http://", NULL) ||
  1016. strstart(p, "rtsp://", NULL))
  1017. return AVPROBE_SCORE_MAX;
  1018. return 0;
  1019. }
  1020. /* called from utils.c */
  1021. int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f)
  1022. {
  1023. char buf[4096], *q;
  1024. int c;
  1025. AVFormatContext *ic = NULL;
  1026. /* parse each URL and try to open it */
  1027. c = url_fgetc(f);
  1028. while (c != URL_EOF) {
  1029. /* skip spaces */
  1030. for(;;) {
  1031. if (!redir_isspace(c))
  1032. break;
  1033. c = url_fgetc(f);
  1034. }
  1035. if (c == URL_EOF)
  1036. break;
  1037. /* record url */
  1038. q = buf;
  1039. for(;;) {
  1040. if (c == URL_EOF || redir_isspace(c))
  1041. break;
  1042. if ((q - buf) < sizeof(buf) - 1)
  1043. *q++ = c;
  1044. c = url_fgetc(f);
  1045. }
  1046. *q = '\0';
  1047. //printf("URL='%s'\n", buf);
  1048. /* try to open the media file */
  1049. if (av_open_input_file(&ic, buf, NULL, 0, NULL) == 0)
  1050. break;
  1051. }
  1052. *ic_ptr = ic;
  1053. if (!ic)
  1054. return AVERROR_IO;
  1055. else
  1056. return 0;
  1057. }
  1058. AVInputFormat redir_demux = {
  1059. "redir",
  1060. "Redirector format",
  1061. 0,
  1062. redir_probe,
  1063. NULL,
  1064. NULL,
  1065. NULL,
  1066. };
  1067. int rtsp_init(void)
  1068. {
  1069. av_register_input_format(&rtsp_demux);
  1070. av_register_input_format(&redir_demux);
  1071. av_register_input_format(&sdp_demux);
  1072. return 0;
  1073. }