static int rtp_open(URLContext *h, const char *uri, int flags) { RTPContext *s = h->priv_data; int rtp_port, rtcp_port, ttl, connect, local_rtp_port, local_rtcp_port, max_packet_size; char hostname[256], include_sources[1024] = "", exclude_sources[1024] = ""; char buf[1024]; char path[1024]; const char *p; int i, max_retry_count = 3; 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; connect = 0; p = strchr(uri, '?'); if (p) { if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) { ttl = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) { rtcp_port = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "localport", p)) { local_rtp_port = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) { local_rtp_port = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) { local_rtcp_port = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) { max_packet_size = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { connect = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) { s->write_to_source = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "sources", p)) { av_strlcpy(include_sources, buf, sizeof(include_sources)); rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs); } if (av_find_info_tag(buf, sizeof(buf), "block", p)) { av_strlcpy(exclude_sources, buf, sizeof(exclude_sources)); rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs); } } for (i = 0;i < max_retry_count;i++) { build_udp_url(buf, sizeof(buf), hostname, rtp_port, local_rtp_port, ttl, max_packet_size, connect, include_sources, exclude_sources); if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) goto fail; local_rtp_port = ff_udp_get_local_port(s->rtp_hd); if(local_rtp_port == 65535) { local_rtp_port = -1; continue; } if (local_rtcp_port<0) { local_rtcp_port = local_rtp_port + 1; build_udp_url(buf, sizeof(buf), hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size, connect, include_sources, exclude_sources); if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) { local_rtp_port = local_rtcp_port = -1; continue; } break; } build_udp_url(buf, sizeof(buf), hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size, connect, include_sources, exclude_sources); if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) goto fail; break; } /* just to ease handle access. XXX: need to suppress direct handle access */ s->rtp_fd = ffurl_get_file_handle(s->rtp_hd); s->rtcp_fd = ffurl_get_file_handle(s->rtcp_hd); h->max_packet_size = s->rtp_hd->max_packet_size; h->is_streamed = 1; return 0; fail: if (s->rtp_hd) ffurl_close(s->rtp_hd); if (s->rtcp_hd) ffurl_close(s->rtcp_hd); return AVERROR(EIO); }
static int rtp_open(URLContext *h, const char *uri, int flags) { RTPContext *s = h->priv_data; int rtp_port; char hostname[256], include_sources[1024] = "", exclude_sources[1024] = ""; char *sources = include_sources, *block = exclude_sources; char buf[1024]; char path[1024]; const char *p; av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port, path, sizeof(path), uri); /* extract parameters */ if (s->rtcp_port < 0) s->rtcp_port = rtp_port + 1; p = strchr(uri, '?'); if (p) { if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) { s->ttl = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) { s->rtcp_port = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "localport", p)) { s->local_rtpport = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) { s->local_rtpport = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) { s->local_rtcpport = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) { s->pkt_size = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { s->connect = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) { s->write_to_source = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "sources", p)) { av_strlcpy(include_sources, buf, sizeof(include_sources)); rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs); } else { rtp_parse_addr_list(h, s->sources, &s->ssm_include_addrs, &s->nb_ssm_include_addrs); sources = s->sources; } if (av_find_info_tag(buf, sizeof(buf), "block", p)) { av_strlcpy(exclude_sources, buf, sizeof(exclude_sources)); rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs); } else { rtp_parse_addr_list(h, s->block, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs); block = s->block; } } build_udp_url(s, buf, sizeof(buf), hostname, rtp_port, s->local_rtpport, sources, block); if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL, h->protocols, h) < 0) goto fail; if (s->local_rtpport >= 0 && s->local_rtcpport < 0) s->local_rtcpport = ff_udp_get_local_port(s->rtp_hd) + 1; build_udp_url(s, buf, sizeof(buf), hostname, s->rtcp_port, s->local_rtcpport, sources, block); if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL, h->protocols, h) < 0) goto fail; /* just to ease handle access. XXX: need to suppress direct handle access */ s->rtp_fd = ffurl_get_file_handle(s->rtp_hd); s->rtcp_fd = ffurl_get_file_handle(s->rtcp_hd); h->max_packet_size = s->rtp_hd->max_packet_size; h->is_streamed = 1; return 0; fail: if (s->rtp_hd) ffurl_close(s->rtp_hd); if (s->rtcp_hd) ffurl_close(s->rtcp_hd); return AVERROR(EIO); }