diff options
author | wm4 <wm4@nowhere> | 2014-05-29 23:56:48 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-05-30 02:15:47 +0200 |
commit | 5929dc458f46f75648af1ee7a293e899e67d8e66 (patch) | |
tree | 6898eb4886328e9cd936ac6a6008acf4bcd6f6ba /audio/out/internal.h | |
parent | 35aba9675dd428f945a09ff9acc20aa068705f46 (diff) | |
download | mpv-5929dc458f46f75648af1ee7a293e899e67d8e66.tar.bz2 mpv-5929dc458f46f75648af1ee7a293e899e67d8e66.tar.xz |
audio/out/push: add mechanism for event-based waiting
Until now, we've always calculated a timeout based on a heuristic when
to refill the audio buffers. Allow AOs to do it completely event-based
by providing wait and wakeup callbacks.
This also shuffles around the heuristic used for other AOs, and there is
a minor possibility that behavior slightly changes in real-world cases.
But in general it should be much more robust now.
ao_pulse.c now makes use of event-based waiting. It already did before,
but the code for time-based waiting was also involved. This commit also
removes one awkward artifact of the PulseAudio API out of the generic
code: the callback asking for more data can be reentrant, and thus
requires a separate lock for waiting (or a recursive mutex).
Diffstat (limited to 'audio/out/internal.h')
-rw-r--r-- | audio/out/internal.h | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/audio/out/internal.h b/audio/out/internal.h index 380b748679..32c6aa7b27 100644 --- a/audio/out/internal.h +++ b/audio/out/internal.h @@ -20,6 +20,7 @@ #define MP_AO_INTERNAL_H_ #include <stdbool.h> +#include <pthread.h> #include "audio/chmap.h" #include "audio/chmap_sel.h" @@ -88,6 +89,8 @@ extern const struct ao_driver ao_api_pull; * Optional: * control * drain + * wait + * wakeup * b) ->play must be NULL. ->resume must be provided, and should make the * audio API start calling the audio callback. Your audio callback should * in turn call ao_read_data() to get audio data. Most functions are @@ -131,6 +134,20 @@ struct ao_driver { float (*get_delay)(struct ao *ao); // push based: block until all queued audio is played (optional) void (*drain)(struct ao *ao); + // Wait until the audio buffer needs to be refilled. The lock is the + // internal mutex usually protecting the internal AO state (and used to + // protect driver calls), and must be temporarily unlocked while waiting. + // ->wakeup will be called (with lock held) if the wait should be canceled. + // Returns 0 on success, -1 on error. + // Optional; if this is not provided, generic code using audio timing is + // used to estimate when the AO needs to be refilled. + // Warning: it's only called if the feed thread truly needs to know when + // the audio thread takes data again. Often, it will just copy + // the complete soft-buffer to the AO, and then wait for the + // decoder instead. Don't do necessary work in this callback. + int (*wait)(struct ao *ao, pthread_mutex_t *lock); + // In combination with wait(). Lock may or may not be held. + void (*wakeup)(struct ao *ao); // For option parsing (see vo.h) int priv_size; @@ -141,7 +158,6 @@ struct ao_driver { // These functions can be called by AOs. int ao_play_silence(struct ao *ao, int samples); -void ao_need_data(struct ao *ao); void ao_wait_drain(struct ao *ao); int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us); |