output/control: add command `RELEASE`
With the new command, the decision to pause or close the output moves into the output thread.
This commit is contained in:
parent
9a813cd3b1
commit
e097fef79e
|
@ -347,10 +347,22 @@ AudioOutputControl::LockAllowPlay() noexcept
|
||||||
void
|
void
|
||||||
AudioOutputControl::LockRelease() noexcept
|
AudioOutputControl::LockRelease() noexcept
|
||||||
{
|
{
|
||||||
if (always_on)
|
if (output->mixer != nullptr &&
|
||||||
LockPauseAsync();
|
(!always_on || !output->SupportsPause()))
|
||||||
|
/* the device has no pause mode: close the mixer,
|
||||||
|
unless its "global" flag is set (checked by
|
||||||
|
mixer_auto_close()) */
|
||||||
|
mixer_auto_close(output->mixer);
|
||||||
|
|
||||||
|
const std::lock_guard<Mutex> protect(mutex);
|
||||||
|
|
||||||
|
assert(!open || !fail_timer.IsDefined());
|
||||||
|
assert(allow_play);
|
||||||
|
|
||||||
|
if (IsOpen())
|
||||||
|
CommandWait(Command::RELEASE);
|
||||||
else
|
else
|
||||||
LockCloseWait();
|
fail_timer.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -131,6 +131,12 @@ class AudioOutputControl {
|
||||||
CLOSE,
|
CLOSE,
|
||||||
PAUSE,
|
PAUSE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close or pause the device, depending on the
|
||||||
|
* #always_on setting.
|
||||||
|
*/
|
||||||
|
RELEASE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drains the internal (hardware) buffers of the device. This
|
* Drains the internal (hardware) buffers of the device. This
|
||||||
* operation may take a while to complete.
|
* operation may take a while to complete.
|
||||||
|
|
|
@ -456,6 +456,30 @@ AudioOutputControl::Task() noexcept
|
||||||
the new command first */
|
the new command first */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case Command::RELEASE:
|
||||||
|
if (!open) {
|
||||||
|
/* the output has failed after
|
||||||
|
the PAUSE command was submitted; bail
|
||||||
|
out */
|
||||||
|
CommandFinished();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (always_on) {
|
||||||
|
/* in "always_on" mode, the output is
|
||||||
|
paused instead of being closed */
|
||||||
|
InternalPause();
|
||||||
|
} else {
|
||||||
|
InternalClose(false);
|
||||||
|
CommandFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't "break" here: this might cause
|
||||||
|
Play() to be called when command==CLOSE
|
||||||
|
ends the paused state - "continue" checks
|
||||||
|
the new command first */
|
||||||
|
continue;
|
||||||
|
|
||||||
case Command::DRAIN:
|
case Command::DRAIN:
|
||||||
if (open)
|
if (open)
|
||||||
InternalDrain();
|
InternalDrain();
|
||||||
|
|
Loading…
Reference in New Issue