ffmpeg: fix multicast support, from Brad

This commit is contained in:
sthen 2022-02-13 19:42:11 +00:00
parent 8d59763382
commit ff5d03d803
3 changed files with 102 additions and 2 deletions

View File

@ -1,10 +1,10 @@
# $OpenBSD: Makefile,v 1.216 2021/11/20 14:34:35 sthen Exp $
# $OpenBSD: Makefile,v 1.217 2022/02/13 19:42:11 sthen Exp $
COMMENT= audio/video converter and streamer
V= 4.4.1
DISTNAME= ffmpeg-${V}
REVISION= 0
REVISION= 1
EPOCH= 1
CATEGORIES= graphics multimedia
MASTER_SITES= https://ffmpeg.org/releases/

View File

@ -0,0 +1,16 @@
$OpenBSD: patch-libavformat_rtpproto_c,v 1.1 2022/02/13 19:42:11 sthen Exp $
avformat/rtpproto: set ttl upper bound to 255
Index: libavformat/rtpproto.c
--- libavformat/rtpproto.c.orig
+++ libavformat/rtpproto.c
@@ -67,7 +67,7 @@ typedef struct RTPContext {
#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "ttl", "Time to live (in milliseconds, multicast only)", OFFSET(ttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "ttl", "Time to live (multicast only)", OFFSET(ttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
{ "buffer_size", "Send/Receive buffer size (in bytes)", OFFSET(buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "rtcp_port", "Custom rtcp port", OFFSET(rtcp_port), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
{ "local_rtpport", "Local rtp port", OFFSET(local_rtpport), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },

View File

@ -0,0 +1,84 @@
$OpenBSD: patch-libavformat_udp_c,v 1.1 2022/02/13 19:42:11 sthen Exp $
- avformat/udp: set ttl upper bound to 255
- avformat/udp: properly check for valid ttl in url
- avformat/udp: use one setsockopt for ipv4/ipv6
- avformat/udp: Fix IP_MULTICAST_TTL for BSD compatibility
- avformat/udp: remove IPPROTO_IPV6 macro
Index: libavformat/udp.c
--- libavformat/udp.c.orig
+++ libavformat/udp.c
@@ -134,7 +134,7 @@ static const AVOption options[] = {
{ "reuse", "explicitly allow reusing UDP sockets", OFFSET(reuse_socket), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, D|E },
{ "reuse_socket", "explicitly allow reusing UDP sockets", OFFSET(reuse_socket), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
{ "broadcast", "explicitly allow or disallow broadcast destination", OFFSET(is_broadcast), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
- { "ttl", "Time to live (multicast only)", OFFSET(ttl), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, INT_MAX, E },
+ { "ttl", "Time to live (multicast only)", OFFSET(ttl), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 255, E },
{ "connect", "set if connect() should be called on socket", OFFSET(is_connected), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E },
{ "fifo_size", "set the UDP receiving circular buffer size, expressed as a number of packets with size of 188 bytes", OFFSET(circular_buffer_size), AV_OPT_TYPE_INT, {.i64 = 7*4096}, 0, INT_MAX, D },
{ "overrun_nonfatal", "survive in case of UDP receiving circular buffer overrun", OFFSET(overrun_nonfatal), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, D },
@@ -161,22 +161,40 @@ static const AVClass udplite_context_class = {
static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
struct sockaddr *addr)
{
+ int protocol, cmd;
+
+ /* There is some confusion in the world whether IP_MULTICAST_TTL
+ * takes a byte or an int as an argument.
+ * BSD seems to indicate byte so we are going with that and use
+ * int and fall back to byte to be safe */
+ switch (addr->sa_family) {
#ifdef IP_MULTICAST_TTL
- if (addr->sa_family == AF_INET) {
- if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
- ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)");
- return ff_neterrno();
- }
- }
+ case AF_INET:
+ protocol = IPPROTO_IP;
+ cmd = IP_MULTICAST_TTL;
+ break;
#endif
-#if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
- if (addr->sa_family == AF_INET6) {
- if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
- ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)");
+#ifdef IPV6_MULTICAST_HOPS
+ case AF_INET6:
+ protocol = IPPROTO_IPV6;
+ cmd = IPV6_MULTICAST_HOPS;
+ break;
+#endif
+ default:
+ return 0;
+ }
+
+ if (setsockopt(sockfd, protocol, cmd, &mcastTTL, sizeof(mcastTTL)) < 0) {
+ /* BSD compatibility */
+ unsigned char ttl = (unsigned char) mcastTTL;
+
+ ff_log_net_error(NULL, AV_LOG_DEBUG, "setsockopt(IPV4/IPV6 MULTICAST TTL)");
+ if (setsockopt(sockfd, protocol, cmd, &ttl, sizeof(ttl)) < 0) {
+ ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV4/IPV6 MULTICAST TTL)");
return ff_neterrno();
}
}
-#endif
+
return 0;
}
@@ -673,6 +691,11 @@ static int udp_open(URLContext *h, const char *uri, in
}
if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
s->ttl = strtol(buf, NULL, 10);
+ if (s->ttl < 0 || s->ttl > 255) {
+ av_log(h, AV_LOG_ERROR, "ttl(%d) should be in range [0,255]\n", s->ttl);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
}
if (av_find_info_tag(buf, sizeof(buf), "udplite_coverage", p)) {
s->udplite_coverage = strtol(buf, NULL, 10);