From patchwork Fri Nov 26 10:49:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 31748 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:d206:0:0:0:0:0 with SMTP id q6csp2033763iob; Fri, 26 Nov 2021 02:49:24 -0800 (PST) X-Google-Smtp-Source: ABdhPJyM+6HhLijMl+No4e91usxs16vkoHeCqUHFKVg7xRhmrCRbjcQWBnaNMVoBeECLPIq7vgc3 X-Received: by 2002:a17:907:7d8f:: with SMTP id oz15mr36274668ejc.245.1637923764273; Fri, 26 Nov 2021 02:49:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637923764; cv=none; d=google.com; s=arc-20160816; b=rCNV04eP3PcoF2MqnP9I/Hm7QwvOkPLnu7scC56e3UPW+4cUsnGfEWjPF23YTYkqA2 XkF7KCAYeYrShWZhzZybrAYGoZRIg4jgnbG/WK9/LYytxxqVvnE5w0e8Gg2zkyusLRFT kRbjH/b2Hb/SKdiu8WXH1lgzusIB3kAdx45vw/26DNuli3MZJ/zD6Ixk3QOQEUf3iutY UfC2d8LdK1gzer0OgAfOcx6u/p9O/ngz/ISRd5/xm2Y4l48TMm9dqpBcN5KCzh+nxOVD /ROtAUoeNBSKF8KPenyb/vTLIZY45pIn/U3FbCyualyi3mnTRa289BYafUIBpEuUY1Gl Zrcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=IW3hCY+gCtZRQRfDyaLLa0wSPSnSrDxgr/ZipJSUzjE=; b=mubP0MbWMjU3sssLCRINCG5PAgR/Tk+rvCPEb8KLwTD+HbXMf/mbOdquEMqMy0X2Bs x/CDBsfw7+l8foV7iMhHus2yddC7Dbj1aolKh1GQjQidxpBTDQK+7tg/Gr/zdZz60B5b Y0h2vDiSEwDEkqdGBsVRPxZPnK2AkjhTvknyw8yaHmt5SbLRxkA8ZdvbJexMV7Rejn4W MNk2JY1uc9vAwxF3DOMP9qEil3CHYZVL16Ed1I73I9Csa0pmX4yoQb/lIRUOQYajlQuQ L+MJ0BEap0jSTIOIRtf8Tdexz5viGzOlO81xNOb2XUo2t4A7/8pxBVe+57K+m02ODmMV YMig== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=drLU71u9; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id he42si11620081ejc.634.2021.11.26.02.49.23; Fri, 26 Nov 2021 02:49:24 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=drLU71u9; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AB8D968A2EC; Fri, 26 Nov 2021 12:49:21 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f177.google.com (mail-pf1-f177.google.com [209.85.210.177]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A95E868A2EC for ; Fri, 26 Nov 2021 12:49:14 +0200 (EET) Received: by mail-pf1-f177.google.com with SMTP id i12so8577060pfd.6 for ; Fri, 26 Nov 2021 02:49:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jmMa453rZdsSdHFySfhr72+ZfEYAw2VqEXXueDy/ZSY=; b=drLU71u96AfeVRGWT1mDVIHTJqwGaLDafkikWdUmk/1G+12z/VkRHXQTqdAtIbwSKI LhSxUyJInQlhkVmbgaXkSDuhDzQQyJpaFihm1kym6Z+mRLwdxgkIRymrnnGQ8KErIqqR I+EjtQon0mMvez3hMtqDwxb/pKVbvgcIGpd0B+Ut23UKnqRUcRD4wwB4BcN/hKCESoIX 2hU+EPt3KbH6fzFT/e/YHKXZ+0JAbJfEWPTJC5EAzCtltdxrJVxd+8xH3zlDLKGbsG4f ae183HLJuA8uBlLh9RLZicxR7RNOyjwCohqgM2k/rbfbwds1uC97amh/T3FKTWUERthQ TJng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jmMa453rZdsSdHFySfhr72+ZfEYAw2VqEXXueDy/ZSY=; b=yIPmcD7EmyvQDY7udx5ps+qu8lTDZ96TrWvzCvVpAYV2bW4M8FkBpf+YUY0lLD1ZcB flVznsIniEh2Se8Nfrn8joUwCsiJdWhPHceUz9PwHr+fVcl4ndklJlvrBkWeRJC1DvZ/ SIm1sFFedKE/Iv4Gudoil3/wsur9syeT8CZP4PtmGZ5OGWYHGGTxJMKlO1SCW+aXBG3v qOkI/j75VFk3xpYlLYLkZJkgZqlVHp8KF4+0ZbOz/IsaDnlmMwB+ZGmmUsZ3jHWZQSIU nMAu4UdVWnJfre5/lYt4MWGf6WyhGKqRT4+utrds+RA38ZPDX2faBi2zHui5dmgaaqOx KpjA== X-Gm-Message-State: AOAM530NpC96QqpRA3kLuQkrc2mE8uXW7SqhMEEd+J/Ujm/CqKW22zCU p65ynp6Hq+KZy9lge0zAHsW8STDgGrc= X-Received: by 2002:a62:18d2:0:b0:4a2:b2d0:c39f with SMTP id 201-20020a6218d2000000b004a2b2d0c39fmr20127725pfy.69.1637923752683; Fri, 26 Nov 2021 02:49:12 -0800 (PST) Received: from vpn2.localdomain ([161.117.202.209]) by smtp.gmail.com with ESMTPSA id w1sm6380975pfg.11.2021.11.26.02.49.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Nov 2021 02:49:12 -0800 (PST) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Fri, 26 Nov 2021 18:49:07 +0800 Message-Id: <1637923747-21913-1-git-send-email-lance.lmwang@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637837128-31393-1-git-send-email-lance.lmwang@gmail.com> References: <1637837128-31393-1-git-send-email-lance.lmwang@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2] avformat/rtp: add localaddr for network interface selection X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Limin Wang Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: M+jgvk+o5Gqr From: Limin Wang Reviewed-by: Martin Storsjö Signed-off-by: Limin Wang --- support for both sdp and rtp for v2: 1, -localaddr xx.xx.xx.xx -i 1.sdp 2, -localaddr xx.xx.xx.xx -i rtp://xx.xx.xx.xx:xx 3, -i rtp://xx.xx.xx.xx:xx?localadd xx.xx.xx.xx doc/protocols.texi | 4 ++++ libavformat/rtpproto.c | 17 ++++++++++++++--- libavformat/rtsp.c | 11 +++++++++++ libavformat/rtsp.h | 1 + 4 files changed, 30 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. + @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..38df94f 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -105,6 +105,7 @@ static const AVOption sdp_options[] = { { "custom_io", "use custom I/O", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" }, { "rtcp_to_source", "send RTCP packets to the source address of received packets", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_RTCP_TO_SOURCE}, 0, 0, DEC, "rtsp_flags" }, { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections", OFFSET(stimeout), AV_OPT_TYPE_DURATION, {.i64 = READ_PACKET_TIMEOUT_S*1000000}, INT_MIN, INT64_MAX, DEC }, + { "localaddr", "local address", OFFSET(localaddr), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \ RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"), COMMON_OPTS(), { NULL }, @@ -113,6 +114,7 @@ static const AVOption sdp_options[] = { static const AVOption rtp_options[] = { RTSP_FLAG_OPTS("rtp_flags", "set RTP flags"), { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections", OFFSET(stimeout), AV_OPT_TYPE_DURATION, {.i64 = READ_PACKET_TIMEOUT_S*1000000}, INT_MIN, INT64_MAX, DEC }, + { "localaddr", "local address", OFFSET(localaddr),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \ RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"), COMMON_OPTS(), { NULL }, @@ -125,6 +127,8 @@ static AVDictionary *map_to_opts(RTSPState *rt) av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0); av_dict_set_int(&opts, "pkt_size", rt->pkt_size, 0); + if (rt->localaddr && rt->localaddr[0]) + av_dict_set(&opts, "localaddr", rt->localaddr, 0); return opts; } @@ -2407,6 +2411,8 @@ static int sdp_read_header(AVFormatContext *s) if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) { AVDictionary *opts = map_to_opts(rt); + char buf[MAX_URL_SIZE]; + const char *p; err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip), @@ -2424,6 +2430,11 @@ 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_strlcatf(url, sizeof(url), "&localaddr=%s", buf); + else 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 -