[FFmpeg-devel] [PATCH] aevalsrc: add duration option

Stefano Sabatini stefasab at gmail.com
Sat Dec 3 00:43:26 CET 2011


---
 doc/filters.texi            |   10 ++++++++++
 libavfilter/asrc_aevalsrc.c |   23 ++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 2885f21..edc21af 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -472,6 +472,16 @@ The description of the accepted options follows.
 
 @table @option
 
+ at item duration, d
+Set the minimum duration of the sourced audio. See the function
+ at code{av_parse_time()} for the accepted format.
+Note that the resulting duration may be greater than the specified
+duration, as the generated audio is always cut at the end of a
+complete frame.
+
+If not specified, or the expressed duration is negative, the audio is
+supposed to be generated forever.
+
 @item nb_samples, n
 Set the number of samples per channel per each output frame,
 default to 1024.
diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c
index 6e91dd1..7bd6a89 100644
--- a/libavfilter/asrc_aevalsrc.c
+++ b/libavfilter/asrc_aevalsrc.c
@@ -28,6 +28,7 @@
 #include "libavutil/avstring.h"
 #include "libavutil/eval.h"
 #include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
 #include "avfilter.h"
 #include "internal.h"
 
@@ -55,6 +56,8 @@ typedef struct {
     AVExpr *expr[8];
     char *expr_str[8];
     int nb_samples;             ///< number of samples per requested frame
+    char *duration_str;         ///< total duration of the generated audio
+    double duration;
     uint64_t n;
     double var_values[VAR_VARS_NB];
 } EvalContext;
@@ -66,6 +69,8 @@ static const AVOption eval_options[]= {
     { "n",           "set the number of samples per requested frame", OFFSET(nb_samples),      AV_OPT_TYPE_INT,    {.dbl = 1024},    0,        INT_MAX },
     { "sample_rate", "set the sample rate",                           OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX },
     { "s",           "set the sample rate",                           OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX },
+    { "duration",    "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
+    { "d",           "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
 {NULL},
 };
 
@@ -127,6 +132,16 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
 
     if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx)))
         goto end;
+
+    eval->duration = -1;
+    if (eval->duration_str) {
+        int64_t us = -1;
+        if ((ret = av_parse_time(&us, eval->duration_str, 1)) < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", eval->duration_str);
+            goto end;
+        }
+        eval->duration = (double)us / 1000000;
+    }
     eval->n = 0;
 
 end:
@@ -143,6 +158,7 @@ static void uninit(AVFilterContext *ctx)
         av_expr_free(eval->expr[i]);
         eval->expr[i] = NULL;
     }
+    av_freep(&eval->duration_str);
     av_freep(&eval->sample_rate_str);
 }
 
@@ -159,7 +175,8 @@ static int config_props(AVFilterLink *outlink)
     av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout);
 
     av_log(outlink->src, AV_LOG_INFO,
-           "sample_rate:%d chlayout:%s\n", eval->sample_rate, buf);
+           "sample_rate:%d chlayout:%s duration:%f\n",
+           eval->sample_rate, buf, eval->duration);
 
     return 0;
 }
@@ -183,6 +200,10 @@ static int request_frame(AVFilterLink *outlink)
     EvalContext *eval = outlink->src->priv;
     AVFilterBufferRef *samplesref;
     int i, j;
+    double t = eval->var_values[VAR_N] * (double)1/eval->sample_rate;
+
+    if (eval->duration >= 0 && t > eval->duration)
+        return AVERROR_EOF;
 
     samplesref = avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, eval->nb_samples);
 
-- 
1.7.5.4



More information about the ffmpeg-devel mailing list