summaryrefslogtreecommitdiffstats
path: root/audio/out/internal.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-29 23:56:48 +0200
committerwm4 <wm4@nowhere>2014-05-30 02:15:47 +0200
commit5929dc458f46f75648af1ee7a293e899e67d8e66 (patch)
tree6898eb4886328e9cd936ac6a6008acf4bcd6f6ba /audio/out/internal.h
parent35aba9675dd428f945a09ff9acc20aa068705f46 (diff)
downloadmpv-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.h18
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);