aboutsummaryrefslogtreecommitdiffstats
path: root/src/filter
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-11-11 16:15:38 +0100
committerMax Kellermann <max@duempel.org>2013-11-13 21:06:33 +0100
commitd2679f59c5a6c8df7a2140d40ab65a17b8e5c023 (patch)
tree803edccbb6c7d383199eba5f91a8610ee3c63c96 /src/filter
parent4ee147ea34057c0bcef31afed55f98b025b997dc (diff)
downloadmpd-d2679f59c5a6c8df7a2140d40ab65a17b8e5c023.tar.gz
mpd-d2679f59c5a6c8df7a2140d40ab65a17b8e5c023.tar.xz
mpd-d2679f59c5a6c8df7a2140d40ab65a17b8e5c023.zip
PcmConvert: add methods Open(), Close()
Replaces Reset() and eliminates the AudioFormat parameters from the Convert() method.
Diffstat (limited to 'src/filter')
-rw-r--r--src/filter/AutoConvertFilterPlugin.cxx6
-rw-r--r--src/filter/ConvertFilterPlugin.cxx65
-rw-r--r--src/filter/ConvertFilterPlugin.hxx6
3 files changed, 57 insertions, 20 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..416b6e81a 100644
--- a/src/filter/ConvertFilterPlugin.cxx
+++ b/src/filter/ConvertFilterPlugin.cxx
@@ -39,21 +39,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 +66,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 +108,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 +123,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 +140,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