diff options
authorwm4 <wm4@nowhere>2013-05-12 21:34:44 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:45:05 +0200
commit48f94311516dc1426644b3e68b2a48c22727e1e7 (patch)
parent9dd9ccbd8d79a7dccd93be0a1e26028ca1d89d42 (diff)
af: improve filter chain setup retry limit
af_reinit() is responsible for inserting automatic conversion filters for channel remixing, format conversion, and resampling. We don't require that a single filter can do all these (even though af_lavrresample does nearly all of this, sometimes af_format has to be used instead for format conversions). This makes setting up the chain more complicated, and a way is needed to prevent endless appending of conversion filters if a conversion is not possible. Until now, this used a stupidly simple yet robust static retry limit to detect failure. This is perfectly fine, and the limit (20) was good enough to handle about ~5 filters. But with more filters, and if each filter requires 3 additional conversion filters, this would fail. So raise the limit to 4 retries per filter. This is still stupidly simple and robust, but won't arbitrarily fail if the filter count is too large.
1 files changed, 10 insertions, 1 deletions
diff --git a/audio/filter/af.c b/audio/filter/af.c
index 77df3e443b..137e7cc407 100644
--- a/audio/filter/af.c
+++ b/audio/filter/af.c
@@ -329,6 +329,14 @@ static void af_print_filter_chain(struct af_stream *s, struct af_instance *at,
+static int af_count_filters(struct af_stream *s)
+ int count = 0;
+ for (struct af_instance *af = s->first; af; af = af->next)
+ count++;
+ return count;
static const char *af_find_conversion_filter(int srcfmt, int dstfmt)
for (int n = 0; filter_list[n]; n++) {
@@ -438,9 +446,10 @@ int af_reinit(struct af_stream *s)
// Start with the second filter, as the first filter is the special input
// filter which needs no initialization.
struct af_instance *af = s->first->next;
+ int max_retry = af_count_filters(s) * 4; // up to 4 retries per filter
int retry = 0;
while (af) {
- if (retry >= 20)
+ if (retry >= max_retry)
goto negotiate_error;
// Check if this is the first filter