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.

1258 lines
34KB

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