diff mbox series

[FFmpeg-devel,1/2] avformat/rtp: add localaddr for network interface selection

Message ID 1637837128-31393-1-git-send-email-lance.lmwang@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/2] avformat/rtp: add localaddr for network interface selection | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Lance Wang Nov. 25, 2021, 10:45 a.m. UTC
From: Limin Wang <lance.lmwang@gmail.com>

Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
---
 doc/protocols.texi     |  4 ++++
 libavformat/rtpproto.c | 17 ++++++++++++++---
 libavformat/rtsp.c     |  3 +++
 libavformat/rtsp.h     |  1 +
 4 files changed, 22 insertions(+), 3 deletions(-)

Comments

Martin Storsjö Nov. 25, 2021, 10:56 a.m. UTC | #1
On Thu, 25 Nov 2021, lance.lmwang@gmail.com wrote:

> From: Limin Wang <lance.lmwang@gmail.com>
>
> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> ---
> doc/protocols.texi     |  4 ++++
> libavformat/rtpproto.c | 17 ++++++++++++++---
> libavformat/rtsp.c     |  3 +++
> libavformat/rtsp.h     |  1 +
> 4 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/doc/protocols.texi b/doc/protocols.texi
> index c100f23..d207df0 100644
> --- a/doc/protocols.texi
> +++ b/doc/protocols.texi
> @@ -1087,6 +1087,10 @@ set to 1) or to a default remote address (if set to 0).
> @item localport=@var{n}
> Set the local RTP port to @var{n}.
>
> +@item localaddr=@var{addr}
> +Local IP address of a network interface used for sending packets or joining
> +multicast groups.

Just to clarify things for myself for understanding this: Today, if 
receiving UDP unicast, we can use udp://<localip>:<port> to select which 
local IP address to listen on? But for multicast, we'd do 
udp://<multicast-ip>:<port>?localaddr=<localip> to select which address to 
use for joining the group?

// Martin
Lance Wang Nov. 25, 2021, 1:53 p.m. UTC | #2
On Thu, Nov 25, 2021 at 12:56:24PM +0200, Martin Storsjö wrote:
> On Thu, 25 Nov 2021, lance.lmwang@gmail.com wrote:
> 
> > From: Limin Wang <lance.lmwang@gmail.com>
> > 
> > Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> > ---
> > doc/protocols.texi     |  4 ++++
> > libavformat/rtpproto.c | 17 ++++++++++++++---
> > libavformat/rtsp.c     |  3 +++
> > libavformat/rtsp.h     |  1 +
> > 4 files changed, 22 insertions(+), 3 deletions(-)
> > 
> > diff --git a/doc/protocols.texi b/doc/protocols.texi
> > index c100f23..d207df0 100644
> > --- a/doc/protocols.texi
> > +++ b/doc/protocols.texi
> > @@ -1087,6 +1087,10 @@ set to 1) or to a default remote address (if set to 0).
> > @item localport=@var{n}
> > Set the local RTP port to @var{n}.
> > 
> > +@item localaddr=@var{addr}
> > +Local IP address of a network interface used for sending packets or joining
> > +multicast groups.
> 
> Just to clarify things for myself for understanding this: Today, if
> receiving UDP unicast, we can use udp://<localip>:<port> to select which
> local IP address to listen on? But for multicast, we'd do
> udp://<multicast-ip>:<port>?localaddr=<localip> to select which address to
> use for joining the group?

yes, it's useful to select/bind which network interface to use for the multicast
stream in case you have many network port, udp have support it already, but rtp haven't
yet. 

> 
> // Martin
>
Martin Storsjö Nov. 25, 2021, 8:09 p.m. UTC | #3
On Thu, 25 Nov 2021, lance.lmwang@gmail.com wrote:

