From c6e2ae51073120b063a46ec49748bfb3534afeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Mon, 15 Jun 2026 02:13:16 +0200 Subject: [PATCH] avformat: add parent AVFormatContext to URLContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a URLContext.fmt_ctx back-reference, set by io_open_default before url_open() runs. Will be used to access shared resources per avfc. Signed-off-by: Kacper Michajłow --- libavformat/avio.c | 36 ++++++++++++++++++++++++++++-------- libavformat/avio_internal.h | 12 ++++++++++++ libavformat/internal.h | 2 ++ libavformat/options.c | 3 ++- libavformat/url.h | 1 + 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index 34aad24683..88bc9557de 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -365,16 +365,17 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, return AVERROR_PROTOCOL_NOT_FOUND; } -int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options, - const char *whitelist, const char* blacklist, - URLContext *parent) +static int url_open_whitelist(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist, const char* blacklist, + URLContext *parent, AVFormatContext *avfc) { AVDictionary *tmp_opts = NULL; AVDictionaryEntry *e; int ret = ffurl_alloc(puc, filename, flags, int_cb); if (ret < 0) return ret; + (*puc)->avfc = avfc; if (parent) { ret = av_opt_copy(*puc, parent); if (ret < 0) @@ -415,6 +416,15 @@ fail: return ret; } +int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist, const char* blacklist, + URLContext *parent) +{ + return url_open_whitelist(puc, filename, flags, int_cb, options, + whitelist, blacklist, parent, NULL); +} + int ffio_fdopen(AVIOContext **sp, URLContext *h) { AVIOContext *s; @@ -474,16 +484,18 @@ int ffio_fdopen(AVIOContext **sp, URLContext *h) return 0; } -int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options, - const char *whitelist, const char *blacklist) +int ffio_open_whitelist2(AVIOContext **s, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist, const char *blacklist, + AVFormatContext *avfc) { URLContext *h; int err; *s = NULL; - err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL); + err = url_open_whitelist(&h, filename, flags, int_cb, options, whitelist, + blacklist, NULL, avfc); if (err < 0) return err; err = ffio_fdopen(s, h); @@ -494,6 +506,14 @@ int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, return 0; } +int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist, const char *blacklist) +{ + return ffio_open_whitelist2(s, filename, flags, int_cb, options, + whitelist, blacklist, NULL); +} + int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options) { diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index fadf19dae5..c7f340780e 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -23,6 +23,8 @@ #include "libavutil/log.h" +typedef struct AVFormatContext AVFormatContext; + extern const AVClass ff_avio_class; typedef struct FFIOContext { @@ -255,6 +257,16 @@ int ffio_open_whitelist(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist); +/** + * Like ffio_open_whitelist(), but additionally records @p avfc on the + * underlying URLContext before it is connected, so protocols can use shared + * per-format resource. Pass NULL for standalone use. + */ +int ffio_open_whitelist2(AVIOContext **s, const char *url, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist, const char *blacklist, + AVFormatContext *avfc); + /** * Close a null buffer. * diff --git a/libavformat/internal.h b/libavformat/internal.h index cf42389062..759f1a9492 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -23,6 +23,8 @@ #include +#include "config_components.h" + #include "packet_internal.h" #include "avformat.h" diff --git a/libavformat/options.c b/libavformat/options.c index 4b743bb529..54dafdf5bf 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -153,7 +153,8 @@ static int io_open_default(AVFormatContext *s, AVIOContext **pb, av_log(s, loglevel, "Opening \'%s\' for %s\n", url, flags & AVIO_FLAG_WRITE ? "writing" : "reading"); - return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist); + return ffio_open_whitelist2(pb, url, flags, &s->interrupt_callback, options, + s->protocol_whitelist, s->protocol_blacklist, s); } static int io_close2_default(AVFormatContext *s, AVIOContext *pb) diff --git a/libavformat/url.h b/libavformat/url.h index 0784d77b64..eba7a39cca 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -46,6 +46,7 @@ typedef struct URLContext { const char *protocol_whitelist; const char *protocol_blacklist; int min_packet_size; /**< if non zero, the stream is packetized with this min packet size */ + struct AVFormatContext *avfc; /**< the AVFormatContext that opened this URLContext, or NULL for standalone use */ } URLContext; typedef struct URLProtocol {