From b54bde6f2b9f826cd7189182d733aada66c95dd8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 25 Dec 2009 14:27:32 +0100 Subject: 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. --- src/filter/chain_filter_plugin.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'src/filter/chain_filter_plugin.c') 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 @@ -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); -- cgit v1.2.3