output/Thread: split Open()
Simplify the code, eliminate duplicate rollback code and eliminate the "goto" kludge.
This commit is contained in:
parent
093cb475bb
commit
ceba6816de
@ -401,6 +401,26 @@ private:
|
||||
void Disable();
|
||||
|
||||
void Open();
|
||||
|
||||
/**
|
||||
* Open the #ChainFilter and call OpenOutputAndConvert().
|
||||
*
|
||||
* Caller must not lock the mutex.
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool OpenFilterAndOutput();
|
||||
|
||||
/**
|
||||
* Invoke OutputPlugin::open() and configure the
|
||||
* #ConvertFilter.
|
||||
*
|
||||
* Caller must not lock the mutex.
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool OpenOutputAndConvert(AudioFormat audio_format);
|
||||
|
||||
void Close(bool drain);
|
||||
void Reopen();
|
||||
|
||||
|
@ -131,8 +131,6 @@ AudioOutput::CloseFilter()
|
||||
inline void
|
||||
AudioOutput::Open()
|
||||
{
|
||||
struct audio_format_string af_string;
|
||||
|
||||
assert(!open);
|
||||
assert(in_audio_format.IsValid());
|
||||
|
||||
@ -144,42 +142,55 @@ AudioOutput::Open()
|
||||
/* still no luck */
|
||||
return;
|
||||
|
||||
/* open the filter */
|
||||
bool success;
|
||||
|
||||
const ScopeUnlock unlock(mutex);
|
||||
{
|
||||
const ScopeUnlock unlock(mutex);
|
||||
success = OpenFilterAndOutput();
|
||||
}
|
||||
|
||||
if (success)
|
||||
open = true;
|
||||
else
|
||||
fail_timer.Update();
|
||||
}
|
||||
|
||||
bool
|
||||
AudioOutput::OpenFilterAndOutput()
|
||||
{
|
||||
AudioFormat filter_audio_format;
|
||||
try {
|
||||
filter_audio_format = OpenFilter(in_audio_format);
|
||||
} catch (const std::runtime_error &e) {
|
||||
FormatError(e, "Failed to open filter for \"%s\" [%s]",
|
||||
name, plugin.name);
|
||||
|
||||
fail_timer.Update();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(filter_audio_format.IsValid());
|
||||
|
||||
const auto retry_audio_format = out_audio_format =
|
||||
const auto audio_format =
|
||||
filter_audio_format.WithMask(config_audio_format);
|
||||
bool success = OpenOutputAndConvert(audio_format);
|
||||
if (!success)
|
||||
CloseFilter();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
|
||||
{
|
||||
out_audio_format = desired_audio_format;
|
||||
|
||||
retry_without_dsd:
|
||||
try {
|
||||
ao_plugin_open(this, out_audio_format);
|
||||
} catch (const std::runtime_error &e) {
|
||||
FormatError(e, "Failed to open \"%s\" [%s]",
|
||||
name, plugin.name);
|
||||
|
||||
CloseFilter();
|
||||
|
||||
const ScopeLock lock(mutex);
|
||||
fail_timer.Update();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(!open);
|
||||
|
||||
try {
|
||||
convert_filter_set(convert_filter.Get(), out_audio_format);
|
||||
} catch (const std::runtime_error &e) {
|
||||
@ -195,26 +206,16 @@ AudioOutput::Open()
|
||||
implemented; our last resort is to give up
|
||||
DSD and fall back to PCM */
|
||||
|
||||
// TODO: clean up this workaround
|
||||
|
||||
FormatError(output_domain, "Retrying without DSD");
|
||||
|
||||
out_audio_format = retry_audio_format;
|
||||
out_audio_format.format = SampleFormat::FLOAT;
|
||||
|
||||
/* sorry for the "goto" - this is a workaround
|
||||
for the stable branch that should be as
|
||||
unintrusive as possible */
|
||||
goto retry_without_dsd;
|
||||
desired_audio_format.format = SampleFormat::FLOAT;
|
||||
return OpenOutputAndConvert(desired_audio_format);
|
||||
}
|
||||
|
||||
CloseFilter();
|
||||
|
||||
const ScopeLock lock(mutex);
|
||||
fail_timer.Update();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct audio_format_string af_string;
|
||||
FormatDebug(output_domain,
|
||||
"opened plugin=%s name=\"%s\" audio_format=%s",
|
||||
plugin.name, name,
|
||||
@ -225,8 +226,7 @@ AudioOutput::Open()
|
||||
audio_format_to_string(in_audio_format,
|
||||
&af_string));
|
||||
|
||||
const ScopeLock lock(mutex);
|
||||
open = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user