#include "libavutil/avstring.h"
#include "libavutil/eval.h"
#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
#include "avfilter.h"
#include "internal.h"
-static const char *var_names[] = {
+static const char * const var_names[] = {
"n", ///< number of frame
"t", ///< timestamp expressed in seconds
"s", ///< sample rate
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;
{ "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},
};
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:
av_expr_free(eval->expr[i]);
eval->expr[i] = NULL;
}
+ av_freep(&eval->duration_str);
av_freep(&eval->sample_rate_str);
}
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;
}
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);
.uninit = uninit,
.priv_size = sizeof(EvalContext),
- .inputs = (AVFilterPad[]) {{ .name = NULL}},
+ .inputs = (const AVFilterPad[]) {{ .name = NULL}},
- .outputs = (AVFilterPad[]) {{ .name = "default",
+ .outputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_AUDIO,
.config_props = config_props,
.request_frame = request_frame, },