output/Thread: unify exception handling
This commit is contained in:
parent
6fc47fbb69
commit
a9f2d25957
@ -410,20 +410,27 @@ public:
|
|||||||
private:
|
private:
|
||||||
void CommandFinished();
|
void CommandFinished();
|
||||||
|
|
||||||
bool Enable();
|
/**
|
||||||
|
* Throws #std::runtime_error on error.
|
||||||
|
*/
|
||||||
|
void Enable();
|
||||||
|
|
||||||
void Disable();
|
void Disable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws #std::runtime_error on error.
|
||||||
|
*/
|
||||||
void Open();
|
void Open();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke OutputPlugin::open() and configure the
|
* Invoke OutputPlugin::open() and configure the
|
||||||
* #ConvertFilter.
|
* #ConvertFilter.
|
||||||
*
|
*
|
||||||
* Caller must not lock the mutex.
|
* Throws #std::runtime_error on error.
|
||||||
*
|
*
|
||||||
* @return true on success
|
* Caller must not lock the mutex.
|
||||||
*/
|
*/
|
||||||
bool OpenOutputAndConvert(AudioFormat audio_format);
|
void OpenOutputAndConvert(AudioFormat audio_format);
|
||||||
|
|
||||||
void Close(bool drain);
|
void Close(bool drain);
|
||||||
|
|
||||||
|
@ -55,24 +55,21 @@ AudioOutput::CommandFinished()
|
|||||||
audio_output_client_notify.Signal();
|
audio_output_client_notify.Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
AudioOutput::Enable()
|
AudioOutput::Enable()
|
||||||
{
|
{
|
||||||
if (really_enabled)
|
if (really_enabled)
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
ao_plugin_enable(this);
|
ao_plugin_enable(this);
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e,
|
std::throw_with_nested(FormatRuntimeError("Failed to enable output \"%s\" [%s]",
|
||||||
"Failed to enable \"%s\" [%s]",
|
name, plugin.name));
|
||||||
name, plugin.name);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
really_enabled = true;
|
really_enabled = true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
@ -106,11 +103,7 @@ AudioOutput::Open()
|
|||||||
fail_timer.Reset();
|
fail_timer.Reset();
|
||||||
|
|
||||||
/* enable the device (just in case the last enable has failed) */
|
/* enable the device (just in case the last enable has failed) */
|
||||||
if (!Enable()) {
|
Enable();
|
||||||
/* still no luck */
|
|
||||||
fail_timer.Update();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioFormat f;
|
AudioFormat f;
|
||||||
|
|
||||||
@ -124,10 +117,8 @@ AudioOutput::Open()
|
|||||||
if (mixer != nullptr && mixer->IsPlugin(software_mixer_plugin))
|
if (mixer != nullptr && mixer->IsPlugin(software_mixer_plugin))
|
||||||
software_mixer_set_filter(*mixer, volume_filter.Get());
|
software_mixer_set_filter(*mixer, volume_filter.Get());
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e, "Failed to open filter for \"%s\" [%s]",
|
std::throw_with_nested(FormatRuntimeError("Failed to open filter for \"%s\" [%s]",
|
||||||
name, plugin.name);
|
name, plugin.name));
|
||||||
fail_timer.Update();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open && f != filter_audio_format) {
|
if (open && f != filter_audio_format) {
|
||||||
@ -140,16 +131,18 @@ AudioOutput::Open()
|
|||||||
filter_audio_format = f;
|
filter_audio_format = f;
|
||||||
|
|
||||||
if (!open) {
|
if (!open) {
|
||||||
if (OpenOutputAndConvert(filter_audio_format)) {
|
try {
|
||||||
open = true;
|
OpenOutputAndConvert(filter_audio_format);
|
||||||
} else {
|
} catch (...) {
|
||||||
CloseFilter();
|
CloseFilter();
|
||||||
fail_timer.Update();
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
|
AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
|
||||||
{
|
{
|
||||||
out_audio_format = desired_audio_format;
|
out_audio_format = desired_audio_format;
|
||||||
@ -157,17 +150,13 @@ AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
|
|||||||
try {
|
try {
|
||||||
ao_plugin_open(this, out_audio_format);
|
ao_plugin_open(this, out_audio_format);
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e, "Failed to open \"%s\" [%s]",
|
std::throw_with_nested(FormatRuntimeError("Failed to open \"%s\" [%s]",
|
||||||
name, plugin.name);
|
name, plugin.name));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
convert_filter_set(convert_filter.Get(), out_audio_format);
|
convert_filter_set(convert_filter.Get(), out_audio_format);
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e, "Failed to convert for \"%s\" [%s]",
|
|
||||||
name, plugin.name);
|
|
||||||
|
|
||||||
ao_plugin_close(this);
|
ao_plugin_close(this);
|
||||||
|
|
||||||
if (out_audio_format.format == SampleFormat::DSD) {
|
if (out_audio_format.format == SampleFormat::DSD) {
|
||||||
@ -177,13 +166,16 @@ AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
|
|||||||
implemented; our last resort is to give up
|
implemented; our last resort is to give up
|
||||||
DSD and fall back to PCM */
|
DSD and fall back to PCM */
|
||||||
|
|
||||||
|
LogError(e);
|
||||||
FormatError(output_domain, "Retrying without DSD");
|
FormatError(output_domain, "Retrying without DSD");
|
||||||
|
|
||||||
desired_audio_format.format = SampleFormat::FLOAT;
|
desired_audio_format.format = SampleFormat::FLOAT;
|
||||||
return OpenOutputAndConvert(desired_audio_format);
|
OpenOutputAndConvert(desired_audio_format);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
std::throw_with_nested(FormatRuntimeError("Failed to convert for \"%s\" [%s]",
|
||||||
|
name, plugin.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct audio_format_string af_string;
|
struct audio_format_string af_string;
|
||||||
@ -196,8 +188,6 @@ AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
|
|||||||
FormatDebug(output_domain, "converting from %s",
|
FormatDebug(output_domain, "converting from %s",
|
||||||
audio_format_to_string(source.GetInputAudioFormat(),
|
audio_format_to_string(source.GetInputAudioFormat(),
|
||||||
&af_string));
|
&af_string));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -415,7 +405,13 @@ AudioOutput::Task()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::ENABLE:
|
case Command::ENABLE:
|
||||||
Enable();
|
try {
|
||||||
|
Enable();
|
||||||
|
} catch (const std::runtime_error &e) {
|
||||||
|
LogError(e);
|
||||||
|
fail_timer.Update();
|
||||||
|
}
|
||||||
|
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -425,7 +421,13 @@ AudioOutput::Task()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::OPEN:
|
case Command::OPEN:
|
||||||
Open();
|
try {
|
||||||
|
Open();
|
||||||
|
} catch (const std::runtime_error &e) {
|
||||||
|
LogError(e);
|
||||||
|
fail_timer.Update();
|
||||||
|
}
|
||||||
|
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user