[FFmpeg-devel] [PATCH] libavformat/rtpproto, libavformat/rtsp: receive multicast rtp input
UsingtcNower
nowerzt at gmail.com
Tue Jul 3 12:16:27 EEST 2018
Signed-off-by: UsingtcNower <nowerzt at 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
More information about the ffmpeg-devel
mailing list