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

Git pushed a commit to branch master
in repository ffmpeg.

commit dea75789c38ade62f5d598e19b2952b72a607d04
Author:     Kacper Michajłow <[email protected]>
AuthorDate: Mon Sep 7 00:49:19 2026 +0200
Commit:     Kacper Michajłow <[email protected]>
CommitDate: Wed Sep 23 16:50:45 2026 +0200

    avutil/file: add av_file_map_shared() and av_file_unmap_shared()
    
    av_file_map() maps a private copy of a file by name. Code that shares a
    file between processes needs the opposite, a writable mapping backed by
    the file, of a descriptor it opened itself, that grows with the file.
    Provide it with mmap() on POSIX and with a file mapping object on
    Windows, which also extends the file to the requested size.
    
    Signed-off-by: Kacper Michajłow <[email protected]>
---
 doc/APIchanges      |   3 ++
 libavutil/file.c    | 109 +++++++++++++++++++++++++++++++++++++---------------
 libavutil/file.h    |  29 ++++++++++++++
 libavutil/version.h |   2 +-
 4 files changed, 110 insertions(+), 33 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 5d81cd92d7..0e01005a63 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2026-06-23.
 
 API changes, most recent first:
 
+2026-09-xx - xxxxxxxxxx - lavu 61.8.100 - file.h
+  Add av_file_map_shared() and av_file_unmap_shared().
+
 2026-09-12 - xxxxxxxxxx - lavc 63.13.100 - codec_id.h, defs.h
   Add AV_CODEC_ID_ASTC and the AV_PROFILE_ASTC_* profile values.
 
diff --git a/libavutil/file.c b/libavutil/file.c
index 4c5632ff50..ba5142f847 100644
--- a/libavutil/file.c
+++ b/libavutil/file.c
@@ -60,6 +60,57 @@ static const AVClass file_log_ctx_class = {
     .parent_log_context_offset = offsetof(FileLogContext, log_ctx),
 };
 
+#if HAVE_MMAP || HAVE_MAPVIEWOFFILE
+/* Map the first size bytes of the file, as a private copy or shared and
+ * writable. The shared mapping extends the file to size, on Windows the
+ * mapping object does it. */
+static int map_file(int fd, size_t size, int shared, void **ptr)
+{
+#if HAVE_MMAP
+    if (shared) {
+        struct stat st;
+        if (fstat(fd, &st) < 0)
+            return AVERROR(errno);
+        if (st.st_size < size && ftruncate(fd, size) < 0)
+            return AVERROR(errno);
+    }
+
+    void *map = mmap(NULL, size, PROT_READ | PROT_WRITE,
+                     shared ? MAP_SHARED : MAP_PRIVATE, fd, 0);
+    if (map == MAP_FAILED)
+        return AVERROR(errno);
+#else
+    HANDLE fh = (HANDLE)_get_osfhandle(fd);
+    if (fh == INVALID_HANDLE_VALUE)
+        return AVERROR(EBADF);
+
+    HANDLE mh = CreateFileMapping(fh, NULL,
+                                  shared ? PAGE_READWRITE : PAGE_READONLY,
+                                  (uint64_t)size >> 32, size, NULL);
+    if (!mh)
+        return AVERROR(EIO);
+
+    void *map = MapViewOfFile(mh, shared ? FILE_MAP_ALL_ACCESS : FILE_MAP_COPY,
+                              0, 0, size);
+    CloseHandle(mh);
+    if (!map)
+        return AVERROR(EIO);
+#endif
+
+    *ptr = map;
+    return 0;
+}
+
+static void unmap_file(void *ptr, size_t size)
+{
+#if HAVE_MMAP
+    munmap(ptr, size);
+#else
+    UnmapViewOfFile(ptr);
+#endif
+}
+#endif
+
 int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
                 int log_offset, void *log_ctx)
 {
@@ -96,39 +147,15 @@ int av_file_map(const char *filename, uint8_t **bufptr, 
size_t *size,
         goto out;
     }
 
-#if HAVE_MMAP
-    ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
-    if (ptr == MAP_FAILED) {
-        err = AVERROR(errno);
-        av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", 
av_err2str(err));
+#if HAVE_MMAP || HAVE_MAPVIEWOFFILE
+    err = map_file(fd, *size, 0, &ptr);
+    if (err < 0) {
+        av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot map file '%s': %s\n", 
filename, av_err2str(err));
         close(fd);
         *size = 0;
         return err;
     }
     *bufptr = ptr;
