summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/out/ao.c5
-rw-r--r--audio/out/ao.h1
-rw-r--r--audio/out/ao_pcm.c1
-rw-r--r--audio/out/ao_sdl.c1
-rw-r--r--audio/out/internal.h2
-rw-r--r--audio/out/pull.c27
-rw-r--r--audio/out/push.c2
-rw-r--r--player/playloop.c9
8 files changed, 25 insertions, 23 deletions
diff --git a/audio/out/ao.c b/audio/out/ao.c
index fa6cc9e76d..a4d6ad5db6 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -535,11 +535,6 @@ const char *ao_get_description(struct ao *ao)
return ao->driver->description;
}
-bool ao_get_reports_underruns(struct ao *ao)
-{
- return ao->driver->reports_underruns;
-}
-
bool ao_untimed(struct ao *ao)
{
return ao->untimed;
diff --git a/audio/out/ao.h b/audio/out/ao.h
index eb9e29dacb..da81be103c 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -97,7 +97,6 @@ void ao_get_format(struct ao *ao,
int *samplerate, int *format, struct mp_chmap *channels);
const char *ao_get_name(struct ao *ao);
const char *ao_get_description(struct ao *ao);
-bool ao_get_reports_underruns(struct ao *ao);
bool ao_untimed(struct ao *ao);
int ao_play(struct ao *ao, void **data, int samples, int flags);
int ao_control(struct ao *ao, enum aocontrol cmd, void *arg);
diff --git a/audio/out/ao_pcm.c b/audio/out/ao_pcm.c
index a36b71fa16..689d5c019a 100644
--- a/audio/out/ao_pcm.c
+++ b/audio/out/ao_pcm.c
@@ -215,6 +215,7 @@ const struct ao_driver audio_out_pcm = {
.uninit = uninit,
.get_space = get_space,
.play = play,
+ .reports_underruns = true, // not a thing
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) { .waveheader = 1 },
.options = (const struct m_option[]) {
diff --git a/audio/out/ao_sdl.c b/audio/out/ao_sdl.c
index 1390eb64d0..6144918dfe 100644
--- a/audio/out/ao_sdl.c
+++ b/audio/out/ao_sdl.c
@@ -205,7 +205,6 @@ const struct ao_driver audio_out_sdl = {
.uninit = uninit,
.reset = reset,
.resume = resume,
- .reports_underruns = true,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.buflen = 0, // use SDL default
diff --git a/audio/out/internal.h b/audio/out/internal.h
index 7d1d744991..7bdd17ad8a 100644
--- a/audio/out/internal.h
+++ b/audio/out/internal.h
@@ -138,6 +138,8 @@ struct ao_driver {
// Do not set this to true if underruns may be missed in some way. If the
// AO can't guarantee to play silence after underruns, it may be better not
// to set this.
+ // If not set, the generic buffer code will report an underrun if the buffer
+ // becomes empty.
bool reports_underruns;
// Init the device using ao->format/ao->channels/ao->samplerate. If the
// device doesn't accept these parameters, you can attempt to negotiate
diff --git a/audio/out/pull.c b/audio/out/pull.c
index 985d6d9f67..a3d4b024b1 100644
--- a/audio/out/pull.c
+++ b/audio/out/pull.c
@@ -83,9 +83,23 @@ static void set_state(struct ao *ao, int new_state)
}
}
+static void report_underruns(struct ao *ao)
+{
+ struct ao_pull_state *p = ao->api_priv;
+
+ int underflow = atomic_fetch_and(&p->underflow, 0);
+ if (underflow) {
+ if (ao_underrun_event(ao))
+ MP_VERBOSE(ao, "Audio underrun by %d samples.\n", underflow);
+ }
+}
+
static int get_space(struct ao *ao)
{
struct ao_pull_state *p = ao->api_priv;
+
+ report_underruns(ao);
+
// Since the reader will read the last plane last, its free space is the
// minimum free space across all planes.
return mp_ring_available(p->buffers[ao->num_planes - 1]) / ao->sstride;
@@ -119,9 +133,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
bool draining = write_samples == samples && (flags & AOPLAY_FINAL_CHUNK);
atomic_store(&p->draining, draining);
- int underflow = atomic_fetch_and(&p->underflow, 0);
- if (underflow)
- MP_WARN(ao, "Audio underflow by %d samples.\n", underflow);
+ report_underruns(ao);
return write_samples;
}
@@ -153,13 +165,8 @@ int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us)
int buffered_bytes = mp_ring_buffered(p->buffers[0]);
bytes = MPMIN(buffered_bytes, full_bytes);
- if (full_bytes > bytes && !atomic_load(&p->draining)) {
- if (ao->driver->reports_underruns) {
- ao_underrun_event(ao);
- } else {
- atomic_fetch_add(&p->underflow, (full_bytes - bytes) / ao->sstride);
- }
- }
+ if (full_bytes > bytes && !atomic_load(&p->draining))
+ atomic_fetch_add(&p->underflow, (full_bytes - bytes) / ao->sstride);
if (bytes > 0)
atomic_store(&p->end_time_us, out_time_us);
diff --git a/audio/out/push.c b/audio/out/push.c
index 470f521c68..92fd53631b 100644
--- a/audio/out/push.c
+++ b/audio/out/push.c
@@ -347,6 +347,8 @@ static void ao_play_data(struct ao *ao)
!(flags & AOPLAY_FINAL_CHUNK);
if (more)
ao->wakeup_cb(ao->wakeup_ctx); // request more data
+ if (!samples && space && !ao->driver->reports_underruns && p->still_playing)
+ ao_underrun_event(ao);
MP_TRACE(ao, "in=%d flags=%d space=%d r=%d wa/pl=%d/%d needed=%d more=%d\n",
max, flags, space, r, p->wait_on_ao, p->still_playing, needed, more);
}
diff --git a/player/playloop.c b/player/playloop.c
index 4f0efad275..66ce211322 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -691,7 +691,7 @@ static void handle_update_cache(struct MPContext *mpctx)
bool force_update = false;
struct MPOpts *opts = mpctx->opts;
- if (!mpctx->demuxer) {
+ if (!mpctx->demuxer || mpctx->encode_lavc_ctx) {
clear_underruns(mpctx);
return;
}
@@ -726,11 +726,8 @@ static void handle_update_cache(struct MPContext *mpctx)
// underrun detection.)
bool output_underrun = false;
- if (mpctx->ao_chain) {
- output_underrun |=
- !(mpctx->ao && ao_get_reports_underruns(mpctx->ao)) ||
- mpctx->ao_chain->underrun;
- }
+ if (mpctx->ao_chain)
+ output_underrun |= mpctx->ao_chain->underrun;
if (mpctx->vo_chain)
output_underrun |= mpctx->vo_chain->underrun;