summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-10-11 19:25:45 +0200
committerwm4 <wm4@nowhere>2019-10-11 19:25:45 +0200
commitc84ec021287d72d122071d5c211f9bfbeb13a3fe (patch)
tree563612b5ecef18b9d26889445cbd53914e184b62 /audio
parent52f3dee16a81ca4ed4d3a5a12e5f4fbf74cc3ddb (diff)
downloadmpv-c84ec021287d72d122071d5c211f9bfbeb13a3fe.tar.bz2
mpv-c84ec021287d72d122071d5c211f9bfbeb13a3fe.tar.xz
ao: add API for underrun reporting
AOs can now call ao_underrun_event() (in any context) if an underrun has happened. It will print a message. This will be used in the following commits. But for now, audio.c only clears the underrun bit, so that subsequent underruns still print the warning message. Since the underrun flag will be used in fragile ways by the playback state machine, there is the "reports_underruns" field that signals strong support for underrun reporting. (Otherwise, underrun events will not be used by it.)
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao.c14
-rw-r--r--audio/out/ao.h2
-rw-r--r--audio/out/internal.h8
3 files changed, 23 insertions, 1 deletions
diff --git a/audio/out/ao.c b/audio/out/ao.c
index e7af02276f..817aa29399 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -402,6 +402,7 @@ void ao_reset(struct ao *ao)
{
if (ao->api->reset)
ao->api->reset(ao);
+ atomic_fetch_and(&ao->events_, ~(unsigned int)AO_EVENT_UNDERRUN);
}
// Pause playback. Keep the current buffer. ao_get_delay() must return the
@@ -457,6 +458,14 @@ void ao_hotplug_event(struct ao *ao)
ao_add_events(ao, AO_EVENT_HOTPLUG);
}
+void ao_underrun_event(struct ao *ao)
+{
+ // Racy check, but it's just for the message.
+ if (!(atomic_load(&ao->events_) & AO_EVENT_UNDERRUN))
+ MP_WARN(ao, "Device underrun detected.\n");
+ ao_add_events(ao, AO_EVENT_UNDERRUN);
+}
+
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map)
{
@@ -517,6 +526,11 @@ 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 d66391ef1d..f8b3e676fa 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -49,6 +49,7 @@ enum {
AO_EVENT_RELOAD = 1,
AO_EVENT_HOTPLUG = 2,
AO_EVENT_INITIAL_UNBLOCK = 4,
+ AO_EVENT_UNDERRUN = 8,
};
enum {
@@ -100,6 +101,7 @@ 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/internal.h b/audio/out/internal.h
index bf769d7e1c..807f124a17 100644
--- a/audio/out/internal.h
+++ b/audio/out/internal.h
@@ -68,7 +68,7 @@ struct ao {
char *redirect;
// Internal events (use ao_request_reload(), ao_hotplug_event())
- atomic_int events_;
+ atomic_uint events_;
// Float gain multiplicator
mp_atomic_float gain;
@@ -134,6 +134,11 @@ struct ao_driver {
// first play() call is done. Encode mode uses this, and push mode
// respects it automatically (don't use with pull mode).
bool initially_blocked;
+ // Whether underruns are strictly _always_ reported via ao_underrun_event().
+ // 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.
+ 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
// fallback parameters, and set the ao format fields accordingly.
@@ -206,6 +211,7 @@ struct pollfd;
int ao_wait_poll(struct ao *ao, struct pollfd *fds, int num_fds,
pthread_mutex_t *lock);
void ao_wakeup_poll(struct ao *ao);
+void ao_underrun_event(struct ao *ao);
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map);