audio: wake up the core when audio buffer is running low (2)

Same change as in e2184fcb, but this time for pull based AOs. This is
slightly controversial, because it will make a fast syscall from e.g.
ao_jack. And according to JackAudio developers, syscalls are evil and
will destroy realtime operation. But I don't think this is an issue at
all.

Still avoid locking a mutex. I'm not sure what jackaudio does in the
worst case - but if they set the jackaudio thread (and only this thread)
to realtime, we might run into deadlock situations due to priority
inversion and such. I'm not quite sure whether this can happen, but I'll
readily follow the cargo cult if it makes hack happy.
This commit is contained in:
wm4 2014-04-15 22:50:16 +02:00
parent ad75b8e339
commit 5aeec9aa70
3 changed files with 17 additions and 2 deletions

View File

@ -26,6 +26,8 @@
#include "common/msg.h"
#include "common/common.h"
#include "input/input.h"
#include "osdep/timer.h"
#include "osdep/threads.h"
#include "compat/atomics.h"
@ -110,8 +112,8 @@ int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us)
// Since the writer will write the first plane last, its buffered amount
// of data is the minimum amount across all planes.
int bytes = mp_ring_buffered(p->buffers[0]);
bytes = MPMIN(bytes, full_bytes);
int buffered_bytes = mp_ring_buffered(p->buffers[0]);
int bytes = MPMIN(buffered_bytes, full_bytes);
if (bytes > 0)
p->end_time_us = out_time_us;
@ -128,6 +130,11 @@ int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us)
if (silence)
af_fill_silence((char *)data[n] + bytes, silence, ao->format);
}
// Half of the buffer played -> request more.
if (buffered_bytes - bytes <= mp_ring_size(p->buffers[0]) / 2)
mp_input_wakeup_nolock(ao->input_ctx);
return bytes / ao->sstride;
}

View File

@ -1653,6 +1653,12 @@ void mp_input_wakeup(struct input_ctx *ictx)
write(ictx->wakeup_pipe[1], &(char){0}, 1);
}
void mp_input_wakeup_nolock(struct input_ctx *ictx)
{
if (ictx->wakeup_pipe[1] >= 0)
write(ictx->wakeup_pipe[1], &(char){0}, 1);
}
static bool test_abort(struct input_ctx *ictx)
{
if (async_quit_request || queue_has_abort_cmds(&ictx->cmd_queue)) {

View File

@ -206,6 +206,8 @@ void mp_input_uninit(struct input_ctx *ictx);
// Wake up sleeping input loop from another thread.
void mp_input_wakeup(struct input_ctx *ictx);
void mp_input_wakeup_nolock(struct input_ctx *ictx);
// Interruptible usleep: (used by demux)
int mp_input_check_interrupt(struct input_ctx *ictx, int time);