[FFmpeg-devel] [PATCH] lavfi/aevalsrc: duplicate last expression for the missing channels if channel layout was specified

Stefano Sabatini stefasab at gmail.com
Thu Dec 5 19:03:50 CET 2013


Extend syntax.
---
 doc/filters.texi            |  3 ++-
 libavfilter/asrc_aevalsrc.c | 32 +++++++++++++++++++++-----------
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 0804bb4..2a2fd50 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 6b1eba0..2c8070b 100644
--- a/libavfilter/asrc_aevalsrc.c
+++ b/libavfilter/asrc_aevalsrc.c
@@ -84,7 +84,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,21 +94,31 @@ static av_cold int init(AVFilterContext *ctx)
     }
 
     /* parse expressions */
+#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)
+
     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;
+        last_expr = expr;
+        ADD_EXPRESSION(expr);
     }
 
     if (eval->chlayout) {
-        int n = av_get_channel_layout_nb_channels(eval->chlayout);
+        int i, 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 channel expressions '%d' "
-- 
1.8.1.2



More information about the ffmpeg-devel mailing list