summaryrefslogtreecommitdiffstats
path: root/audio/out
diff options
context:
space:
mode:
authorThomas Weißschuh <thomas@t-8ch.de>2023-11-05 08:58:15 +0100
committersfan5 <sfan5@live.de>2023-11-08 20:26:23 +0100
commit4a134f441d61f24bc1d041740a61ad2be652d17d (patch)
tree80a1e53e0a215ff395a797f461f85ace8d45feb3 /audio/out
parenta5c32ea52e6f943a4221f6f18239510502d9b3e4 (diff)
downloadmpv-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.c46
-rw-r--r--audio/out/internal.h2
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);