summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_openal.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-05-31 15:00:35 +0200
committerwm4 <wm4@nowhere>2020-06-01 01:08:16 +0200
commitd27ad9654218463694093697e3d09f8983b4ccf3 (patch)
tree54d889bbed1b32b2a702fee6825c66ff6fb60c33 /audio/out/ao_openal.c
parentd448dd5bf26408ccced1bd6df8f9eaf62a370c8e (diff)
downloadmpv-d27ad9654218463694093697e3d09f8983b4ccf3.tar.bz2
mpv-d27ad9654218463694093697e3d09f8983b4ccf3.tar.xz
audio: redo internal AO API
This affects "pull" AOs only: ao_alsa, ao_pulse, ao_openal, ao_pcm, ao_lavc. There are changes to the other AOs too, but that's only about renaming ao_driver.resume to ao_driver.start. ao_openal is broken because I didn't manage to fix it, so it exits with an error message. If you want it, why don't _you_ put effort into it? I see no reason to waste my own precious lifetime over this (I realize the irony). ao_alsa loses the poll() mechanism, but it was mostly broken and didn't really do what it was supposed to. There doesn't seem to be anything in the ALSA API to watch the playback status without polling (unless you want to use raw UNIX signals). No idea if ao_pulse is correct, or whether it's subtly broken now. There is no documentation, so I can't tell what is correct, without reverse engineering the whole project. I recommend using ALSA. This was supposed to be just a simple fix, but somehow it expanded scope like a train wreck. Very high chance of regressions, but probably only for the AOs listed above. The rest you can figure out from reading the diff.
Diffstat (limited to 'audio/out/ao_openal.c')
-rw-r--r--audio/out/ao_openal.c90
1 files changed, 30 insertions, 60 deletions
diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c
index aa20fb8bed..64d957e893 100644
--- a/audio/out/ao_openal.c
+++ b/audio/out/ao_openal.c
@@ -61,8 +61,6 @@ struct priv {
int direct_channels;
};
-static void reset(struct ao *ao);
-
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
switch (cmd) {
@@ -177,6 +175,9 @@ static void uninit(struct ao *ao)
static int init(struct ao *ao)
{
+ MP_FATAL(ao, "broken.\n");
+ return -1;
+
float position[3] = {0, 0, 0};
float direction[6] = {0, 0, -1, 0, 1, 0};
ALCdevice *dev = NULL;
@@ -291,67 +292,32 @@ static void unqueue_buffers(struct ao *ao)
}
}
-/**
- * \brief stop playing and empty buffers (for seeking/pause)
- */
static void reset(struct ao *ao)
{
alSourceStop(source);
unqueue_buffers(ao);
}
-/**
- * \brief stop playing, keep buffers (for pause)
- */
-static void audio_pause(struct ao *ao)
-{
- alSourcePause(source);
-}
-
-/**
- * \brief resume playing, after audio_pause()
- */
-static void audio_resume(struct ao *ao)
-{
- alSourcePlay(source);
-}
-
-static int get_space(struct ao *ao)
+static bool audio_set_pause(struct ao *ao, bool pause)
{
- struct priv *p = ao->priv;
- ALint queued;
- unqueue_buffers(ao);
- alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
- queued = p->num_buffers - queued;
- if (queued < 0)
- return 0;
- return p->num_samples * queued;
+ if (pause) {
+ alSourcePause(source);
+ } else {
+ alSourcePlay(source);
+ }
+ return true;
}
-/**
- * \brief write data into buffer and reset underrun flag
- */
-static int play(struct ao *ao, void **data, int samples, int flags)
+static bool audio_write(struct ao *ao, void **data, int samples)
{
struct priv *p = ao->priv;
- int buffered_samples = 0;
- int num = 0;
- if (flags & AOPLAY_FINAL_CHUNK) {
- num = 1;
- buffered_samples = samples;
- } else {
- num = samples / p->num_samples;
- buffered_samples = num * p->num_samples;
- }
+ int num = (samples + p->num_samples - 1) / p->num_samples;
for (int i = 0; i < num; i++) {
char *d = *data;
- if (flags & AOPLAY_FINAL_CHUNK) {
- buffer_size[cur_buf] = samples;
- } else {
- buffer_size[cur_buf] = p->num_samples;
- }
+ buffer_size[cur_buf] =
+ MPMIN(samples - num * p->num_samples, p->num_samples);
d += i * buffer_size[cur_buf] * ao->sstride;
alBufferData(buffers[cur_buf], p->al_format, d,
buffer_size[cur_buf] * ao->sstride, ao->samplerate);
@@ -359,17 +325,18 @@ static int play(struct ao *ao, void **data, int samples, int flags)
cur_buf = (cur_buf + 1) % p->num_buffers;
}
- ALint state;
- alGetSourcei(source, AL_SOURCE_STATE, &state);
- if (state != AL_PLAYING) // checked here in case of an underrun
- alSourcePlay(source);
+ return true;
+}
- return buffered_samples;
+static void audio_start(struct ao *ao)
+{
+ alSourcePlay(source);
}
-static double get_delay(struct ao *ao)
+static void get_state(struct ao *ao, struct mp_pcm_state *state)
{
struct priv *p = ao->priv;
+
ALint queued;
unqueue_buffers(ao);
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
@@ -393,7 +360,11 @@ static double get_delay(struct ao *ao)
queued_samples += buffer_size[index];
index = (index + 1) % p->num_buffers;
}
- return (queued_samples / (double)ao->samplerate) + soft_source_latency;
+
+ state->delay = queued_samples / (double)ao->samplerate + soft_source_latency;
+
+ state->queued_samples = queued_samples;
+ state->free_samples = MPMAX(p->num_buffers - queued, 0) * p->num_samples;
}
#define OPT_BASE_STRUCT struct priv
@@ -404,11 +375,10 @@ const struct ao_driver audio_out_openal = {
.init = init,
.uninit = uninit,
.control = control,
- .get_space = get_space,
- .play = play,
- .get_delay = get_delay,
- .pause = audio_pause,
- .resume = audio_resume,
+ .get_state = get_state,
+ .write = audio_write,
+ .start = audio_start,
+ .set_pause = audio_set_pause,
.reset = reset,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {