[FFmpeg-devel] libavformat/rtpproto, libavformat/rtsp: receive multicast rtp input

Submitted by UsingtcNower on July 3, 2018, 9:16 a.m.

Details

Message ID 1530609387-38382-1-git-send-email-nowerzt@gmail.com
State New
Headers show

Commit Message

UsingtcNower July 3, 2018, 9:16 a.m.
Signed-off-by: UsingtcNower <nowerzt@gmail.com>
---
 libavformat/rtpproto.c | 20 +++++++++++++++-----
 libavformat/rtsp.c     | 16 +++++++++++++++-
 libavformat/rtsp.h     |  5 +++++
 3 files changed, 35 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

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 -