mirror of https://github.com/mpv-player/mpv
ao: set_pause for pull based ao
This commit is contained in:
parent
8d85627aad
commit
93a924a553
|
@ -62,6 +62,11 @@ struct buffer_state {
|
||||||
bool paused; // logically paused
|
bool paused; // logically paused
|
||||||
|
|
||||||
int64_t end_time_ns; // absolute output time of last played sample
|
int64_t end_time_ns; // absolute output time of last played sample
|
||||||
|
int64_t queued_time_ns; // duration of samples that have been queued to
|
||||||
|
// the device but have not been played.
|
||||||
|
// This field is only set in ao_set_paused(),
|
||||||
|
// and is considered as a temporary solution;
|
||||||
|
// DO NOT USE IT IN OTHER PLACES.
|
||||||
|
|
||||||
bool initial_unblocked;
|
bool initial_unblocked;
|
||||||
|
|
||||||
|
@ -381,7 +386,7 @@ void ao_set_paused(struct ao *ao, bool paused, bool eof)
|
||||||
{
|
{
|
||||||
struct buffer_state *p = ao->buffer_state;
|
struct buffer_state *p = ao->buffer_state;
|
||||||
bool wakeup = false;
|
bool wakeup = false;
|
||||||
bool do_reset = false, do_start = false;
|
bool do_change_state = false;
|
||||||
|
|
||||||
// If we are going to pause on eof and ao is still playing,
|
// If we are going to pause on eof and ao is still playing,
|
||||||
// be sure to drain the ao first for gapless.
|
// be sure to drain the ao first for gapless.
|
||||||
|
@ -402,9 +407,9 @@ void ao_set_paused(struct ao *ao, bool paused, bool eof)
|
||||||
p->streaming = false;
|
p->streaming = false;
|
||||||
p->recover_pause = !ao->untimed;
|
p->recover_pause = !ao->untimed;
|
||||||
}
|
}
|
||||||
} else if (ao->driver->reset) {
|
} else if (ao->driver->reset || ao->driver->set_pause) {
|
||||||
// See ao_reset() why this is done outside of the lock.
|
// See ao_reset() why this is done outside of the lock.
|
||||||
do_reset = true;
|
do_change_state = true;
|
||||||
p->streaming = false;
|
p->streaming = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,7 +421,7 @@ void ao_set_paused(struct ao *ao, bool paused, bool eof)
|
||||||
p->hw_paused = false;
|
p->hw_paused = false;
|
||||||
} else {
|
} else {
|
||||||
if (!p->streaming)
|
if (!p->streaming)
|
||||||
do_start = true;
|
do_change_state = true;
|
||||||
p->streaming = true;
|
p->streaming = true;
|
||||||
}
|
}
|
||||||
wakeup = true;
|
wakeup = true;
|
||||||
|
@ -425,10 +430,22 @@ void ao_set_paused(struct ao *ao, bool paused, bool eof)
|
||||||
|
|
||||||
mp_mutex_unlock(&p->lock);
|
mp_mutex_unlock(&p->lock);
|
||||||
|
|
||||||
if (do_reset)
|
if (do_change_state) {
|
||||||
|
if (ao->driver->set_pause) {
|
||||||
|
if (paused) {
|
||||||
|
ao->driver->set_pause(ao, true);
|
||||||
|
p->queued_time_ns = p->end_time_ns - mp_time_ns();
|
||||||
|
} else {
|
||||||
|
p->end_time_ns = p->queued_time_ns + mp_time_ns();
|
||||||
|
ao->driver->set_pause(ao, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (paused)
|
||||||
ao->driver->reset(ao);
|
ao->driver->reset(ao);
|
||||||
if (do_start)
|
else
|
||||||
ao->driver->start(ao);
|
ao->driver->start(ao);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (wakeup)
|
if (wakeup)
|
||||||
ao_wakeup_playthread(ao);
|
ao_wakeup_playthread(ao);
|
||||||
|
|
|
@ -108,6 +108,7 @@ struct mp_pcm_state {
|
||||||
* start
|
* start
|
||||||
* Optional for both types:
|
* Optional for both types:
|
||||||
* control
|
* control
|
||||||
|
* set_pause
|
||||||
* a) ->write is called to queue audio. push.c creates a thread to regularly
|
* a) ->write is called to queue audio. push.c creates a thread to regularly
|
||||||
* refill audio device buffers with ->write, but all driver functions are
|
* refill audio device buffers with ->write, but all driver functions are
|
||||||
* always called under an exclusive lock.
|
* always called under an exclusive lock.
|
||||||
|
@ -115,8 +116,6 @@ struct mp_pcm_state {
|
||||||
* reset
|
* reset
|
||||||
* write
|
* write
|
||||||
* get_state
|
* get_state
|
||||||
* Optional:
|
|
||||||
* set_pause
|
|
||||||
* b) ->write must be NULL. ->start must be provided, and should make the
|
* b) ->write must be NULL. ->start must be provided, and should make the
|
||||||
* audio API start calling the audio callback. Your audio callback should
|
* audio API start calling the audio callback. Your audio callback should
|
||||||
* in turn call ao_read_data() to get audio data. Most functions are
|
* in turn call ao_read_data() to get audio data. Most functions are
|
||||||
|
@ -149,6 +148,9 @@ struct ao_driver {
|
||||||
// Stop all audio playback, clear buffers, back to state after init().
|
// Stop all audio playback, clear buffers, back to state after init().
|
||||||
// Optional for pull AOs.
|
// Optional for pull AOs.
|
||||||
void (*reset)(struct ao *ao);
|
void (*reset)(struct ao *ao);
|
||||||
|
// pull based: set pause state. Only called after start() and before reset().
|
||||||
|
// The return value is ignored.
|
||||||
|
// The pausing state is also cleared by reset().
|
||||||
// push based: set pause state. Only called after start() and before reset().
|
// push based: set pause state. Only called after start() and before reset().
|
||||||
// returns success (this is intended for paused=true; if it
|
// returns success (this is intended for paused=true; if it
|
||||||
// returns false, playback continues, and the core emulates via
|
// returns false, playback continues, and the core emulates via
|
||||||
|
|
Loading…
Reference in New Issue