aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/options.rst7
-rw-r--r--Makefile3
-rw-r--r--audio/out/ao_wasapi0.c107
-rwxr-xr-xconfigure38
-rw-r--r--core/input/input.c293
-rw-r--r--core/input/input.h3
-rw-r--r--core/m_struct.h10
-rw-r--r--core/mp_ring.c2
-rw-r--r--core/mp_ring.h13
-rw-r--r--core/mplayer.c2
-rw-r--r--core/options.c3
-rw-r--r--core/options.h1
-rw-r--r--core/timeline/tl_matroska.c4
-rw-r--r--core/version.c6
-rw-r--r--osdep/getch2-win.c234
-rw-r--r--osdep/mpv.exe.manifest18
-rw-r--r--stream/cache.c2
-rw-r--r--stream/stream.c38
-rw-r--r--stream/stream.h4
-rw-r--r--stream/stream_vcd.c2
-rw-r--r--video/filter/vf.c2
-rw-r--r--video/out/cocoa_common.m8
22 files changed, 396 insertions, 404 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index a6e5fee7ed..58fc365db1 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -309,7 +309,7 @@
Set the size of the cache in kilobytes, disable it with ``no``, or
automatically enable it if needed with ``auto`` (default: ``auto``).
With ``auto``, the cache will usually be enabled for network streams,
- using a default size.
+ using the size set by ``--cache-default``.
May be useful when playing files from slow media, but can also have
negative effects, especially with file formats that require a lot of
@@ -321,6 +321,11 @@
seeking back. Likewise, when starting a file the cache will be at 100%,
because no space is reserved for seeking back yet.
+``--cache-default=<kBytes|no>``
+ Set the size of the cache in kilobytes (default: 320 KB). Using ``no``
+ will not automatically enable the cache e.h. when playing from a network
+ stream. Note that using ``--cache`` will always override this option.
+
``--cache-pause=<no|percentage>``
If the cache percentage goes below the specified value, pause and wait
until the percentage set by ``--cache-min`` is reached, then resume
diff --git a/Makefile b/Makefile
index ad4728270c..5c0c1c6490 100644
--- a/Makefile
+++ b/Makefile
@@ -116,6 +116,8 @@ ifeq ($(HAVE_AVUTIL_REFCOUNTING),no)
SOURCES-yes += video/decode/lavc_dr1.c
endif
+SOURCES-$(DLOPEN) += video/filter/vf_dlopen.c
+
SOURCES = talloc.c \
audio/audio.c \
audio/chmap.c \
@@ -235,7 +237,6 @@ SOURCES = talloc.c \
video/filter/vf_crop.c \
video/filter/vf_delogo.c \
video/filter/vf_divtc.c \
- video/filter/vf_dlopen.c \
video/filter/vf_down3dright.c \
video/filter/vf_dsize.c \
video/filter/vf_eq.c \
diff --git a/audio/out/ao_wasapi0.c b/audio/out/ao_wasapi0.c
index 8d0fe27801..a45ca829e5 100644
--- a/audio/out/ao_wasapi0.c
+++ b/audio/out/ao_wasapi0.c
@@ -30,6 +30,7 @@
#include "core/subopt-helper.h"
#include "audio/format.h"
#include "core/mp_msg.h"
+#include "core/mp_ring.h"
#include "ao.h"
#define RING_BUFFER_COUNT 64
@@ -75,17 +76,13 @@ typedef struct wasapi0_state {
CRITICAL_SECTION print_lock;
/* Buffers */
- CRITICAL_SECTION buffer_lock;
+ struct mp_ring *ringbuff;
size_t buffer_block_size; /* Size of each block in bytes */
- LONG read_block_ptr, write_block_ptr; /*Which block are we in?*/
- LONG write_ahead_count; /* how many blocks writer is ahead of reader? should be less than RING_BUFFER_COUNT*/
- uintptr_t write_offset; /*offset while writing partial blocks, used only in main thread */
REFERENCE_TIME
minRequestedDuration; /* minimum wasapi buffer block size, in 100-nanosecond units */
REFERENCE_TIME
defaultRequestedDuration; /* default wasapi default block size, in 100-nanosecond units */
UINT32 bufferFrameCount; /* wasapi buffer block size, number of frames, frame size at format.nBlockAlign */
- void *ring_buffer[RING_BUFFER_COUNT]; /* each bufferFrameCount sized, owned by main thread */
/* WASAPI handles, owned by other thread */
IMMDeviceEnumerator *pEnumerator;
@@ -317,7 +314,6 @@ static int fix_format(struct wasapi0_state *state)
/* cargo cult code to negotiate buffer block size, affected by hardware/drivers combinations,
gradually grow it to 10s, by 0.5s, consider failure if it still doesn't work
*/
- EnterCriticalSection(&state->buffer_lock);
hr = IAudioClient_GetDevicePeriod(state->pAudioClient,
&state->defaultRequestedDuration,
&state->minRequestedDuration);
@@ -365,7 +361,6 @@ reinit:
EXIT_ON_ERROR(hr)
state->buffer_block_size = state->format.Format.nBlockAlign *
state->bufferFrameCount;
- LeaveCriticalSection(&state->buffer_lock);
state->hTask =
state->VistaBlob.pAvSetMmThreadCharacteristicsW(L"Pro Audio", &state->taskIndex);
EnterCriticalSection(&state->print_lock);
@@ -380,7 +375,6 @@ exit_label:
"ao-wasapi: fix_format fails with %s, failed to determine buffer block size!\n",
explain_err(hr));
LeaveCriticalSection(&state->print_lock);
- LeaveCriticalSection(&state->buffer_lock);
SetEvent(state->fatal_error);
return 1;
}
@@ -440,22 +434,23 @@ static void thread_reset(wasapi0_state *state)
IAudioClient_Reset(state->pAudioClient);
}
-static void thread_feed(wasapi0_state *state)
+/* force_feed - feed in even if available data is smaller than required buffer, to clear the buffer */
+static void thread_feed(wasapi0_state *state,int force_feed)
{
BYTE *pData;
+ int buffer_size;
HRESULT hr = IAudioRenderClient_GetBuffer(state->pRenderClient,
state->bufferFrameCount, &pData);
EXIT_ON_ERROR(hr)
- EnterCriticalSection(&state->buffer_lock);
- if (state->write_ahead_count > 0) { /* OK to copy! */
- memcpy(pData, state->ring_buffer[state->read_block_ptr],
- state->buffer_block_size);
- state->read_block_ptr++;
- state->read_block_ptr = state->read_block_ptr % RING_BUFFER_COUNT;
- state->write_ahead_count--;
- LeaveCriticalSection(&state->buffer_lock);
+ buffer_size = mp_ring_buffered(state->ringbuff);
+ if( buffer_size > state->buffer_block_size) { /* OK to copy! */
+ mp_ring_read(state->ringbuff, (unsigned char *)pData,
+ state->buffer_block_size);
+ } else if(force_feed) {
+ /* should be smaller than buffer block size by now */
+ memset(pData,0,state->buffer_block_size);
+ mp_ring_read(state->ringbuff, (unsigned char *)pData, buffer_size);
} else {
- LeaveCriticalSection(&state->buffer_lock);
/* buffer underrun?! abort */
hr = IAudioRenderClient_ReleaseBuffer(state->pRenderClient,
state->bufferFrameCount,
@@ -475,7 +470,7 @@ exit_label:
static void thread_play(wasapi0_state *state)
{
- thread_feed(state);
+ thread_feed(state, 0);
IAudioClient_Start(state->pAudioClient);
return;
}
@@ -499,11 +494,10 @@ static void thread_uninit(wasapi0_state *state)
if (!state->immed) {
/* feed until empty */
while (1) {
- EnterCriticalSection(&state->buffer_lock);
- LONG ahead = state->write_ahead_count;
- LeaveCriticalSection(&state->buffer_lock);
- if (WaitForSingleObject(state->hFeed, 2000) == WAIT_OBJECT_0 && ahead) {
- thread_feed(state);
+ if (WaitForSingleObject(state->hFeed,2000) == WAIT_OBJECT_0 &&
+ mp_ring_buffered(state->ringbuff))
+ {
+ thread_feed(state, 1);
} else
break;
}
@@ -568,7 +562,7 @@ static unsigned int __stdcall ThreadLoop(void *lpParameter)
break;
case (WAIT_OBJECT_0 + 6): /* feed */
feedwatch = 1;
- thread_feed(state);
+ thread_feed(state, 0);
break;
case WAIT_TIMEOUT: /* Did our feed die? */
if (feedwatch)
@@ -608,48 +602,22 @@ static void closehandles(struct ao *ao)
static int get_space(struct ao *ao)
{
- int ret = 0;
if (!ao || !ao->priv)
return -1;
struct wasapi0_state *state = (struct wasapi0_state *)ao->priv;
- EnterCriticalSection(&state->buffer_lock);
- LONG ahead = state->write_ahead_count;
- size_t block_size = state->buffer_block_size;
- LeaveCriticalSection(&state->buffer_lock);
- ret = (RING_BUFFER_COUNT - ahead) * block_size; /* rough */
- return ret - (block_size - state->write_offset); /* take offset into account */
+ return mp_ring_available(state->ringbuff);
}
static void reset_buffers(struct wasapi0_state *state)
{
- EnterCriticalSection(&state->buffer_lock);
- state->read_block_ptr = state->write_block_ptr = 0;
- state->write_ahead_count = 0;
- state->write_offset = 0;
- LeaveCriticalSection(&state->buffer_lock);
-}
-
-static void free_buffers(struct wasapi0_state *state)
-{
- int iter;
- for (iter = 0; iter < RING_BUFFER_COUNT; iter++) {
- free(state->ring_buffer[iter]);
- state->ring_buffer[iter] = NULL;
- }
+ mp_ring_reset(state->ringbuff);
}
static int setup_buffers(struct wasapi0_state *state)
{
- int iter;
- reset_buffers(state);
- for (iter = 0; iter < RING_BUFFER_COUNT; iter++) {
- state->ring_buffer[iter] = malloc(state->buffer_block_size);
- if (!state->ring_buffer[iter]) {
- free_buffers(state);
- return 1; /* failed */
- }
- }
- return 0;
+ state->ringbuff =
+ mp_ring_new(state, RING_BUFFER_COUNT * state->buffer_block_size);
+ return !state->ringbuff;
}
static void uninit(struct ao *ao, bool immed)
@@ -663,9 +631,7 @@ static void uninit(struct ao *ao, bool immed)
SetEvent(state->fatal_error);
if (state->VistaBlob.hAvrt)
FreeLibrary(state->VistaBlob.hAvrt);
- free_buffers(state);
closehandles(ao);
- DeleteCriticalSection(&state->buffer_lock);
DeleteCriticalSection(&state->print_lock);
talloc_free(state);
ao->priv = NULL;
@@ -694,7 +660,6 @@ static int init(struct ao *ao, char *params)
state->hUninit = CreateEventW(NULL, FALSE, FALSE, NULL);
state->fatal_error = CreateEventW(NULL, TRUE, FALSE, NULL);
state->hFeed = CreateEvent(NULL, FALSE, FALSE, NULL); /* for wasapi event mode */
- InitializeCriticalSection(&state->buffer_lock);
InitializeCriticalSection(&state->print_lock);
if (!state->init_done || !state->fatal_error || !state->hPlay ||
!state->hPause || !state->hFeed || !state->hReset || !state->hGetvol ||
@@ -772,7 +737,6 @@ static void reset(struct ao *ao)
static int play(struct ao *ao, void *data, int len, int flags)
{
int ret = 0;
- unsigned char *dat = data;
if (!ao || !ao->priv)
return ret;
struct wasapi0_state *state = (struct wasapi0_state *)ao->priv;
@@ -781,28 +745,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
return ret;
}
- /* round to nearest block size? */
- EnterCriticalSection(&state->buffer_lock);
- /* make sure write ahead does not bust buffer count */
- while ((RING_BUFFER_COUNT - 1) > state->write_ahead_count) {
- /* data left is larger than block size, do block by block copy */
- if ((len - ret) > state->buffer_block_size) {
- memcpy(state->ring_buffer[state->write_block_ptr], &dat[ret],
- state->buffer_block_size);
- } else if (flags & AOPLAY_FINAL_CHUNK) {
- /* zero out and fill with whatever that is left, but only if it is final block */
- memset(state->ring_buffer[state->write_block_ptr], 0,
- state->buffer_block_size);
- memcpy(state->ring_buffer[state->write_block_ptr], &dat[ret],
- (len - ret));
- } else
- break; /* otherwise leave buffers outside of block alignment and let player figure it out */
- state->write_block_ptr++;
- state->write_block_ptr %= RING_BUFFER_COUNT;
- state->write_ahead_count++;
- ret += state->buffer_block_size;
- }
- LeaveCriticalSection(&state->buffer_lock);
+ ret = mp_ring_write(state->ringbuff, data, len);
if (!state->is_playing) {
/* start playing */
diff --git a/configure b/configure
index f84cff678d..d9d48f6b1e 100755
--- a/configure
+++ b/configure
@@ -379,6 +379,7 @@ Miscellaneous options:
--enable-static build a statically linked binary
--with-install=PATH path to a custom install program
--disable-manpage do not build and install manpage [auto]
+ --disable-build-date do not include binary compile time
Advanced options:
--enable-shm enable shm [autodetect]
@@ -487,6 +488,7 @@ _priority=no
def_dos_paths="#define HAVE_DOS_PATHS 0"
def_priority="#undef CONFIG_PRIORITY"
_build_man=auto
+_build_date=yes
for ac_option do
case "$ac_option" in
--help|-help|-h)
@@ -708,6 +710,8 @@ for ac_option do
--enable-manpage) _build_man=yes ;;
--disable-manpage) _build_man=no ;;
+ --enable-build-date) _build_date=yes ;;
+ --disable-build-date) _build_date=no ;;
*)
echo "Unknown parameter: $ac_option" >&2
exit 1
@@ -861,7 +865,9 @@ if darwin; then
_timer=timer-darwin.c
fi
+_win32=no
if win32 ; then
+ _win32=yes
_exesuf=".exe"
extra_cflags="$extra_cflags -fno-common"
# -lwinmm is always needed for osdep/timer-win2.c
@@ -900,6 +906,16 @@ else
fi
echores "$_build_man"
+echocheck "whether to print binary build date"
+if test "$_build_date" = yes ; then
+ _build_yes=yes
+else
+ _build_date=no
+ extra_cflags="$extra_cflags -DNO_BUILD_TIMESTAMPS"
+fi
+echores "$_build_date"
+
+
TMPC="$mplayer_tmpdir/tmp.c"
TMPCPP="$mplayer_tmpdir/tmp.cpp"
@@ -2356,7 +2372,7 @@ if test "$_vcd" = auto; then
if linux || freebsd || netbsd || openbsd || dragonfly || darwin ; then
_vcd=yes
elif mingw32; then
- header_check ntddcdrm.h && _vcd=yes
+ header_check_broken windows.h ntddcdrm.h && _vcd=yes
fi
fi
if test "$_vcd" = yes; then
@@ -2493,7 +2509,9 @@ echores "$_mpg123"
echocheck "LADSPA plugin support"
if test "$_ladspa" = auto ; then
_ladspa=no
- statement_check ladspa.h 'LADSPA_Descriptor ld = {0}' && _ladspa=yes
+ if test "$_dl" = yes ; then
+ statement_check ladspa.h 'LADSPA_Descriptor ld = {0}' && _ladspa=yes
+ fi
fi
if test "$_ladspa" = yes; then
def_ladspa="#define CONFIG_LADSPA 1"
@@ -2824,6 +2842,18 @@ fi
echores "$_encoding"
+# needs dlopen on unix, uses winapi on windows
+_dlopen="$_dl"
+if win32 ; then
+ _dlopen=yes
+fi
+
+if test "$_dlopen" = yes ; then
+ def_dlopen='#define CONFIG_DLOPEN 1'
+else
+ def_dlopen='#undef CONFIG_DLOPEN'
+fi
+
#############################################################################
echocheck "compiler support for noexecstack"
@@ -2947,6 +2977,8 @@ COCOA = $_cocoa
COREAUDIO = $_coreaudio
COREVIDEO = $_corevideo
DIRECT3D = $_direct3d
+DL = $_dl
+DLOPEN = $_dlopen
SDL = $_sdl
SDL2 = $_sdl2
DSOUND = $_dsound
@@ -2999,6 +3031,7 @@ TV = $_tv
TV_V4L2 = $_tv_v4l2
VCD = $_vcd
VDPAU = $_vdpau
+WIN32 = $_win32
X11 = $_x11
WAYLAND = $_wayland
XV = $_xv
@@ -3106,6 +3139,7 @@ $def_libavfilter
$def_vf_lavfi
$def_af_lavfi
+$def_dlopen
/* Audio output drivers */
$def_alsa
diff --git a/core/input/input.c b/core/input/input.c
index e736c6486d..7ae76b9e04 100644
--- a/core/input/input.c
+++ b/core/input/input.c
@@ -462,27 +462,19 @@ struct key_name modifier_names[] = {
{ 0 }
};
-#ifndef MP_MAX_KEY_FD
-#define MP_MAX_KEY_FD 10
-#endif
-
-#ifndef MP_MAX_CMD_FD
-#define MP_MAX_CMD_FD 10
-#endif
+#define MP_MAX_FDS 10
struct input_fd {
int fd;
- union {
- int (*key)(void *ctx, int fd);
- int (*cmd)(int fd, char *dest, int size);
- } read_func;
+ int (*read_key)(void *ctx, int fd);
+ int (*read_cmd)(int fd, char *dest, int size);
int (*close_func)(int fd);
void *ctx;
unsigned eof : 1;
unsigned drop : 1;
unsigned dead : 1;
unsigned got_cmd : 1;
- unsigned no_select : 1;
+ unsigned select : 1;
// These fields are for the cmd fds.
char *buffer;
int pos, size;
@@ -553,11 +545,8 @@ struct input_ctx {
unsigned int mouse_event_counter;
- struct input_fd key_fds[MP_MAX_KEY_FD];
- unsigned int num_key_fd;
-
- struct input_fd cmd_fds[MP_MAX_CMD_FD];
- unsigned int num_cmd_fd;
+ struct input_fd fds[MP_MAX_FDS];
+ unsigned int num_fds;
struct cmd_queue key_cmd_queue;
struct cmd_queue control_cmd_queue;
@@ -700,98 +689,89 @@ static void queue_add(struct cmd_queue *queue, struct mp_cmd *cmd,
}
}
-int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select,
+static struct input_fd *mp_input_add_fd(struct input_ctx *ictx)
+{
+ if (ictx->num_fds == MP_MAX_FDS) {
+ mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many file descriptors.\n");
+ return NULL;
+ }
+
+ struct input_fd *fd = &ictx->fds[ictx->num_fds];
+ *fd = (struct input_fd){
+ .fd = -1,
+ };
+ ictx->num_fds++;
+
+ return fd;
+}
+
+int mp_input_add_cmd_fd(struct input_ctx *ictx, int unix_fd, int select,
int read_func(int fd, char *dest, int size),
int close_func(int fd))
{
- if (ictx->num_cmd_fd == MP_MAX_CMD_FD) {
- mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many command file descriptors, "
- "cannot register file descriptor %d.\n", fd);
- return 0;
- }
- if (select && fd < 0) {
+ if (select && unix_fd < 0) {
mp_msg(MSGT_INPUT, MSGL_ERR,
- "Invalid fd %d in mp_input_add_cmd_fd", fd);
+ "Invalid fd %d in mp_input_add_cmd_fd", unix_fd);
return 0;
}
- ictx->cmd_fds[ictx->num_cmd_fd] = (struct input_fd){
- .fd = fd,
- .read_func.cmd = read_func ? read_func : default_cmd_func,
- .close_func = close_func,
- .no_select = !select
- };
- ictx->num_cmd_fd++;
-
+ struct input_fd *fd = mp_input_add_fd(ictx);
+ if (!fd)
+ return 0;
+ fd->fd = unix_fd;
+ fd->select = select;
+ fd->read_cmd = read_func ? read_func : default_cmd_func;
+ fd->close_func = close_func;
return 1;
}
-void mp_input_rm_cmd_fd(struct input_ctx *ictx, int fd)
+int mp_input_add_key_fd(struct input_ctx *ictx, int unix_fd, int select,
+ int read_func(void *ctx, int fd),
+ int close_func(int fd), void *ctx)
{
- struct input_fd *cmd_fds = ictx->cmd_fds;
- unsigned int i;
-
- for (i = 0; i < ictx->num_cmd_fd; i++) {
- if (cmd_fds[i].fd == fd)
- break;
+ if (select && unix_fd < 0) {
+ mp_msg(MSGT_INPUT, MSGL_ERR,
+ "Invalid fd %d in mp_input_add_key_fd", unix_fd);
+ return 0;
}
- if (i == ictx->num_cmd_fd)
- return;
- if (cmd_fds[i].close_func)
- cmd_fds[i].close_func(cmd_fds[i].fd);
- talloc_free(cmd_fds[i].buffer);
+ assert(read_func);
- if (i + 1 < ictx->num_cmd_fd)
- memmove(&cmd_fds[i], &cmd_fds[i + 1],
- (ictx->num_cmd_fd - i - 1) * sizeof(struct input_fd));
- ictx->num_cmd_fd--;
+ struct input_fd *fd = mp_input_add_fd(ictx);
+ if (!fd)
+ return 0;
+ fd->fd = unix_fd;
+ fd->select = select;
+ fd->read_key = read_func;
+ fd->close_func = close_func;
+ fd->ctx = ctx;
+ return 1;
}
-void mp_input_rm_key_fd(struct input_ctx *ictx, int fd)
+
+static void mp_input_rm_fd(struct input_ctx *ictx, int fd)
{
- struct input_fd *key_fds = ictx->key_fds;
+ struct input_fd *fds = ictx->fds;
unsigned int i;
- for (i = 0; i < ictx->num_key_fd; i++) {
- if (key_fds[i].fd == fd)
+ for (i = 0; i < ictx->num_fds; i++) {
+ if (fds[i].fd == fd)
break;
}
- if (i == ictx->num_key_fd)
+ if (i == ictx->num_fds)
return;
- if (key_fds[i].close_func)
- key_fds[i].close_func(key_fds[i].fd);
+ if (fds[i].close_func)
+ fds[i].close_func(fds[i].fd);
+ talloc_free(fds[i].buffer);
- if (i + 1 < ictx->num_key_fd)
- memmove(&key_fds[i], &key_fds[i + 1],
- (ictx->num_key_fd - i - 1) * sizeof(struct input_fd));
- ictx->num_key_fd--;
+ if (i + 1 < ictx->num_fds)
+ memmove(&fds[i], &fds[i + 1],
+ (ictx->num_fds - i - 1) * sizeof(struct input_fd));
+ ictx->num_fds--;
}
-int mp_input_add_key_fd(struct input_ctx *ictx, int fd, int select,
- int read_func(void *ctx, int fd),
- int close_func(int fd), void *ctx)
+void mp_input_rm_key_fd(struct input_ctx *ictx, int fd)
{
- if (ictx->num_key_fd == MP_MAX_KEY_FD) {
- mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many key file descriptors, "
- "cannot register file descriptor %d.\n", fd);
- return 0;
- }
- if (select && fd < 0) {
- mp_msg(MSGT_INPUT, MSGL_ERR,
- "Invalid fd %d in mp_input_add_key_fd", fd);
- return 0;
- }
-
- ictx->key_fds[ictx->num_key_fd] = (struct input_fd){
- .fd = fd,
- .read_func.key = read_func,
- .close_func = close_func,
- .no_select = !select,
- .ctx = ctx,
- };
- ictx->num_key_fd++;
-
- return 1;
+ mp_input_rm_fd(ictx, fd);
}
static int parse_cycle_dir(const struct m_option *opt, struct bstr name,
@@ -1068,8 +1048,8 @@ static int read_cmd(struct input_fd *mp_fd, char **ret)
// Get some data if needed/possible
while (!mp_fd->got_cmd && !mp_fd->eof && (mp_fd->size - mp_fd->pos > 1)) {
- int r = mp_fd->read_func.cmd(mp_fd->fd, mp_fd->buffer + mp_fd->pos,
- mp_fd->size - 1 - mp_fd->pos);
+ int r = mp_fd->read_cmd(mp_fd->fd, mp_fd->buffer + mp_fd->pos,
+ mp_fd->size - 1 - mp_fd->pos);
// Error ?
if (r < 0) {
switch (r) {
@@ -1154,12 +1134,14 @@ static int default_cmd_func(int fd, char *buf, int l)
}
}
+#ifndef __MINGW32__
static int read_wakeup(void *ctx, int fd)
{
char buf[100];
read(fd, buf, sizeof(buf));
return MP_INPUT_NOTHING;
}
+#endif
static bool bind_matches_key(struct cmd_bind *bind, int n, const int *keys);
@@ -1593,7 +1575,7 @@ static void read_cmd_fd(struct input_ctx *ictx, struct input_fd *cmd_fd)
static void read_key_fd(struct input_ctx *ictx, struct input_fd *key_fd)
{
- int code = key_fd->read_func.key(key_fd->ctx, key_fd->fd);
+ int code = key_fd->read_key(key_fd->ctx, key_fd->fd);
if (code >= 0 || code == MP_INPUT_RELEASE_ALL) {
mp_input_feed_key(ictx, code);
return;
@@ -1609,50 +1591,38 @@ static void read_key_fd(struct input_ctx *ictx, struct input_fd *key_fd)
}
}
-/**
- * \param time time to wait at most for an event in milliseconds
- */
-static void read_events(struct input_ctx *ictx, int time)
+static void read_fd(struct input_ctx *ictx, struct input_fd *fd)
{
- if (ictx->num_key_down) {
- time = FFMIN(time, 1000 / ictx->ar_rate);
- time = FFMIN(time, ictx->ar_delay);
+ if (fd->read_cmd) {
+ read_cmd_fd(ictx, fd);
+ } else {
+ read_key_fd(ictx, fd);
}
- time = FFMAX(time, 0);
- ictx->got_new_events = false;
- struct input_fd *key_fds = ictx->key_fds;
- struct input_fd *cmd_fds = ictx->cmd_fds;
- for (int i = 0; i < ictx->num_key_fd; i++)
- if (key_fds[i].dead) {
- mp_input_rm_key_fd(ictx, key_fds[i].fd);
- i--;
- } else if (time && key_fds[i].no_select)
- read_key_fd(ictx, &key_fds[i]);
- for (int i = 0; i < ictx->num_cmd_fd; i++)
- if (cmd_fds[i].dead || cmd_fds[i].eof) {
- mp_input_rm_cmd_fd(ictx, cmd_fds[i].fd);
+}
+
+static void remove_dead_fds(struct input_ctx *ictx)
+{
+ for (int i = 0; i < ictx->num_fds; i++) {
+ if (ictx->fds[i].dead) {
+ mp_input_rm_fd(ictx, ictx->fds[i].fd);
i--;
- } else if (time && cmd_fds[i].no_select)
- read_cmd_fd(ictx, &cmd_fds[i]);
- if (ictx->got_new_events)
- time = 0;
+ }
+ }
+}
+
#ifdef HAVE_POSIX_SELECT
+
+static void input_wait_read(struct input_ctx *ictx, int time)
+{
fd_set fds;
FD_ZERO(&fds);
int max_fd = 0;
- for (int i = 0; i < ictx->num_key_fd; i++) {
- if (key_fds[i].no_select)
- continue;
- if (key_fds[i].fd > max_fd)
- max_fd = key_fds[i].fd;
- FD_SET(key_fds[i].fd, &fds);
- }
- for (int i = 0; i < ictx->num_cmd_fd; i++) {
- if (cmd_fds[i].no_select)
+ for (int i = 0; i < ictx->num_fds; i++) {
+ if (!ictx->fds[i].select)
continue;
- if (cmd_fds[i].fd > max_fd)
- max_fd = cmd_fds[i].fd;
- FD_SET(cmd_fds[i].fd, &fds);
+ if (ictx->fds[i].fd > max_fd)
+ max_fd = ictx->fds[i].fd;
+ FD_SET(ictx->fds[i].fd, &fds);
}
struct timeval tv, *time_val;
tv.tv_sec = time / 1000;
@@ -1664,40 +1634,59 @@ static void read_events(struct input_ctx *ictx, int time)
strerror(errno));
FD_ZERO(&fds);
}
+ for (int i = 0; i < ictx->num_fds; i++) {
+ if (ictx->fds[i].select && !FD_ISSET(ictx->fds[i].fd, &fds))
+ continue;
+ read_fd(ictx, &ictx->fds[i]);
+ }
+}
+
#else
+
+static void input_wait_read(struct input_ctx *ictx, int time)
+{
if (time > 0)
mp_sleep_us(time * 1000);
-#endif
-
- for (int i = 0; i < ictx->num_key_fd; i++) {
-#ifdef HAVE_POSIX_SELECT
- if (!key_fds[i].no_select && !FD_ISSET(key_fds[i].fd, &fds))
- continue;
-#endif
- read_key_fd(ictx, &key_fds[i]);
- }
+ for (int i = 0; i < ictx->num_fds; i++)
+ read_fd(ictx, &ictx->fds[i]);
+}
- for (int i = 0; i < ictx->num_cmd_fd; i++) {
-#ifdef HAVE_POSIX_SELECT
- if (!cmd_fds[i].no_select && !FD_ISSET(cmd_fds[i].fd, &fds))
- continue;
#endif
- read_cmd_fd(ictx, &cmd_fds[i]);
- }
-}
-/* To support blocking file descriptors we don't loop the read over
- * every source until it's known to be empty. Instead we use this wrapper
- * to run select() again.
+/**
+ * \param time time to wait at most for an event in milliseconds
*/
-static void read_all_fd_events(struct input_ctx *ictx, int time)
+static void read_events(struct input_ctx *ictx, int time)
{
+ if (ictx->num_key_down) {
+ time = FFMIN(time, 1000 / ictx->ar_rate);
+ time = FFMIN(time, ictx->ar_delay);
+ }
+ time = FFMAX(time, 0);
+
while (1) {
- read_events(ictx, time);
+ if (ictx->got_new_events)
+ time = 0;
+ ictx->got_new_events = false;
+
+ remove_dead_fds(ictx);
+
+ if (time) {
+ for (int i = 0; i < ictx->num_fds; i++) {
+ if (!ictx->fds[i].select)
+ read_fd(ictx, &ictx->fds[i]);
+ }
+ }
+
+ if (ictx->got_new_events)
+ time = 0;
+
+ input_wait_read(ictx, time);
+
+ // Read until all input FDs are empty
if (!ictx->got_new_events)
- return;
- time = 0;
+ break;
}
}
@@ -1707,7 +1696,7 @@ static void read_all_events(struct input_ctx *ictx, int time)
#ifdef CONFIG_COCOA
cocoa_check_events();
#endif
- read_all_fd_events(ictx, time);
+ read_events(ictx, time);
}
int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t *cmd)
@@ -2209,13 +2198,9 @@ void mp_input_uninit(struct input_ctx *ictx, struct input_conf *input_conf)
}
#endif
- for (int i = 0; i < ictx->num_key_fd; i++) {
- if (ictx->key_fds[i].close_func)
- ictx->key_fds[i].close_func(ictx->key_fds[i].fd);
- }
- for (int i = 0; i < ictx->num_cmd_fd; i++) {
- if (ictx->cmd_fds[i].close_func)
- ictx->cmd_fds[i].close_func(ictx->cmd_fds[i].fd);
+ for (int i = 0; i < ictx->num_fds; i++) {
+ if (ictx->fds[i].close_func)
+ ictx->fds[i].close_func(ictx->fds[i].fd);
}
for (int i = 0; i < 2; i++) {
if (ictx->wakeup_pipe[i] != -1)
diff --git a/core/input/input.h b/core/input/input.h
index da92efd373..1a0f2529ce 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -170,9 +170,6 @@ int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select,
int read_func(int fd, char *dest, int size),
int close_func(int fd));
-// This removes a cmd driver, you usually don't need to use it.
-void mp_input_rm_cmd_fd(struct input_ctx *ictx, int fd);
-
/* The args are similar to the cmd version above, except you must give
* a read_func, and it should return key codes (ASCII plus keycodes.h).
*/
diff --git a/core/m_struct.h b/core/m_struct.h
index 6ddd221f1b..b0b0afe23d 100644
--- a/core/m_struct.h
+++ b/core/m_struct.h
@@ -19,6 +19,9 @@
#ifndef MPLAYER_M_STRUCT_H
#define MPLAYER_M_STRUCT_H
+#include <stddef.h>
+#include <inttypes.h>
+
#include "core/bstr.h"
/// \defgroup OptionsStruct Options struct
@@ -46,15 +49,12 @@ typedef struct m_struct_st {
} m_struct_t;
-// From glib.h (modified ;-)
-
/// Get the offset of a struct field.
/** \param struct_type Struct type.
* \param member Name of the field.
* \return The offset of the field in bytes.
*/
-#define M_ST_OFF(struct_type, member) \
- ((void*) &((struct_type*) 0)->member)
+#define M_ST_OFF (void *)(uintptr_t)offsetof
/// Get a pointer to a struct field.
/** \param struct_p Pointer to the struct.
@@ -62,7 +62,7 @@ typedef struct m_struct_st {
* \return Pointer to the struct field.
*/
#define M_ST_MB_P(struct_p, struct_offset) \
- ((void *)((char *)(struct_p) + (unsigned long)(struct_offset)))
+ ((void *)((char *)(struct_p) + (uintptr_t)(struct_offset)))
/// Access a struct field at a given offset.
/** \param member_type Type of the field.
diff --git a/core/mp_ring.c b/core/mp_ring.c
index 207dc62e86..bd94870710 100644
--- a/core/mp_ring.c
+++ b/core/mp_ring.c
@@ -99,7 +99,7 @@ int mp_ring_read_cb(struct mp_ring *buffer, void *ctx, int len,
int read_len = FFMIN(len, buffered);
int read_ptr = mp_ring_get_rpos(buffer) % size;
- func(ctx, buffer->buffer + read_ptr, len);
+ func(ctx, buffer->buffer + read_ptr, read_len);
return mp_ring_drain(buffer, read_len);
}
diff --git a/core/mp_ring.h b/core/mp_ring.h
index 52e885287d..ba104af625 100644
--- a/core/mp_ring.h
+++ b/core/mp_ring.h
@@ -49,7 +49,7 @@ int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len);
/**
* Read data from the ringbuffer
*
- * This function behaves similarly to `av_fifo_generic_read` and was actually
+ * This function behaves similarly to `av_fifo_generic_read` and was actually
* added for compatibility with code that was written for it.
* This function will drain the returned amount of bytes from the ringbuffer
* so you don't have to handle that in inside `func`.
@@ -57,11 +57,16 @@ int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len);
* buffer: target ringbuffer instance
* ctx: context for the callback function
* len: maximum number of bytes to read
- * func: callback function to customize reading behaviour
+ * func: callback function to customize reading behaviour. It will be called
+ * by `mp_ring_read_cb` with the following parameters:
+ * ctx: context data provided to `mp_ring_read_cb`
+ * src: source buffer to read from
+ * len: the *exact* amount of bytes to read. These will be drained
+ * by the ring after this callback is called.
* return: number of bytes read
*/
int mp_ring_read_cb(struct mp_ring *buffer, void *ctx, int len,
- void (*func)(void*, void*, int));
+ void (*func)(void *ctx, void *src, int len));
/**
* Write data to the ringbuffer
@@ -101,7 +106,7 @@ int mp_ring_available(struct mp_ring *buffer);
* Get the total size
*
* buffer: target ringbuffer instance
- * return: total ringbuffer size
+ * return: total ringbuffer size in bytes
*/
int mp_ring_size(struct mp_ring *buffer);
diff --git a/core/mplayer.c b/core/mplayer.c
index 5c894012c8..95a31aa15b 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -3879,6 +3879,7 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename,
if (!stream)
goto err_out;
stream_enable_cache_percent(&stream, stream_cache,
+ opts->stream_cache_def_size,
opts->stream_cache_min_percent,
opts->stream_cache_seek_min_percent);
struct demuxer_params params = {
@@ -4162,6 +4163,7 @@ static void play_current_file(struct MPContext *mpctx)
// CACHE2: initial prefill: 20% later: 5% (should be set by -cacheopts)
int res = stream_enable_cache_percent(&mpctx->stream,
opts->stream_cache_size,
+ opts->stream_cache_def_size,
opts->stream_cache_min_percent,
opts->stream_cache_seek_min_percent);
if (res == 0)
diff --git a/core/options.c b/core/options.c
index 2298d112b8..c28817db68 100644
--- a/core/options.c
+++ b/core/options.c
@@ -332,6 +332,9 @@ const m_option_t mp_opts[] = {
({"no", 0},
{"auto", -1}),
OPTDEF_INT(-1)),
+ OPT_CHOICE_OR_INT("cache-default", stream_cache_def_size, 0, 32, 0x7fffffff,
+ ({"no", 0}),
+ OPTDEF_INT(320)),
OPT_FLOATRANGE("cache-min", stream_cache_min_percent, 0, 0, 99),
OPT_FLOATRANGE("cache-seek-min", stream_cache_seek_min_percent, 0, 0, 99),
OPT_CHOICE_OR_INT("cache-pause", stream_cache_pause, 0,
diff --git a/core/options.h b/core/options.h
index 345835656b..d7c3bd715e 100644
--- a/core/options.h
+++ b/core/options.h
@@ -92,6 +92,7 @@ typedef struct MPOpts {
int load_config;
int use_filedir_conf;
int stream_cache_size;
+ int stream_cache_def_size;
float stream_cache_min_percent;
float stream_cache_seek_min_percent;
int stream_cache_pause;
diff --git a/core/timeline/tl_matroska.c b/core/timeline/tl_matroska.c
index f01160b60e..7c100618a3 100644
--- a/core/timeline/tl_matroska.c
+++ b/core/timeline/tl_matroska.c
@@ -118,8 +118,7 @@ static int enable_cache(struct MPContext *mpctx, struct stream **stream,
{
struct MPOpts *opts = &mpctx->opts;
- if (!(opts->stream_cache_size > 0 ||
- opts->stream_cache_size < 0 && (*stream)->cache_size))
+ if (opts->stream_cache_size <= 0)
return 0;
char *filename = talloc_strdup(NULL, (*demuxer)->filename);
@@ -134,6 +133,7 @@ static int enable_cache(struct MPContext *mpctx, struct stream **stream,
stream_enable_cache_percent(stream,
opts->stream_cache_size,
+ opts->stream_cache_def_size,
opts->stream_cache_min_percent,
opts->stream_cache_seek_min_percent);
diff --git a/core/version.c b/core/version.c
index 7e747044a3..23a0c59bc3 100644
--- a/core/version.c
+++ b/core/version.c
@@ -17,6 +17,10 @@
*/
#include "version.h"
+#ifdef NO_BUILD_TIMESTAMPS
+#undef BUILDDATE
+#define BUILDDATE "UNKNOWN"
+#endif
const char *mplayer_version = "mpv " VERSION;
-const char *mplayer_builddate = BUILDDATE; \ No newline at end of file
+const char *mplayer_builddate = BUILDDATE;
diff --git a/osdep/getch2-win.c b/osdep/getch2-win.c
index 3cafcbeb7e..0750f95c78 100644
--- a/osdep/getch2-win.c
+++ b/osdep/getch2-win.c
@@ -32,156 +32,158 @@
#include "core/input/input.h"
#include "getch2.h"
-int mp_input_slave_cmd_func(int fd,char* dest,int size){
- DWORD retval;
- HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
- if(PeekNamedPipe(in, NULL, size, &retval, NULL, NULL)){
- if (size > retval) size = retval;
- } else {
- if (WaitForSingleObject(in, 0))
- size = 0;
- }
- if(!size){
- return MP_INPUT_NOTHING;
- }
- ReadFile(in, dest, size, &retval, NULL);
- if(retval)return retval;
- return MP_INPUT_NOTHING;
+int mp_input_slave_cmd_func(int fd, char *dest, int size)
+{
+ DWORD retval;
+ HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
+ if (PeekNamedPipe(in, NULL, size, &retval, NULL, NULL)) {
+ if (size > retval)
+ size = retval;
+ } else {
+ if (WaitForSingleObject(in, 0))
+ size = 0;
+ }
+ if (!size)
+ return MP_INPUT_NOTHING;
+ ReadFile(in, dest, size, &retval, NULL);
+ if (retval)
+ return retval;
+ return MP_INPUT_NOTHING;
}
-int screen_width=80;
-int screen_height=24;
-char * erase_to_end_of_line = NULL;
+int screen_width = 80;
+int screen_height = 24;
+char *erase_to_end_of_line = NULL;
-void get_screen_size(void){
+void get_screen_size(void)
+{
CONSOLE_SCREEN_BUFFER_INFO cinfo;
- if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cinfo))
- {
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cinfo)) {
screen_width = cinfo.dwMaximumWindowSize.X;
screen_height = cinfo.dwMaximumWindowSize.Y;
}
}
static HANDLE in;
-static int getch2_status=0;
+static int getch2_status = 0;
static int getch2_internal(void)
{
- INPUT_RECORD eventbuffer[128];
+ INPUT_RECORD eventbuffer[128];
DWORD retval;
- int i=0;
- if(!getch2_status){
- // supports e.g. MinGW xterm, unfortunately keys are only received after
- // enter was pressed.
- uint8_t c;
- if (!PeekNamedPipe(in, NULL, 1, &retval, NULL, NULL) || !retval)
- return -1;
- ReadFile(in, &c, 1, &retval, NULL);
- return retval == 1 ? c : -1;
+ int i = 0;
+ if (!getch2_status) {
+ // supports e.g. MinGW xterm, unfortunately keys are only received after
+ // enter was pressed.
+ uint8_t c;
+ if (!PeekNamedPipe(in, NULL, 1, &retval, NULL, NULL) || !retval)
+ return -1;
+ ReadFile(in, &c, 1, &retval, NULL);
+ return retval == 1 ? c : -1;
}
/*check if there are input events*/
- if(!GetNumberOfConsoleInputEvents(in,&retval))
- {
- printf("getch2: can't get number of input events: %i\n",(int)GetLastError());
- return -1;
- }
- if(retval<=0)return -1;
-
- /*read all events*/
- if(!ReadConsoleInput(in,eventbuffer,128,&retval))
- {
- printf("getch: can't read input events\n");
- return -1;
- }
-
- /*filter out keyevents*/
- for (i = 0; i < retval; i++)
- {
- switch(eventbuffer[i].EventType)
- {
- case KEY_EVENT:
- /*only a pressed key is interresting for us*/
- if(eventbuffer[i].Event.KeyEvent.bKeyDown == TRUE)
- {
- /*check for special keys*/
- switch(eventbuffer[i].Event.KeyEvent.wVirtualKeyCode)
- {
- case VK_HOME:
- return MP_KEY_HOME;
- case VK_END:
- return MP_KEY_END;
- case VK_DELETE:
- return MP_KEY_DEL;
- case VK_INSERT:
- return MP_KEY_INS;
- case VK_BACK:
- return MP_KEY_BS;
- case VK_PRIOR:
- return MP_KEY_PGUP;
- case VK_NEXT:
- return MP_KEY_PGDWN;
- case VK_RETURN:
- return MP_KEY_ENTER;
- case VK_ESCAPE:
- return MP_KEY_ESC;
- case VK_LEFT:
- return MP_KEY_LEFT;
- case VK_UP:
- return MP_KEY_UP;
- case VK_RIGHT:
- return MP_KEY_RIGHT;
- case VK_DOWN:
- return MP_KEY_DOWN;
- case VK_SHIFT:
- continue;
- }
- /*check for function keys*/
- if(0x87 >= eventbuffer[i].Event.KeyEvent.wVirtualKeyCode && eventbuffer[i].Event.KeyEvent.wVirtualKeyCode >= 0x70)
- return MP_KEY_F + 1 + eventbuffer[i].Event.KeyEvent.wVirtualKeyCode - 0x70;
-
- /*only characters should be remaining*/
- //printf("getch2: YOU PRESSED \"%c\" \n",eventbuffer[i].Event.KeyEvent.uChar.AsciiChar);
- return eventbuffer[i].Event.KeyEvent.uChar.AsciiChar;
- }
- break;
-
- case MOUSE_EVENT:
- case WINDOW_BUFFER_SIZE_EVENT:
- case FOCUS_EVENT:
- case MENU_EVENT:
- default:
- //printf("getch2: unsupported event type");
- break;
+ if (!GetNumberOfConsoleInputEvents(in, &retval)) {
+ printf("getch2: can't get number of input events: %i\n",
+ (int)GetLastError());
+ return -1;
+ }
+ if (retval <= 0)
+ return -1;
+
+ /*read all events*/
+ if (!ReadConsoleInput(in, eventbuffer, 128, &retval)) {
+ printf("getch: can't read input events\n");
+ return -1;
+ }
+
+ /*filter out keyevents*/
+ for (i = 0; i < retval; i++) {
+ switch (eventbuffer[i].EventType) {
+ case KEY_EVENT:
+ /*only a pressed key is interresting for us*/
+ if (eventbuffer[i].Event.KeyEvent.bKeyDown == TRUE) {
+ /*check for special keys*/
+ switch (eventbuffer[i].Event.KeyEvent.wVirtualKeyCode) {
+ case VK_HOME:
+ return MP_KEY_HOME;
+ case VK_END:
+ return MP_KEY_END;
+ case VK_DELETE:
+ return MP_KEY_DEL;
+ case VK_INSERT:
+ return MP_KEY_INS;
+ case VK_BACK:
+ return MP_KEY_BS;
+ case VK_PRIOR:
+ return MP_KEY_PGUP;
+ case VK_NEXT:
+ return MP_KEY_PGDWN;
+ case VK_RETURN:
+ return MP_KEY_ENTER;
+ case VK_ESCAPE:
+ return MP_KEY_ESC;
+ case VK_LEFT:
+ return MP_KEY_LEFT;
+ case VK_UP:
+ return MP_KEY_UP;
+ case VK_RIGHT:
+ return MP_KEY_RIGHT;
+ case VK_DOWN:
+ return MP_KEY_DOWN;
+ case VK_SHIFT:
+ continue;
+ }
+ /*check for function keys*/
+ if (0x87 >= eventbuffer[i].Event.KeyEvent.wVirtualKeyCode &&
+ eventbuffer[i].Event.KeyEvent.wVirtualKeyCode >= 0x70)
+ return MP_KEY_F + 1 +
+ eventbuffer[i].Event.KeyEvent.wVirtualKeyCode - 0x70;
+
+ /*only characters should be remaining*/
+ //printf("getch2: YOU PRESSED \"%c\" \n",eventbuffer[i].Event.KeyEvent.uChar.AsciiChar);
+ return eventbuffer[i].Event.KeyEvent.uChar.AsciiChar;
+ }
+ break;
+
+ case MOUSE_EVENT:
+ case WINDOW_BUFFER_SIZE_EVENT:
+ case FOCUS_EVENT:
+ case MENU_EVENT:
+ default:
+ //printf("getch2: unsupported event type");
+ break;
}
}
- return -1;
+ return -1;
}
bool getch2(struct input_ctx *ctx)
{
int r = getch2_internal();
if (r >= 0)
- mp_input_put_key(ctx, r);
+ mp_input_put_key(ctx, r);
return true;
}
-void getch2_poll(void){
+void getch2_poll(void)
+{
}
void getch2_enable(void)
{
- DWORD retval;
+ DWORD retval;
in = GetStdHandle(STD_INPUT_HANDLE);
- if(!GetNumberOfConsoleInputEvents(in,&retval))
- {
- printf("getch2: %i can't get number of input events [disabling console input]\n",(int)GetLastError());
- getch2_status = 0;
- }
- else getch2_status=1;
+ if (!GetNumberOfConsoleInputEvents(in, &retval)) {
+ printf("getch2: %i can't get number of input events "
+ "[disabling console input]\n", (int)GetLastError());
+ getch2_status = 0;
+ } else
+ getch2_status = 1;
}
void getch2_disable(void)
{
- if(!getch2_status) return; // already disabled / never enabled
- getch2_status=0;
+ if (!getch2_status)
+ return; // already disabled / never enabled
+ getch2_status = 0;
}
diff --git a/osdep/mpv.exe.manifest b/osdep/mpv.exe.manifest
index c924377c4b..c30993e80c 100644
--- a/osdep/mpv.exe.manifest
+++ b/osdep/mpv.exe.manifest
@@ -7,13 +7,31 @@
type="win32"
/>
<description>mpv - The Movie Player</description>
+ <application xmlns="urn:schemas-microsoft-com:asm.v3">
+ <windowsSettings xmlns:ws="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <ws:dpiAware>True/PM</ws:dpiAware>
+ </windowsSettings>
+ </application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
+ uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!-- Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!-- Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!-- Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!-- Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ </application>
+ </compatibility>
</assembly>
diff --git a/stream/cache.c b/stream/cache.c
index 4a062538db..364ef68891 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -134,7 +134,7 @@ static int cond_timed_wait(pthread_cond_t *cond, pthread_mutex_t *mutex,
double timeout)
{
struct timespec ts;
-#if _POSIX_TIMERS > 0
+#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
clock_gettime(CLOCK_REALTIME, &ts);
#else
struct timeval tv;
diff --git a/stream/stream.c b/stream/stream.c
index 7716e51a56..523fcc2e8e 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -60,18 +60,11 @@ static struct input_ctx *stream_check_interrupt_ctx;
extern const stream_info_t stream_info_vcd;
extern const stream_info_t stream_info_cdda;
-extern const stream_info_t stream_info_asf;
-extern const stream_info_t stream_info_udp;
-extern const stream_info_t stream_info_http1;
-extern const stream_info_t stream_info_http2;
extern const stream_info_t stream_info_dvb;
extern const stream_info_t stream_info_tv;
extern const stream_info_t stream_info_radio;
extern const stream_info_t stream_info_pvr;
-extern const stream_info_t stream_info_ftp;
-extern const stream_info_t stream_info_vstream;
extern const stream_info_t stream_info_smb;
-
extern const stream_info_t stream_info_null;
extern const stream_info_t stream_info_memory;
extern const stream_info_t stream_info_mf;
@@ -103,12 +96,6 @@ static const stream_info_t *const auto_open_streams[] = {
#ifdef CONFIG_PVR
&stream_info_pvr,
#endif
-#ifdef CONFIG_FTP
- &stream_info_ftp,
-#endif
-#ifdef CONFIG_VSTREAM
- &stream_info_vstream,
-#endif
#ifdef CONFIG_LIBSMBCLIENT
&stream_info_smb,
#endif
@@ -169,11 +156,6 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
if (!s->read_chunk)
s->read_chunk = 4 * (s->sector_size ? s->sector_size : STREAM_BUFFER_SIZE);
- if (s->streaming && !s->cache_size) {
- // Set default cache size to use if user does not specify it.
- s->cache_size = 320;
- }
-
if (!s->seek)
s->flags &= ~MP_STREAM_SEEK;
if (s->seek && !(s->flags & MP_STREAM_SEEK))
@@ -622,16 +604,22 @@ stream_t *open_memory_stream(void *data, int len)
return s;
}
+static int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
+ int64_t seek_limit);
+
+/**
+ * \return 1 on success, 0 if the function was interrupted and -1 on error, or
+ * if the cache is disabled
+ */
int stream_enable_cache_percent(stream_t **stream, int64_t stream_cache_size,
+ int64_t stream_cache_def_size,
float stream_cache_min_percent,
float stream_cache_seek_min_percent)
{
-
if (stream_cache_size == -1)
- stream_cache_size = (*stream)->cache_size;
+ stream_cache_size = (*stream)->streaming ? stream_cache_def_size : 0;
stream_cache_size = stream_cache_size * 1024; // input is in KiB
-
return stream_enable_cache(stream, stream_cache_size,
stream_cache_size *
(stream_cache_min_percent / 100.0),
@@ -639,12 +627,8 @@ int stream_enable_cache_percent(stream_t **stream, int64_t stream_cache_size,
(stream_cache_seek_min_percent / 100.0));
}
-/**
- * \return 1 on success, 0 if the function was interrupted and -1 on error, or
- * if the cache is disabled
- */
-int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
- int64_t seek_limit)
+static int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
+ int64_t seek_limit)
{
stream_t *orig = *stream;
diff --git a/stream/stream.h b/stream/stream.h
index 554c4e2ec3..a0cd3d58fc 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -141,7 +141,6 @@ typedef struct stream {
int eof;
int mode; //STREAM_READ or STREAM_WRITE
bool streaming; // known to be a network stream if true
- int cache_size; // cache size in KB to use if enabled
void *priv; // used for DVD, TV, RTSP etc
char *url; // strdup() of filename/url
char *mime_type; // when HTTP streaming is used
@@ -163,10 +162,9 @@ int stream_fill_buffer(stream_t *s);
void stream_set_capture_file(stream_t *s, const char *filename);
int stream_enable_cache_percent(stream_t **stream, int64_t stream_cache_size,
+ int64_t stream_cache_def_size,
float stream_cache_min_percent,
float stream_cache_seek_min_percent);
-int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
- int64_t seek_limit);
// Internal
int stream_cache_init(stream_t *cache, stream_t *stream, int64_t size,
diff --git a/stream/stream_vcd.c b/stream/stream_vcd.c
index be345a507b..0fd2998c58 100644
--- a/stream/stream_vcd.c
+++ b/stream/stream_vcd.c
@@ -134,7 +134,7 @@ static int open_s(stream_t *stream,int mode, void* opts)
/* open() can't be used for devices so do it the complicated way */
hd = CreateFile(device, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
- f = _open_osfhandle((long)hd, _O_RDONLY);
+ f = _open_osfhandle((intptr_t)hd, _O_RDONLY);
#else
f=open(p->device,O_RDONLY);
#endif
diff --git a/video/filter/vf.c b/video/filter/vf.c
index 0f7cc58ee5..1402ad3efc 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -109,7 +109,9 @@ static const vf_info_t *const filter_list[] = {
&vf_info_sub,
&vf_info_yadif,
&vf_info_stereo3d,
+#ifdef CONFIG_DLOPEN
&vf_info_dlopen,
+#endif
NULL
};
diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m
index dc95e537a1..f8a4e44cd9 100644
--- a/video/out/cocoa_common.m
+++ b/video/out/cocoa_common.m
@@ -617,6 +617,14 @@ int vo_cocoa_cgl_color_size(struct vo *vo)
s->did_resize = YES;
}
}
+
+- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
+ if (self.videoOutput) {
+ struct vo_cocoa_state *s = self.videoOutput->cocoa;
+ s->did_resize = YES;
+ }
+}
+
- (void)toggleMissionControlFullScreen:(BOOL)willBeFullscreen
{
struct vo_cocoa_state *s = self.videoOutput->cocoa;