mirror of https://github.com/mpv-player/mpv
Universal Windows Plaform (UWP) support
libmpv only. Some things are still missing. Heavily reworked. Signed-off-by: wm4 <wm4@nowhere>
This commit is contained in:
parent
f22d12ac51
commit
4637b029cd
|
@ -663,11 +663,13 @@ static HRESULT fix_format(struct ao *ao, bool align_hack)
|
||||||
init_session_display(state);
|
init_session_display(state);
|
||||||
init_volume_control(state);
|
init_volume_control(state);
|
||||||
|
|
||||||
|
#if !HAVE_UWP
|
||||||
state->hTask = AvSetMmThreadCharacteristics(L"Pro Audio", &(DWORD){0});
|
state->hTask = AvSetMmThreadCharacteristics(L"Pro Audio", &(DWORD){0});
|
||||||
if (!state->hTask) {
|
if (!state->hTask) {
|
||||||
MP_WARN(state, "Failed to set AV thread to Pro Audio: %s\n",
|
MP_WARN(state, "Failed to set AV thread to Pro Audio: %s\n",
|
||||||
mp_LastError_to_str());
|
mp_LastError_to_str());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
exit_label:
|
exit_label:
|
||||||
|
@ -980,6 +982,8 @@ void wasapi_thread_uninit(struct ao *ao)
|
||||||
SAFE_RELEASE(state->pSessionControl);
|
SAFE_RELEASE(state->pSessionControl);
|
||||||
SAFE_RELEASE(state->pAudioClient);
|
SAFE_RELEASE(state->pAudioClient);
|
||||||
SAFE_RELEASE(state->pDevice);
|
SAFE_RELEASE(state->pDevice);
|
||||||
|
#if !HAVE_UWP
|
||||||
SAFE_DESTROY(state->hTask, AvRevertMmThreadCharacteristics(state->hTask));
|
SAFE_DESTROY(state->hTask, AvRevertMmThreadCharacteristics(state->hTask));
|
||||||
|
#endif
|
||||||
MP_DBG(ao, "Thread uninit done\n");
|
MP_DBG(ao, "Thread uninit done\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,9 @@ static const mp_get_platform_path_cb path_resolvers[] = {
|
||||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||||
mp_get_platform_path_unix,
|
mp_get_platform_path_unix,
|
||||||
#endif
|
#endif
|
||||||
#if defined(_WIN32)
|
#if HAVE_UWP
|
||||||
|
mp_get_platform_path_uwp,
|
||||||
|
#elif defined(_WIN32)
|
||||||
mp_get_platform_path_win,
|
mp_get_platform_path_win,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,13 @@
|
||||||
#include "osdep/io.h"
|
#include "osdep/io.h"
|
||||||
#include "mpv_talloc.h"
|
#include "mpv_talloc.h"
|
||||||
|
|
||||||
|
#if HAVE_UWP
|
||||||
|
// Missing from MinGW headers.
|
||||||
|
WINBASEAPI HANDLE WINAPI FindFirstFileExW(LPCWSTR lpFileName,
|
||||||
|
FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
|
||||||
|
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags);
|
||||||
|
#endif
|
||||||
|
|
||||||
static wchar_t *talloc_wcsdup(void *ctx, const wchar_t *wcs)
|
static wchar_t *talloc_wcsdup(void *ctx, const wchar_t *wcs)
|
||||||
{
|
{
|
||||||
size_t len = (wcslen(wcs) + 1) * sizeof(wchar_t);
|
size_t len = (wcslen(wcs) + 1) * sizeof(wchar_t);
|
||||||
|
@ -88,7 +95,7 @@ int mp_glob(const char *restrict pattern, int flags,
|
||||||
|
|
||||||
wchar_t *wpattern = mp_from_utf8(NULL, pattern);
|
wchar_t *wpattern = mp_from_utf8(NULL, pattern);
|
||||||
WIN32_FIND_DATAW data;
|
WIN32_FIND_DATAW data;
|
||||||
HANDLE find = FindFirstFileW(wpattern, &data);
|
HANDLE find = FindFirstFileExW(wpattern, FindExInfoBasic, &data, FindExSearchNameMatch, NULL, 0);
|
||||||
talloc_free(wpattern);
|
talloc_free(wpattern);
|
||||||
|
|
||||||
// Assume an error means there were no matches. mpv doesn't check for
|
// Assume an error means there were no matches. mpv doesn't check for
|
||||||
|
|
41
osdep/io.c
41
osdep/io.c
|
@ -29,6 +29,16 @@
|
||||||
#include "osdep/io.h"
|
#include "osdep/io.h"
|
||||||
#include "osdep/terminal.h"
|
#include "osdep/terminal.h"
|
||||||
|
|
||||||
|
#if HAVE_UWP
|
||||||
|
// Missing from MinGW headers.
|
||||||
|
#include <windows.h>
|
||||||
|
WINBASEAPI UINT WINAPI GetTempFileNameW(LPCWSTR lpPathName, LPCWSTR lpPrefixString,
|
||||||
|
UINT uUnique, LPWSTR lpTempFileName);
|
||||||
|
WINBASEAPI DWORD WINAPI GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer);
|
||||||
|
WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength,
|
||||||
|
LPWSTR lpBuffer, LPWSTR *lpFilePart);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set the CLOEXEC flag on the given fd.
|
// Set the CLOEXEC flag on the given fd.
|
||||||
// On error, false is returned (and errno set).
|
// On error, false is returned (and errno set).
|
||||||
bool mp_set_cloexec(int fd)
|
bool mp_set_cloexec(int fd)
|
||||||
|
@ -164,6 +174,12 @@ int mp_fstat(int fd, struct mp_stat *buf)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_UWP
|
||||||
|
static int mp_vfprintf(FILE *stream, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
return vfprintf(stream, format, args);
|
||||||
|
}
|
||||||
|
#else
|
||||||
static int mp_check_console(HANDLE wstream)
|
static int mp_check_console(HANDLE wstream)
|
||||||
{
|
{
|
||||||
if (wstream != INVALID_HANDLE_VALUE) {
|
if (wstream != INVALID_HANDLE_VALUE) {
|
||||||
|
@ -215,6 +231,7 @@ static int mp_vfprintf(FILE *stream, const char *format, va_list args)
|
||||||
|
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int mp_fprintf(FILE *stream, const char *format, ...)
|
int mp_fprintf(FILE *stream, const char *format, ...)
|
||||||
{
|
{
|
||||||
|
@ -412,8 +429,7 @@ static void free_env(void)
|
||||||
// at runtime, and converting/allocating them in advance is ok.
|
// at runtime, and converting/allocating them in advance is ok.
|
||||||
static void init_getenv(void)
|
static void init_getenv(void)
|
||||||
{
|
{
|
||||||
if (utf8_environ_ctx)
|
#if !HAVE_UWP
|
||||||
return;
|
|
||||||
wchar_t *wenv = GetEnvironmentStringsW();
|
wchar_t *wenv = GetEnvironmentStringsW();
|
||||||
if (!wenv)
|
if (!wenv)
|
||||||
return;
|
return;
|
||||||
|
@ -430,6 +446,7 @@ static void init_getenv(void)
|
||||||
MP_TARRAY_APPEND(utf8_environ_ctx, utf8_environ, num_env, NULL);
|
MP_TARRAY_APPEND(utf8_environ_ctx, utf8_environ, num_env, NULL);
|
||||||
// Avoid showing up in leak detectors etc.
|
// Avoid showing up in leak detectors etc.
|
||||||
atexit(free_env);
|
atexit(free_env);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *mp_getenv(const char *name)
|
char *mp_getenv(const char *name)
|
||||||
|
@ -457,6 +474,25 @@ off_t mp_lseek(int fd, off_t offset, int whence)
|
||||||
return _lseeki64(fd, offset, whence);
|
return _lseeki64(fd, offset, whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_UWP
|
||||||
|
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return MAP_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int munmap(void *addr, size_t length)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msync(void *addr, size_t length, int flags)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
// Limited mmap() wrapper, inspired by:
|
// Limited mmap() wrapper, inspired by:
|
||||||
// http://code.google.com/p/mman-win32/source/browse/trunk/mman.c
|
// http://code.google.com/p/mman-win32/source/browse/trunk/mman.c
|
||||||
|
|
||||||
|
@ -514,5 +550,6 @@ int msync(void *addr, size_t length, int flags)
|
||||||
FlushViewOfFile(addr, length);
|
FlushViewOfFile(addr, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __MINGW32__
|
#endif // __MINGW32__
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of mpv.
|
||||||
|
*
|
||||||
|
* mpv is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* mpv is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "osdep/path.h"
|
||||||
|
#include "osdep/io.h"
|
||||||
|
#include "options/path.h"
|
||||||
|
|
||||||
|
// Missing from MinGW headers.
|
||||||
|
WINBASEAPI DWORD WINAPI GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer);
|
||||||
|
|
||||||
|
const char *mp_get_platform_path_uwp(void *talloc_ctx, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "home") == 0) {
|
||||||
|
wchar_t homeDir[_MAX_PATH];
|
||||||
|
if (GetCurrentDirectoryW(_MAX_PATH, homeDir) != 0)
|
||||||
|
return mp_to_utf8(talloc_ctx, homeDir);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
typedef const char *(*mp_get_platform_path_cb)(void *talloc_ctx, const char *type);
|
typedef const char *(*mp_get_platform_path_cb)(void *talloc_ctx, const char *type);
|
||||||
|
|
||||||
// Conforming to mp_get_platform_path_cb.
|
// Conforming to mp_get_platform_path_cb.
|
||||||
|
const char *mp_get_platform_path_uwp(void *talloc_ctx, const char *type);
|
||||||
const char *mp_get_platform_path_win(void *talloc_ctx, const char *type);
|
const char *mp_get_platform_path_win(void *talloc_ctx, const char *type);
|
||||||
const char *mp_get_platform_path_osx(void *talloc_ctx, const char *type);
|
const char *mp_get_platform_path_osx(void *talloc_ctx, const char *type);
|
||||||
const char *mp_get_platform_path_unix(void *talloc_ctx, const char *type);
|
const char *mp_get_platform_path_unix(void *talloc_ctx, const char *type);
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
static LARGE_INTEGER perf_freq;
|
static LARGE_INTEGER perf_freq;
|
||||||
|
|
||||||
void mp_sleep_us(int64_t us)
|
void mp_sleep_us(int64_t us)
|
||||||
|
@ -50,5 +52,7 @@ uint64_t mp_raw_time_us(void)
|
||||||
void mp_raw_time_init(void)
|
void mp_raw_time_init(void)
|
||||||
{
|
{
|
||||||
QueryPerformanceFrequency(&perf_freq);
|
QueryPerformanceFrequency(&perf_freq);
|
||||||
|
#if !HAVE_UWP
|
||||||
timeBeginPeriod(1); // request 1ms timer resolution
|
timeBeginPeriod(1); // request 1ms timer resolution
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,7 @@ done:
|
||||||
|
|
||||||
void pthread_set_name_np(pthread_t thread, const char *name)
|
void pthread_set_name_np(pthread_t thread, const char *name)
|
||||||
{
|
{
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && defined(_PROCESSTHREADSAPI_H_)
|
||||||
HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
|
HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
|
||||||
if (!kernel32)
|
if (!kernel32)
|
||||||
return;
|
return;
|
||||||
|
@ -263,6 +264,7 @@ void pthread_set_name_np(pthread_t thread, const char *name)
|
||||||
pSetThreadDescription(th, wname);
|
pSetThreadDescription(th, wname);
|
||||||
}
|
}
|
||||||
CloseHandle(th);
|
CloseHandle(th);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int sem_init(sem_t *sem, int pshared, unsigned int value)
|
int sem_init(sem_t *sem, int pshared, unsigned int value)
|
||||||
|
|
|
@ -684,6 +684,7 @@ int get_cache_buffering_percentage(struct MPContext *mpctx)
|
||||||
|
|
||||||
static void handle_heartbeat_cmd(struct MPContext *mpctx)
|
static void handle_heartbeat_cmd(struct MPContext *mpctx)
|
||||||
{
|
{
|
||||||
|
#if !HAVE_UWP
|
||||||
struct MPOpts *opts = mpctx->opts;
|
struct MPOpts *opts = mpctx->opts;
|
||||||
if (opts->heartbeat_cmd && !mpctx->paused && mpctx->video_out) {
|
if (opts->heartbeat_cmd && !mpctx->paused && mpctx->video_out) {
|
||||||
double now = mp_time_sec();
|
double now = mp_time_sec();
|
||||||
|
@ -693,6 +694,7 @@ static void handle_heartbeat_cmd(struct MPContext *mpctx)
|
||||||
}
|
}
|
||||||
mp_set_timeout(mpctx, mpctx->next_heartbeat - now);
|
mp_set_timeout(mpctx, mpctx->next_heartbeat - now);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_cursor_autohide(struct MPContext *mpctx)
|
static void handle_cursor_autohide(struct MPContext *mpctx)
|
||||||
|
|
11
wscript
11
wscript
|
@ -22,6 +22,7 @@ Dependency identifiers (for win32 vs. Unix):
|
||||||
(Windows without Cygwin)
|
(Windows without Cygwin)
|
||||||
os-win32 / _WIN32: defined if basic windows.h API is available
|
os-win32 / _WIN32: defined if basic windows.h API is available
|
||||||
win32-desktop / HAVE_WIN32_DESKTOP: defined if desktop windows.h API is available
|
win32-desktop / HAVE_WIN32_DESKTOP: defined if desktop windows.h API is available
|
||||||
|
uwp / HAVE_UWP: defined if building for UWP (basic Windows only)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
build_options = [
|
build_options = [
|
||||||
|
@ -143,10 +144,18 @@ main_dependencies = [
|
||||||
'req': True,
|
'req': True,
|
||||||
'fmsg': 'Unable to find either POSIX or MinGW-w64 environment, ' \
|
'fmsg': 'Unable to find either POSIX or MinGW-w64 environment, ' \
|
||||||
'or compiler does not work.',
|
'or compiler does not work.',
|
||||||
|
}, {
|
||||||
|
'name': '--uwp',
|
||||||
|
'desc': 'Universal Windows Platform',
|
||||||
|
'default': 'disable',
|
||||||
|
'deps': [ 'os-win32', 'mingw' ],
|
||||||
|
'deps_neg': [ 'cplayer' ],
|
||||||
|
'func': check_cc(lib=['windowsapp']),
|
||||||
}, {
|
}, {
|
||||||
'name': 'win32-desktop',
|
'name': 'win32-desktop',
|
||||||
'desc': 'win32 desktop APIs',
|
'desc': 'win32 desktop APIs',
|
||||||
'deps_any': [ 'os-win32', 'os-cygwin' ],
|
'deps_any': [ 'os-win32', 'os-cygwin' ],
|
||||||
|
'deps_neg': [ 'uwp' ],
|
||||||
'func': check_cc(lib=['winmm', 'gdi32', 'ole32', 'uuid', 'avrt', 'dwmapi']),
|
'func': check_cc(lib=['winmm', 'gdi32', 'ole32', 'uuid', 'avrt', 'dwmapi']),
|
||||||
}, {
|
}, {
|
||||||
'name': '--win32-internal-pthreads',
|
'name': '--win32-internal-pthreads',
|
||||||
|
@ -519,7 +528,7 @@ audio_output_features = [
|
||||||
}, {
|
}, {
|
||||||
'name': '--wasapi',
|
'name': '--wasapi',
|
||||||
'desc': 'WASAPI audio output',
|
'desc': 'WASAPI audio output',
|
||||||
'deps': ['win32-desktop'],
|
'deps': ['os-win32'],
|
||||||
'func': check_cc(fragment=load_fragment('wasapi.c')),
|
'func': check_cc(fragment=load_fragment('wasapi.c')),
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -442,8 +442,9 @@ def build(ctx):
|
||||||
( subprocess_c ),
|
( subprocess_c ),
|
||||||
( "osdep/path-macosx.m", "cocoa" ),
|
( "osdep/path-macosx.m", "cocoa" ),
|
||||||
( "osdep/path-unix.c"),
|
( "osdep/path-unix.c"),
|
||||||
( "osdep/path-win.c", "os-win32" ),
|
( "osdep/path-win.c", "win32-desktop" ),
|
||||||
( "osdep/path-win.c", "os-cygwin" ),
|
( "osdep/path-win.c", "os-cygwin" ),
|
||||||
|
( "osdep/path-uwp.c", "uwp" ),
|
||||||
( "osdep/glob-win.c", "glob-win32" ),
|
( "osdep/glob-win.c", "glob-win32" ),
|
||||||
( "osdep/w32_keyboard.c", "os-win32" ),
|
( "osdep/w32_keyboard.c", "os-win32" ),
|
||||||
( "osdep/w32_keyboard.c", "os-cygwin" ),
|
( "osdep/w32_keyboard.c", "os-cygwin" ),
|
||||||
|
|
Loading…
Reference in New Issue