summaryrefslogtreecommitdiffstats
path: root/audio/out/internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'audio/out/internal.h')
-rw-r--r--audio/out/internal.h39
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