This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 30afbfcf6fe590b0ff58e0194223fec6353fffc5
Author:     Niklas Haas <[email protected]>
AuthorDate: Fri Aug 14 17:24:53 2026 +0200
Commit:     Niklas Haas <[email protected]>
CommitDate: Tue Sep 15 10:04:36 2026 +0000

    avformat/shared: add -cache_size_max option
    
    This allows users to limit the amount of cached data. Note that this is
    *not* a limit on the size of the file cached. For example, a 10 GB file can
    work with a 1 GB cache size limit if the user only ever plays some parts of
    the file (e.g. 1 minute from a 100 minute stream).
    
    After this point, s->read_only is simply turned on, giving us the expected
    fallback behavior for uncached blocks.
    
    Sponsored-by: nxtedition AB
    Signed-off-by: Niklas Haas <[email protected]>
---
 doc/protocols.texi   | 15 +++++++++++++++
 libavformat/shared.c | 16 ++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/doc/protocols.texi b/doc/protocols.texi
index 33f62e5d5b..031bc5c88e 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1758,6 +1758,21 @@ If true (the default), blocks whose contents fail the 
CRC integrity check are
 re-fetched from the underlying input stream, overwriting the corrupt cached
 data. If false, cache corruption is treated as a fatal read error.
 
+@item cache_size_max
+Maximum amount of data to cache, in bytes, rounded down to a multiple of the
+chosen block size. Accepts the usual size suffixes, e.g. @code{10G} for
+10*10^9 bytes, or @code{10Gi} for 10*2^30 bytes. Defaults to 0, meaning no
+limit.
+
+Once this limit is reached, the protocol switches to read-only mode (see
+@option{read_only}). Already cached data is never evicted, so once this limit
+is reached, no new data will ever be cached until the cache file is deleted.
+
+Note that this option is best-effort only, and may over-write up to N-1
+blocks, where N is the number of concurrent processes using the same cache
+file. Note also that the underlying file system may reserve more space than
+written, if the underlying allocation granularity is larger than the block
+size.
 @end table
 
 URL Syntax is
diff --git a/libavformat/shared.c b/libavformat/shared.c
index cd545d54ba..2205f15377 100644
--- a/libavformat/shared.c
+++ b/libavformat/shared.c
@@ -167,6 +167,7 @@ typedef struct SharedContext {
     int retry_errors;
     int retry_corrupt;
     int verify;
+    int64_t cache_size_max;
 
     /* misc state */
     int64_t pos; ///< current logical position
@@ -175,6 +176,7 @@ typedef struct SharedContext {
     int write_err; ///< write error occurred
     int num_corrupt;
     int64_t filesize; ///< once known
+    int64_t blocks_max; ///< maximum number of blocks to cache
 
     /* cache file */
     uint8_t *cache_data; ///< optional mmap of the cache file
@@ -329,6 +331,7 @@ static int shared_open(URLContext *h, const char *arg, int 
flags, AVDictionary *
 
     /* s->block_shift is fully settled after spacemap_init() */
     s->block_size = 1 << s->block_shift;
+    s->blocks_max = s->cache_size_max >> s->block_shift;
 
     int64_t filesize = get_filesize(h);
     if (filesize < 0) {
@@ -731,6 +734,18 @@ read_block:
     case BLOCK_NONE:
         if (s->read_only || s->write_err || !s->inner)
             break; /* don't mark block as pending */
+        else if (s->cache_size_max) {
+            int64_t cached = atomic_load_explicit(&s->spacemap->blocks_cached,
+                                                  memory_order_relaxed);
+            if (cached >= s->blocks_max) {
+                av_log(h, AV_LOG_WARNING, "Cache size limit reached (%"PRId64" 
"
+                       "blocks = %"PRId64" bytes), switching to read-only 
mode.\n",
+                       s->blocks_max, s->blocks_max << s->block_shift);
+                s->read_only = 1;
+                break;
+            }
+        }
+
         if (atomic_compare_exchange_strong_explicit(&block->state, &state,
                                                     BLOCK_PENDING,
                                                     memory_order_acquire,
@@ -999,6 +1014,7 @@ static const AVOption options[] = {
     { "ignore_errors",  "Continue even if the inner URL failed",            
OFFSET(ignore_errors),  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, .flags = D },
     { "retry_errors",   "Re-request blocks even if they previously failed", 
OFFSET(retry_errors),   AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, .flags = D },
     { "retry_corrupt",  "Re-request blocks that fail the CRC check",        
OFFSET(retry_corrupt),  AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, .flags = D },
+    { "cache_size_max", "Limit the maximum amount of data cached",          
OFFSET(cache_size_max), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, .flags = D 
},
     {0},
 };
 

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to