From 48f94311516dc1426644b3e68b2a48c22727e1e7 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 12 May 2013 21:34:44 +0200 Subject: [PATCH] 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. --- audio/filter/af.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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, talloc_free(info); } +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