-#elif HAVE_MAPVIEWOFFILE
-    {
-        HANDLE mh, fh = (HANDLE)_get_osfhandle(fd);
-
-        mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL);
-        if (!mh) {
-            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in 
CreateFileMapping()\n");
-            close(fd);
-            *size = 0;
-            return -1;
-        }
-
-        ptr = MapViewOfFile(mh, FILE_MAP_COPY, 0, 0, *size);
-        CloseHandle(mh);
-        if (!ptr) {
-            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in 
MapViewOfFile()\n");
-            close(fd);
-            *size = 0;
-            return -1;
-        }
-
-        *bufptr = ptr;
-    }
 #else
     *bufptr = av_malloc(*size);
     if (!*bufptr) {
@@ -149,11 +176,29 @@ void av_file_unmap(uint8_t *bufptr, size_t size)
 {
     if (!size || !bufptr)
         return;
-#if HAVE_MMAP
-    munmap(bufptr, size);
-#elif HAVE_MAPVIEWOFFILE
-    UnmapViewOfFile(bufptr);
+#if HAVE_MMAP || HAVE_MAPVIEWOFFILE
+    unmap_file(bufptr, size);
 #else
     av_free(bufptr);
 #endif
 }
+
+int av_file_map_shared(int fd, size_t size, void **bufptr)
+{
+    *bufptr = NULL;
+    if (!size)
+        return AVERROR(EINVAL);
+#if HAVE_MMAP || HAVE_MAPVIEWOFFILE
+    return map_file(fd, size, 1, bufptr);
+#else
+    return AVERROR(ENOSYS);
+#endif
+}
+
+void av_file_unmap_shared(void *bufptr, size_t size)
+{
+#if HAVE_MMAP || HAVE_MAPVIEWOFFILE
+    if (size && bufptr)
+        unmap_file(bufptr, size);
+#endif
+}
diff --git a/libavutil/file.h b/libavutil/file.h
index fced170108..d542a6fd56 100644
--- a/libavutil/file.h
+++ b/libavutil/file.h
@@ -59,4 +59,33 @@ int av_file_map(const char *filename, uint8_t **bufptr, 
size_t *size,
  */
 void av_file_unmap(uint8_t *bufptr, size_t size);
 
+/**
+ * Map the beginning of an open file into memory for shared read and write
+ * access.
+ *
+ * Unlike av_file_map() the mapping is not a private copy of the file, every
+ * store to the returned memory is written to the file and is visible to
+ * every other mapping of it, in this process and in other processes. The
+ * file is extended to size bytes if it is shorter, it is never shortened.
+ * The mapping must be released with av_file_unmap_shared().
+ *
+ * @param fd file descriptor of a file opened for reading and writing
+ * @param size number of bytes to map, must not be zero
+ * @param[out] bufptr pointee is set to the mapped memory
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR error code in case of failure, AVERROR(ENOSYS) when the platform
+ * has no shared file mappings
+ */
+av_warn_unused_result
+int av_file_map_shared(int fd, size_t size, void **bufptr);
+
+/**
+ * Unmap the memory mapped by av_file_map_shared().
+ *
+ * @param bufptr the memory previously mapped by av_file_map_shared()
+ * @param size size in bytes of the mapping, must be the same as passed
+ * to av_file_map_shared()
+ */
+void av_file_unmap_shared(void *bufptr, size_t size);
+
 #endif /* AVUTIL_FILE_H */
diff --git a/libavutil/version.h b/libavutil/version.h
index b83c74d755..a05c516c3d 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  61
-#define LIBAVUTIL_VERSION_MINOR   7
+#define LIBAVUTIL_VERSION_MINOR   8
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

-- 
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