diff options
Diffstat (limited to 'audio/out/internal.h')
-rw-r--r-- | audio/out/internal.h | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/audio/out/internal.h b/audio/out/internal.h index 5cf99a02b7..51429b9c06 100644 --- a/audio/out/internal.h +++ b/audio/out/internal.h @@ -18,10 +18,9 @@ #ifndef MP_AO_INTERNAL_H_ #define MP_AO_INTERNAL_H_ +#include <stdatomic.h> #include <stdbool.h> -#include <pthread.h> -#include "osdep/atomic.h" #include "audio/out/ao.h" /* global data used by ao.c and ao drivers */ @@ -48,12 +47,6 @@ struct ao { int init_flags; // AO_INIT_* flags bool stream_silence; // if audio inactive, just play silence - // Set by the driver on init. - // This value is in complete samples (i.e. 1 for stereo means 1 sample - // for both channels each). - // Used for push based API only. - int period_size; - // The device as selected by the user, usually using ao_device_desc.name // from an entry from the list returned by driver->list_devices. If the // default device should be used, this is set to NULL. @@ -69,12 +62,11 @@ struct ao { atomic_uint events_; // Float gain multiplicator - mp_atomic_float gain; + _Atomic float gain; int buffer; double def_buffer; struct buffer_state *buffer_state; - void *api_priv; }; void init_buffer_pre(struct ao *ao); @@ -83,7 +75,12 @@ bool init_buffer_post(struct ao *ao); struct mp_pcm_state { // Note: free_samples+queued_samples <= ao->device_buffer; the sum may be // less if the audio API can report partial periods played, while - // free_samples should be period-size aligned. + // free_samples should be period-size aligned. If free_samples is not + // period-size aligned, the AO thread might get into a situation where + // it writes a very small number of samples in each iteration, leading + // to extremely inefficient behavior. + // Keep in mind that write() may write less than free_samples (or your + // period size alignment) anyway. int free_samples; // number of free space in ring buffer int queued_samples; // number of samples to play in ring buffer double delay; // total latency in seconds (includes queued_samples) @@ -111,6 +108,7 @@ struct mp_pcm_state { * start * Optional for both types: * control + * set_pause * a) ->write is called to queue audio. push.c creates a thread to regularly * refill audio device buffers with ->write, but all driver functions are * always called under an exclusive lock. @@ -118,8 +116,6 @@ struct mp_pcm_state { * reset * write * get_state - * Optional: - * set_pause * b) ->write must be NULL. ->start 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 @@ -139,6 +135,9 @@ struct ao_driver { // first write() call is done. Encode mode uses this, and push mode // respects it automatically (don't use with pull mode). bool initially_blocked; + // If true, write units of entire frames. The write() call is modified to + // use data==mp_aframe. Useful for encoding AO only. + bool write_frames; // Init the device using ao->format/ao->channels/ao->samplerate. If the // device doesn't accept these parameters, you can attempt to negotiate // fallback parameters, and set the ao format fields accordingly. @@ -149,14 +148,18 @@ struct ao_driver { // Stop all audio playback, clear buffers, back to state after init(). // Optional for pull AOs. void (*reset)(struct ao *ao); + // pull based: set pause state. Only called after start() and before reset(). + // The return value is ignored. + // The pausing state is also cleared by reset(). // push based: set pause state. Only called after start() and before reset(). // returns success (this is intended for paused=true; if it // returns false, playback continues, and the core emulates via // reset(); unpausing always works) + // The pausing state is also cleared by reset(). bool (*set_pause)(struct ao *ao, bool paused); // pull based: start the audio callback // push based: start playing queued data - // AO should call ao_wakeup_playthread() if a period boundary + // AO should call ao_wakeup() if a period boundary // is crossed, or playback stops due to external reasons // (including underruns or device removal) // must set mp_pcm_state.playing; unset on error/underrun/end @@ -198,7 +201,9 @@ struct ao_driver { // These functions can be called by AOs. -int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us); +int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_ns); +MP_WARN_UNUSED_RESULT +int ao_read_data_nonblocking(struct ao *ao, void **data, int samples, int64_t out_time_ns); bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s, struct mp_chmap *map); @@ -226,9 +231,9 @@ bool ao_can_convert_inplace(struct ao_convert_fmt *fmt); bool ao_need_conversion(struct ao_convert_fmt *fmt); void ao_convert_inplace(struct ao_convert_fmt *fmt, void **data, int num_samples); -void ao_wakeup_playthread(struct ao *ao); +void ao_wakeup(struct ao *ao); int ao_read_data_converted(struct ao *ao, struct ao_convert_fmt *fmt, - void **data, int samples, int64_t out_time_us); + void **data, int samples, int64_t out_time_ns); #endif |