Signed-off-by: UsingtcNower <nowe...@gmail.com> --- libavformat/rtpproto.c | 20 +++++++++++++++----- libavformat/rtsp.c | 16 +++++++++++++++- libavformat/rtsp.h | 5 +++++ 3 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index c01d9ce..6bb0324 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -59,6 +59,7 @@ typedef struct RTPContext { char *sources; char *block; char *fec_options_str; + char *localaddr; } RTPContext; #define OFFSET(x) offsetof(RTPContext, x) @@ -77,6 +78,7 @@ static const AVOption options[] = { { "sources", "Source list", OFFSET(sources), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { "block", "Block list", OFFSET(block), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { "fec", "FEC", OFFSET(fec_options_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = E }, + { "localaddr", "Local address", OFFSET(localaddr), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { NULL } }; @@ -230,7 +232,8 @@ static void build_udp_url(RTPContext *s, const char *hostname, int port, int local_port, const char *include_sources, - const char *exclude_sources) + const char *exclude_sources, + const char *localaddr) { ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL); if (local_port >= 0) @@ -250,6 +253,8 @@ static void build_udp_url(RTPContext *s, url_add_option(buf, buf_size, "sources=%s", include_sources); if (exclude_sources && exclude_sources[0]) url_add_option(buf, buf_size, "block=%s", exclude_sources); + if (localaddr && localaddr[0]) + url_add_option(buf, buf_size, "localaddr=%s", localaddr); } static void rtp_parse_addr_list(URLContext *h, char *buf, @@ -320,7 +325,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) RTPContext *s = h->priv_data; AVDictionary *fec_opts = NULL; int rtp_port; - char hostname[256], include_sources[1024] = "", exclude_sources[1024] = ""; + char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "", localaddr[1024] = ""; char *sources = include_sources, *block = exclude_sources; char *fec_protocol = NULL; char buf[1024]; @@ -379,7 +384,12 @@ static int rtp_open(URLContext *h, const char *uri, int flags) rtp_parse_addr_list(h, s->block, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs); block = s->block; } + if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) { + av_strlcpy(localaddr, buf, sizeof(localaddr)); + } } + if(!localaddr[0] && s->localaddr) + av_strlcpy(localaddr, s->localaddr, sizeof(localaddr)); if (s->fec_options_str) { p = s->fec_options_str; @@ -409,7 +419,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) for (i = 0; i < max_retry_count; i++) { build_udp_url(s, buf, sizeof(buf), hostname, rtp_port, s->local_rtpport, - sources, block); + sources, block, localaddr); if (ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist, h) < 0) goto fail; @@ -423,7 +433,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) s->local_rtcpport = s->local_rtpport + 1; build_udp_url(s, buf, sizeof(buf), hostname, s->rtcp_port, s->local_rtcpport, - sources, block); + sources, block, localaddr); if (ffurl_open_whitelist(&s->rtcp_hd, buf, rtcpflags, &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist, h) < 0) { @@ -434,7 +444,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) } build_udp_url(s, buf, sizeof(buf), hostname, s->rtcp_port, s->local_rtcpport, - sources, block); + sources, block, localaddr); if (ffurl_open_whitelist(&s->rtcp_hd, buf, rtcpflags, &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist, h) < 0) goto fail; diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index ceb770a..e18efbf 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -120,6 +120,7 @@ static const AVOption sdp_options[] = { static const AVOption rtp_options[] = { RTSP_FLAG_OPTS("rtp_flags", "set RTP flags"), COMMON_OPTS(), + { "localaddr", "Local address", OFFSET(localaddr), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = DEC|ENC}, { NULL }, }; @@ -2314,6 +2315,8 @@ static int sdp_read_header(AVFormatContext *s) int size, i, err; char *content; char url[1024]; + char buf[1024]; + const char *p; if (!ff_network_init()) return AVERROR(EIO); @@ -2363,6 +2366,14 @@ static int sdp_read_header(AVFormatContext *s) rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0, rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0); + p = strchr(s->url, '?'); + if(p && av_find_info_tag(buf, sizeof(buf), "localaddr", p)) { + av_strlcat(url, "&localaddr=", sizeof(url)); + av_strlcat(url, buf, sizeof(url)); + } else if(rt->localaddr) { + av_strlcat(url, "&localaddr=", sizeof(url)); + av_strlcat(url, rt->localaddr, sizeof(url)); + } append_source_addrs(url, sizeof(url), "sources", rtsp_st->nb_include_source_addrs, rtsp_st->include_source_addrs); @@ -2435,12 +2446,15 @@ static int rtp_read_header(AVFormatContext *s) AVIOContext pb; socklen_t addrlen = sizeof(addr); RTSPState *rt = s->priv_data; + AVDictionary *opts = NULL; if (!ff_network_init()) return AVERROR(EIO); + av_dict_set(&opts, "localaddr", rt->localaddr, 0); ret = ffurl_open_whitelist(&in, s->url, AVIO_FLAG_READ, - &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL); + &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL); + av_dict_free(&opts); if (ret) goto fail; diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index 9a7f366..6a32788 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -409,6 +409,11 @@ typedef struct RTSPState { char default_lang[4]; int buffer_size; + + /** + * Multicast local address + */ + char *localaddr; } RTSPState; #define RTSP_FLAG_FILTER_SRC 0x1 /**< Filter incoming UDP packets - -- 1.8.3.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel