[FFmpeg-devel] [PATCH] Windows support for av_file_map()

Daniel Verkamp daniel
Wed Jan 5 08:16:44 CET 2011


On Tue, Jan 4, 2011 at 10:47 PM, Daniel Verkamp <daniel at drv.nu> wrote:
> On Sat, Jan 1, 2011 at 11:39 AM, Michael Niedermayer <michaelni at gmx.at> wrote:
>> On Fri, Dec 31, 2010 at 02:35:50AM -0700, Daniel Verkamp wrote:
>>> Hi,
>>>
>>> Here's a simple implementation of av_file_map() using
>>> CreateFileMapping() and MapViewOfFile(), which are the rough Win32
>>> equivalent of mmap().
>>>
>>> This currently maps a read-only view of the file; this could be
>>> changed to R/W to match the mmap() path if desired, but any code
>>> expecting to actually use it for writing will fail with the non-mmap()
>>> path anyway since the file is never written back in that case.
>>>
>>> Thanks,
>>> -- Daniel Verkamp
>>
>> lgtm if tested
>>
>
> Applied with a small modification recommended by Ramiro on IRC.
>
> An (ugly hack of an) idea occurred to me: for the malloc() (non-mmap)
> case, the buffer could be allocated with some extra space at the
> beginning to store a fd or other information to be used to flush the
> file at close time; this follows the same API with working write
> access. ?A first try at implementing this is attached.
>
> On the other hand, this API is not very useful on 32-bit machines,
> since it only maps full files, and large files will obviously not fit
> into a 32-bit address space no matter how hard they are squeezed. ?It
> might not be a bad idea to have some kind of windowing/view support
> like mmap() et. al. if this is really intended to be used for anything
> other than the trivial small file case (and if that's all it's for, it
> seems like overkill).
>

Slightly changed version that doesn't depend on undefined integer
overflow semantics attached.
-------------- next part --------------
Index: file.c
===================================================================
--- file.c	(revision 26221)
+++ file.c	(working copy)
@@ -33,16 +33,21 @@
     void *log_ctx;
 } FileLogContext;
 
+/// Stored immediately preceding file data in memory in non-memory-mapped implementation
+typedef struct {
+    int fd;
+} FileMapContext;
+
 static const AVClass file_log_ctx_class = {
     "FILE", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT,
-    offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx)
+/////    offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx)
 };
 
 int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
                 int log_offset, void *log_ctx)
 {
     FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
-    int err, fd = open(filename, O_RDONLY);
+    int err, fd = open(filename, O_RDWR);
     struct stat st;
     av_unused void *ptr;
     off_t off_size;
@@ -84,6 +89,7 @@
         return err;
     }
     *bufptr = ptr;
+    close(fd);
 #elif HAVE_MAPVIEWOFFILE
     {
         HANDLE mh, fh = (HANDLE)_get_osfhandle(fd);
@@ -104,18 +110,31 @@
         }
 
         *bufptr = ptr;
+        close(fd);
     }
 #else
-    *bufptr = av_malloc(*size);
-    if (!*bufptr) {
+    if (*size > max_size - sizeof(FileMapContext))
+    {
+        av_log(&file_log_ctx, AV_LOG_ERROR,
+               "File size for file '%s' is too big\n", filename);
+        close(fd);
+        return AVERROR(EINVAL);
+    }
+
+    {
+    FileMapContext* buf = av_malloc(*size + sizeof(FileMapContext));
+    if (!buf) {
         av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n");
         close(fd);
         return AVERROR(ENOMEM);
     }
+
+    buf->fd = fd;
+    *bufptr = (uint8_t*)(buf + 1);
     read(fd, *bufptr, *size);
+    }
 #endif
 
-    close(fd);
     return 0;
 }
 
@@ -126,7 +145,13 @@
 #elif HAVE_MAPVIEWOFFILE
     UnmapViewOfFile(bufptr);
 #else
-    av_free(bufptr);
+    {
+        FileMapContext* buf = (FileMapContext*)bufptr - 1;
+        if (!lseek(buf->fd, 0, SEEK_SET))
+            write(buf->fd, bufptr, size);
+        close(buf->fd);
+        av_free(buf);
+    }
 #endif
 }
 



More information about the ffmpeg-devel mailing list