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.

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