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]
