summaryrefslogtreecommitdiffstats
path: root/input
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2012-03-25 22:58:48 +0300
committerUoti Urpala <uau@mplayer2.org>2012-03-26 03:55:31 +0300
commita0de4bc5000823c058aab6b02a7fdfb48275cb32 (patch)
tree799a49605b04f39e2bc79604f0d93727a43e167d /input
parent4fed8ad19771f6c3cfdd01414ba11456007fd9b8 (diff)
downloadmpv-a0de4bc5000823c058aab6b02a7fdfb48275cb32.tar.bz2
mpv-a0de4bc5000823c058aab6b02a7fdfb48275cb32.tar.xz
ao_pulse, core: make pulse thread wake up core for more data
For ao_pulse, the current latency is not a good indicator of how soon the AO requires new data to avoid underflow. Add an internal pipe that can be used to wake up the input loop from select(), and make the pulseaudio main loop (which runs in a separate thread) use this mechanism when pulse requests more data. The wakeup signal currently contains no information about the reason for the wakup, but audio buffers are always filled when the event loop wakes up. Also, request a latency of 1 second from the Pulseaudio server. The default is normally significantly higher. We don't need low latency, while higher latency helps prevent underflows reduces need for wakeups.
Diffstat (limited to 'input')
-rw-r--r--input/input.c44
-rw-r--r--input/input.h3
2 files changed, 41 insertions, 6 deletions
diff --git a/input/input.c b/input/input.c
index 6b457bad7f..e422e9f1a2 100644
--- a/input/input.c
+++ b/input/input.c
@@ -622,6 +622,8 @@ struct input_ctx {
struct cmd_queue key_cmd_queue;
struct cmd_queue control_cmd_queue;
+
+ int wakeup_pipe[2];
};
@@ -1104,6 +1106,13 @@ static int default_cmd_func(int fd, char *buf, int l)
}
}
+static int read_wakeup(void *ctx, int fd)
+{
+ char buf[100];
+ read(fd, buf, sizeof(buf));
+ return MP_INPUT_NOTHING;
+}
+
static char *find_bind_for_key(const struct cmd_bind *binds, int n, int *keys)
{
@@ -1126,7 +1135,7 @@ static char *find_bind_for_key(const struct cmd_bind *binds, int n, int *keys)
}
static struct cmd_bind_section *get_bind_section(struct input_ctx *ictx,
- char *section)
+ char *section)
{
struct cmd_bind_section *bind_section = ictx->cmd_bind_sections;
@@ -1731,8 +1740,25 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf)
.ar_delay = input_conf->ar_delay,
.ar_rate = input_conf->ar_rate,
.default_bindings = input_conf->default_bindings,
+ .wakeup_pipe = {-1, -1},
};
+#ifndef __MINGW32__
+ long ret = pipe(ictx->wakeup_pipe);
+ for (int i = 0; i < 2 && ret >= 0; i++) {
+ ret = fcntl(ictx->wakeup_pipe[i], F_GETFL);
+ if (ret < 0)
+ break;
+ ret = fcntl(ictx->wakeup_pipe[i], F_SETFL, ret | O_NONBLOCK);
+ }
+ if (ret < 0)
+ mp_msg(MSGT_INPUT, MSGL_ERR,
+ "Failed to initialize wakeup pipe: %s\n", strerror(errno));
+ else
+ mp_input_add_key_fd(ictx, ictx->wakeup_pipe[0], true, read_wakeup,
+ NULL, NULL);
+#endif
+
char *file;
char *config_file = input_conf->config_file;
file = config_file[0] != '/' ? get_path(config_file) : config_file;
@@ -1830,17 +1856,17 @@ void mp_input_uninit(struct input_ctx *ictx)
if (!ictx)
return;
- unsigned int i;
-
- for (i = 0; i < ictx->num_key_fd; i++) {
+ 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 (i = 0; i < ictx->num_cmd_fd; i++) {
+ 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 < 2; i++)
+ if (ictx->wakeup_pipe[i] != -1)
+ close(ictx->wakeup_pipe[i]);
talloc_free(ictx);
}
@@ -1890,6 +1916,12 @@ static int print_cmd_list(m_option_t *cfg)
exit(0);
}
+void mp_input_wakeup(struct input_ctx *ictx)
+{
+ if (ictx->wakeup_pipe[1] >= 0)
+ write(ictx->wakeup_pipe[1], &(char){0}, 1);
+}
+
/**
* \param time time to wait for an interruption in milliseconds
*/
diff --git a/input/input.h b/input/input.h
index 4cd006fa9a..c5f6940990 100644
--- a/input/input.h
+++ b/input/input.h
@@ -272,6 +272,9 @@ void mp_input_uninit(struct input_ctx *ictx);
struct m_config;
void mp_input_register_options(struct m_config *cfg);
+// Wake up sleeping input loop from another thread.
+void mp_input_wakeup(struct input_ctx *ictx);
+
// Interruptible usleep: (used by libmpdemux)
int mp_input_check_interrupt(struct input_ctx *ictx, int time);