diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/input/input.c | 293 | ||||
-rw-r--r-- | core/input/input.h | 3 | ||||
-rw-r--r-- | core/m_struct.h | 10 | ||||
-rw-r--r-- | core/mp_ring.c | 2 | ||||
-rw-r--r-- | core/mp_ring.h | 13 | ||||
-rw-r--r-- | core/mplayer.c | 2 | ||||
-rw-r--r-- | core/options.c | 3 | ||||
-rw-r--r-- | core/options.h | 1 | ||||
-rw-r--r-- | core/timeline/tl_matroska.c | 4 | ||||
-rw-r--r-- | core/version.c | 6 |
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; |