output/Thread: split Open()

Simplify the code, eliminate duplicate rollback code and eliminate the
"goto" kludge.
This commit is contained in:
Max Kellermann 2016-12-13 21:46:27 +01:00
parent 093cb475bb
commit ceba6816de
2 changed files with 53 additions and 33 deletions

View File

@ -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();

View File

@ -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