diff --git a/doc/filters.texi b/doc/filters.texi index 8329bf0c07..76394de375 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1896,7 +1896,8 @@ This source accepts the following options: @item exprs Set the '|'-separated expressions list for each separate channel. In case the @option{channel_layout} option is not specified, the selected channel layout -depends on the number of provided expressions. +depends on the number of provided expressions. Otherwise the last +specified expression is applied to the remaining output channels. @item channel_layout, c Set the channel layout. The number of channels in the specified layout diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c index 41ad632145..9bf9675363 100644 --- a/libavfilter/asrc_aevalsrc.c +++ b/libavfilter/asrc_aevalsrc.c @@ -85,7 +85,7 @@ static av_cold int init(AVFilterContext *ctx) { EvalContext *eval = ctx->priv; char *args1 = av_strdup(eval->exprs); - char *expr, *buf; + char *expr, *last_expr, *buf; int ret; if (!args1) { @@ -94,27 +94,39 @@ static av_cold int init(AVFilterContext *ctx) goto end; } +#define ADD_EXPRESSION(expr_) do { \ + if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, \ + sizeof(*eval->expr), NULL)) { \ + ret = AVERROR(ENOMEM); \ + goto end; \ + } \ + eval->expr[eval->nb_channels-1] = NULL; \ + ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr_, \ + var_names, NULL, NULL, \ + NULL, NULL, 0, ctx); \ + if (ret < 0) \ + goto end; \ + } while (0) + /* parse expressions */ buf = args1; while (expr = av_strtok(buf, "|", &buf)) { - if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, sizeof(*eval->expr), NULL)) { - ret = AVERROR(ENOMEM); - goto end; - } - eval->expr[eval->nb_channels-1] = NULL; - ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr, var_names, - NULL, NULL, NULL, NULL, 0, ctx); - if (ret < 0) - goto end; + ADD_EXPRESSION(expr); + last_expr = expr; } if (eval->chlayout_str) { - int n; + int i, n; ret = ff_parse_channel_layout(&eval->chlayout, NULL, eval->chlayout_str, ctx); if (ret < 0) goto end; n = av_get_channel_layout_nb_channels(eval->chlayout); + if (n > eval->nb_channels) { + for (i = eval->nb_channels; i < n; i++) + ADD_EXPRESSION(last_expr); + } + if (n != eval->nb_channels) { av_log(ctx, AV_LOG_ERROR, "Mismatch between the specified number of channels '%d' " diff --git a/libavfilter/version.h b/libavfilter/version.h index bbc1208eaf..17c656362e 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MINOR 91 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \