/* * url syntax: rtp://host:port[?option=val...] * option: 'multicast=1' : enable multicast * 'ttl=n' : set the ttl value (for multicast only) * 'localport=n' : set the local port to n * */ static int rtp_open(URLContext *h, const char *uri, int flags) { RTPContext *s; int port, is_output, is_multicast, ttl, local_port; char hostname[256]; char buf[1024]; char path[1024]; const char *p; is_output = (flags & URL_WRONLY); s = av_mallocz(sizeof(RTPContext)); if (!s) return AVERROR(ENOMEM); h->priv_data = s; url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); /* extract parameters */ is_multicast = 0; ttl = -1; local_port = -1; p = strchr(uri, '?'); if (p) { is_multicast = find_info_tag(buf, sizeof(buf), "multicast", p); if (find_info_tag(buf, sizeof(buf), "ttl", p)) { ttl = strtol(buf, NULL, 10); } if (find_info_tag(buf, sizeof(buf), "localport", p)) { local_port = strtol(buf, NULL, 10); } } build_udp_url(buf, sizeof(buf), hostname, port, local_port, is_multicast, ttl); if (url_open(&s->rtp_hd, buf, flags) < 0) goto fail; local_port = udp_get_local_port(s->rtp_hd); /* XXX: need to open another connexion if the port is not even */ /* well, should suppress localport in path */ build_udp_url(buf, sizeof(buf), hostname, port + 1, local_port + 1, is_multicast, ttl); if (url_open(&s->rtcp_hd, buf, flags) < 0) goto fail; /* just to ease handle access. XXX: need to suppress direct handle access */ s->rtp_fd = udp_get_file_handle(s->rtp_hd); s->rtcp_fd = udp_get_file_handle(s->rtcp_hd); h->max_packet_size = url_get_max_packet_size(s->rtp_hd); h->is_streamed = 1; return 0; fail: if (s->rtp_hd) url_close(s->rtp_hd); if (s->rtcp_hd) url_close(s->rtcp_hd); av_free(s); return AVERROR_IO; }
/** * Return the local port used by the RTP connexion * @param s1 media file context * @return the local port number */ int rtp_get_local_port(URLContext *h) { RTPContext *s = h->priv_data; return udp_get_local_port(s->rtp_hd); }
static int rtp_open(URLContext *h, const char *uri, int flags) { RTPContext *s; int rtp_port, rtcp_port, is_output, ttl, local_rtp_port, local_rtcp_port, max_packet_size; char hostname[256]; char buf[1024]; char path[1024]; const char *p; is_output = (flags & URL_WRONLY); s = av_mallocz(sizeof(RTPContext)); if (!s) return AVERROR(ENOMEM); h->priv_data = s; av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port, path, sizeof(path), uri); /* extract parameters */ ttl = -1; rtcp_port = rtp_port+1; local_rtp_port = -1; local_rtcp_port = -1; max_packet_size = -1; p = strchr(uri, '?'); if (p) { if (find_info_tag(buf, sizeof(buf), "ttl", p)) { ttl = strtol(buf, NULL, 10); } if (find_info_tag(buf, sizeof(buf), "rtcpport", p)) { rtcp_port = strtol(buf, NULL, 10); } if (find_info_tag(buf, sizeof(buf), "localport", p)) { local_rtp_port = strtol(buf, NULL, 10); } if (find_info_tag(buf, sizeof(buf), "localrtpport", p)) { local_rtp_port = strtol(buf, NULL, 10); } if (find_info_tag(buf, sizeof(buf), "localrtcpport", p)) { local_rtcp_port = strtol(buf, NULL, 10); } if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) { max_packet_size = strtol(buf, NULL, 10); } } build_udp_url(buf, sizeof(buf), hostname, rtp_port, local_rtp_port, ttl, max_packet_size); if (url_open(&s->rtp_hd, buf, flags) < 0) goto fail; if (local_rtp_port>=0 && local_rtcp_port<0) local_rtcp_port = udp_get_local_port(s->rtp_hd) + 1; build_udp_url(buf, sizeof(buf), hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size); if (url_open(&s->rtcp_hd, buf, flags) < 0) goto fail; /* just to ease handle access. XXX: need to suppress direct handle access */ s->rtp_fd = url_get_file_handle(s->rtp_hd); s->rtcp_fd = url_get_file_handle(s->rtcp_hd); h->max_packet_size = url_get_max_packet_size(s->rtp_hd); h->is_streamed = 1; return 0; fail: if (s->rtp_hd) url_close(s->rtp_hd); if (s->rtcp_hd) url_close(s->rtcp_hd); av_free(s); return AVERROR(EIO); }