diff options
-rw-r--r-- | audio/out/buffer.c | 46 | ||||
-rw-r--r-- | audio/out/internal.h | 2 | ||||
-rw-r--r-- | osdep/compiler.h | 2 |
3 files changed, 40 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); diff --git a/osdep/compiler.h b/osdep/compiler.h index 2908f6e0f2..f5658979e3 100644 --- a/osdep/compiler.h +++ b/osdep/compiler.h @@ -7,10 +7,12 @@ #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format(printf, a1, a2))) #define MP_NORETURN __attribute__((noreturn)) #define MP_FALLTHROUGH __attribute__((fallthrough)) +#define MP_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #else #define PRINTF_ATTRIBUTE(a1, a2) #define MP_NORETURN #define MP_FALLTHROUGH do {} while (0) +#define MP_WARN_UNUSED_RESULT #endif // Broken crap with __USE_MINGW_ANSI_STDIO |