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.

425 lines
14KB

  1. /*
  2. * RTP network protocol
  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. /**
  22. * @file
  23. * RTP protocol
  24. */
  25. #include "libavutil/parseutils.h"
  26. #include "libavutil/avstring.h"
  27. #include "avformat.h"
  28. #include "avio_internal.h"
  29. #include "rtpdec.h"
  30. #include "url.h"
  31. #include <stdarg.h>
  32. #include "internal.h"
  33. #include "network.h"
  34. #include "os_support.h"
  35. #include <fcntl.h>
  36. #if HAVE_POLL_H
  37. #include <sys/poll.h>
  38. #endif
  39. typedef struct RTPContext {
  40. URLContext *rtp_hd, *rtcp_hd;
  41. int rtp_fd, rtcp_fd, ssm;
  42. struct sockaddr_storage ssm_addr;
  43. } RTPContext;
  44. /**
  45. * If no filename is given to av_open_input_file because you want to
  46. * get the local port first, then you must call this function to set
  47. * the remote server address.
  48. *
  49. * @param h media file context
  50. * @param uri of the remote server
  51. * @return zero if no error.
  52. */
  53. int ff_rtp_set_remote_url(URLContext *h, const char *uri)
  54. {
  55. RTPContext *s = h->priv_data;
  56. char hostname[256];
  57. int port;
  58. char buf[1024];
  59. char path[1024];
  60. av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
  61. path, sizeof(path), uri);
  62. ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port, "%s", path);
  63. ff_udp_set_remote_url(s->rtp_hd, buf);
  64. ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port + 1, "%s", path);
  65. ff_udp_set_remote_url(s->rtcp_hd, buf);
  66. return 0;
  67. }
  68. static struct addrinfo* rtp_resolve_host(const char *hostname, int port,
  69. int type, int family, int flags)
  70. {
  71. struct addrinfo hints = { 0 }, *res = 0;
  72. int error;
  73. char sport[16];
  74. const char *node = 0, *service = "0";
  75. if (port > 0) {
  76. snprintf(sport, sizeof(sport), "%d", port);
  77. service = sport;
  78. }
  79. if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) {
  80. node = hostname;
  81. }
  82. hints.ai_socktype = type;
  83. hints.ai_family = family;
  84. hints.ai_flags = flags;
  85. if ((error = getaddrinfo(node, service, &hints, &res))) {
  86. res = NULL;
  87. av_log(NULL, AV_LOG_ERROR, "rtp_resolve_host: %s\n", gai_strerror(error));
  88. }
  89. return res;
  90. }
  91. /**
  92. * add option to url of the form:
  93. * "http://host:port/path?option1=val1&option2=val2...
  94. */
  95. static av_printf_format(3, 4) void url_add_option(char *buf, int buf_size, const char *fmt, ...)
  96. {
  97. char buf1[1024];
  98. va_list ap;
  99. va_start(ap, fmt);
  100. if (strchr(buf, '?'))
  101. av_strlcat(buf, "&", buf_size);
  102. else
  103. av_strlcat(buf, "?", buf_size);
  104. vsnprintf(buf1, sizeof(buf1), fmt, ap);
  105. av_strlcat(buf, buf1, buf_size);
  106. va_end(ap);
  107. }
  108. static void build_udp_url(char *buf, int buf_size,
  109. const char *hostname, int port,
  110. int ssm, const char* source_addr,
  111. int local_port, int ttl,
  112. int max_packet_size, int connect)
  113. {
  114. ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL);
  115. if (local_port >= 0)
  116. url_add_option(buf, buf_size, "localport=%d", local_port);
  117. if (ttl >= 0)
  118. url_add_option(buf, buf_size, "ttl=%d", ttl);
  119. if (max_packet_size >=0)
  120. url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size);
  121. if (ssm)
  122. url_add_option(buf, buf_size, "sources=%s", source_addr);
  123. if (connect)
  124. url_add_option(buf, buf_size, "connect=1");
  125. url_add_option(buf, buf_size, "fifo_size=0");
  126. }
  127. /**
  128. * url syntax: rtp://host:port[?option=val...]
  129. * option: 'ttl=n' : set the ttl value (for multicast only)
  130. * 'rtcpport=n' : set the remote rtcp port to n
  131. * 'localrtpport=n' : set the local rtp port to n
  132. * 'localrtcpport=n' : set the local rtcp port to n
  133. * 'pkt_size=n' : set max packet size
  134. * 'connect=0/1' : do a connect() on the UDP socket
  135. * deprecated option:
  136. * 'localport=n' : set the local port to n
  137. * 'ssm=ip' : use ip as source-specific multicast address
  138. *
  139. * if rtcpport isn't set the rtcp port will be the rtp port + 1
  140. * if local rtp port isn't set any available port will be used for the local
  141. * rtp and rtcp ports
  142. * if the local rtcp port is not set it will be the local rtp port + 1
  143. */
  144. static int rtp_open(URLContext *h, const char *uri, int flags)
  145. {
  146. RTPContext *s = h->priv_data;
  147. int rtp_port, rtcp_port,
  148. ttl, connect,
  149. local_rtp_port, local_rtcp_port, max_packet_size;
  150. char hostname[256],source_ip[50];
  151. char buf[1024];
  152. char path[1024];
  153. const char *p;
  154. struct addrinfo *sourceaddr;
  155. av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
  156. path, sizeof(path), uri);
  157. /* extract parameters */
  158. ttl = -1;
  159. rtcp_port = rtp_port+1;
  160. local_rtp_port = -1;
  161. local_rtcp_port = -1;
  162. max_packet_size = -1;
  163. s->ssm = 0;
  164. connect = 0;
  165. p = strchr(uri, '?');
  166. if (p) {
  167. if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
  168. ttl = strtol(buf, NULL, 10);
  169. }
  170. if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
  171. rtcp_port = strtol(buf, NULL, 10);
  172. }
  173. if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
  174. local_rtp_port = strtol(buf, NULL, 10);
  175. }
  176. if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
  177. local_rtp_port = strtol(buf, NULL, 10);
  178. }
  179. if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
  180. local_rtcp_port = strtol(buf, NULL, 10);
  181. }
  182. if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
  183. max_packet_size = strtol(buf, NULL, 10);
  184. }
  185. if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
  186. connect = strtol(buf, NULL, 10);
  187. }
  188. if (av_find_info_tag(buf, sizeof(buf), "ssm", p)) {
  189. s->ssm = 1;
  190. snprintf(source_ip, sizeof(source_ip), "%s", buf);
  191. sourceaddr = rtp_resolve_host(source_ip, 0,
  192. SOCK_DGRAM, AF_UNSPEC,
  193. AI_NUMERICHOST);
  194. memcpy(&s->ssm_addr, sourceaddr->ai_addr, sourceaddr->ai_addrlen);
  195. freeaddrinfo(sourceaddr);
  196. }
  197. }
  198. build_udp_url(buf, sizeof(buf),
  199. hostname, rtp_port, s->ssm, source_ip, local_rtp_port, ttl, max_packet_size,
  200. connect);
  201. if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
  202. goto fail;
  203. if (local_rtp_port>=0 && local_rtcp_port<0)
  204. local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1;
  205. build_udp_url(buf, sizeof(buf),
  206. hostname, rtcp_port, s->ssm, source_ip, local_rtcp_port, ttl, max_packet_size,
  207. connect);
  208. if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
  209. goto fail;
  210. /* just to ease handle access. XXX: need to suppress direct handle
  211. access */
  212. s->rtp_fd = ffurl_get_file_handle(s->rtp_hd);
  213. s->rtcp_fd = ffurl_get_file_handle(s->rtcp_hd);
  214. h->max_packet_size = s->rtp_hd->max_packet_size;
  215. h->is_streamed = 1;
  216. return 0;
  217. fail:
  218. if (s->rtp_hd)
  219. ffurl_close(s->rtp_hd);
  220. if (s->rtcp_hd)
  221. ffurl_close(s->rtcp_hd);
  222. return AVERROR(EIO);
  223. }
  224. static int rtp_read(URLContext *h, uint8_t *buf, int size)
  225. {
  226. RTPContext *s = h->priv_data;
  227. struct sockaddr_storage from;
  228. socklen_t from_len;
  229. int len, n;
  230. struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
  231. for(;;) {
  232. if (ff_check_interrupt(&h->interrupt_callback))
  233. return AVERROR_EXIT;
  234. /* build fdset to listen to RTP and RTCP packets */
  235. n = poll(p, 2, 100);
  236. if (n > 0) {
  237. /* first try RTCP */
  238. if (p[1].revents & POLLIN) {
  239. from_len = sizeof(from);
  240. len = recvfrom (s->rtcp_fd, buf, size, 0,
  241. (struct sockaddr *)&from, &from_len);
  242. if (len < 0) {
  243. if (ff_neterrno() == AVERROR(EAGAIN) ||
  244. ff_neterrno() == AVERROR(EINTR))
  245. continue;
  246. return AVERROR(EIO);
  247. }
  248. if (s->ssm) {
  249. if (from.ss_family == AF_INET && s->ssm_addr.ss_family == AF_INET) {
  250. uint32_t intended_source = ((struct sockaddr_in *)&s->ssm_addr)->sin_addr.s_addr;
  251. uint32_t actual_source = ((struct sockaddr_in *)&from)->sin_addr.s_addr;
  252. if (intended_source != actual_source) {
  253. // discard the packet without any processing
  254. continue;
  255. }
  256. }
  257. #if defined(IPPROTO_IPV6)
  258. if (from.ss_family == AF_INET6 && s->ssm_addr.ss_family == AF_INET6) {
  259. unsigned char* intended_source = ((struct sockaddr_in6 *)&s->ssm_addr)->sin6_addr.s6_addr;
  260. unsigned char* actual_source = ((struct sockaddr_in6 *)&from)->sin6_addr.s6_addr;
  261. if (memcmp(intended_source, actual_source, 16) != 0) {
  262. // discard the packet without any processing
  263. continue;
  264. }
  265. }
  266. #endif
  267. }
  268. break;
  269. }
  270. /* then RTP */
  271. if (p[0].revents & POLLIN) {
  272. from_len = sizeof(from);
  273. len = recvfrom (s->rtp_fd, buf, size, 0,
  274. (struct sockaddr *)&from, &from_len);
  275. if (len < 0) {
  276. if (ff_neterrno() == AVERROR(EAGAIN) ||
  277. ff_neterrno() == AVERROR(EINTR))
  278. continue;
  279. return AVERROR(EIO);
  280. }
  281. if (s->ssm) {
  282. if (from.ss_family == AF_INET && s->ssm_addr.ss_family == AF_INET) {
  283. uint32_t intended_source = ((struct sockaddr_in *)&s->ssm_addr)->sin_addr.s_addr;
  284. uint32_t actual_source = ((struct sockaddr_in *)&from)->sin_addr.s_addr;
  285. if (intended_source != actual_source) {
  286. // discard the packet without any processing
  287. continue;
  288. }
  289. }
  290. #if defined(IPPROTO_IPV6)
  291. if (from.ss_family == AF_INET6 && s->ssm_addr.ss_family == AF_INET6) {
  292. unsigned char* intended_source = ((struct sockaddr_in6 *)&s->ssm_addr)->sin6_addr.s6_addr;
  293. unsigned char* actual_source = ((struct sockaddr_in6 *)&from)->sin6_addr.s6_addr;
  294. if (memcmp(intended_source, actual_source, 16) != 0) {
  295. // discard the packet without any processing
  296. continue;
  297. }
  298. }
  299. #endif
  300. }
  301. break;
  302. }
  303. } else if (n < 0) {
  304. if (ff_neterrno() == AVERROR(EINTR))
  305. continue;
  306. return AVERROR(EIO);
  307. }
  308. }
  309. return len;
  310. }
  311. static int rtp_write(URLContext *h, const uint8_t *buf, int size)
  312. {
  313. RTPContext *s = h->priv_data;
  314. int ret;
  315. URLContext *hd;
  316. if (RTP_PT_IS_RTCP(buf[1])) {
  317. /* RTCP payload type */
  318. hd = s->rtcp_hd;
  319. } else {
  320. /* RTP payload type */
  321. hd = s->rtp_hd;
  322. }
  323. ret = ffurl_write(hd, buf, size);
  324. return ret;
  325. }
  326. static int rtp_close(URLContext *h)
  327. {
  328. RTPContext *s = h->priv_data;
  329. ffurl_close(s->rtp_hd);
  330. ffurl_close(s->rtcp_hd);
  331. return 0;
  332. }
  333. /**
  334. * Return the local rtp port used by the RTP connection
  335. * @param h media file context
  336. * @return the local port number
  337. */
  338. int ff_rtp_get_local_rtp_port(URLContext *h)
  339. {
  340. RTPContext *s = h->priv_data;
  341. return ff_udp_get_local_port(s->rtp_hd);
  342. }
  343. /**
  344. * Return the local rtcp port used by the RTP connection
  345. * @param h media file context
  346. * @return the local port number
  347. */
  348. int ff_rtp_get_local_rtcp_port(URLContext *h)
  349. {
  350. RTPContext *s = h->priv_data;
  351. return ff_udp_get_local_port(s->rtcp_hd);
  352. }
  353. static int rtp_get_file_handle(URLContext *h)
  354. {
  355. RTPContext *s = h->priv_data;
  356. return s->rtp_fd;
  357. }
  358. static int rtp_get_multi_file_handle(URLContext *h, int **handles,
  359. int *numhandles)
  360. {
  361. RTPContext *s = h->priv_data;
  362. int *hs = *handles = av_malloc(sizeof(**handles) * 2);
  363. if (!hs)
  364. return AVERROR(ENOMEM);
  365. hs[0] = s->rtp_fd;
  366. hs[1] = s->rtcp_fd;
  367. *numhandles = 2;
  368. return 0;
  369. }
  370. URLProtocol ff_rtp_protocol = {
  371. .name = "rtp",
  372. .url_open = rtp_open,
  373. .url_read = rtp_read,
  374. .url_write = rtp_write,
  375. .url_close = rtp_close,
  376. .url_get_file_handle = rtp_get_file_handle,
  377. .url_get_multi_file_handle = rtp_get_multi_file_handle,
  378. .priv_data_size = sizeof(RTPContext),
  379. .flags = URL_PROTOCOL_FLAG_NETWORK,
  380. };