Commit 7d92f8e34e for ffmpeg
commit 7d92f8e34e423e5cb280fdcd8cfa009a2f8ee699
Author: Niklas Haas <git@haasn.dev>
Date: Wed Sep 30 14:43:07 2026 +0200
avformat/shared: add -metadata_dir option
This allows storing metadata in a separate directory, e.g. on a faster
drive, a tmpfs, or in a volume without quota limits.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 606ce07f3f..dbb1f166c7 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1748,6 +1748,10 @@ The accepted options are:
@item cache_dir
Path to the directory where cache files are stored. This option is required.
+@item metadata_dir
+Path to the directory where metadata files are stored. Optional. If not
+specified, metadata is stored in the same directory as the cache file.
+
@item block_shift
Shift factor (log2) of the block size used for internal reads/writes. Defaults
to 15, i.e. 32KB blocks. If this does not match the value that was specified
diff --git a/libavformat/shared.c b/libavformat/shared.c
index f5b87c45b0..4f438d8e7c 100644
--- a/libavformat/shared.c
+++ b/libavformat/shared.c
@@ -165,6 +165,7 @@ typedef struct SharedContext {
/* options */
char *cache_dir;
+ char *metadata_dir;
int block_shift; ///< requested shift; updated on init if it disagrees
int read_only;
int64_t timeout;
@@ -287,6 +288,10 @@ static int shared_open(URLContext *h, const char *arg, int flags, AVDictionary *
return AVERROR(EINVAL);
}
+ const char *spacemap_dir = s->cache_dir;
+ if (s->metadata_dir && s->metadata_dir[0])
+ spacemap_dir = s->metadata_dir;
+
s->fd = s->mapfd = -1; /* Set these early for shared_close() failure path */
/* Open underlying protocol */
@@ -309,7 +314,7 @@ static int shared_open(URLContext *h, const char *arg, int flags, AVDictionary *
char filename[2 * 16 + 1];
ff_data_to_hex(filename, hash, sizeof(filename)/2, 0);
s->cache_path = av_asprintf("%s/%s.cache", s->cache_dir, filename);
- s->map_path = av_asprintf("%s/%s.spacemap", s->cache_dir, filename);
+ s->map_path = av_asprintf("%s/%s.spacemap", spacemap_dir, filename);
if (!s->cache_path || !s->map_path) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -996,6 +1001,7 @@ static int shared_get_short_seek(URLContext *h)
static const AVOption options[] = {
{ "cache_dir", "Directory path for shared file cache", OFFSET(cache_dir), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = D },
+ { "metadata_dir", "Directory path for shared file cache metadata", OFFSET(metadata_dir), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = D },
{ "block_shift", "Set the base 2 logarithm of the block size", OFFSET(block_shift), AV_OPT_TYPE_INT, {.i64 = 15}, 9, 30, .flags = D },
{ "read_only", "Don't write data to the cache, only read from it", OFFSET(read_only), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, .flags = D },
{ "cache_verify", "Verify correctness of the cache against the source", OFFSET(verify), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, .flags = D },