win32: add mmap() emulation

Makes all of overlay_add work on windows/mingw.

Since we now don't explicitly check for mmap() anymore (it's always
present), this also requires us to make af_export.c compile, but I
haven't tested it.
This commit is contained in:
wm4 2014-12-26 17:14:48 +01:00
parent 9317071bc3
commit 3fdb6be316
9 changed files with 77 additions and 25 deletions

View File

@ -504,11 +504,6 @@ Input Commands that are Possibly Subject to Change
Passing the wrong thing here will crash the player. The ``offset`` parameter
is not used and must be 0. This mode might be useful for use with libmpv.
On Windows, currently only raw memory addresses work. File mapping is not
implemented because a ``mmap`` compatibility layer is missing, and because
this kind of shared memory method would perhaps not be overly useful on
Windows.
``offset`` is the offset of the first pixel in the source file. It is
passed directly to ``mmap`` and is subject to certain restrictions
(see ``man mmap`` for details). In particular, this value has to be a

View File

@ -70,9 +70,7 @@ static const struct af_info *const filter_list[] = {
&af_info_pan,
&af_info_surround,
&af_info_sub,
#if HAVE_SYS_MMAN_H
&af_info_export,
#endif
&af_info_drc,
&af_info_extrastereo,
&af_info_lavcac3enc,

View File

@ -34,7 +34,6 @@
#include "config.h"
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

View File

@ -963,7 +963,6 @@ cat > $TMPC << EOF
#define HAVE_DOS_PATHS 0
#define HAVE_PRIORITY 0
#define HAVE_GLOB 1
#define HAVE_SYS_MMAN_H 1
#define HAVE_NANOSLEEP 1
#define HAVE_SDL1 0
#define HAVE_WAIO 0

View File

@ -19,6 +19,7 @@
*/
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include "talloc.h"
@ -445,4 +446,62 @@ off_t mp_lseek(int fd, off_t offset, int whence)
return _lseeki64(fd, offset, whence);
}
// Limited mmap() wrapper, inspired by:
// http://code.google.com/p/mman-win32/source/browse/trunk/mman.c
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
assert(addr == NULL); // not implemented
assert(flags == MAP_SHARED); // not implemented
HANDLE osf = (HANDLE)_get_osfhandle(fd);
if (!osf) {
errno = EBADF;
return MAP_FAILED;
}
DWORD protect = 0;
DWORD access = 0;
if (prot & PROT_WRITE) {
protect = PAGE_READWRITE;
access = FILE_MAP_WRITE;
} else if (prot & PROT_READ) {
protect = PAGE_READONLY;
access = FILE_MAP_READ;
}
DWORD l_low = (uint32_t)length;
DWORD l_high = ((uint64_t)length) >> 32;
HANDLE map = CreateFileMapping(osf, NULL, protect, l_high, l_low, NULL);
if (!map) {
errno = EACCES; // something random
return MAP_FAILED;
}
DWORD o_low = (uint32_t)offset;
DWORD o_high = ((uint64_t)offset) >> 32;
void *p = MapViewOfFile(map, access, o_high, o_low, length);
CloseHandle(map);
if (!p) {
errno = EINVAL;
return MAP_FAILED;
}
return p;
}
int munmap(void *addr, size_t length)
{
UnmapViewOfFile(addr);
return 0;
}
int msync(void *addr, size_t length, int flags)
{
FlushViewOfFile(addr, length);
return 0;
}
#endif // __MINGW32__

View File

@ -135,6 +135,17 @@ void mp_globfree(mp_glob_t *pglob);
#undef fstat
#define fstat(...) mp_fstat(__VA_ARGS__)
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);
int msync(void *addr, size_t length, int flags);
#define PROT_READ 1
#define PROT_WRITE 2
#define MAP_SHARED 1
#define MAP_FAILED ((void *)-1)
#define MS_ASYNC 1
#define MS_SYNC 2
#define MS_INVALIDATE 4
#ifndef GLOB_NOMATCH
#define GLOB_NOMATCH 3
#endif
@ -143,6 +154,10 @@ void mp_globfree(mp_glob_t *pglob);
#define glob(...) mp_glob(__VA_ARGS__)
#define globfree(...) mp_globfree(__VA_ARGS__)
#else /* __MINGW32__ */
#include <sys/mman.h>
#endif /* __MINGW32__ */
#endif

View File

@ -60,9 +60,6 @@
#include "audio/decode/dec_audio.h"
#include "options/path.h"
#include "screenshot.h"
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifndef __MINGW32__
#include <sys/wait.h>
#endif
@ -3825,13 +3822,9 @@ static void replace_overlay(struct MPContext *mpctx, int id, struct overlay *new
*ptr = *new;
recreate_overlays(mpctx);
#if HAVE_SYS_MMAN_H
// Do this afterwards, so we never unmap while the OSD is using it.
if (old.osd.bitmap && old.map_size)
munmap(old.osd.bitmap, old.map_size);
#else
(void)old;
#endif
}
static int overlay_add(struct MPContext *mpctx, int id, int x, int y,
@ -3878,10 +3871,8 @@ static int overlay_add(struct MPContext *mpctx, int id, int x, int y,
fd = open(file, O_RDONLY | O_BINARY | O_CLOEXEC);
}
if (fd >= 0) {
#if HAVE_SYS_MMAN_H
overlay.map_size = h * stride;
p = mmap(NULL, overlay.map_size, PROT_READ, MAP_SHARED, fd, offset);
#endif
if (close_fd)
close(fd);
}

View File

@ -110,8 +110,8 @@ main_dependencies = [
'name': 'posix',
'desc': 'POSIX environment',
# This should be good enough.
'func': check_statement(['poll.h', 'unistd.h'],
'struct pollfd pfd; poll(&pfd, 1, 0); fork(); int f[2]; pipe(f)'),
'func': check_statement(['poll.h', 'unistd.h', 'sys/mman.h'],
'struct pollfd pfd; poll(&pfd, 1, 0); fork(); int f[2]; pipe(f); munmap(f,0)'),
}, {
'name': 'posix-or-mingw',
'desc': 'programming environment',
@ -196,10 +196,6 @@ iconv support use --disable-iconv.",
'desc': 'shm',
'func': check_statement(['sys/types.h', 'sys/ipc.h', 'sys/shm.h'],
'shmget(0, 0, 0); shmat(0, 0, 0); shmctl(0, 0, 0)')
}, {
'name': 'sys-mman-h',
'desc': 'mman.h',
'func': check_statement('sys/mman.h', 'mmap(0, 0, 0, 0, 0, 0)')
}, {
'name': 'nanosleep',
'desc': 'nanosleep',

View File

@ -103,7 +103,7 @@ def build(ctx):
( "audio/filter/af_drc.c" ),
( "audio/filter/af_dummy.c" ),
( "audio/filter/af_equalizer.c" ),
( "audio/filter/af_export.c", "sys-mman-h" ),
( "audio/filter/af_export.c" ),
( "audio/filter/af_extrastereo.c" ),
( "audio/filter/af_forcespeed.c" ),
( "audio/filter/af_format.c" ),