diff options
author | Max Kellermann <max@duempel.org> | 2009-12-25 14:27:32 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-12-25 17:29:41 +0100 |
commit | b54bde6f2b9f826cd7189182d733aada66c95dd8 (patch) | |
tree | f07f7b57f0d83879e6aa35ba3bbdaa06b4cbf4f1 /src/filter/chain_filter_plugin.c | |
parent | d2051c7f50deff0532566c070aaf4fec5d774558 (diff) | |
download | mpd-b54bde6f2b9f826cd7189182d733aada66c95dd8.tar.gz mpd-b54bde6f2b9f826cd7189182d733aada66c95dd8.tar.xz mpd-b54bde6f2b9f826cd7189182d733aada66c95dd8.zip |
filter_plugin: allow open() to force an input format
Make the audio_format argument non-const. Allow the open() method to
modify it, to indicate that it wants a different input audio format
than the one specified. Check that condition in chain_filter_open(),
and fail.
Diffstat (limited to 'src/filter/chain_filter_plugin.c')
-rw-r--r-- | src/filter/chain_filter_plugin.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/filter/chain_filter_plugin.c b/src/filter/chain_filter_plugin.c index edfa70f35..56fa3a5e1 100644 --- a/src/filter/chain_filter_plugin.c +++ b/src/filter/chain_filter_plugin.c @@ -23,6 +23,7 @@ #include "filter_plugin.h" #include "filter_internal.h" #include "filter_registry.h" +#include "audio_format.h" #include <assert.h> @@ -33,6 +34,12 @@ struct filter_chain { GSList *children; }; +static inline GQuark +filter_quark(void) +{ + return g_quark_from_static_string("filter"); +} + static struct filter * chain_filter_init(G_GNUC_UNUSED const struct config_param *param, G_GNUC_UNUSED GError **error_r) @@ -92,16 +99,42 @@ chain_close_until(struct filter_chain *chain, const struct filter *until) } static const struct audio_format * -chain_filter_open(struct filter *_filter, - const struct audio_format *audio_format, +chain_open_child(struct filter *filter, + const struct audio_format *prev_audio_format, + GError **error_r) +{ + struct audio_format conv_audio_format = *prev_audio_format; + const struct audio_format *next_audio_format; + + next_audio_format = filter_open(filter, &conv_audio_format, error_r); + if (next_audio_format == NULL) + return NULL; + + if (!audio_format_equals(&conv_audio_format, prev_audio_format)) { + struct audio_format_string s; + + filter_close(filter); + g_set_error(error_r, filter_quark(), 0, + "Audio format not supported by filter '%s': %s", + filter->plugin->name, + audio_format_to_string(prev_audio_format, &s)); + return NULL; + } + + return next_audio_format; +} + +static const struct audio_format * +chain_filter_open(struct filter *_filter, struct audio_format *in_audio_format, GError **error_r) { struct filter_chain *chain = (struct filter_chain *)_filter; + const struct audio_format *audio_format = in_audio_format; for (GSList *i = chain->children; i != NULL; i = g_slist_next(i)) { struct filter *filter = i->data; - audio_format = filter_open(filter, audio_format, error_r); + audio_format = chain_open_child(filter, audio_format, error_r); if (audio_format == NULL) { /* rollback, close all children */ chain_close_until(chain, filter); |