mirror of
https://github.com/mpv-player/mpv
synced 2024-12-26 00:42:57 +00:00
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.)
This commit is contained in:
parent
52f3dee16a
commit
c84ec02128
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -855,6 +855,8 @@ void fill_audio_out_buffers(struct MPContext *mpctx)
|
||||
|
||||
int playsize = ao_get_space(mpctx->ao);
|
||||
|
||||
ao_query_and_reset_events(mpctx->ao, AO_EVENT_UNDERRUN);
|
||||
|
||||
int skip = 0;
|
||||
bool sync_known = get_sync_samples(mpctx, &skip);
|
||||
if (skip > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user