The branch, master has been updated
via 8e11e2cdb82299e7f0b6d8884bf2bc65c1c3f5e8 (commit)
via 2762ae74c53b058345660019ecce4ba41a85a050 (commit)
via 3166e3b5394540dd827691773f499e98d7c0c69b (commit)
via f231439ee747f2e72bacc9fe7af30bd117eb46a9 (commit)
via 49c6e6cc44f011ea43a3cab1b965510569bd229d (commit)
via 7e58fff9d0b9b05f118917b5eb5704bb3514c6bd (commit)
via 2d06ed9308ebaa785d8b3389ad8da033b8839c89 (commit)
via 70e0e3e2572447c559aac5179578be5a584e942b (commit)
via c5be4b70754d276e7370dd90e807e883c4bec627 (commit)
via 6f17053e6c75e5c44eaee9d4da0a4c80470274d0 (commit)
from 8cb1ff78ac62ff0f652b0cb06369ba50d5e946c6 (commit)
- Log -----------------------------------------------------------------
commit 8e11e2cdb82299e7f0b6d8884bf2bc65c1c3f5e8
Author: Marton Balint <[email protected]>
AuthorDate: Wed Sep 3 00:55:46 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:19 2025 +0200
avformat/tls_openssl: initialize underlying protocol early for dtls_start()
The same way we do with TLS, so all tls URL options will be properly
supported.
Signed-off-by: Marton Balint <[email protected]>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 9f88f005b9..b74383122a 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -2052,12 +2052,19 @@ Datagram Transport Layer Security (DTLS)
The required syntax for a DTLS URL is:
@example
-dtls://@var{hostname}:@var{port}
+dtls://@var{hostname}:@var{port}[?@var{options}]
@end example
+@var{options} contains a list of &-separated options of the form
+@var{key}=@var{val}. Standard percent-encoding (and using the plus sign for
+space) can be used to escape keys and values.
+
+Options can also can be specified via command line options (or in code via
+@code{AVOption}s).
+
DTLS shares most options with TLS, but operates over UDP instead of TCP.
-The following parameters can be set via command line options
-(or in code via @code{AVOption}s):
+
+The list of supported options follows.
@table @option
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 5fc0b639d7..c2adaa38d1 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -747,6 +747,13 @@ static int dtls_start(URLContext *h, const char *url, int
flags, AVDictionary **
int ret = 0;
s->is_dtls = 1;
+ if (!c->tls_shared.external_sock) {
+ if ((ret = ff_tls_open_underlying(&c->tls_shared, h, url, options)) <
0) {
+ av_log(c, AV_LOG_ERROR, "Failed to connect %s\n", url);
+ return ret;
+ }
+ }
+
c->ctx = SSL_CTX_new(s->listen ? DTLS_server_method() :
DTLS_client_method());
if (!c->ctx) {
ret = AVERROR(ENOMEM);
@@ -799,13 +806,6 @@ static int dtls_start(URLContext *h, const char *url, int
flags, AVDictionary **
DTLS_set_link_mtu(c->ssl, s->mtu);
init_bio_method(h);
- if (!c->tls_shared.external_sock) {
- if ((ret = ff_tls_open_underlying(&c->tls_shared, h, url, options)) <
0) {
- av_log(c, AV_LOG_ERROR, "Failed to connect %s\n", url);
- return ret;
- }
- }
-
/* This seems to be necessary despite explicitly setting client/server
method above. */
if (s->listen)
SSL_set_accept_state(c->ssl);
@@ -836,6 +836,7 @@ static int dtls_start(URLContext *h, const char *url, int
flags, AVDictionary **
ret = 0;
fail:
+ tls_close(h);
return ret;
}
commit 2762ae74c53b058345660019ecce4ba41a85a050
Author: Marton Balint <[email protected]>
AuthorDate: Tue Aug 26 00:23:16 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:19 2025 +0200
avformat/tls: use ff_parse_opts_from_query_string() to set URL parameters
Note that this changes the code to work the same way as other protocols
where
an URL parameter can override an AVOption.
Signed-off-by: Marton Balint <[email protected]>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 3d9685ed6d..9f88f005b9 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1984,8 +1984,14 @@ The required syntax for a TLS/SSL url is:
tls://@var{hostname}:@var{port}[?@var{options}]
@end example
-The following parameters can be set via command line options
-(or in code via @code{AVOption}s):
+@var{options} contains a list of &-separated options of the form
+@var{key}=@var{val}. Standard percent-encoding (and using the plus sign for
+space) can be used to escape keys and values.
+
+Options can also can be specified via command line options (or in code via
+@code{AVOption}s).
+
+The list of supported options follows.
@table @option
diff --git a/libavformat/tls.c b/libavformat/tls.c
index bd9c05e6dc..2cf0c99a6b 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -31,41 +31,6 @@
#include "libavutil/mem.h"
#include "libavutil/parseutils.h"
-static int set_options(TLSShared *c, const char *uri)
-{
- char buf[1024];
- const char *p = strchr(uri, '?');
- if (!p)
- return 0;
-
- if (!c->ca_file && av_find_info_tag(buf, sizeof(buf), "cafile", p)) {
- c->ca_file = av_strdup(buf);
- if (!c->ca_file)
- return AVERROR(ENOMEM);
- }
-
- if (!c->verify && av_find_info_tag(buf, sizeof(buf), "verify", p)) {
- char *endptr = NULL;
- c->verify = strtol(buf, &endptr, 10);
- if (buf == endptr)
- c->verify = 1;
- }
-
- if (!c->cert_file && av_find_info_tag(buf, sizeof(buf), "cert", p)) {
- c->cert_file = av_strdup(buf);
- if (!c->cert_file)
- return AVERROR(ENOMEM);
- }
-
- if (!c->key_file && av_find_info_tag(buf, sizeof(buf), "key", p)) {
- c->key_file = av_strdup(buf);
- if (!c->key_file)
- return AVERROR(ENOMEM);
- }
-
- return 0;
-}
-
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri,
AVDictionary **options)
{
int port;
@@ -77,17 +42,18 @@ int ff_tls_open_underlying(TLSShared *c, URLContext
*parent, const char *uri, AV
int use_proxy;
int ret;
- ret = set_options(c, uri);
- if (ret < 0)
- return ret;
+ p = strchr(uri, '?');
+ if (p) {
+ ret = ff_parse_opts_from_query_string(c, p, 1);
+ if (ret < 0)
+ return ret;
+ }
if (c->listen && !c->is_dtls)
snprintf(opts, sizeof(opts), "?listen=1");
av_url_split(NULL, 0, NULL, 0, c->underlying_host,
sizeof(c->underlying_host), &port, NULL, 0, uri);
- p = strchr(uri, '?');
-
if (!p) {
p = opts;
} else {
diff --git a/libavformat/tls_mbedtls.c b/libavformat/tls_mbedtls.c
index 2bcd3cca63..8aa142b9d2 100644
--- a/libavformat/tls_mbedtls.c
+++ b/libavformat/tls_mbedtls.c
@@ -174,17 +174,6 @@ static void handle_handshake_error(URLContext *h, int ret)
}
}
-static void parse_options(TLSContext *tls_ctxc, const char *uri)
-{
- char buf[1024];
- const char *p = strchr(uri, '?');
- if (!p)
- return;
-
- if (!tls_ctxc->priv_key_pw && av_find_info_tag(buf, sizeof(buf),
"key_password", p))
- tls_ctxc->priv_key_pw = av_strdup(buf);
-}
-
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary
**options)
{
TLSContext *tls_ctx = h->priv_data;
@@ -192,9 +181,6 @@ static int tls_open(URLContext *h, const char *uri, int
flags, AVDictionary **op
uint32_t verify_res_flags;
int ret;
- // parse additional options
- parse_options(tls_ctx, uri);
-
if ((ret = ff_tls_open_underlying(shr, h, uri, options)) < 0)
goto fail;
commit 3166e3b5394540dd827691773f499e98d7c0c69b
Author: Marton Balint <[email protected]>
AuthorDate: Mon Aug 25 21:35:40 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:19 2025 +0200
avformat/rtpproto: use ff_parse_opts_from_query_string() to set URL
parameters
Signed-off-by: Marton Balint <[email protected]>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 563aee6cc7..3d9685ed6d 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1162,9 +1162,13 @@ rtp://@var{hostname}[:@var{port}][?@var{options}]
@var{port} specifies the RTP port to use.
@var{options} contains a list of &-separated options of the form
-@var{key}=@var{val}.
+@var{key}=@var{val}. Standard percent-encoding (and using the plus sign for
+space) can be used to escape keys and values.
-The following options are supported:
+Options can also can be specified via command line options (or in code via
+@code{AVOption}s).
+
+The list of supported options follows.
@table @option
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index 69879b7fa8..c4309c19e4 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -29,6 +29,7 @@
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "avformat.h"
+#include "internal.h"
#include "rtp.h"
#include "rtpproto.h"
#include "url.h"
@@ -232,8 +233,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 *sources = include_sources, *block = exclude_sources;
+ char hostname[256];
char *fec_protocol = NULL;
char buf[1024];
char path[1024];
@@ -250,58 +250,17 @@ static int rtp_open(URLContext *h, const char *uri, int
flags)
p = strchr(uri, '?');
if (p) {
- if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
- s->ttl = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
- s->rtcp_port = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
- s->local_rtpport = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
- s->local_rtpport = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
- s->local_rtcpport = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
- s->pkt_size = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
- s->connect = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
- s->write_to_source = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) {
- s->dscp = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
- s->rw_timeout = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
- av_strlcpy(include_sources, buf, sizeof(include_sources));
- ff_ip_parse_sources(h, buf, &s->filters);
- } else {
- ff_ip_parse_sources(h, s->sources, &s->filters);
- sources = s->sources;
- }
- if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
- av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
- ff_ip_parse_blocks(h, buf, &s->filters);
- } else {
- 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) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- }
+ ret = ff_parse_opts_from_query_string(s, p, 1);
+ if (ret < 0)
+ goto fail;
+ }
+ if (s->sources) {
+ if ((ret = ff_ip_parse_sources(h, s->sources, &s->filters)) < 0)
+ goto fail;
+ }
+ if (s->block) {
+ if ((ret = ff_ip_parse_blocks(h, s->block, &s->filters)) < 0)
+ goto fail;
}
if (s->rw_timeout >= 0)
h->rw_timeout = s->rw_timeout;
@@ -334,6 +293,8 @@ static int rtp_open(URLContext *h, const char *uri, int
flags)
}
for (i = 0; i < max_retry_count; i++) {
+ const char *sources = s->sources ? s->sources : "";
+ const char *block = s->block ? s->block : "";
build_udp_url(s, buf, sizeof(buf),
hostname, s->localaddr, rtp_port, s->local_rtpport,
sources, block);
commit f231439ee747f2e72bacc9fe7af30bd117eb46a9
Author: Marton Balint <[email protected]>
AuthorDate: Mon Aug 25 02:09:26 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:19 2025 +0200
avformat/sctp: use ff_parse_opts_from_query_string() to set URL parameters
Signed-off-by: Marton Balint <[email protected]>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index a329f59fe3..563aee6cc7 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1535,7 +1535,15 @@ The accepted URL syntax is:
sctp://@var{host}:@var{port}[?@var{options}]
@end example
-The protocol accepts the following options:
+@var{options} contains a list of &-separated options of the form
+@var{key}=@var{val}. Standard percent-encoding (and using the plus sign for
+space) can be used to escape keys and values.
+
+Options can also can be specified via command line options (or in code via
+@code{AVOption}s).
+
+The list of supported options follows.
+
@table @option
@item listen
If set to any value, listen for an incoming connection. Outgoing connection is
done by default.
diff --git a/libavformat/sctp.c b/libavformat/sctp.c
index 9d9e90097e..4122fbe312 100644
--- a/libavformat/sctp.c
+++ b/libavformat/sctp.c
@@ -185,7 +185,6 @@ static int sctp_open(URLContext *h, const char *uri, int
flags)
int fd = -1;
SCTPContext *s = h->priv_data;
const char *p;
- char buf[256];
int ret;
char hostname[1024], proto[1024], path[1024];
char portstr[10];
@@ -201,10 +200,9 @@ static int sctp_open(URLContext *h, const char *uri, int
flags)
p = strchr(uri, '?');
if (p) {
- if (av_find_info_tag(buf, sizeof(buf), "listen", p))
- s->listen = 1;
- if (av_find_info_tag(buf, sizeof(buf), "max_streams", p))
- s->max_streams = strtol(buf, NULL, 10);
+ ret = ff_parse_opts_from_query_string(s, p, 0);
+ if (ret < 0)
+ return ret;
}
hints.ai_family = AF_UNSPEC;
commit 49c6e6cc44f011ea43a3cab1b965510569bd229d
Author: Marton Balint <[email protected]>
AuthorDate: Mon Aug 25 01:52:00 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:19 2025 +0200
avformat/tcp: use ff_parse_opts_from_query_string() to set URL parameters
Signed-off-by: Marton Balint <[email protected]>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index b4b6c25579..a329f59fe3 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1913,7 +1913,11 @@ tcp://@var{hostname}:@var{port}[?@var{options}]
@end example
@var{options} contains a list of &-separated options of the form
-@var{key}=@var{val}.
+@var{key}=@var{val}. Standard percent-encoding (and using the plus sign for
+space) can be used to escape keys and values.
+
+Options can also can be specified via command line options (or in code via
+@code{AVOption}s).
The list of supported options follows.
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index c286698d33..ce9f69a50b 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -25,6 +25,7 @@
#include "libavutil/opt.h"
#include "libavutil/time.h"
+#include "internal.h"
#include "network.h"
#include "os_support.h"
#include "url.h"
@@ -151,7 +152,6 @@ static int tcp_open(URLContext *h, const char *uri, int
flags)
int port, fd = -1;
TCPContext *s = h->priv_data;
const char *p;
- char buf[256];
int ret;
char hostname[1024],proto[1024],path[1024];
char portstr[10];
@@ -167,37 +167,9 @@ static int tcp_open(URLContext *h, const char *uri, int
flags)
}
p = strchr(uri, '?');
if (p) {
- if (av_find_info_tag(buf, sizeof(buf), "listen", p)) {
- char *endptr = NULL;
- s->listen = strtol(buf, &endptr, 10);
- /* assume if no digits were found it is a request to enable it */
- if (buf == endptr)
- s->listen = 1;
- }
- if (av_find_info_tag(buf, sizeof(buf), "local_port", p)) {
- av_freep(&s->local_port);
- s->local_port = av_strdup(buf);
- if (!s->local_port)
- return AVERROR(ENOMEM);
- }
- if (av_find_info_tag(buf, sizeof(buf), "local_addr", p)) {
- av_freep(&s->local_addr);
- s->local_addr = av_strdup(buf);
- if (!s->local_addr)
- return AVERROR(ENOMEM);
- }
- if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
- s->rw_timeout = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
- s->listen_timeout = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "tcp_nodelay", p)) {
- s->tcp_nodelay = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "tcp_keepalive", p)) {
- s->tcp_keepalive = strtol(buf, NULL, 10);
- }
+ int ret = ff_parse_opts_from_query_string(s, p, 1);
+ if (ret < 0)
+ return ret;
}
if (s->rw_timeout >= 0) {
s->open_timeout =
commit 7e58fff9d0b9b05f118917b5eb5704bb3514c6bd
Author: Marton Balint <[email protected]>
AuthorDate: Mon Aug 25 01:51:15 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:19 2025 +0200
avformat/udp: use ff_parse_opts_from_query_string() to set URL parameters
Signed-off-by: Marton Balint <[email protected]>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 133574b4db..b4b6c25579 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -2114,7 +2114,12 @@ The required syntax for an UDP URL is:
udp://@var{hostname}:@var{port}[?@var{options}]
@end example
-@var{options} contains a list of &-separated options of the form
@var{key}=@var{val}.
+@var{options} contains a list of &-separated options of the form
+@var{key}=@var{val}. Standard percent-encoding (and using the plus sign for
+space) can be used to escape keys and values.
+
+Options can also can be specified via command line options (or in code via
+@code{AVOption}s).
In case threading is enabled on the system, a circular buffer is used
to store the incoming data, which allows one to reduce loss of data due to
diff --git a/libavformat/udp.c b/libavformat/udp.c
index 839c301369..87a9d5d431 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -36,6 +36,7 @@
#include "libavutil/opt.h"
#include "libavutil/log.h"
#include "libavutil/time.h"
+#include "internal.h"
#include "network.h"
#include "os_support.h"
#include "url.h"
@@ -695,7 +696,6 @@ static int udp_open(URLContext *h, const char *uri, int
flags)
UDPContext *s = h->priv_data;
int is_output;
const char *p;
- char buf[256];
struct sockaddr_storage my_addr;
socklen_t len;
int ret;
@@ -706,87 +706,11 @@ static int udp_open(URLContext *h, const char *uri, int
flags)
if (s->buffer_size < 0)
s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_RX_BUF_SIZE;
- if (s->sources) {
- if ((ret = ff_ip_parse_sources(h, s->sources, &s->filters)) < 0)
- goto fail;
- }
-
- if (s->block) {
- if ((ret = ff_ip_parse_blocks(h, s->block, &s->filters)) < 0)
- goto fail;
- }
-
p = strchr(uri, '?');
if (p) {
- if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {
- char *endptr = NULL;
- s->reuse_socket = strtol(buf, &endptr, 10);
- /* assume if no digits were found it is a request to enable it */
- if (buf == endptr)
- s->reuse_socket = 1;
- }
- if (av_find_info_tag(buf, sizeof(buf), "overrun_nonfatal", p)) {
- char *endptr = NULL;
- s->overrun_nonfatal = strtol(buf, &endptr, 10);
- /* assume if no digits were found it is a request to enable it */
- if (buf == endptr)
- s->overrun_nonfatal = 1;
- }
- 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);
- }
- 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), "pkt_size", p)) {
- s->pkt_size = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) {
- s->buffer_size = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
- s->is_connected = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) {
- s->dscp = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) {
- s->circular_buffer_size = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "bitrate", p)) {
- s->bitrate = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "burst_bits", p)) {
- s->burst_bits = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
- av_freep(&s->localaddr);
- s->localaddr = av_strdup(buf);
- if (!s->localaddr) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- }
- if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
- if ((ret = ff_ip_parse_sources(h, buf, &s->filters)) < 0)
- goto fail;
- }
- if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
- if ((ret = ff_ip_parse_blocks(h, buf, &s->filters)) < 0)
- goto fail;
- }
- if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p))
- s->timeout = strtol(buf, NULL, 10);
- if (is_output && av_find_info_tag(buf, sizeof(buf), "broadcast", p))
- s->is_broadcast = strtol(buf, NULL, 10);
+ ret = ff_parse_opts_from_query_string(s, p, 1);
+ if (ret < 0)
+ goto fail;
}
if (!HAVE_PTHREAD_CANCEL) {
int64_t optvals[] = {s->overrun_nonfatal, s->bitrate,
s->circular_buffer_size};
@@ -798,6 +722,15 @@ static int udp_open(URLContext *h, const char *uri, int
flags)
"on this build (pthread support is required)\n",
optnames[i]);
}
}
+ if (s->sources) {
+ if ((ret = ff_ip_parse_sources(h, s->sources, &s->filters)) < 0)
+ goto fail;
+ }
+ if (s->block) {
+ if ((ret = ff_ip_parse_blocks(h, s->block, &s->filters)) < 0)
+ goto fail;
+ }
+
/* handling needed to support options picking from both AVOption and URL */
s->circular_buffer_size *= 188;
if (flags & AVIO_FLAG_WRITE) {
commit 2d06ed9308ebaa785d8b3389ad8da033b8839c89
Author: Marton Balint <[email protected]>
AuthorDate: Mon Aug 25 01:50:13 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:19 2025 +0200
avformat/libsrt: use ff_parse_opts_from_query_string() to set URL parameters
Signed-off-by: Marton Balint <[email protected]>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index cd0726cc7a..133574b4db 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1554,18 +1554,13 @@ srt://@var{hostname}:@var{port}[?@var{options}]
@end example
@var{options} contains a list of &-separated options of the form
-@var{key}=@var{val}.
-
-or
+@var{key}=@var{val}. Standard percent-encoding (and using the plus sign for
+space) can be used to escape keys and values.
-@example
-@var{options} srt://@var{hostname}:@var{port}
-@end example
+Options can also can be specified via command line options (or in code via
+@code{AVOption}s).
-@var{options} contains a list of '-@var{key} @var{val}'
-options.
-
-This protocol accepts the following options.
+The list of supported options follows.
@table @option
@item connect_timeout=@var{milliseconds}
diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c
index 9e860abccd..ba04d9f782 100644
--- a/libavformat/libsrt.c
+++ b/libavformat/libsrt.c
@@ -386,8 +386,6 @@ static int libsrt_setup(URLContext *h, const char *uri, int
flags)
struct addrinfo hints = { 0 }, *ai, *cur_ai;
int port, fd;
SRTContext *s = h->priv_data;
- const char *p;
- char buf[256];
int ret;
char hostname[1024],proto[1024],path[1024];
char portstr[10];
@@ -402,15 +400,6 @@ static int libsrt_setup(URLContext *h, const char *uri,
int flags)
av_log(h, AV_LOG_ERROR, "Port missing in uri\n");
return AVERROR(EINVAL);
}
- p = strchr(uri, '?');
- if (p) {
- if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
- s->rw_timeout = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
- s->listen_timeout = strtoll(buf, NULL, 10);
- }
- }
if (s->rw_timeout >= 0) {
open_timeout = h->rw_timeout = s->rw_timeout;
}
@@ -534,7 +523,6 @@ static int libsrt_open(URLContext *h, const char *uri, int
flags)
{
SRTContext *s = h->priv_data;
const char * p;
- char buf[1024];
int ret = 0;
if (srt_startup() < 0) {
@@ -544,133 +532,9 @@ static int libsrt_open(URLContext *h, const char *uri,
int flags)
/* SRT options (srt/srt.h) */
p = strchr(uri, '?');
if (p) {
- if (av_find_info_tag(buf, sizeof(buf), "maxbw", p)) {
- s->maxbw = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "pbkeylen", p)) {
- s->pbkeylen = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "passphrase", p)) {
- av_freep(&s->passphrase);
- s->passphrase = ff_urldecode(buf, 1);
- if (!s->passphrase) {
- ret = AVERROR(ENOMEM);
- goto err;
- }
- }
-#if SRT_VERSION_VALUE >= 0x010302
- if (av_find_info_tag(buf, sizeof(buf), "enforced_encryption", p)) {
- s->enforced_encryption = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "kmrefreshrate", p)) {
- s->kmrefreshrate = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "kmpreannounce", p)) {
- s->kmpreannounce = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "snddropdelay", p)) {
- s->snddropdelay = strtoll(buf, NULL, 10);
- }
-#endif
- if (av_find_info_tag(buf, sizeof(buf), "mss", p)) {
- s->mss = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "ffs", p)) {
- s->ffs = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "ipttl", p)) {
- s->ipttl = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "iptos", p)) {
- s->iptos = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "inputbw", p)) {
- s->inputbw = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "oheadbw", p)) {
- s->oheadbw = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "latency", p)) {
- s->latency = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "tsbpddelay", p)) {
- s->latency = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "rcvlatency", p)) {
- s->rcvlatency = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "peerlatency", p)) {
- s->peerlatency = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "tlpktdrop", p)) {
- s->tlpktdrop = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "nakreport", p)) {
- s->nakreport = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "connect_timeout", p)) {
- s->connect_timeout = strtoll(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "payload_size", p) ||
- av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
- s->payload_size = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "mode", p)) {
- if (!strcmp(buf, "caller")) {
- s->mode = SRT_MODE_CALLER;
- } else if (!strcmp(buf, "listener")) {
- s->mode = SRT_MODE_LISTENER;
- } else if (!strcmp(buf, "rendezvous")) {
- s->mode = SRT_MODE_RENDEZVOUS;
- } else {
- ret = AVERROR(EINVAL);
- goto err;
- }
- }
- if (av_find_info_tag(buf, sizeof(buf), "sndbuf", p)) {
- s->sndbuf = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "rcvbuf", p)) {
- s->rcvbuf = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "lossmaxttl", p)) {
- s->lossmaxttl = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "minversion", p)) {
- s->minversion = strtol(buf, NULL, 0);
- }
- if (av_find_info_tag(buf, sizeof(buf), "streamid", p)) {
- av_freep(&s->streamid);
- s->streamid = ff_urldecode(buf, 1);
- if (!s->streamid) {
- ret = AVERROR(ENOMEM);
- goto err;
- }
- }
- if (av_find_info_tag(buf, sizeof(buf), "smoother", p)) {
- av_freep(&s->smoother);
- s->smoother = ff_urldecode(buf, 1);
- if(!s->smoother) {
- ret = AVERROR(ENOMEM);
- goto err;
- }
- }
- if (av_find_info_tag(buf, sizeof(buf), "messageapi", p)) {
- s->messageapi = strtol(buf, NULL, 10);
- }
- if (av_find_info_tag(buf, sizeof(buf), "transtype", p)) {
- if (!strcmp(buf, "live")) {
- s->transtype = SRTT_LIVE;
- } else if (!strcmp(buf, "file")) {
- s->transtype = SRTT_FILE;
- } else {
- ret = AVERROR(EINVAL);
- goto err;
- }
- }
- if (av_find_info_tag(buf, sizeof(buf), "linger", p)) {
- s->linger = strtol(buf, NULL, 10);
- }
+ ret = ff_parse_opts_from_query_string(s, p, 0);
+ if (ret < 0)
+ goto err;
}
ret = libsrt_setup(h, uri, flags);
if (ret < 0)
commit 70e0e3e2572447c559aac5179578be5a584e942b
Author: Marton Balint <[email protected]>
AuthorDate: Mon Aug 25 00:54:29 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Wed Oct 1 00:34:18 2025 +0200
avformat/utils: add helper function to set opts from query string
Signed-off-by: Marton Balint <[email protected]>
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 0dfbf02ca0..1a50ba07d3 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -649,4 +649,16 @@ int ff_bprint_get_frame_filename(struct AVBPrint *buf,
const char *path, int64_t
*/
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t
timestamp);
+/**
+ * Set a list of query string options on an object. Only the objects own
+ * options will be set.
+ *
+ * @param obj the object to set options on
+ * @param str the query string
+ * @param allow_unknown ignore unknown query string options. This can be OK if
+ * nested protocols are used.
+ * @return <0 on error
+ */
+int ff_parse_opts_from_query_string(void *obj, const char *str, int
allow_unkown);
+
#endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 3573aa918e..7a74e63d68 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -24,11 +24,14 @@
#include "config.h"
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/bprint.h"
#include "libavutil/dict.h"
#include "libavutil/internal.h"
#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
#include "libavutil/time.h"
#include "libavutil/time_internal.h"
@@ -41,6 +44,7 @@
#include "network.h"
#endif
#include "os_support.h"
+#include "urldecode.h"
/**
* @file
@@ -618,3 +622,65 @@ int ff_dict_set_timestamp(AVDictionary **dict, const char
*key, int64_t timestam
return AVERROR_EXTERNAL;
}
}
+
+static const AVOption* find_opt(void *obj, const char *name, size_t len)
+{
+ char decoded_name[128];
+
+ if (ff_urldecode_len(decoded_name, sizeof(decoded_name), name, len, 1) < 0)
+ return NULL;
+
+ return av_opt_find(obj, decoded_name, NULL, 0, 0);
+}
+
+int ff_parse_opts_from_query_string(void *obj, const char *str, int
allow_unknown)
+{
+ const AVOption *opt;
+ char optval[512];
+ int ret;
+
+ if (*str == '?')
+ str++;
+ while (*str) {
+ size_t len = strcspn(str, "=&");
+ opt = find_opt(obj, str, len);
+ if (!opt) {
+ if (!allow_unknown) {
+ av_log(obj, AV_LOG_ERROR, "Query string option '%.*s' does not
exist\n", (int)len, str);
+ return AVERROR_OPTION_NOT_FOUND;
+ }
+ av_log(obj, AV_LOG_VERBOSE, "Ignoring unknown query string option
'%.*s'\n", (int)len, str);
+ }
+ str += len;
+ if (!opt) {
+ len = strcspn(str, "&");
+ str += len;
+ } else if (*str == '&' || *str == '\0') {
+ /* Check for bool options without value, e.g. "?verify".
+ * Unfortunately "listen" is a tri-state INT for some protocols so
+ * we also have to allow that for backward compatibility. */
+ if (opt->type != AV_OPT_TYPE_BOOL && strcmp(opt->name, "listen")) {
+ av_log(obj, AV_LOG_ERROR, "Non-bool query string option '%s'
has no value\n", opt->name);
+ return AVERROR(EINVAL);
+ }
+ ret = av_opt_set_int(obj, opt->name, 1, 0);
+ if (ret < 0)
+ return ret;
+ } else {
+ av_assert2(*str == '=');
+ str++;
+ len = strcspn(str, "&");
+ if (ff_urldecode_len(optval, sizeof(optval), str, len, 1) < 0) {
+ av_log(obj, AV_LOG_ERROR, "Query string option '%s' value is
too long\n", opt->name);
+ return AVERROR(EINVAL);
+ }
+ ret = av_opt_set(obj, opt->name, optval, 0);
+ if (ret < 0)
+ return ret;
+ str += len;
+ }
+ if (*str)
+ str++;
+ }
+ return 0;
+}
commit c5be4b70754d276e7370dd90e807e883c4bec627
Author: Marton Balint <[email protected]>
AuthorDate: Tue Aug 26 23:03:40 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Tue Sep 30 23:48:14 2025 +0200
avformat: compile urldecode unconditionally
It will be used by the generic helper function to set options from URLs.
Signed-off-by: Marton Balint <[email protected]>
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 19ed1d4374..ed93458f03 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -28,6 +28,7 @@ OBJS = allformats.o \
sdp.o \
seek.o \
url.o \
+ urldecode.o \
utils.o \
version.o \
@@ -537,10 +538,8 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \
rtpenc_vp8.o \
rtpenc_vp9.o \
rtpenc_xiph.o
-OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o rtspdec.o httpauth.o \
- urldecode.o
-OBJS-$(CONFIG_RTSP_MUXER) += rtsp.o rtspenc.o httpauth.o \
- urldecode.o
+OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o rtspdec.o httpauth.o
+OBJS-$(CONFIG_RTSP_MUXER) += rtsp.o rtspenc.o httpauth.o
OBJS-$(CONFIG_S337M_DEMUXER) += s337m.o spdif.o
OBJS-$(CONFIG_SAMI_DEMUXER) += samidec.o subtitles.o
OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o
@@ -685,13 +684,13 @@ OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpcrypt.o
rtmpdigest.o rtmpdh.o
OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL) += rtmphttp.o
OBJS-$(CONFIG_FILE_PROTOCOL) += file.o
OBJS-$(CONFIG_FD_PROTOCOL) += file.o
-OBJS-$(CONFIG_FTP_PROTOCOL) += ftp.o urldecode.o
+OBJS-$(CONFIG_FTP_PROTOCOL) += ftp.o
OBJS-$(CONFIG_GOPHER_PROTOCOL) += gopher.o
OBJS-$(CONFIG_GOPHERS_PROTOCOL) += gopher.o
OBJS-$(CONFIG_HLS_PROTOCOL) += hlsproto.o
-OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o urldecode.o
-OBJS-$(CONFIG_HTTPPROXY_PROTOCOL) += http.o httpauth.o urldecode.o
-OBJS-$(CONFIG_HTTPS_PROTOCOL) += http.o httpauth.o urldecode.o
+OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o
+OBJS-$(CONFIG_HTTPPROXY_PROTOCOL) += http.o httpauth.o
+OBJS-$(CONFIG_HTTPS_PROTOCOL) += http.o httpauth.o
OBJS-$(CONFIG_ICECAST_PROTOCOL) += icecast.o
OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o
OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf_tags.o
@@ -725,7 +724,7 @@ OBJS-$(CONFIG_UDPLITE_PROTOCOL) += udp.o ip.o
OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o
# external library protocols
-OBJS-$(CONFIG_LIBAMQP_PROTOCOL) += libamqp.o urldecode.o
+OBJS-$(CONFIG_LIBAMQP_PROTOCOL) += libamqp.o
OBJS-$(CONFIG_LIBRIST_PROTOCOL) += librist.o
OBJS-$(CONFIG_LIBRTMP_PROTOCOL) += librtmp.o
OBJS-$(CONFIG_LIBRTMPE_PROTOCOL) += librtmp.o
@@ -733,7 +732,7 @@ OBJS-$(CONFIG_LIBRTMPS_PROTOCOL) += librtmp.o
OBJS-$(CONFIG_LIBRTMPT_PROTOCOL) += librtmp.o
OBJS-$(CONFIG_LIBRTMPTE_PROTOCOL) += librtmp.o
OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o
-OBJS-$(CONFIG_LIBSRT_PROTOCOL) += libsrt.o urldecode.o
+OBJS-$(CONFIG_LIBSRT_PROTOCOL) += libsrt.o
OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o
OBJS-$(CONFIG_LIBZMQ_PROTOCOL) += libzmq.o
commit 6f17053e6c75e5c44eaee9d4da0a4c80470274d0
Author: Marton Balint <[email protected]>
AuthorDate: Tue Aug 26 22:57:40 2025 +0200
Commit: Marton Balint <[email protected]>
CommitDate: Tue Sep 30 23:48:14 2025 +0200
avformat/urldecode: add ff_urldecode_len function
This will be used later to decode partial strings.
Signed-off-by: Marton Balint <[email protected]>
diff --git a/libavformat/urldecode.c b/libavformat/urldecode.c
index e7fa27b3fa..fdaa41784f 100644
--- a/libavformat/urldecode.c
+++ b/libavformat/urldecode.c
@@ -28,6 +28,8 @@
#include <string.h>
+#include "libavutil/error.h"
+#include "libavutil/macros.h"
#include "libavutil/mem.h"
#include "libavutil/avstring.h"
#include "urldecode.h"
@@ -93,3 +95,19 @@ char *ff_urldecode(const char *url, int decode_plus_sign)
return dest;
}
+
+int ff_urldecode_len(char *dest, size_t dest_len, const char *url, size_t
url_max_len, int decode_plus_sign)
+{
+ size_t written_bytes;
+ size_t url_len = strlen(url);
+
+ url_len = FFMIN(url_len, url_max_len);
+
+ if (dest_len <= url_len)
+ return AVERROR(EINVAL);
+
+ written_bytes = urldecode(dest, url, url_len, decode_plus_sign);
+ dest[written_bytes] = '\0';
+
+ return written_bytes;
+}
diff --git a/libavformat/urldecode.h b/libavformat/urldecode.h
index 80b11c3428..246d9c9fda 100644
--- a/libavformat/urldecode.h
+++ b/libavformat/urldecode.h
@@ -19,6 +19,8 @@
#ifndef AVFORMAT_URLDECODE_H
#define AVFORMAT_URLDECODE_H
+#include <stddef.h>
+
/**
* Decodes an URL from its percent-encoded form back into normal
* representation. This function returns the decoded URL in a string.
@@ -33,4 +35,20 @@
*/
char *ff_urldecode(const char *url, int decode_plus_sign);
+/**
+ * Decodes an URL from its percent-encoded form back into normal
+ * representation. This function returns the decoded URL in a string.
+ * The URL to be decoded does not necessarily have to be encoded but
+ * in that case the original string is duplicated.
+ *
+ * @param dest the destination buffer.
+ * @param dest_len the maximum available space in the destination buffer.
+ * Must be bigger than FFMIN(strlen(url), url_max_len) to avoid
+ * an AVERROR(EINVAL) result
+ * @param url_max_len the maximum number of chars to read from url
+ * @param decode_plus_sign if nonzero plus sign is decoded to space
+ * @return the number of written bytes to dest excluding the zero terminator,
+ * negative on error
+ */
+int ff_urldecode_len(char *dest, size_t dest_len, const char *url, size_t
url_max_len, int decode_plus_sign);
#endif /* AVFORMAT_URLDECODE_H */
-----------------------------------------------------------------------
Summary of changes:
doc/protocols.texi | 69 +++++++++++++++-------
libavformat/Makefile | 19 +++----
libavformat/internal.h | 12 ++++
libavformat/libsrt.c | 142 +---------------------------------------------
libavformat/rtpproto.c | 69 +++++-----------------
libavformat/sctp.c | 8 +--
libavformat/tcp.c | 36 ++----------
libavformat/tls.c | 46 ++-------------
libavformat/tls_mbedtls.c | 14 -----
libavformat/tls_openssl.c | 15 ++---
libavformat/udp.c | 93 +++++-------------------------
libavformat/urldecode.c | 18 ++++++
libavformat/urldecode.h | 18 ++++++
libavformat/utils.c | 66 +++++++++++++++++++++
14 files changed, 224 insertions(+), 401 deletions(-)
hooks/post-receive
--
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]