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.

933 lines
32KB

  1. /*
  2. * RTSP demuxer
  3. * Copyright (c) 2002 Fabrice Bellard
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "libavutil/avstring.h"
  22. #include "libavutil/intreadwrite.h"
  23. #include "libavutil/mathematics.h"
  24. #include "libavutil/random_seed.h"
  25. #include "avformat.h"
  26. #include "internal.h"
  27. #include "network.h"
  28. #include "os_support.h"
  29. #include "rtsp.h"
  30. #include "rdt.h"
  31. #include "url.h"
  32. static const struct RTSPStatusMessage {
  33. enum RTSPStatusCode code;
  34. const char *message;
  35. } status_messages[] = {
  36. { RTSP_STATUS_OK, "OK" },
  37. { RTSP_STATUS_METHOD, "Method Not Allowed" },
  38. { RTSP_STATUS_BANDWIDTH, "Not Enough Bandwidth" },
  39. { RTSP_STATUS_SESSION, "Session Not Found" },
  40. { RTSP_STATUS_STATE, "Method Not Valid in This State" },
  41. { RTSP_STATUS_AGGREGATE, "Aggregate operation not allowed" },
  42. { RTSP_STATUS_ONLY_AGGREGATE, "Only aggregate operation allowed" },
  43. { RTSP_STATUS_TRANSPORT, "Unsupported transport" },
  44. { RTSP_STATUS_INTERNAL, "Internal Server Error" },
  45. { RTSP_STATUS_SERVICE, "Service Unavailable" },
  46. { RTSP_STATUS_VERSION, "RTSP Version not supported" },
  47. { 0, "NULL" }
  48. };
  49. static int rtsp_read_close(AVFormatContext *s)
  50. {
  51. RTSPState *rt = s->priv_data;
  52. if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN))
  53. ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
  54. ff_rtsp_close_streams(s);
  55. ff_rtsp_close_connections(s);
  56. ff_network_close();
  57. rt->real_setup = NULL;
  58. av_freep(&rt->real_setup_cache);
  59. return 0;
  60. }
  61. static inline int read_line(AVFormatContext *s, char *rbuf, const int rbufsize,
  62. int *rbuflen)
  63. {
  64. RTSPState *rt = s->priv_data;
  65. int idx = 0;
  66. int ret = 0;
  67. *rbuflen = 0;
  68. do {
  69. ret = ffurl_read_complete(rt->rtsp_hd, rbuf + idx, 1);
  70. if (ret < 0)
  71. return ret;
  72. if (rbuf[idx] == '\r') {
  73. /* Ignore */
  74. } else if (rbuf[idx] == '\n') {
  75. rbuf[idx] = '\0';
  76. *rbuflen = idx;
  77. return 0;
  78. } else
  79. idx++;
  80. } while (idx < rbufsize);
  81. av_log(s, AV_LOG_ERROR, "Message too long\n");
  82. return AVERROR(EIO);
  83. }
  84. static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code,
  85. const char *extracontent, uint16_t seq)
  86. {
  87. RTSPState *rt = s->priv_data;
  88. char message[4096];
  89. int index = 0;
  90. while (status_messages[index].code) {
  91. if (status_messages[index].code == code) {
  92. snprintf(message, sizeof(message), "RTSP/1.0 %d %s\r\n",
  93. code, status_messages[index].message);
  94. break;
  95. }
  96. index++;
  97. }
  98. if (!status_messages[index].code)
  99. return AVERROR(EINVAL);
  100. av_strlcatf(message, sizeof(message), "CSeq: %d\r\n", seq);
  101. av_strlcatf(message, sizeof(message), "Server: %s\r\n", LIBAVFORMAT_IDENT);
  102. if (extracontent)
  103. av_strlcat(message, extracontent, sizeof(message));
  104. av_strlcat(message, "\r\n", sizeof(message));
  105. av_dlog(s, "Sending response:\n%s", message);
  106. ffurl_write(rt->rtsp_hd, message, strlen(message));
  107. return 0;
  108. }
  109. static inline int check_sessionid(AVFormatContext *s,
  110. RTSPMessageHeader *request)
  111. {
  112. RTSPState *rt = s->priv_data;
  113. unsigned char *session_id = rt->session_id;
  114. if (!session_id[0]) {
  115. av_log(s, AV_LOG_WARNING, "There is no session-id at the moment\n");
  116. return 0;
  117. }
  118. if (strcmp(session_id, request->session_id)) {
  119. av_log(s, AV_LOG_ERROR, "Unexpected session-id %s\n",
  120. request->session_id);
  121. rtsp_send_reply(s, RTSP_STATUS_SESSION, NULL, request->seq);
  122. return AVERROR_STREAM_NOT_FOUND;
  123. }
  124. return 0;
  125. }
  126. static inline int rtsp_read_request(AVFormatContext *s,
  127. RTSPMessageHeader *request,
  128. const char *method)
  129. {
  130. RTSPState *rt = s->priv_data;
  131. char rbuf[1024];
  132. int rbuflen, ret;
  133. do {
  134. ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
  135. if (ret)
  136. return ret;
  137. if (rbuflen > 1) {
  138. av_dlog(s, "Parsing[%d]: %s\n", rbuflen, rbuf);
  139. ff_rtsp_parse_line(request, rbuf, rt, method);
  140. }
  141. } while (rbuflen > 0);
  142. if (request->seq != rt->seq + 1) {
  143. av_log(s, AV_LOG_ERROR, "Unexpected Sequence number %d\n",
  144. request->seq);
  145. return AVERROR(EINVAL);
  146. }
  147. if (rt->session_id[0] && strcmp(method, "OPTIONS")) {
  148. ret = check_sessionid(s, request);
  149. if (ret)
  150. return ret;
  151. }
  152. return 0;
  153. }
  154. static int rtsp_read_announce(AVFormatContext *s)
  155. {
  156. RTSPState *rt = s->priv_data;
  157. RTSPMessageHeader request = { 0 };
  158. char sdp[4096];
  159. int ret;
  160. ret = rtsp_read_request(s, &request, "ANNOUNCE");
  161. if (ret)
  162. return ret;
  163. rt->seq++;
  164. if (strcmp(request.content_type, "application/sdp")) {
  165. av_log(s, AV_LOG_ERROR, "Unexpected content type %s\n",
  166. request.content_type);
  167. rtsp_send_reply(s, RTSP_STATUS_SERVICE, NULL, request.seq);
  168. return AVERROR_OPTION_NOT_FOUND;
  169. }
  170. if (request.content_length && request.content_length < sizeof(sdp) - 1) {
  171. /* Read SDP */
  172. if (ffurl_read_complete(rt->rtsp_hd, sdp, request.content_length)
  173. < request.content_length) {
  174. av_log(s, AV_LOG_ERROR,
  175. "Unable to get complete SDP Description in ANNOUNCE\n");
  176. rtsp_send_reply(s, RTSP_STATUS_INTERNAL, NULL, request.seq);
  177. return AVERROR(EIO);
  178. }
  179. sdp[request.content_length] = '\0';
  180. av_log(s, AV_LOG_VERBOSE, "SDP: %s\n", sdp);
  181. ret = ff_sdp_parse(s, sdp);
  182. if (ret)
  183. return ret;
  184. rtsp_send_reply(s, RTSP_STATUS_OK, NULL, request.seq);
  185. return 0;
  186. }
  187. av_log(s, AV_LOG_ERROR,
  188. "Content-Length header value exceeds sdp allocated buffer (4KB)\n");
  189. rtsp_send_reply(s, RTSP_STATUS_INTERNAL,
  190. "Content-Length exceeds buffer size", request.seq);
  191. return AVERROR(EIO);
  192. }
  193. static int rtsp_read_options(AVFormatContext *s)
  194. {
  195. RTSPState *rt = s->priv_data;
  196. RTSPMessageHeader request = { 0 };
  197. int ret = 0;
  198. /* Parsing headers */
  199. ret = rtsp_read_request(s, &request, "OPTIONS");
  200. if (ret)
  201. return ret;
  202. rt->seq++;
  203. /* Send Reply */
  204. rtsp_send_reply(s, RTSP_STATUS_OK,
  205. "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, RECORD\r\n",
  206. request.seq);
  207. return 0;
  208. }
  209. static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
  210. {
  211. RTSPState *rt = s->priv_data;
  212. RTSPMessageHeader request = { 0 };
  213. int ret = 0;
  214. char url[1024];
  215. RTSPStream *rtsp_st;
  216. char responseheaders[1024];
  217. int localport = -1;
  218. int transportidx = 0;
  219. int streamid = 0;
  220. ret = rtsp_read_request(s, &request, "SETUP");
  221. if (ret)
  222. return ret;
  223. rt->seq++;
  224. if (!request.nb_transports) {
  225. av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
  226. return AVERROR_INVALIDDATA;
  227. }
  228. for (transportidx = 0; transportidx < request.nb_transports;
  229. transportidx++) {
  230. if (!request.transports[transportidx].mode_record ||
  231. (request.transports[transportidx].lower_transport !=
  232. RTSP_LOWER_TRANSPORT_UDP &&
  233. request.transports[transportidx].lower_transport !=
  234. RTSP_LOWER_TRANSPORT_TCP)) {
  235. av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
  236. " protocol not supported (yet)\n");
  237. return AVERROR_INVALIDDATA;
  238. }
  239. }
  240. if (request.nb_transports > 1)
  241. av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
  242. "using first of all\n");
  243. for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
  244. if (!strcmp(rt->rtsp_streams[streamid]->control_url,
  245. controlurl))
  246. break;
  247. }
  248. if (streamid == rt->nb_rtsp_streams) {
  249. av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
  250. return AVERROR_STREAM_NOT_FOUND;
  251. }
  252. rtsp_st = rt->rtsp_streams[streamid];
  253. localport = rt->rtp_port_min;
  254. if (request.transports[0].lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
  255. rt->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
  256. if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
  257. rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
  258. return ret;
  259. }
  260. rtsp_st->interleaved_min = request.transports[0].interleaved_min;
  261. rtsp_st->interleaved_max = request.transports[0].interleaved_max;
  262. snprintf(responseheaders, sizeof(responseheaders), "Transport: "
  263. "RTP/AVP/TCP;unicast;mode=receive;interleaved=%d-%d"
  264. "\r\n", request.transports[0].interleaved_min,
  265. request.transports[0].interleaved_max);
  266. } else {
  267. do {
  268. ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
  269. av_dlog(s, "Opening: %s", url);
  270. ret = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
  271. &s->interrupt_callback, NULL);
  272. if (ret)
  273. localport += 2;
  274. } while (ret || localport > rt->rtp_port_max);
  275. if (localport > rt->rtp_port_max) {
  276. rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
  277. return ret;
  278. }
  279. av_dlog(s, "Listening on: %d",
  280. ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle));
  281. if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
  282. rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
  283. return ret;
  284. }
  285. localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
  286. snprintf(responseheaders, sizeof(responseheaders), "Transport: "
  287. "RTP/AVP/UDP;unicast;mode=receive;source=%s;"
  288. "client_port=%d-%d;server_port=%d-%d\r\n",
  289. host, request.transports[0].client_port_min,
  290. request.transports[0].client_port_max, localport,
  291. localport + 1);
  292. }
  293. /* Establish sessionid if not previously set */
  294. /* Put this in a function? */
  295. /* RFC 2326: session id must be at least 8 digits */
  296. while (strlen(rt->session_id) < 8)
  297. av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
  298. av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
  299. rt->session_id);
  300. /* Send Reply */
  301. rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
  302. rt->state = RTSP_STATE_PAUSED;
  303. return 0;
  304. }
  305. static int rtsp_read_record(AVFormatContext *s)
  306. {
  307. RTSPState *rt = s->priv_data;
  308. RTSPMessageHeader request = { 0 };
  309. int ret = 0;
  310. char responseheaders[1024];
  311. ret = rtsp_read_request(s, &request, "RECORD");
  312. if (ret)
  313. return ret;
  314. ret = check_sessionid(s, &request);
  315. if (ret)
  316. return ret;
  317. rt->seq++;
  318. snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
  319. rt->session_id);
  320. rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
  321. rt->state = RTSP_STATE_STREAMING;
  322. return 0;
  323. }
  324. static inline int parse_command_line(AVFormatContext *s, const char *line,
  325. int linelen, char *uri, int urisize,
  326. char *method, int methodsize,
  327. enum RTSPMethod *methodcode)
  328. {
  329. RTSPState *rt = s->priv_data;
  330. const char *linept, *searchlinept;
  331. linept = strchr(line, ' ');
  332. if (linept - line > methodsize - 1) {
  333. av_log(s, AV_LOG_ERROR, "Method string too long\n");
  334. return AVERROR(EIO);
  335. }
  336. memcpy(method, line, linept - line);
  337. method[linept - line] = '\0';
  338. linept++;
  339. if (!strcmp(method, "ANNOUNCE"))
  340. *methodcode = ANNOUNCE;
  341. else if (!strcmp(method, "OPTIONS"))
  342. *methodcode = OPTIONS;
  343. else if (!strcmp(method, "RECORD"))
  344. *methodcode = RECORD;
  345. else if (!strcmp(method, "SETUP"))
  346. *methodcode = SETUP;
  347. else if (!strcmp(method, "PAUSE"))
  348. *methodcode = PAUSE;
  349. else if (!strcmp(method, "TEARDOWN"))
  350. *methodcode = TEARDOWN;
  351. else
  352. *methodcode = UNKNOWN;
  353. /* Check method with the state */
  354. if (rt->state == RTSP_STATE_IDLE) {
  355. if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
  356. av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
  357. line);
  358. return AVERROR_PROTOCOL_NOT_FOUND;
  359. }
  360. } else if (rt->state == RTSP_STATE_PAUSED) {
  361. if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
  362. && (*methodcode != SETUP)) {
  363. av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
  364. line);
  365. return AVERROR_PROTOCOL_NOT_FOUND;
  366. }
  367. } else if (rt->state == RTSP_STATE_STREAMING) {
  368. if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
  369. && (*methodcode != TEARDOWN)) {
  370. av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
  371. " %s\n", line);
  372. return AVERROR_PROTOCOL_NOT_FOUND;
  373. }
  374. } else {
  375. av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
  376. return AVERROR_BUG;
  377. }
  378. searchlinept = strchr(linept, ' ');
  379. if (searchlinept == NULL) {
  380. av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
  381. return AVERROR_INVALIDDATA;
  382. }
  383. if (searchlinept - linept > urisize - 1) {
  384. av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
  385. return AVERROR(EIO);
  386. }
  387. memcpy(uri, linept, searchlinept - linept);
  388. uri[searchlinept - linept] = '\0';
  389. if (strcmp(rt->control_uri, uri)) {
  390. char host[128], path[512], auth[128];
  391. int port;
  392. char ctl_host[128], ctl_path[512], ctl_auth[128];
  393. int ctl_port;
  394. av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
  395. path, sizeof(path), uri);
  396. av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
  397. sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
  398. rt->control_uri);
  399. if (strcmp(host, ctl_host))
  400. av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
  401. host, ctl_host);
  402. if (strcmp(path, ctl_path) && *methodcode != SETUP)
  403. av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
  404. " %s\n", path, ctl_path);
  405. if (*methodcode == ANNOUNCE) {
  406. av_log(s, AV_LOG_INFO,
  407. "Updating control URI to %s\n", uri);
  408. strcpy(rt->control_uri, uri);
  409. }
  410. }
  411. linept = searchlinept + 1;
  412. if (!av_strstart(linept, "RTSP/1.0", NULL)) {
  413. av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
  414. return AVERROR_PROTOCOL_NOT_FOUND;
  415. }
  416. return 0;
  417. }
  418. int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
  419. {
  420. RTSPState *rt = s->priv_data;
  421. unsigned char rbuf[4096];
  422. unsigned char method[10];
  423. char uri[500];
  424. int ret;
  425. int rbuflen = 0;
  426. RTSPMessageHeader request = { 0 };
  427. enum RTSPMethod methodcode;
  428. ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
  429. if (ret < 0)
  430. return ret;
  431. ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
  432. sizeof(method), &methodcode);
  433. if (ret) {
  434. av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
  435. return ret;
  436. }
  437. ret = rtsp_read_request(s, &request, method);
  438. if (ret)
  439. return ret;
  440. rt->seq++;
  441. if (methodcode == PAUSE) {
  442. rt->state = RTSP_STATE_PAUSED;
  443. ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
  444. // TODO: Missing date header in response
  445. } else if (methodcode == OPTIONS) {
  446. ret = rtsp_send_reply(s, RTSP_STATUS_OK,
  447. "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
  448. "RECORD\r\n", request.seq);
  449. } else if (methodcode == TEARDOWN) {
  450. rt->state = RTSP_STATE_IDLE;
  451. ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
  452. return 0;
  453. }
  454. return ret;
  455. }
  456. static int rtsp_read_play(AVFormatContext *s)
  457. {
  458. RTSPState *rt = s->priv_data;
  459. RTSPMessageHeader reply1, *reply = &reply1;
  460. int i;
  461. char cmd[1024];
  462. av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
  463. rt->nb_byes = 0;
  464. if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
  465. if (rt->transport == RTSP_TRANSPORT_RTP) {
  466. for (i = 0; i < rt->nb_rtsp_streams; i++) {
  467. RTSPStream *rtsp_st = rt->rtsp_streams[i];
  468. RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
  469. if (!rtpctx)
  470. continue;
  471. ff_rtp_reset_packet_queue(rtpctx);
  472. rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
  473. rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
  474. rtpctx->base_timestamp = 0;
  475. rtpctx->timestamp = 0;
  476. rtpctx->unwrapped_timestamp = 0;
  477. rtpctx->rtcp_ts_offset = 0;
  478. }
  479. }
  480. if (rt->state == RTSP_STATE_PAUSED) {
  481. cmd[0] = 0;
  482. } else {
  483. snprintf(cmd, sizeof(cmd),
  484. "Range: npt=%"PRId64".%03"PRId64"-\r\n",
  485. rt->seek_timestamp / AV_TIME_BASE,
  486. rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
  487. }
  488. ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
  489. if (reply->status_code != RTSP_STATUS_OK) {
  490. return -1;
  491. }
  492. if (rt->transport == RTSP_TRANSPORT_RTP &&
  493. reply->range_start != AV_NOPTS_VALUE) {
  494. for (i = 0; i < rt->nb_rtsp_streams; i++) {
  495. RTSPStream *rtsp_st = rt->rtsp_streams[i];
  496. RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
  497. AVStream *st = NULL;
  498. if (!rtpctx || rtsp_st->stream_index < 0)
  499. continue;
  500. st = s->streams[rtsp_st->stream_index];
  501. rtpctx->range_start_offset =
  502. av_rescale_q(reply->range_start, AV_TIME_BASE_Q,
  503. st->time_base);
  504. }
  505. }
  506. }
  507. rt->state = RTSP_STATE_STREAMING;
  508. return 0;
  509. }
  510. /* pause the stream */
  511. static int rtsp_read_pause(AVFormatContext *s)
  512. {
  513. RTSPState *rt = s->priv_data;
  514. RTSPMessageHeader reply1, *reply = &reply1;
  515. if (rt->state != RTSP_STATE_STREAMING)
  516. return 0;
  517. else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
  518. ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
  519. if (reply->status_code != RTSP_STATUS_OK) {
  520. return -1;
  521. }
  522. }
  523. rt->state = RTSP_STATE_PAUSED;
  524. return 0;
  525. }
  526. int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
  527. {
  528. RTSPState *rt = s->priv_data;
  529. char cmd[1024];
  530. unsigned char *content = NULL;
  531. int ret;
  532. /* describe the stream */
  533. snprintf(cmd, sizeof(cmd),
  534. "Accept: application/sdp\r\n");
  535. if (rt->server_type == RTSP_SERVER_REAL) {
  536. /**
  537. * The Require: attribute is needed for proper streaming from
  538. * Realmedia servers.
  539. */
  540. av_strlcat(cmd,
  541. "Require: com.real.retain-entity-for-setup\r\n",
  542. sizeof(cmd));
  543. }
  544. ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
  545. if (!content)
  546. return AVERROR_INVALIDDATA;
  547. if (reply->status_code != RTSP_STATUS_OK) {
  548. av_freep(&content);
  549. return AVERROR_INVALIDDATA;
  550. }
  551. av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
  552. /* now we got the SDP description, we parse it */
  553. ret = ff_sdp_parse(s, (const char *)content);
  554. av_freep(&content);
  555. if (ret < 0)
  556. return ret;
  557. return 0;
  558. }
  559. static int rtsp_listen(AVFormatContext *s)
  560. {
  561. RTSPState *rt = s->priv_data;
  562. char host[128], path[512], auth[128];
  563. char uri[500];
  564. int port;
  565. char tcpname[500];
  566. unsigned char rbuf[4096];
  567. unsigned char method[10];
  568. int rbuflen = 0;
  569. int ret;
  570. enum RTSPMethod methodcode;
  571. /* extract hostname and port */
  572. av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
  573. path, sizeof(path), s->filename);
  574. /* ff_url_join. No authorization by now (NULL) */
  575. ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, host,
  576. port, "%s", path);
  577. /* Create TCP connection */
  578. ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
  579. "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
  580. if (ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
  581. &s->interrupt_callback, NULL)) {
  582. av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
  583. return ret;
  584. }
  585. rt->state = RTSP_STATE_IDLE;
  586. rt->rtsp_hd_out = rt->rtsp_hd;
  587. for (;;) { /* Wait for incoming RTSP messages */
  588. ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
  589. if (ret < 0)
  590. return ret;
  591. ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
  592. sizeof(method), &methodcode);
  593. if (ret) {
  594. av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
  595. return ret;
  596. }
  597. if (methodcode == ANNOUNCE) {
  598. ret = rtsp_read_announce(s);
  599. rt->state = RTSP_STATE_PAUSED;
  600. } else if (methodcode == OPTIONS) {
  601. ret = rtsp_read_options(s);
  602. } else if (methodcode == RECORD) {
  603. ret = rtsp_read_record(s);
  604. if (!ret)
  605. return 0; // We are ready for streaming
  606. } else if (methodcode == SETUP)
  607. ret = rtsp_read_setup(s, host, uri);
  608. if (ret) {
  609. ffurl_close(rt->rtsp_hd);
  610. return AVERROR_INVALIDDATA;
  611. }
  612. }
  613. return 0;
  614. }
  615. static int rtsp_probe(AVProbeData *p)
  616. {
  617. if (av_strstart(p->filename, "rtsp:", NULL))
  618. return AVPROBE_SCORE_MAX;
  619. return 0;
  620. }
  621. static int rtsp_read_header(AVFormatContext *s)
  622. {
  623. RTSPState *rt = s->priv_data;
  624. int ret;
  625. if (rt->initial_timeout > 0)
  626. rt->rtsp_flags |= RTSP_FLAG_LISTEN;
  627. if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
  628. ret = rtsp_listen(s);
  629. if (ret)
  630. return ret;
  631. } else {
  632. ret = ff_rtsp_connect(s);
  633. if (ret)
  634. return ret;
  635. rt->real_setup_cache = !s->nb_streams ? NULL :
  636. av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache));
  637. if (!rt->real_setup_cache && s->nb_streams)
  638. return AVERROR(ENOMEM);
  639. rt->real_setup = rt->real_setup_cache + s->nb_streams;
  640. if (rt->initial_pause) {
  641. /* do not start immediately */
  642. } else {
  643. if (rtsp_read_play(s) < 0) {
  644. ff_rtsp_close_streams(s);
  645. ff_rtsp_close_connections(s);
  646. return AVERROR_INVALIDDATA;
  647. }
  648. }
  649. }
  650. return 0;
  651. }
  652. int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
  653. uint8_t *buf, int buf_size)
  654. {
  655. RTSPState *rt = s->priv_data;
  656. int id, len, i, ret;
  657. RTSPStream *rtsp_st;
  658. av_dlog(s, "tcp_read_packet:\n");
  659. redo:
  660. for (;;) {
  661. RTSPMessageHeader reply;
  662. ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
  663. if (ret < 0)
  664. return ret;
  665. if (ret == 1) /* received '$' */
  666. break;
  667. /* XXX: parse message */
  668. if (rt->state != RTSP_STATE_STREAMING)
  669. return 0;
  670. }
  671. ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
  672. if (ret != 3)
  673. return -1;
  674. id = buf[0];
  675. len = AV_RB16(buf + 1);
  676. av_dlog(s, "id=%d len=%d\n", id, len);
  677. if (len > buf_size || len < 8)
  678. goto redo;
  679. /* get the data */
  680. ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
  681. if (ret != len)
  682. return -1;
  683. if (rt->transport == RTSP_TRANSPORT_RDT &&
  684. ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
  685. return -1;
  686. /* find the matching stream */
  687. for (i = 0; i < rt->nb_rtsp_streams; i++) {
  688. rtsp_st = rt->rtsp_streams[i];
  689. if (id >= rtsp_st->interleaved_min &&
  690. id <= rtsp_st->interleaved_max)
  691. goto found;
  692. }
  693. goto redo;
  694. found:
  695. *prtsp_st = rtsp_st;
  696. return len;
  697. }
  698. static int resetup_tcp(AVFormatContext *s)
  699. {
  700. RTSPState *rt = s->priv_data;
  701. char host[1024];
  702. int port;
  703. av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
  704. s->filename);
  705. ff_rtsp_undo_setup(s);
  706. return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
  707. rt->real_challenge);
  708. }
  709. static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
  710. {
  711. RTSPState *rt = s->priv_data;
  712. int ret;
  713. RTSPMessageHeader reply1, *reply = &reply1;
  714. char cmd[1024];
  715. retry:
  716. if (rt->server_type == RTSP_SERVER_REAL) {
  717. int i;
  718. for (i = 0; i < s->nb_streams; i++)
  719. rt->real_setup[i] = s->streams[i]->discard;
  720. if (!rt->need_subscription) {
  721. if (memcmp (rt->real_setup, rt->real_setup_cache,
  722. sizeof(enum AVDiscard) * s->nb_streams)) {
  723. snprintf(cmd, sizeof(cmd),
  724. "Unsubscribe: %s\r\n",
  725. rt->last_subscription);
  726. ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
  727. cmd, reply, NULL);
  728. if (reply->status_code != RTSP_STATUS_OK)
  729. return AVERROR_INVALIDDATA;
  730. rt->need_subscription = 1;
  731. }
  732. }
  733. if (rt->need_subscription) {
  734. int r, rule_nr, first = 1;
  735. memcpy(rt->real_setup_cache, rt->real_setup,
  736. sizeof(enum AVDiscard) * s->nb_streams);
  737. rt->last_subscription[0] = 0;
  738. snprintf(cmd, sizeof(cmd),
  739. "Subscribe: ");
  740. for (i = 0; i < rt->nb_rtsp_streams; i++) {
  741. rule_nr = 0;
  742. for (r = 0; r < s->nb_streams; r++) {
  743. if (s->streams[r]->id == i) {
  744. if (s->streams[r]->discard != AVDISCARD_ALL) {
  745. if (!first)
  746. av_strlcat(rt->last_subscription, ",",
  747. sizeof(rt->last_subscription));
  748. ff_rdt_subscribe_rule(
  749. rt->last_subscription,
  750. sizeof(rt->last_subscription), i, rule_nr);
  751. first = 0;
  752. }
  753. rule_nr++;
  754. }
  755. }
  756. }
  757. av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
  758. ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
  759. cmd, reply, NULL);
  760. if (reply->status_code != RTSP_STATUS_OK)
  761. return AVERROR_INVALIDDATA;
  762. rt->need_subscription = 0;
  763. if (rt->state == RTSP_STATE_STREAMING)
  764. rtsp_read_play (s);
  765. }
  766. }
  767. ret = ff_rtsp_fetch_packet(s, pkt);
  768. if (ret < 0) {
  769. if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
  770. if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
  771. rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) {
  772. RTSPMessageHeader reply1, *reply = &reply1;
  773. av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
  774. if (rtsp_read_pause(s) != 0)
  775. return -1;
  776. // TEARDOWN is required on Real-RTSP, but might make
  777. // other servers close the connection.
  778. if (rt->server_type == RTSP_SERVER_REAL)
  779. ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
  780. reply, NULL);
  781. rt->session_id[0] = '\0';
  782. if (resetup_tcp(s) == 0) {
  783. rt->state = RTSP_STATE_IDLE;
  784. rt->need_subscription = 1;
  785. if (rtsp_read_play(s) != 0)
  786. return -1;
  787. goto retry;
  788. }
  789. }
  790. }
  791. return ret;
  792. }
  793. rt->packets++;
  794. if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
  795. /* send dummy request to keep TCP connection alive */
  796. if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
  797. rt->auth_state.stale) {
  798. if (rt->server_type == RTSP_SERVER_WMS ||
  799. (rt->server_type != RTSP_SERVER_REAL &&
  800. rt->get_parameter_supported)) {
  801. ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
  802. } else {
  803. ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
  804. }
  805. /* The stale flag should be reset when creating the auth response in
  806. * ff_rtsp_send_cmd_async, but reset it here just in case we never
  807. * called the auth code (if we didn't have any credentials set). */
  808. rt->auth_state.stale = 0;
  809. }
  810. }
  811. return 0;
  812. }
  813. static int rtsp_read_seek(AVFormatContext *s, int stream_index,
  814. int64_t timestamp, int flags)
  815. {
  816. RTSPState *rt = s->priv_data;
  817. rt->seek_timestamp = av_rescale_q(timestamp,
  818. s->streams[stream_index]->time_base,
  819. AV_TIME_BASE_Q);
  820. switch(rt->state) {
  821. default:
  822. case RTSP_STATE_IDLE:
  823. break;
  824. case RTSP_STATE_STREAMING:
  825. if (rtsp_read_pause(s) != 0)
  826. return -1;
  827. rt->state = RTSP_STATE_SEEKING;
  828. if (rtsp_read_play(s) != 0)
  829. return -1;
  830. break;
  831. case RTSP_STATE_PAUSED:
  832. rt->state = RTSP_STATE_IDLE;
  833. break;
  834. }
  835. return 0;
  836. }
  837. static const AVClass rtsp_demuxer_class = {
  838. .class_name = "RTSP demuxer",
  839. .item_name = av_default_item_name,
  840. .option = ff_rtsp_options,
  841. .version = LIBAVUTIL_VERSION_INT,
  842. };
  843. AVInputFormat ff_rtsp_demuxer = {
  844. .name = "rtsp",
  845. .long_name = NULL_IF_CONFIG_SMALL("RTSP input format"),
  846. .priv_data_size = sizeof(RTSPState),
  847. .read_probe = rtsp_probe,
  848. .read_header = rtsp_read_header,
  849. .read_packet = rtsp_read_packet,
  850. .read_close = rtsp_read_close,
  851. .read_seek = rtsp_read_seek,
  852. .flags = AVFMT_NOFILE,
  853. .read_play = rtsp_read_play,
  854. .read_pause = rtsp_read_pause,
  855. .priv_class = &rtsp_demuxer_class,
  856. };