summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-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
10 files changed, 167 insertions, 170 deletions
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;