diff options
author | Thomas Weißschuh <thomas@t-8ch.de> | 2023-11-05 08:58:15 +0100 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2023-11-08 20:26:23 +0100 |
commit | 4a134f441d61f24bc1d041740a61ad2be652d17d (patch) | |
tree | 80a1e53e0a215ff395a797f461f85ace8d45feb3 /audio/out | |
parent | a5c32ea52e6f943a4221f6f18239510502d9b3e4 (diff) | |
download | mpv-4a134f441d61f24bc1d041740a61ad2be652d17d.tar.bz2 mpv-4a134f441d61f24bc1d041740a61ad2be652d17d.tar.xz |
audio: introduce ao_read_data_nonblocking()
This behaves similar to ao_read_data() but does not block and may return
partial data.
Diffstat (limited to 'audio/out')
-rw-r--r-- | audio/out/buffer.c | 46 | ||||
-rw-r--r-- | audio/out/internal.h | 2 |
2 files changed, 38 insertions, 10 deletions
diff --git a/audio/out/buffer.c b/audio/out/buffer.c index 4ab3e405bc..a5520f3a21 100644 --- a/audio/out/buffer.c +++ b/audio/out/buffer.c @@ -170,6 +170,27 @@ static int read_buffer(struct ao *ao, void **data, int samples, bool *eof) return pos; } +static int ao_read_data_unlocked(struct ao *ao, void **data, int samples, + int64_t out_time_ns) +{ + struct buffer_state *p = ao->buffer_state; + assert(!ao->driver->write); + + int pos = read_buffer(ao, data, samples, &(bool){0}); + + if (pos > 0) + p->end_time_ns = out_time_ns; + + if (pos < samples && p->playing && !p->paused) { + p->playing = false; + ao->wakeup_cb(ao->wakeup_ctx); + // For ao_drain(). + mp_cond_broadcast(&p->wakeup); + } + + return pos; +} + // Read the given amount of samples in the user-provided data buffer. Returns // the number of samples copied. If there is not enough data (buffer underrun // or EOF), return the number of samples that could be copied, and fill the @@ -181,21 +202,26 @@ static int read_buffer(struct ao *ao, void **data, int samples, bool *eof) int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_ns) { struct buffer_state *p = ao->buffer_state; - assert(!ao->driver->write); mp_mutex_lock(&p->lock); - int pos = read_buffer(ao, data, samples, &(bool){0}); + int pos = ao_read_data_unlocked(ao, data, samples, out_time_ns); - if (pos > 0) - p->end_time_ns = out_time_ns; + mp_mutex_unlock(&p->lock); - if (pos < samples && p->playing && !p->paused) { - p->playing = false; - ao->wakeup_cb(ao->wakeup_ctx); - // For ao_drain(). - mp_cond_broadcast(&p->wakeup); - } + return pos; +} + +// Like ao_read_data() but does not block and also may return partial data. +// Callers have to check the return value. +int ao_read_data_nonblocking(struct ao *ao, void **data, int samples, int64_t out_time_ns) +{ + struct buffer_state *p = ao->buffer_state; + + if (mp_mutex_trylock(&p->lock)) + return 0; + + int pos = ao_read_data_unlocked(ao, data, samples, out_time_ns); mp_mutex_unlock(&p->lock); diff --git a/audio/out/internal.h b/audio/out/internal.h index 1ae92a8b92..7951b3861e 100644 --- a/audio/out/internal.h +++ b/audio/out/internal.h @@ -200,6 +200,8 @@ 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_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); |