From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 89AB94BE8F for ; Fri, 29 Aug 2025 14:07:34 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'VEkcMgFyRKxbuepUBko8s+LpVUUlPz+txjLoWQKXaTc=', expected b'4xY7+Bhy/m1GMrHbVo+pNj+4dXCLQX/XjDqwrZrh3bg=')) header.d=axis.com header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1756476412; h=to : date : message-id : in-reply-to : references : mime-version : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=plEtnrneK8wkpzHWLmDaaojrgV6qVQ1CjVPsGVOXZS4=; b=c8mOZALahuBWLI41Ln/66rmhytG2ppCs2xihS2YWo96ckY3UZZWk3SJyDiTTMch3mE7mT oOz5hkwqOexUH9anRlGEaLCMq9TU9uZHRX+KNhcYT3UTi+giB4CraWfIDT5PI7BnCkxc82s 3xD5eH7ZrDfFg8Et9CZlkGu4WrDgFy8G1Z/638t3qMl2Lt2yk5kghDeWeMnUmEsf65Yv9CZ lcpY2KPTNW2QcnmgiChDm4nkqV7GSgg+CmgOSmGnq/kYnPW7q0fyaCi8t8j1rToH/CHPqaI t6GPgiUSiFbZItUL1t6dF5986HiW3ZPfERqHD047vNxHTkvblZI/B28gC6RQ== Received: from [172.19.0.4] (unknown [172.19.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 4FF4D68E804; Fri, 29 Aug 2025 17:06:52 +0300 (EEST) ARC-Seal: i=2; cv=pass; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1756476398; b=UWko8KKsLQLRgszUdXZYFlVg3buiROcRsosbQC0qVVJaIYE8jRdGoClDRugBkKrkBskfj s/Jds2QgSUEBnzsm1ZUVTOEmlM0LGWpF4O38oX5RNgFI7+bqPNA09QugBVaC60jWOqc0YkJ PRza4DKVplAfmvskvMskWoewOA8gEfeKhMsPkhTdPM9krkwnNgfuftU2tBsAu/hrMr7c22d Tsbyx80bc+itepYWRlbHn5zeYA/Y6PIbeiPA2JYF3atG1RjpOcv4mBaDTeYm/2WPlwlyxSa SrVva6NM7ZIr8ILVAZ1MS0P2UmRxk0sSVLUNOAlAvS1Lrj7AHz1wY1v9LsNA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1756476398; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=VEkcMgFyRKxbuepUBko8s+LpVUUlPz+txjLoWQKXaTc=; b=DI7jCXxX33DkHEmUTKqXhN5vR6jT5HiBVKV53l6CR6mGrhzw0PIAMcsANlGMS72O6LdGK xmJHZN+VrGK4ORMoxbrzMC7AL/EBzFVwSw8hc3AjE118FVtln5ONBsxCKIR+bGjRWwCHqIm Rg0RUtNKctqUZhXU5Nendj3ojojpEy9N4XcENVgdSWU8e7SzwXf/glb9ui8BVHBpLZa5lhM s6oXSjbR94l2InPKTVgAP+btGwl1Dw+vgynwvJU7TqrmvodbfmNw4PMXnl22VlfU1wCYvgD TO+Xg161VsjjVjELlP+5r/Rh/rubJkrtqFIdlwA73PCYwKL6PdT9JADNwRAA== ARC-Authentication-Results: i=2; ffmpeg.org; dkim=pass header.d=axis.com; arc=pass; dmarc=pass header.from=axis.com policy.dmarc=none Authentication-Results: ffmpeg.org; dkim=pass header.d=axis.com; arc=pass; dmarc=pass (Used From Domain Record) header.from=axis.com policy.dmarc=none Received: from AM0PR02CU008.outbound.protection.outlook.com (mail-westeuropeazon11013071.outbound.protection.outlook.com [52.101.72.71]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id C159A68E714 for ; Fri, 29 Aug 2025 17:05:18 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FAegjQYLsa9Pp8rQoddszKR/qdcieZnwg97RdkJQHX5lI/YXA94vBQ8geHY4uI4l1N5/vF69kdmXEhLGR6sN8I+akE3bWGNrEC0ZkU4r0tEgIJFVQW2zXUB6w6eZFNorg2BDy29zQIJT19njC28oqJcuHNsqOOAsMp0IXMxIm6JeEJwHeafapMqujiWQLxJmNSn93wEqWzbzgPwzHNgo0+Z2C6jLdm5oobmai4TqEfvaUBPOc92+hFw0Cw7a6S/EQrnTbFQMYjkIdEGQakVZasBqh+jSdd+34UnPDqBb/LUtFH4yjvTShoAdDEsvC54m7JYVaEGHgO5DhlW3yZmqxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=4xY7+Bhy/m1GMrHbVo+pNj+4dXCLQX/XjDqwrZrh3bg=; b=EMsllh2EcAVtwqGiH/iRLNsVk+ogLuj3YxCoj6t0HZMZU2jFk38J1YMMSAXSc/hq1pCaJ+2QexBgctHwKr16EABsfuqd6mkJYwc8TwO69g6kIz5q/zRQ10147rwIgPK/C2Jl7mVmvgngpsPtzRx896r2TQfQ1RrDNxmCSfuqgnGm/NleeGA9IYZgh9mOvn9EaNF09iYaLEA+1Dz+YFkUOPRe1vWnivwIf17+kKF8s3Ld2C0yw2sr//SUT44+sQn/D4CImc5sT/97Y/f/vQQQP6S58s5bWXVrl3VNt755nnxR+hSaABtnlc0P5QQLwn4crBALXj8m/WX2lf/HdsiXBA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 195.60.68.100) smtp.rcpttodomain=ffmpeg.org smtp.mailfrom=axis.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=axis.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=4xY7+Bhy/m1GMrHbVo+pNj+4dXCLQX/XjDqwrZrh3bg=; b=O2xY7Kn20lP12lgGyitlQLMO7aBQ2aOfH+gGnEE4sUo7rUmXXwZ+HNE2Hc5YZjbXY87ypq6cmOOT9qPLLwl/30NY7crKSqfl8ESFjEvp7DPa61M/yLp34pGULkxhDcHz30ff/8tlZ1olns8AntB9QImIXz88JO13w1inqq5d554= Received: from AM9P195CA0030.EURP195.PROD.OUTLOOK.COM (2603:10a6:20b:21f::35) by PAWPR02MB9056.eurprd02.prod.outlook.com (2603:10a6:102:339::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9052.21; Fri, 29 Aug 2025 14:05:12 +0000 Received: from AM3PEPF0000A78D.eurprd04.prod.outlook.com (2603:10a6:20b:21f:cafe::70) by AM9P195CA0030.outlook.office365.com (2603:10a6:20b:21f::35) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9073.19 via Frontend Transport; Fri, 29 Aug 2025 14:05:11 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 195.60.68.100) smtp.mailfrom=axis.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=axis.com; Received-SPF: Pass (protection.outlook.com: domain of axis.com designates 195.60.68.100 as permitted sender) receiver=protection.outlook.com; client-ip=195.60.68.100; helo=mail.axis.com; pr=C Received: from mail.axis.com (195.60.68.100) by AM3PEPF0000A78D.mail.protection.outlook.com (10.167.16.116) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9073.11 via Frontend Transport; Fri, 29 Aug 2025 14:05:11 +0000 Received: from se-mail02w.axis.com (10.20.40.8) by se-mail02w.axis.com (10.20.40.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.58; Fri, 29 Aug 2025 16:05:07 +0200 Received: from se-intmail01x.se.axis.com (10.4.0.28) by se-mail02w.axis.com (10.20.40.8) with Microsoft SMTP Server id 15.1.2507.58 via Frontend Transport; Fri, 29 Aug 2025 16:05:07 +0200 Received: from pc55631-2335.se.axis.com (pc55631-2335.se.axis.com [10.94.180.160]) by se-intmail01x.se.axis.com (Postfix) with ESMTP id DD29D4C6A; Fri, 29 Aug 2025 16:05:07 +0200 (CEST) Received: by pc55631-2335.se.axis.com (Postfix, from userid 18910) id D9F9B43A5199; Fri, 29 Aug 2025 16:05:07 +0200 (CEST) To: , , Date: Fri, 29 Aug 2025 16:04:57 +0200 Message-ID: <20250829140459.3220037-4-peterend@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250829140459.3220037-1-peterend@axis.com> References: <0250811223419.GF29660@pb2> <20250829140459.3220037-1-peterend@axis.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM3PEPF0000A78D:EE_|PAWPR02MB9056:EE_ X-MS-Office365-Filtering-Correlation-Id: 2fa21797-6342-4234-b6de-08dde70511fc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?MUJB09N6hfW8v55BhEkoLTGWiFRz2LbEfpwepHARPeAWHUH40ZJwt2KOz4zU?= =?us-ascii?Q?dZMgBZj2NbsUH8S+0AJZumKQI9ZG7PwAcj4BnvTLKocSK5O6PaVyYZmhPcaW?= =?us-ascii?Q?8LPl6Wqe9sSIhdL8oKCtFYbi4sXJ1kxrHf1HIRY+9veGDJyO9/xKxYMSnLoB?= =?us-ascii?Q?6zJnJeLfOwNX85vLibCpY5C2n/n2cdiATFcGdUlBsPZvnm4NsjGjNPs8Oh8I?= =?us-ascii?Q?C2D19iMDsb3y2K5GcUPXmx6EayCqg2w7aOFyRLhAzTlD9Hw+XwuEgUDXRFVZ?= =?us-ascii?Q?tXL6XKM5tmB4uguorWN7TiY72dAZxkirSqzjBJ4fvybmaEphi0KGEJDMapOZ?= =?us-ascii?Q?c1X0TCAFZMib/siH0crTnXrBwbbO8g34SWZOwalBjkt7uSoxsERR84UstNDb?= =?us-ascii?Q?HXZkWXaFEQkDzNyYQ/jVIXPhJ59r+K9xJmWuRL52Ud3ug0Xc0j3d11JxWW4W?= =?us-ascii?Q?ZXyIHNH7DglorC0b/QVsV9wZWbxc/uwn/e6cuRZzIcYmS95jpFHsAmGzVQ2g?= =?us-ascii?Q?qZXETZsMtoONhNRcGln+d8q5GStYCBZ0jC/68gh2xkSbBbZzxQVsAwzaSl17?= =?us-ascii?Q?GAFABxlta8t+AgKLbUslIoO1HXhcplGQH94BhMSwnz+m68u8KkFIqvoS3aaZ?= =?us-ascii?Q?owMrXdW8BNNCWtmRbLY84tVzUH1oRD0vknk4/LGiLvch32NqxK5vc5bcA8xU?= =?us-ascii?Q?iHR2OmXkpLXl0LvAVEYtXAP9XCjLAYqupvOQhQh2+vpz5gkWKa2zATM06sWq?= =?us-ascii?Q?AmCM23Oof9b/iEOxVg/9DeSzoIO3Z8xKDUBSlltWatnPVSDSFqbs9dpvrch9?= =?us-ascii?Q?n2n/Vpq4MT6ElkjFkBsELQFxN/r+L/8sJYBhBhLMw3sY9Dmqw8m7TIj2t68I?= =?us-ascii?Q?xaagaioCGsRDa73rqOCirDSCiBJ+uh/QkyndPu+u/psG+5Y+jzLZezNI98bC?= =?us-ascii?Q?PbLLPA0NCzIh1rG8ul55iWIvew/FqXaC3CGkgEq4v2pHhu+hlwcxc8Zv0Ce1?= =?us-ascii?Q?ZELCFhTtcVMNL5btG2EXkHzq1DZOPMFVgKrsJOg6Vi+VnL7AnMcW1bGaZa/Q?= =?us-ascii?Q?tPiFVG3f78ZIRzSDYgVLeskMSgqx8PS5Jqq3wK3IreYgJoF9UGPhbhXT8goN?= =?us-ascii?Q?/xfPhBL5+UkOIxogSDKXBvHhwAMzzz1b7oSyPQoBvpvBUXeAEDQm9XMaDBVI?= =?us-ascii?Q?0p8WiA35GUMPZOlSVGzPjYCumIXAkTbvtgx0l1HPj34gHR7i7TuTRYdxwRe4?= =?us-ascii?Q?VoN9Ry2Rcoxd0+8SlX4u2VMTVkSSUT3jQvkylzpDdN3JHBUEMZ04KcomN3BY?= =?us-ascii?Q?vKW9HxWDPDOowHFtO8SjUe0Y/0k+BJtyretBonUKZLFjlYaF1mQJpYAPbgG0?= =?us-ascii?Q?55Ufy+2LU0fjIcUDmOgs3btugwlPwGIlm0ML85b1KhazSpzW0FBYJeW+iORv?= =?us-ascii?Q?kzZCEXO928suMbItpIjqeK7ib3lH02p+jUkzEYuioFxGYI6BltcBhdCOyJbc?= =?us-ascii?Q?4dvwAZ9WRGtNsha3ntDUkMtuEV+CjtiEO8/l?= X-Forefront-Antispam-Report: CIP:195.60.68.100;CTRY:SE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.axis.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(82310400026)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: axis.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Aug 2025 14:05:11.8681 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2fa21797-6342-4234-b6de-08dde70511fc X-MS-Exchange-CrossTenant-Id: 78703d3c-b907-432f-b066-88f7af9ca3af X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=78703d3c-b907-432f-b066-88f7af9ca3af;Ip=[195.60.68.100];Helo=[mail.axis.com] X-MS-Exchange-CrossTenant-AuthSource: AM3PEPF0000A78D.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR02MB9056 Message-ID-Hash: JWO64WUBB5I2K7OGFHVPFDWI3QXQGJQV X-Message-ID-Hash: JWO64WUBB5I2K7OGFHVPFDWI3QXQGJQV X-MailFrom: SRS0=YjuK=3J=axis.com=Peter.Enderborg@ffmpeg.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH v3 3/5] libavformat: udp.c Add support for multi or single join List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Peter Enderborg via ffmpeg-devel Cc: Peter Enderborg Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: A new commandline option to set for joining multiple interfaces. The default is one, and it is also a special case falling back to output routing table for selecting interface on group join. On group join it search over all interfaces. Change-Id: Idbf88c3ecd7d27cba0a236a8fa2451a85143d068 Signed-off-by: Peter Enderborg --- libavformat/rtpproto.c | 3 ++ libavformat/rtsp.c | 3 +- libavformat/rtsp.h | 1 + libavformat/udp.c | 82 +++++++++++++++++++++++++++++++----------- 4 files changed, 67 insertions(+), 22 deletions(-) diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 15d0050936..c6abd7a02c 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -61,6 +61,7 @@ typedef struct RTPContext { char *fec_options_str; int64_t rw_timeout; char *localaddr; + int multicast_max_join; } RTPContext; #define OFFSET(x) offsetof(RTPContext, x) @@ -81,6 +82,7 @@ static const AVOption options[] = { { "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 }, + { "multicast_max_join", "Number of ipv6 network intefaces to join multicast group", OFFSET(multicast_max_join), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, .flags = D|E }, { NULL } }; @@ -199,6 +201,7 @@ static void build_udp_url(RTPContext *s, url_add_option(buf, buf_size, "block=%s", exclude_sources); if (localaddr && localaddr[0]) url_add_option(buf, buf_size, "localaddr=%s", localaddr); + url_add_option(buf, buf_size, "multicast_max_join=%d", s->multicast_max_join); } /** diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 10355b89b8..08ce628b0c 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -81,6 +81,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 }, \ + { "multicast_max_join", "Number of ipv6 network intefaces to join multicast group", OFFSET(multicast_max_join), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, ENC }, \ { "pkt_size", "Underlying protocol send packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = 1472 }, -1, INT_MAX, ENC } \ @@ -139,7 +140,7 @@ static AVDictionary *map_to_opts(RTSPState *rt) 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); - + av_dict_set_int(&opts, "multicast_max_join", rt->multicast_max_join, 0); return opts; } diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index ca278acd43..626114fb5a 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -419,6 +419,7 @@ typedef struct RTSPState { int buffer_size; int pkt_size; char *localaddr; + int multicast_max_join; /** * Options used for TLS based RTSP streams. diff --git a/libavformat/udp.c b/libavformat/udp.c index 9ffd55e017..9c2f904e50 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -74,6 +74,7 @@ #include #include #endif +#define IPV6_DEFAULT_JOIN 1 #ifndef IPV6_ADD_MEMBERSHIP #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP @@ -124,6 +125,7 @@ typedef struct UDPContext { uint8_t tmp[UDP_MAX_PKT_SIZE + sizeof(UDPQueuedPacketHeader)]; int remaining_in_dg; char *localaddr; + int multicast_max_join; int timeout; struct sockaddr_storage local_addr_storage; char *sources; @@ -143,6 +145,7 @@ static const AVOption options[] = { { "localport", "Local port", OFFSET(local_port), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, D|E }, { "local_port", "Local port", OFFSET(local_port), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "localaddr", "Local address", OFFSET(localaddr), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, + { "multicast_max_join", "Number of ipv6 network intefaces to join multicast group", OFFSET(multicast_max_join), AV_OPT_TYPE_INT, { .i64 = IPV6_DEFAULT_JOIN }, -1, INT_MAX, .flags = D|E }, { "udplite_coverage", "choose UDPLite head size which should be validated by checksum", OFFSET(udplite_coverage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E }, { "pkt_size", "Maximum UDP packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = 1472 }, -1, INT_MAX, .flags = D|E }, { "reuse", "explicitly allow reusing UDP sockets", OFFSET(reuse_socket), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, D|E }, @@ -255,7 +258,8 @@ static int udp_ipv6_mc_devname_membership(int mop, const char *name, } static int udp_ipv6_multicast_iterate(int sockfd, struct sockaddr_in6 *addr, - struct sockaddr_in6 *local_addr, int mop, void *logctx) + struct sockaddr_in6 *local_addr, int mop, + int multicast_max_join, void *logctx) { struct in6_addr anyipv6 = IN6ADDR_ANY_INIT; struct ifaddrs *ifal=NULL,*ife=NULL; @@ -267,13 +271,16 @@ static int udp_ipv6_multicast_iterate(int sockfd, struct sockaddr_in6 *addr, if (ife->ifa_addr && (ife->ifa_addr->sa_family == AF_INET6) && (ife->ifa_flags & IFF_MULTICAST) && - (ife->ifa_flags & IFF_UP)) { + (ife->ifa_flags & IFF_UP) && + multicast_max_join ) { if ((!memcmp(&local_addr->sin6_addr, &anyipv6, sizeof(struct in6_addr))) || (!memcmp(&local_addr->sin6_addr, &((struct sockaddr_in6 *)ife->ifa_addr)->sin6_addr, sizeof(struct in6_addr)))) { if (udp_ipv6_mc_devname_membership(mop,ife->ifa_name, iindex_fd, &addr->sin6_addr, - sockfd, logctx) == 1) + sockfd, logctx) == 1) { membership_changed = 1; + multicast_max_join--; + } } } } @@ -290,7 +297,8 @@ static int udp_ipv6_multicast_iterate(int sockfd, struct sockaddr_in6 *addr, #endif static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, - struct sockaddr *local_addr, void *logctx) + struct sockaddr *local_addr, + int multicast_max_join, void *logctx) { #ifdef IP_ADD_MEMBERSHIP if (addr->sa_family == AF_INET) { @@ -305,19 +313,33 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)"); return ff_neterrno(); } + if (multicast_max_join) + ff_log_net_error(logctx, AV_LOG_WARNING, "multicast_max_join is not used in ip4"); } #endif #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6) if (addr->sa_family == AF_INET6) { + struct ipv6_mreq mreq6; #if HAVE_IOCTL_GIFINDEX - return udp_ipv6_multicast_iterate(sockfd, - (struct sockaddr_in6 *)addr, - (struct sockaddr_in6 *)local_addr, - IPV6_JOIN_GROUP, - logctx); + /* Fallback to use multicast output routing if we do not have + multiple interface join or a interface name or a local address */ + if (multicast_max_join == IPV6_DEFAULT_JOIN && !local_addr) { + memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); + mreq6.ipv6mr_interface = 0; + if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { + ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); + return ff_neterrno(); + } + } + else { + return udp_ipv6_multicast_iterate(sockfd, + (struct sockaddr_in6 *)addr, + (struct sockaddr_in6 *)local_addr, + IPV6_JOIN_GROUP, + multicast_max_join, + logctx); + } #else - struct ipv6_mreq mreq6; - memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); mreq6.ipv6mr_interface = 0; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { @@ -331,7 +353,8 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, } static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, - struct sockaddr *local_addr, void *logctx) + struct sockaddr *local_addr, + int multicast_max_join, void *logctx) { #ifdef IP_DROP_MEMBERSHIP if (addr->sa_family == AF_INET) { @@ -350,15 +373,27 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, #endif #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6) if (addr->sa_family == AF_INET6) { + struct ipv6_mreq mreq6; #if HAVE_IOCTL_GIFINDEX - return udp_ipv6_multicast_iterate(sockfd, - (struct sockaddr_in6 *)addr, - (struct sockaddr_in6 *)local_addr, - IPV6_LEAVE_GROUP, - logctx); + /* Fallback to use multicast output routing if we do not have + multiple interface join or a interface name or a local address */ + if (multicast_max_join == IPV6_DEFAULT_JOIN && !local_addr) { + memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); + mreq6.ipv6mr_interface = 0; + if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { + ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); + return ff_neterrno(); + } + } + else { + return udp_ipv6_multicast_iterate(sockfd, + (struct sockaddr_in6 *)addr, + (struct sockaddr_in6 *)local_addr, + IPV6_LEAVE_GROUP, + multicast_max_join, + logctx); + } #else - struct ipv6_mreq mreq6; - memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); mreq6.ipv6mr_interface = 0; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { @@ -847,6 +882,9 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "localport", p)) { s->local_port = strtol(buf, NULL, 10); } + if (av_find_info_tag(buf, sizeof(buf), "multicast_max_join", p)) { + s->multicast_max_join = strtol(buf, NULL, 10); + } if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) { s->pkt_size = strtol(buf, NULL, 10); } @@ -1012,7 +1050,8 @@ static int udp_open(URLContext *h, const char *uri, int flags) goto fail; } else { if ((ret = udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr, - (struct sockaddr *)&s->local_addr_storage, h)) < 0) + (struct sockaddr *)&s->local_addr_storage, + s->multicast_max_join, h)) < 0) goto fail; } if (s->filters.nb_exclude_addrs) { @@ -1266,7 +1305,8 @@ static int udp_close(URLContext *h) if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr, - (struct sockaddr *)&s->local_addr_storage, h); + (struct sockaddr *)&s->local_addr_storage, + s->multicast_max_join, h); #if HAVE_PTHREAD_CANCEL if (s->thread_started) { int ret; -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org