| ... | ... |
@@ -405,6 +405,16 @@ The description of the accepted options follows. |
| 405 | 405 |
|
| 406 | 406 |
@table @option |
| 407 | 407 |
|
| 408 |
+@item duration, d |
|
| 409 |
+Set the minimum duration of the sourced audio. See the function |
|
| 410 |
+@code{av_parse_time()} for the accepted format.
|
|
| 411 |
+Note that the resulting duration may be greater than the specified |
|
| 412 |
+duration, as the generated audio is always cut at the end of a |
|
| 413 |
+complete frame. |
|
| 414 |
+ |
|
| 415 |
+If not specified, or the expressed duration is negative, the audio is |
|
| 416 |
+supposed to be generated forever. |
|
| 417 |
+ |
|
| 408 | 418 |
@item nb_samples, n |
| 409 | 419 |
Set the number of samples per channel per each output frame, |
| 410 | 420 |
default to 1024. |
| ... | ... |
@@ -28,6 +28,7 @@ |
| 28 | 28 |
#include "libavutil/avstring.h" |
| 29 | 29 |
#include "libavutil/eval.h" |
| 30 | 30 |
#include "libavutil/opt.h" |
| 31 |
+#include "libavutil/parseutils.h" |
|
| 31 | 32 |
#include "avfilter.h" |
| 32 | 33 |
#include "internal.h" |
| 33 | 34 |
|
| ... | ... |
@@ -55,6 +56,8 @@ typedef struct {
|
| 55 | 55 |
AVExpr *expr[8]; |
| 56 | 56 |
char *expr_str[8]; |
| 57 | 57 |
int nb_samples; ///< number of samples per requested frame |
| 58 |
+ char *duration_str; ///< total duration of the generated audio |
|
| 59 |
+ double duration; |
|
| 58 | 60 |
uint64_t n; |
| 59 | 61 |
double var_values[VAR_VARS_NB]; |
| 60 | 62 |
} EvalContext; |
| ... | ... |
@@ -66,6 +69,8 @@ static const AVOption eval_options[]= {
|
| 66 | 66 |
{ "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.dbl = 1024}, 0, INT_MAX },
|
| 67 | 67 |
{ "sample_rate", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX },
|
| 68 | 68 |
{ "s", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX },
|
| 69 |
+ { "duration", "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
|
|
| 70 |
+ { "d", "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
|
|
| 69 | 71 |
{NULL},
|
| 70 | 72 |
}; |
| 71 | 73 |
|
| ... | ... |
@@ -127,6 +132,16 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 127 | 127 |
|
| 128 | 128 |
if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx))) |
| 129 | 129 |
goto end; |
| 130 |
+ |
|
| 131 |
+ eval->duration = -1; |
|
| 132 |
+ if (eval->duration_str) {
|
|
| 133 |
+ int64_t us = -1; |
|
| 134 |
+ if ((ret = av_parse_time(&us, eval->duration_str, 1)) < 0) {
|
|
| 135 |
+ av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", eval->duration_str); |
|
| 136 |
+ goto end; |
|
| 137 |
+ } |
|
| 138 |
+ eval->duration = (double)us / 1000000; |
|
| 139 |
+ } |
|
| 130 | 140 |
eval->n = 0; |
| 131 | 141 |
|
| 132 | 142 |
end: |
| ... | ... |
@@ -143,6 +158,7 @@ static void uninit(AVFilterContext *ctx) |
| 143 | 143 |
av_expr_free(eval->expr[i]); |
| 144 | 144 |
eval->expr[i] = NULL; |
| 145 | 145 |
} |
| 146 |
+ av_freep(&eval->duration_str); |
|
| 146 | 147 |
av_freep(&eval->sample_rate_str); |
| 147 | 148 |
} |
| 148 | 149 |
|
| ... | ... |
@@ -159,7 +175,8 @@ static int config_props(AVFilterLink *outlink) |
| 159 | 159 |
av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout); |
| 160 | 160 |
|
| 161 | 161 |
av_log(outlink->src, AV_LOG_INFO, |
| 162 |
- "sample_rate:%d chlayout:%s\n", eval->sample_rate, buf); |
|
| 162 |
+ "sample_rate:%d chlayout:%s duration:%f\n", |
|
| 163 |
+ eval->sample_rate, buf, eval->duration); |
|
| 163 | 164 |
|
| 164 | 165 |
return 0; |
| 165 | 166 |
} |
| ... | ... |
@@ -183,6 +200,10 @@ static int request_frame(AVFilterLink *outlink) |
| 183 | 183 |
EvalContext *eval = outlink->src->priv; |
| 184 | 184 |
AVFilterBufferRef *samplesref; |
| 185 | 185 |
int i, j; |
| 186 |
+ double t = eval->var_values[VAR_N] * (double)1/eval->sample_rate; |
|
| 187 |
+ |
|
| 188 |
+ if (eval->duration >= 0 && t > eval->duration) |
|
| 189 |
+ return AVERROR_EOF; |
|
| 186 | 190 |
|
| 187 | 191 |
samplesref = avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, eval->nb_samples); |
| 188 | 192 |
|
| ... | ... |
@@ -30,7 +30,7 @@ |
| 30 | 30 |
|
| 31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 2 |
| 32 | 32 |
#define LIBAVFILTER_VERSION_MINOR 50 |
| 33 |
-#define LIBAVFILTER_VERSION_MICRO 0 |
|
| 33 |
+#define LIBAVFILTER_VERSION_MICRO 1 |
|
| 34 | 34 |
|
| 35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
| 36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |