summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_lavc.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_lavc.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_lavc.c')
-rw-r--r--audio/out/ao_lavc.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c
index ad3865964c..33e82219b0 100644
--- a/audio/out/ao_lavc.c
+++ b/audio/out/ao_lavc.c
@@ -156,7 +156,8 @@ static int init(struct ao *ao)
ao->untimed = true;
- ao->period_size = ac->aframesize * ac->framecount;
+ ao->device_buffer = ac->aframesize * ac->framecount;
+ ao->period_size = ao->device_buffer;
if (ao->channels.num > AV_NUM_DATA_POINTERS)
goto fail;
@@ -188,14 +189,6 @@ static void uninit(struct ao *ao)
}
}
-// return: how many samples can be played without blocking
-static int get_space(struct ao *ao)
-{
- struct priv *ac = ao->priv;
-
- return ac->aframesize * ac->framecount;
-}
-
// must get exactly ac->aframesize amount of data
static void encode(struct ao *ao, double apts, void **data)
{
@@ -249,9 +242,9 @@ static void encode(struct ao *ao, double apts, void **data)
}
}
-// this should round samples down to frame sizes
-// return: number of samples played
-static int play(struct ao *ao, void **data, int samples, int flags)
+// Note: currently relies on samples aligned to period sizes - will not work
+// in the future.
+static bool audio_write(struct ao *ao, void **data, int samples)
{
struct priv *ac = ao->priv;
struct encoder_context *enc = ac->enc;
@@ -271,7 +264,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
void *tempdata = NULL;
void *padded[MP_NUM_CHANNELS];
- if ((flags & AOPLAY_FINAL_CHUNK) && (samples % ac->aframesize)) {
+ if (samples % ac->aframesize) {
tempdata = talloc_new(NULL);
size_t bytelen = samples * ao->sstride;
size_t extralen = (ac->aframesize - 1) * ao->sstride;
@@ -282,6 +275,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
}
data = padded;
samples = (bytelen + extralen) / ao->sstride;
+ MP_VERBOSE(ao, "padding final frame with silence\n");
}
double outpts = pts;
@@ -334,15 +328,28 @@ static int play(struct ao *ao, void **data, int samples, int flags)
pthread_mutex_unlock(&ectx->lock);
- if (flags & AOPLAY_FINAL_CHUNK) {
- if (bufpos < orig_samples)
- MP_ERR(ao, "did not write enough data at the end\n");
- } else {
- if (bufpos > orig_samples)
- MP_ERR(ao, "audio buffer overflow (should never happen)\n");
- }
+ return true;
+}
+
+static void get_state(struct ao *ao, struct mp_pcm_state *state)
+{
+ state->free_samples = ao->device_buffer;
+ state->queued_samples = 0;
+ state->delay = 0;
+}
+
+static bool set_pause(struct ao *ao, bool paused)
+{
+ return true; // signal support so common code doesn't write silence
+}
- return taken;
+static void start(struct ao *ao)
+{
+ // we use data immediately
+}
+
+static void reset(struct ao *ao)
+{
}
const struct ao_driver audio_out_lavc = {
@@ -350,12 +357,14 @@ const struct ao_driver audio_out_lavc = {
.description = "audio encoding using libavcodec",
.name = "lavc",
.initially_blocked = true,
- .reports_underruns = true, // not a thing
.priv_size = sizeof(struct priv),
.init = init,
.uninit = uninit,
- .get_space = get_space,
- .play = play,
+ .get_state = get_state,
+ .set_pause = set_pause,
+ .write = audio_write,
+ .start = start,
+ .reset = reset,
};
// vim: sw=4 ts=4 et tw=80