summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2016-09-04 14:32:09 +0200
committerMax Kellermann <max@musicpd.org>2016-09-04 19:38:41 +0200
commit13c32111a01420e426ad7153973686694cf0bee2 (patch)
tree8f634d9194b86b0980123d7ad1bb603faa866398
parent28c69757320936adac8b9c0d6bd5c592f40a5ec1 (diff)
Filter/Internal: migrate from class Error to C++ exceptions
-rw-r--r--src/filter/FilterInternal.hxx11
-rw-r--r--src/filter/Observer.cxx14
-rw-r--r--src/filter/plugins/AutoConvertFilterPlugin.cxx22
-rw-r--r--src/filter/plugins/ChainFilterPlugin.cxx41
-rw-r--r--src/filter/plugins/ConvertFilterPlugin.cxx56
-rw-r--r--src/filter/plugins/ConvertFilterPlugin.hxx10
-rw-r--r--src/filter/plugins/NormalizeFilterPlugin.cxx9
-rw-r--r--src/filter/plugins/NullFilterPlugin.cxx6
-rw-r--r--src/filter/plugins/ReplayGainFilterPlugin.cxx25
-rw-r--r--src/filter/plugins/RouteFilterPlugin.cxx9
-rw-r--r--src/filter/plugins/VolumeFilterPlugin.cxx28
-rw-r--r--src/output/Internal.hxx5
-rw-r--r--src/output/OutputThread.cxx78
-rw-r--r--test/run_filter.cxx19
14 files changed, 142 insertions, 191 deletions
diff --git a/src/filter/FilterInternal.hxx b/src/filter/FilterInternal.hxx
index 2921314f5..6cf8c37cb 100644
--- a/src/filter/FilterInternal.hxx
+++ b/src/filter/FilterInternal.hxx
@@ -54,13 +54,15 @@ public:
/**
* Filters a block of PCM data.
*
+ * Throws std::runtime_error on error.
+ *
* @param src the input buffer
* @param error location to store the error occurring
* @return the destination buffer on success (will be
* invalidated by deleting this object or the next FilterPCM()
- * call), nullptr on error
+ * call)
*/
- virtual ConstBuffer<void> FilterPCM(ConstBuffer<void> src, Error &error) = 0;
+ virtual ConstBuffer<void> FilterPCM(ConstBuffer<void> src) = 0;
};
class PreparedFilter {
@@ -70,12 +72,13 @@ public:
/**
* Opens the filter, preparing it for FilterPCM().
*
+ * Throws std::runtime_error on error.
+ *
* @param af the audio format of incoming data; the
* plugin may modify the object to enforce another input
* format
- * @param error location to store the error occurring
*/
- virtual Filter *Open(AudioFormat &af, Error &error) = 0;
+ virtual Filter *Open(AudioFormat &af) = 0;
};
#endif
diff --git a/src/filter/Observer.cxx b/src/filter/Observer.cxx
index 310234e95..caad18254 100644
--- a/src/filter/Observer.cxx
+++ b/src/filter/Observer.cxx
@@ -51,7 +51,7 @@ public:
Filter *Get();
- Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
class FilterObserver::Proxy final : public Filter {
@@ -73,9 +73,8 @@ public:
return filter;
}
- ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override {
- return filter->FilterPCM(src, error);
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override {
+ return filter->FilterPCM(src);
}
};
@@ -88,14 +87,11 @@ FilterObserver::PreparedProxy::Get()
}
Filter *
-FilterObserver::PreparedProxy::Open(AudioFormat &af, Error &error)
+FilterObserver::PreparedProxy::Open(AudioFormat &af)
{
assert(child == nullptr);
- Filter *f = prepared_filter->Open(af, error);
- if (f == nullptr)
- return f;
-
+ Filter *f = prepared_filter->Open(af);
return child = new Proxy(*this, f);
}
diff --git a/src/filter/plugins/AutoConvertFilterPlugin.cxx b/src/filter/plugins/AutoConvertFilterPlugin.cxx
index 6ee2aae03..ba2e2fa01 100644
--- a/src/filter/plugins/AutoConvertFilterPlugin.cxx
+++ b/src/filter/plugins/AutoConvertFilterPlugin.cxx
@@ -47,8 +47,7 @@ public:
std::unique_ptr<Filter> &&_convert)
:filter(std::move(_filter)), convert(std::move(_convert)) {}
- virtual ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override;
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
};
class PreparedAutoConvertFilter final : public PreparedFilter {
@@ -63,20 +62,18 @@ public:
delete filter;
}
- virtual Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
Filter *
-PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error)
+PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format)
{
assert(in_audio_format.IsValid());
/* open the "real" filter */
AudioFormat child_audio_format = in_audio_format;
- std::unique_ptr<Filter> new_filter(filter->Open(child_audio_format, error));
- if (!new_filter)
- return nullptr;
+ std::unique_ptr<Filter> new_filter(filter->Open(child_audio_format));
/* need to convert? */
@@ -85,10 +82,7 @@ PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error)
/* yes - create a convert_filter */
convert.reset(convert_filter_new(in_audio_format,
- child_audio_format,
- error));
- if (!convert)
- return nullptr;
+ child_audio_format));
}
return new AutoConvertFilter(std::move(new_filter),
@@ -96,15 +90,15 @@ PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error)
}
ConstBuffer<void>
-AutoConvertFilter::FilterPCM(ConstBuffer<void> src, Error &error)
+AutoConvertFilter::FilterPCM(ConstBuffer<void> src)
{
if (convert != nullptr) {
- src = convert->FilterPCM(src, error);
+ src = convert->FilterPCM(src);
if (src.IsNull())
return nullptr;
}
- return filter->FilterPCM(src, error);
+ return filter->FilterPCM(src);
}
PreparedFilter *
diff --git a/src/filter/plugins/ChainFilterPlugin.cxx b/src/filter/plugins/ChainFilterPlugin.cxx
index 4b79baf5b..fafba0250 100644
--- a/src/filter/plugins/ChainFilterPlugin.cxx
+++ b/src/filter/plugins/ChainFilterPlugin.cxx
@@ -23,9 +23,8 @@
#include "filter/FilterInternal.hxx"
#include "filter/FilterRegistry.hxx"
#include "AudioFormat.hxx"
-#include "util/Error.hxx"
-#include "util/Domain.hxx"
#include "util/ConstBuffer.hxx"
+#include "util/RuntimeError.hxx"
#include <memory>
#include <list>
@@ -62,8 +61,7 @@ public:
}
/* virtual methods from class Filter */
- ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override;
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
};
class PreparedChainFilter final : public PreparedFilter {
@@ -80,8 +78,7 @@ class PreparedChainFilter final : public PreparedFilter {
Child(const Child &) = delete;
Child &operator=(const Child &) = delete;
- Filter *Open(const AudioFormat &prev_audio_format,
- Error &error);
+ Filter *Open(const AudioFormat &prev_audio_format);
};
std::list<Child> children;
@@ -92,11 +89,9 @@ public:
}
/* virtual methods from class PreparedFilter */
- Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
-static constexpr Domain chain_filter_domain("chain_filter");
-
static PreparedFilter *
chain_filter_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error)
@@ -105,39 +100,31 @@ chain_filter_init(gcc_unused const ConfigBlock &block,
}
Filter *
-PreparedChainFilter::Child::Open(const AudioFormat &prev_audio_format,
- Error &error)
+PreparedChainFilter::Child::Open(const AudioFormat &prev_audio_format)
{
AudioFormat conv_audio_format = prev_audio_format;
- Filter *new_filter = filter->Open(conv_audio_format, error);
- if (new_filter == nullptr)
- return nullptr;
+ Filter *new_filter = filter->Open(conv_audio_format);
if (conv_audio_format != prev_audio_format) {
delete new_filter;
struct audio_format_string s;
- error.Format(chain_filter_domain,
- "Audio format not supported by filter '%s': %s",
- name,
- audio_format_to_string(prev_audio_format, &s));
- return nullptr;
+ throw FormatRuntimeError("Audio format not supported by filter '%s': %s",
+ name,
+ audio_format_to_string(prev_audio_format, &s));
}
return new_filter;
}
Filter *
-PreparedChainFilter::Open(AudioFormat &in_audio_format, Error &error)
+PreparedChainFilter::Open(AudioFormat &in_audio_format)
{
std::unique_ptr<ChainFilter> chain(new ChainFilter(in_audio_format));
for (auto &child : children) {
AudioFormat audio_format = chain->GetOutAudioFormat();
- auto *filter = child.Open(audio_format, error);
- if (filter == nullptr)
- return nullptr;
-
+ auto *filter = child.Open(audio_format);
chain->Append(child.name, filter);
}
@@ -145,14 +132,12 @@ PreparedChainFilter::Open(AudioFormat &in_audio_format, Error &error)
}
ConstBuffer<void>
-ChainFilter::FilterPCM(ConstBuffer<void> src, Error &error)
+ChainFilter::FilterPCM(ConstBuffer<void> src)
{
for (auto &child : children) {
/* feed the output of the previous filter as input
into the current one */
- src = child.filter->FilterPCM(src, error);
- if (src.IsNull())
- return nullptr;
+ src = child.filter->FilterPCM(src);
}
/* return the output of the last filter */
diff --git a/src/filter/plugins/ConvertFilterPlugin.cxx b/src/filter/plugins/ConvertFilterPlugin.cxx
index 51022843d..fb8e684b6 100644
--- a/src/filter/plugins/ConvertFilterPlugin.cxx
+++ b/src/filter/plugins/ConvertFilterPlugin.cxx
@@ -25,9 +25,13 @@
#include "pcm/PcmConvert.hxx"
#include "util/Manual.hxx"
#include "util/ConstBuffer.hxx"
+#include "util/Error.hxx"
#include "AudioFormat.hxx"
#include "poison.h"
+#include <stdexcept>
+#include <memory>
+
#include <assert.h>
class ConvertFilter final : public Filter {
@@ -47,17 +51,16 @@ public:
ConvertFilter(const AudioFormat &audio_format);
~ConvertFilter();
- bool Set(const AudioFormat &_out_audio_format, Error &error);
+ void Set(const AudioFormat &_out_audio_format);
- virtual ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override;
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
};
class PreparedConvertFilter final : public PreparedFilter {
public:
- bool Set(const AudioFormat &_out_audio_format, Error &error);
+ void Set(const AudioFormat &_out_audio_format);
- Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
static PreparedFilter *
@@ -67,15 +70,15 @@ convert_filter_init(gcc_unused const ConfigBlock &block,
return new PreparedConvertFilter();
}
-bool
-ConvertFilter::Set(const AudioFormat &_out_audio_format, Error &error)
+void
+ConvertFilter::Set(const AudioFormat &_out_audio_format)
{
assert(in_audio_format.IsValid());
assert(_out_audio_format.IsValid());
if (_out_audio_format == out_audio_format)
/* no change */
- return true;
+ return;
if (out_audio_format != in_audio_format) {
out_audio_format = in_audio_format;
@@ -84,13 +87,13 @@ ConvertFilter::Set(const AudioFormat &_out_audio_format, Error &error)
if (_out_audio_format == in_audio_format)
/* optimized special case: no-op */
- return true;
+ return;
+ Error error;
if (!state.Open(in_audio_format, _out_audio_format, error))
- return false;
+ throw std::runtime_error(error.GetMessage());
out_audio_format = _out_audio_format;
- return true;
}
ConvertFilter::ConvertFilter(const AudioFormat &audio_format)
@@ -99,7 +102,7 @@ ConvertFilter::ConvertFilter(const AudioFormat &audio_format)
}
Filter *
-PreparedConvertFilter::Open(AudioFormat &audio_format, gcc_unused Error &error)
+PreparedConvertFilter::Open(AudioFormat &audio_format)
{
assert(audio_format.IsValid());
@@ -115,7 +118,7 @@ ConvertFilter::~ConvertFilter()
}
ConstBuffer<void>
-ConvertFilter::FilterPCM(ConstBuffer<void> src, Error &error)
+ConvertFilter::FilterPCM(ConstBuffer<void> src)
{
assert(in_audio_format.IsValid());
@@ -123,7 +126,12 @@ ConvertFilter::FilterPCM(ConstBuffer<void> src, Error &error)
/* optimized special case: no-op */
return src;
- return state.Convert(src, error);
+ Error error;
+ auto result = state.Convert(src, error);
+ if (result.IsNull())
+ throw std::runtime_error(error.GetMessage());
+
+ return result;
}
const struct filter_plugin convert_filter_plugin = {
@@ -133,23 +141,17 @@ const struct filter_plugin convert_filter_plugin = {
Filter *
convert_filter_new(const AudioFormat in_audio_format,
- const AudioFormat out_audio_format,
- Error &error)
+ const AudioFormat out_audio_format)
{
- auto *filter = new ConvertFilter(in_audio_format);
- if (!filter->Set(out_audio_format, error)) {
- delete filter;
- return nullptr;
- }
-
- return filter;
+ std::unique_ptr<ConvertFilter> filter(new ConvertFilter(in_audio_format));
+ filter->Set(out_audio_format);
+ return filter.release();
}
-bool
-convert_filter_set(Filter *_filter, AudioFormat out_audio_format,
- Error &error)
+void
+convert_filter_set(Filter *_filter, AudioFormat out_audio_format)
{
ConvertFilter *filter = (ConvertFilter *)_filter;
- return filter->Set(out_audio_format, error);
+ filter->Set(out_audio_format);
}
diff --git a/src/filter/plugins/ConvertFilterPlugin.hxx b/src/filter/plugins/ConvertFilterPlugin.hxx
index 6bdd5ef1b..9d7890574 100644
--- a/src/filter/plugins/ConvertFilterPlugin.hxx
+++ b/src/filter/plugins/ConvertFilterPlugin.hxx
@@ -26,17 +26,17 @@ struct AudioFormat;
Filter *
convert_filter_new(AudioFormat in_audio_format,
- AudioFormat out_audio_format,
- Error &error);
+ AudioFormat out_audio_format);
/**
* Sets the output audio format for the specified filter. You must
* call this after the filter has been opened. Since this audio
* format switch is a violation of the filter API, this filter must be
* the last in a chain.
+ *
+ * Throws std::runtime_error on error.
*/
-bool
-convert_filter_set(Filter *filter, AudioFormat out_audio_format,
- Error &error);
+void
+convert_filter_set(Filter *filter, AudioFormat out_audio_format);
#endif
diff --git a/src/filter/plugins/NormalizeFilterPlugin.cxx b/src/filter/plugins/NormalizeFilterPlugin.cxx
index e83b6553d..4211b8ced 100644
--- a/src/filter/plugins/NormalizeFilterPlugin.cxx
+++ b/src/filter/plugins/NormalizeFilterPlugin.cxx
@@ -43,14 +43,13 @@ public:
}
/* virtual methods from class Filter */
- ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override;
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
};
class PreparedNormalizeFilter final : public PreparedFilter {
public:
/* virtual methods from class PreparedFilter */
- Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
static PreparedFilter *
@@ -61,7 +60,7 @@ normalize_filter_init(gcc_unused const ConfigBlock &block,
}
Filter *
-PreparedNormalizeFilter::Open(AudioFormat &audio_format, gcc_unused Error &error)
+PreparedNormalizeFilter::Open(AudioFormat &audio_format)
{
audio_format.format = SampleFormat::S16;
@@ -69,7 +68,7 @@ PreparedNormalizeFilter::Open(AudioFormat &audio_format, gcc_unused Error &error
}
ConstBuffer<void>
-NormalizeFilter::FilterPCM(ConstBuffer<void> src, gcc_unused Error &error)
+NormalizeFilter::FilterPCM(ConstBuffer<void> src)
{
int16_t *dest = (int16_t *)buffer.Get(src.size);
memcpy(dest, src.data, src.size);
diff --git a/src/filter/plugins/NullFilterPlugin.cxx b/src/filter/plugins/NullFilterPlugin.cxx
index fc43bb7d1..47a7bb555 100644
--- a/src/filter/plugins/NullFilterPlugin.cxx
+++ b/src/filter/plugins/NullFilterPlugin.cxx
@@ -36,16 +36,14 @@ class NullFilter final : public Filter {
public:
explicit NullFilter(const AudioFormat &af):Filter(af) {}
- virtual ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- gcc_unused Error &error) override {
+ virtual ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override {
return src;
}
};
class PreparedNullFilter final : public PreparedFilter {
public:
- virtual Filter *Open(AudioFormat &af,
- gcc_unused Error &error) override {
+ virtual Filter *Open(AudioFormat &af) override {
return new NullFilter(af);
}
};
diff --git a/src/filter/plugins/ReplayGainFilterPlugin.cxx b/src/filter/plugins/ReplayGainFilterPlugin.cxx
index 49b7674c4..1c36a17c7 100644
--- a/src/filter/plugins/ReplayGainFilterPlugin.cxx
+++ b/src/filter/plugins/ReplayGainFilterPlugin.cxx
@@ -32,6 +32,8 @@
#include "util/Domain.hxx"
#include "Log.hxx"
+#include <stdexcept>
+
#include <assert.h>
static constexpr Domain replay_gain_domain("replay_gain");
@@ -73,10 +75,10 @@ public:
:Filter(audio_format),
mixer(_mixer), base(_base), mode(REPLAY_GAIN_OFF) {
info.Clear();
- }
- bool Open(Error &error) {
- return pv.Open(out_audio_format.format, error);
+ Error error;
+ if (!pv.Open(out_audio_format.format, error))
+ throw std::runtime_error(error.GetMessage());
}
void SetInfo(const ReplayGainInfo *_info) {
@@ -108,8 +110,7 @@ public:
void Update();
/* virtual methods from class Filter */
- ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override;
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
};
class PreparedReplayGainFilter final : public PreparedFilter {
@@ -134,7 +135,7 @@ public:
}
/* virtual methods from class Filter */
- Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
void
@@ -174,19 +175,13 @@ replay_gain_filter_init(gcc_unused const ConfigBlock &block,
}
Filter *
-PreparedReplayGainFilter::Open(AudioFormat &af, gcc_unused Error &error)
+PreparedReplayGainFilter::Open(AudioFormat &af)
{
- auto *filter = new ReplayGainFilter(af, mixer, base);
- if (!filter->Open(error)) {
- delete filter;
- return nullptr;
- }
-
- return filter;
+ return new ReplayGainFilter(af, mixer, base);
}
ConstBuffer<void>
-ReplayGainFilter::FilterPCM(ConstBuffer<void> src, gcc_unused Error &error)
+ReplayGainFilter::FilterPCM(ConstBuffer<void> src)
{
return mixer != nullptr
? src
diff --git a/src/filter/plugins/RouteFilterPlugin.cxx b/src/filter/plugins/RouteFilterPlugin.cxx
index b04362c90..f08bf84bc 100644
--- a/src/filter/plugins/RouteFilterPlugin.cxx
+++ b/src/filter/plugins/RouteFilterPlugin.cxx
@@ -96,8 +96,7 @@ public:
const std::array<int8_t, MAX_CHANNELS> &_sources);
/* virtual methods from class Filter */
- ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override;
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
};
class PreparedRouteFilter final : public PreparedFilter {
@@ -136,7 +135,7 @@ public:
bool Configure(const ConfigBlock &block, Error &error);
/* virtual methods from class PreparedFilter */
- Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
bool
@@ -243,13 +242,13 @@ RouteFilter::RouteFilter(const AudioFormat &audio_format,
}
Filter *
-PreparedRouteFilter::Open(AudioFormat &audio_format, gcc_unused Error &error)
+PreparedRouteFilter::Open(AudioFormat &audio_format)
{
return new RouteFilter(audio_format, min_output_channels, sources);
}
ConstBuffer<void>
-RouteFilter::FilterPCM(ConstBuffer<void> src, gcc_unused Error &error)
+RouteFilter::FilterPCM(ConstBuffer<void> src)
{
size_t number_of_frames = src.size / input_frame_size;
diff --git a/src/filter/plugins/VolumeFilterPlugin.cxx b/src/filter/plugins/VolumeFilterPlugin.cxx
index 7e7fa2a4a..530839030 100644
--- a/src/filter/plugins/VolumeFilterPlugin.cxx
+++ b/src/filter/plugins/VolumeFilterPlugin.cxx
@@ -25,16 +25,19 @@
#include "pcm/Volume.hxx"
#include "AudioFormat.hxx"
#include "util/ConstBuffer.hxx"
+#include "util/Error.hxx"
+
+#include <stdexcept>
class VolumeFilter final : public Filter {
PcmVolume pv;
public:
explicit VolumeFilter(const AudioFormat &audio_format)
- :Filter(audio_format) {}
-
- bool Open(Error &error) {
- return pv.Open(out_audio_format.format, error);
+ :Filter(audio_format) {
+ Error error;
+ if (!pv.Open(out_audio_format.format, error))
+ throw std::runtime_error(error.GetMessage());
}
unsigned GetVolume() const {
@@ -46,8 +49,7 @@ public:
}
/* virtual methods from class Filter */
- ConstBuffer<void> FilterPCM(ConstBuffer<void> src,
- Error &error) override;
+ ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
};
class PreparedVolumeFilter final : public PreparedFilter {
@@ -55,7 +57,7 @@ class PreparedVolumeFilter final : public PreparedFilter {
public:
/* virtual methods from class Filter */
- Filter *Open(AudioFormat &af, Error &error) override;
+ Filter *Open(AudioFormat &af) override;
};
static PreparedFilter *
@@ -66,19 +68,13 @@ volume_filter_init(gcc_unused const ConfigBlock &block,
}
Filter *
-PreparedVolumeFilter::Open(AudioFormat &audio_format, Error &error)
+PreparedVolumeFilter::Open(AudioFormat &audio_format)
{
- auto *filter = new VolumeFilter(audio_format);
- if (!filter->Open(error)) {
- delete filter;
- return nullptr;
- }
-
- return filter;
+ return new VolumeFilter(audio_format);
}
ConstBuffer<void>
-VolumeFilter::FilterPCM(ConstBuffer<void> src, gcc_unused Error &error)
+VolumeFilter::FilterPCM(ConstBuffer<void> src)
{
return pv.Apply(src);
}
diff --git a/src/output/Internal.hxx b/src/output/Internal.hxx
index d0a8b3440..d9958f03f 100644
--- a/src/output/Internal.hxx
+++ b/src/output/Internal.hxx
@@ -404,7 +404,10 @@ private:
*/
void CloseOutput(bool drain);
- AudioFormat OpenFilter(AudioFormat &format, Error &error_r);
+ /**
+ * Throws std::runtime_error on error.
+ */
+ AudioFormat OpenFilter(AudioFormat &format);
/**
* Mutex must not be locked.
diff --git a/src/output/OutputThread.cxx b/src/output/OutputThread.cxx
index 6950f7a21..24819feb8 100644
--- a/src/output/OutputThread.cxx
+++ b/src/output/OutputThread.cxx
@@ -93,38 +93,28 @@ AudioOutput::Disable()
}
inline AudioFormat
-AudioOutput::OpenFilter(AudioFormat &format, Error &error_r)
-{
+AudioOutput::OpenFilter(AudioFormat &format)
+try {
assert(format.IsValid());
/* the replay_gain filter cannot fail here */
- if (prepared_replay_gain_filter != nullptr) {
+ if (prepared_replay_gain_filter != nullptr)
replay_gain_filter_instance =
- prepared_replay_gain_filter->Open(format, error_r);
- if (replay_gain_filter_instance == nullptr)
- return AudioFormat::Undefined();
- }
+ prepared_replay_gain_filter->Open(format);
- if (prepared_other_replay_gain_filter != nullptr) {
+ if (prepared_other_replay_gain_filter != nullptr)
other_replay_gain_filter_instance =
- prepared_other_replay_gain_filter->Open(format, error_r);
- if (other_replay_gain_filter_instance == nullptr) {
- delete replay_gain_filter_instance;
- return AudioFormat::Undefined();
- }
- }
+ prepared_other_replay_gain_filter->Open(format);
- filter_instance = prepared_filter->Open(format, error_r);
- if (filter_instance == nullptr) {
- delete other_replay_gain_filter_instance;
- delete replay_gain_filter_instance;
- return AudioFormat::Undefined();
- }
+ filter_instance = prepared_filter->Open(format);
if (mixer != nullptr && mixer->IsPlugin(software_mixer_plugin))
software_mixer_set_filter(*mixer, volume_filter.Get());
return filter_instance->GetOutAudioFormat();
+} catch (...) {
+ CloseFilter();
+ throw;
}
void
@@ -165,10 +155,11 @@ AudioOutput::Open()
/* open the filter */
- const AudioFormat filter_audio_format =
- OpenFilter(in_audio_format, error);
- if (!filter_audio_format.IsDefined()) {
- FormatError(error, "Failed to open filter for \"%s\" [%s]",
+ 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();
@@ -202,9 +193,10 @@ AudioOutput::Open()
return;
}
- if (!convert_filter_set(convert_filter.Get(), out_audio_format,
- error)) {
- FormatError(error, "Failed to convert for \"%s\" [%s]",
+ try {
+ convert_filter_set(convert_filter.Get(), out_audio_format);
+ } catch (const std::runtime_error &e) {
+ FormatError(e, "Failed to convert for \"%s\" [%s]",
name, plugin.name);
mutex.unlock();
@@ -295,12 +287,12 @@ AudioOutput::ReopenFilter()
CloseFilter();
mutex.lock();
- const AudioFormat filter_audio_format =
- OpenFilter(in_audio_format, error);
- if (!filter_audio_format.IsDefined() ||
- !convert_filter_set(convert_filter.Get(), out_audio_format,
- error)) {
- FormatError(error,
+ AudioFormat filter_audio_format;
+ try {
+ filter_audio_format = OpenFilter(in_audio_format);
+ convert_filter_set(convert_filter.Get(), out_audio_format);
+ } catch (const std::runtime_error &e) {
+ FormatError(e,
"Failed to open filter for \"%s\" [%s]",
name, plugin.name);
@@ -383,11 +375,13 @@ ao_chunk_data(AudioOutput *ao, const MusicChunk *chunk,
*replay_gain_serial_p = chunk->replay_gain_serial;
}
- Error error;
- data = replay_gain_filter->FilterPCM(data, error);
- if (data.IsNull())
- FormatError(error, "\"%s\" [%s] failed to filter",
+ try {
+ data = replay_gain_filter->FilterPCM(data);
+ } catch (const std::runtime_error &e) {
+ FormatError(e, "\"%s\" [%s] failed to filter",
ao->name, ao->plugin.name);
+ return nullptr;
+ }
}
return data;
@@ -449,15 +443,13 @@ ao_filter_chunk(AudioOutput *ao, const MusicChunk *chunk)
/* apply filter chain */
- Error error;
- data = ao->filter_instance->FilterPCM(data, error);
- if (data.IsNull()) {
- FormatError(error, "\"%s\" [%s] failed to filter",
+ try {
+ return ao->filter_instance->FilterPCM(data);
+ } catch (const std::runtime_error &e) {
+ FormatError(e, "\"%s\" [%s] failed to filter",
ao->name, ao->plugin.name);
return nullptr;
}
-
- return data;
}
inline bool
diff --git a/test/run_filter.cxx b/test/run_filter.cxx
index 0fa414e39..58f235956 100644
--- a/test/run_filter.cxx
+++ b/test/run_filter.cxx
@@ -105,13 +105,7 @@ try {
/* open the filter */
- Error error;
- std::unique_ptr<Filter> filter(prepared_filter->Open(audio_format,
- error));
- if (!filter) {
- LogError(error, "Failed to open filter");
- return EXIT_FAILURE;
- }
+ std::unique_ptr<Filter> filter(prepared_filter->Open(audio_format));
const AudioFormat out_audio_format = filter->GetOutAudioFormat();
@@ -127,12 +121,7 @@ try {
if (nbytes <= 0)
break;
- auto dest = filter->FilterPCM({(const void *)buffer, (size_t)nbytes},
- error);
- if (dest.IsNull()) {
- LogError(error, "filter/Filter failed");
- return EXIT_FAILURE;
- }
+ auto dest = filter->FilterPCM({(const void *)buffer, (size_t)nbytes});
nbytes = write(1, dest.data, dest.size);
if (nbytes < 0) {
@@ -147,7 +136,7 @@ try {
config_global_finish();
return EXIT_SUCCESS;
- } catch (const std::exception &e) {
+} catch (const std::exception &e) {
LogError(e);
return EXIT_FAILURE;
- }
+}