aboutsummaryrefslogtreecommitdiffstats
path: root/src/filter
diff options
context:
space:
mode:
Diffstat (limited to 'src/filter')
-rw-r--r--src/filter/AutoConvertFilterPlugin.cxx6
-rw-r--r--src/filter/ConvertFilterPlugin.cxx66
-rw-r--r--src/filter/ConvertFilterPlugin.hxx6
-rw-r--r--src/filter/NormalizeFilterPlugin.cxx1
-rw-r--r--src/filter/RouteFilterPlugin.cxx1
5 files changed, 57 insertions, 23 deletions
diff --git a/src/filter/AutoConvertFilterPlugin.cxx b/src/filter/AutoConvertFilterPlugin.cxx
index 918a16e53..44adc8a66 100644
--- a/src/filter/AutoConvertFilterPlugin.cxx
+++ b/src/filter/AutoConvertFilterPlugin.cxx
@@ -88,7 +88,11 @@ AutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error)
assert(audio_format2 == in_audio_format);
- convert_filter_set(convert, child_audio_format);
+ if (!convert_filter_set(convert, child_audio_format, error)) {
+ delete convert;
+ filter->Close();
+ return AudioFormat::Undefined();
+ }
} else
/* no */
convert = nullptr;
diff --git a/src/filter/ConvertFilterPlugin.cxx b/src/filter/ConvertFilterPlugin.cxx
index 040f8426f..e718844e7 100644
--- a/src/filter/ConvertFilterPlugin.cxx
+++ b/src/filter/ConvertFilterPlugin.cxx
@@ -28,7 +28,6 @@
#include "poison.h"
#include <assert.h>
-#include <string.h>
class ConvertFilter final : public Filter {
/**
@@ -39,21 +38,18 @@ class ConvertFilter final : public Filter {
/**
* The output audio format; the consumer of this plugin
- * expects PCM data in this format. This defaults to
- * #in_audio_format, and can be set with convert_filter_set().
+ * expects PCM data in this format.
+ *
+ * If this is AudioFormat::Undefined(), then the #PcmConvert
+ * attribute is not open. This can mean that Set() has failed
+ * or that no conversion is necessary.
*/
AudioFormat out_audio_format;
Manual<PcmConvert> state;
public:
- void Set(const AudioFormat &_out_audio_format) {
- assert(in_audio_format.IsValid());
- assert(out_audio_format.IsValid());
- assert(_out_audio_format.IsValid());
-
- out_audio_format = _out_audio_format;
- }
+ bool Set(const AudioFormat &_out_audio_format, Error &error);
virtual AudioFormat Open(AudioFormat &af, Error &error) override;
virtual void Close() override;
@@ -69,12 +65,40 @@ convert_filter_init(gcc_unused const config_param &param,
return new ConvertFilter();
}
+bool
+ConvertFilter::Set(const AudioFormat &_out_audio_format, Error &error)
+{
+ assert(in_audio_format.IsValid());
+ assert(_out_audio_format.IsValid());
+
+ if (_out_audio_format == out_audio_format)
+ /* no change */
+ return true;
+
+ if (out_audio_format.IsValid()) {
+ out_audio_format.Clear();
+ state->Close();
+ }
+
+ if (_out_audio_format == in_audio_format)
+ /* optimized special case: no-op */
+ return true;
+
+ if (!state->Open(in_audio_format, _out_audio_format, error))
+ return false;
+
+ out_audio_format = _out_audio_format;
+ return true;
+}
+
AudioFormat
ConvertFilter::Open(AudioFormat &audio_format, gcc_unused Error &error)
{
assert(audio_format.IsValid());
- in_audio_format = out_audio_format = audio_format;
+ in_audio_format = audio_format;
+ out_audio_format.Clear();
+
state.Construct();
return in_audio_format;
@@ -83,6 +107,11 @@ ConvertFilter::Open(AudioFormat &audio_format, gcc_unused Error &error)
void
ConvertFilter::Close()
{
+ assert(in_audio_format.IsValid());
+
+ if (out_audio_format.IsValid())
+ state->Close();
+
state.Destruct();
poison_undefined(&in_audio_format, sizeof(in_audio_format));
@@ -93,15 +122,15 @@ const void *
ConvertFilter::FilterPCM(const void *src, size_t src_size,
size_t *dest_size_r, Error &error)
{
- if (in_audio_format == out_audio_format) {
+ assert(in_audio_format.IsValid());
+
+ if (!out_audio_format.IsValid()) {
/* optimized special case: no-op */
*dest_size_r = src_size;
return src;
}
- return state->Convert(in_audio_format,
- src, src_size,
- out_audio_format, dest_size_r,
+ return state->Convert(src, src_size, dest_size_r,
error);
}
@@ -110,10 +139,11 @@ const struct filter_plugin convert_filter_plugin = {
convert_filter_init,
};
-void
-convert_filter_set(Filter *_filter, const AudioFormat out_audio_format)
+bool
+convert_filter_set(Filter *_filter, AudioFormat out_audio_format,
+ Error &error)
{
ConvertFilter *filter = (ConvertFilter *)_filter;
- filter->Set(out_audio_format);
+ return filter->Set(out_audio_format, error);
}
diff --git a/src/filter/ConvertFilterPlugin.hxx b/src/filter/ConvertFilterPlugin.hxx
index c814aaf49..f414e59bf 100644
--- a/src/filter/ConvertFilterPlugin.hxx
+++ b/src/filter/ConvertFilterPlugin.hxx
@@ -21,6 +21,7 @@
#define MPD_CONVERT_FILTER_PLUGIN_HXX
class Filter;
+class Error;
struct AudioFormat;
/**
@@ -29,7 +30,8 @@ struct AudioFormat;
* format switch is a violation of the filter API, this filter must be
* the last in a chain.
*/
-void
-convert_filter_set(Filter *filter, AudioFormat out_audio_format);
+bool
+convert_filter_set(Filter *filter, AudioFormat out_audio_format,
+ Error &error);
#endif
diff --git a/src/filter/NormalizeFilterPlugin.cxx b/src/filter/NormalizeFilterPlugin.cxx
index 6c4f6b0e5..93cca9fef 100644
--- a/src/filter/NormalizeFilterPlugin.cxx
+++ b/src/filter/NormalizeFilterPlugin.cxx
@@ -25,7 +25,6 @@
#include "AudioFormat.hxx"
#include "AudioCompress/compress.h"
-#include <assert.h>
#include <string.h>
class NormalizeFilter final : public Filter {
diff --git a/src/filter/RouteFilterPlugin.cxx b/src/filter/RouteFilterPlugin.cxx
index d9042c21f..d2dc2d563 100644
--- a/src/filter/RouteFilterPlugin.cxx
+++ b/src/filter/RouteFilterPlugin.cxx
@@ -43,7 +43,6 @@
#include "ConfigError.hxx"
#include "ConfigData.hxx"
#include "AudioFormat.hxx"
-#include "CheckAudioFormat.hxx"
#include "FilterPlugin.hxx"
#include "FilterInternal.hxx"
#include "FilterRegistry.hxx"