> From: Limin Wang <lance.lmwang@gmail.com>
>
> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> ---
> doc/protocols.texi     |  4 ++++
> libavformat/rtpproto.c | 17 ++++++++++++++---
> libavformat/rtsp.c     |  3 +++
> libavformat/rtsp.h     |  1 +
> 4 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index a1aa969..3897826 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -74,6 +74,7 @@
> #define COMMON_OPTS() \
>     { "reorder_queue_size", "set number of packets to buffer for handling of reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC }, \
>     { "buffer_size",        "Underlying protocol send/receive buffer size",                  OFFSET(buffer_size),           AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC|ENC }, \
> +    { "localaddr",          "local address",                                                 OFFSET(localaddr),             AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC|ENC }, \
>     { "pkt_size",           "Underlying protocol send packet size",                          OFFSET(pkt_size),              AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC } \

As far as I can see, this is only used in sdp_read_header; wouldn't it be 
better to move this option to sdp_options then?

The rest of the patch seems fine I think.

// Martin
Lance Wang Nov. 26, 2021, 1:31 a.m. UTC | #4
On Thu, Nov 25, 2021 at 10:09:17PM +0200, Martin Storsjö wrote:
> On Thu, 25 Nov 2021, lance.lmwang@gmail.com wrote:
> 
> > From: Limin Wang <lance.lmwang@gmail.com>
> > 
> > Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> > ---
> > doc/protocols.texi     |  4 ++++
> > libavformat/rtpproto.c | 17 ++++++++++++++---
> > libavformat/rtsp.c     |  3 +++
> > libavformat/rtsp.h     |  1 +
> > 4 files changed, 22 insertions(+), 3 deletions(-)
> > 
> > diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> > index a1aa969..3897826 100644
> > --- a/libavformat/rtsp.c
> > +++ b/libavformat/rtsp.c
> > @@ -74,6 +74,7 @@
> > #define COMMON_OPTS() \
> >     { "reorder_queue_size", "set number of packets to buffer for handling of reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC }, \
> >     { "buffer_size",        "Underlying protocol send/receive buffer size",                  OFFSET(buffer_size),           AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC|ENC }, \
> > +    { "localaddr",          "local address",                                                 OFFSET(localaddr),             AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC|ENC }, \
> >     { "pkt_size",           "Underlying protocol send packet size",                          OFFSET(pkt_size),              AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC } \
> 
> As far as I can see, this is only used in sdp_read_header; wouldn't it be
> better to move this option to sdp_options then?

OK, I'll move for sdp_iotions only.

> 
> The rest of the patch seems fine I think.
> 
> // Martin
>
diff mbox series

Patch

diff --git a/doc/protocols.texi b/doc/protocols.texi
index c100f23..d207df0 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1087,6 +1087,10 @@  set to 1) or to a default remote address (if set to 0).
 @item localport=@var{n}
 Set the local RTP port to @var{n}.
 
+@item localaddr=@var{addr}
+Local IP address of a network interface used for sending packets or joining
+multicast groups.
+
 @item timeout=@var{n}
 Set timeout (in microseconds) of socket I/O operations to @var{n}.
 
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index 7dd6042..c92cda6 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -61,6 +61,7 @@  typedef struct RTPContext {
     char *block;
     char *fec_options_str;
     int64_t rw_timeout;
+    char *localaddr;
 } RTPContext;
 
 #define OFFSET(x) offsetof(RTPContext, x)
@@ -80,6 +81,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 }
 };
 
@@ -173,6 +175,7 @@  static av_printf_format(3, 4) void url_add_option(char *buf, int buf_size, const
 static void build_udp_url(RTPContext *s,
                           char *buf, int buf_size,
                           const char *hostname,
+                          const char *localaddr,
                           int port, int local_port,
                           const char *include_sources,
                           const char *exclude_sources)
@@ -195,6 +198,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);
 }
 
 /**
@@ -284,6 +289,12 @@  static int rtp_open(URLContext *h, const char *uri, int flags)
             ff_ip_parse_blocks(h, s->block, &s->filters);
             block = s->block;
         }
+        if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
+            av_freep(&s->localaddr);
+            s->localaddr = av_strdup(buf);
+            if (!s->localaddr)
+                goto fail;
+        }
     }
     if (s->rw_timeout >= 0)
         h->rw_timeout = s->rw_timeout;
@@ -314,7 +325,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,
+                      hostname, s->localaddr, rtp_port, s->local_rtpport,
                       sources, block);
         if (ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback,
                                  NULL, h->protocol_whitelist, h->protocol_blacklist, h) < 0)
@@ -328,7 +339,7 @@  static int rtp_open(URLContext *h, const char *uri, int flags)
         if (s->local_rtcpport < 0) {
             s->local_rtcpport = s->local_rtpport + 1;
             build_udp_url(s, buf, sizeof(buf),
-                          hostname, s->rtcp_port, s->local_rtcpport,
+                          hostname, s->localaddr, s->rtcp_port, s->local_rtcpport,
                           sources, block);
             if (ffurl_open_whitelist(&s->rtcp_hd, buf, rtcpflags,
                                      &h->interrupt_callback, NULL,
@@ -339,7 +350,7 @@  static int rtp_open(URLContext *h, const char *uri, int flags)
             break;
         }
         build_udp_url(s, buf, sizeof(buf),
-                      hostname, s->rtcp_port, s->local_rtcpport,
+                      hostname, s->localaddr, s->rtcp_port, s->local_rtcpport,
                       sources, block);
         if (ffurl_open_whitelist(&s->rtcp_hd, buf, rtcpflags, &h->interrupt_callback,
                                  NULL, h->protocol_whitelist, h->protocol_blacklist, h) < 0)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index a1aa969..3897826 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -74,6 +74,7 @@ 
 #define COMMON_OPTS() \
     { "reorder_queue_size", "set number of packets to buffer for handling of reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC }, \
     { "buffer_size",        "Underlying protocol send/receive buffer size",                  OFFSET(buffer_size),           AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC|ENC }, \
+    { "localaddr",          "local address",                                                 OFFSET(localaddr),             AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC|ENC }, \
     { "pkt_size",           "Underlying protocol send packet size",                          OFFSET(pkt_size),              AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC } \
 
 
@@ -2424,6 +2425,8 @@  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);
 
+            if (rt->localaddr && rt->localaddr[0])
+                av_strlcatf(url, sizeof(url), "&localaddr=%s", rt->localaddr);
             append_source_addrs(url, sizeof(url), "sources",
                                 rtsp_st->nb_include_source_addrs,
                                 rtsp_st->include_source_addrs);
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 4ec974e..d6fdfe0 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -419,6 +419,7 @@  typedef struct RTSPState {
     char default_lang[4];
     int buffer_size;
     int pkt_size;
+    char *localaddr;
 } RTSPState;
 
 #define RTSP_FLAG_FILTER_SRC  0x1    /**< Filter incoming UDP packets -