diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/out/ao.c | 5 | ||||
-rw-r--r-- | audio/out/ao.h | 1 | ||||
-rw-r--r-- | audio/out/ao_pcm.c | 1 | ||||
-rw-r--r-- | audio/out/ao_sdl.c | 1 | ||||
-rw-r--r-- | audio/out/internal.h | 2 | ||||
-rw-r--r-- | audio/out/pull.c | 27 | ||||
-rw-r--r-- | audio/out/push.c | 2 |
7 files changed, 22 insertions, 17 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); } |