diff options
author | Clément Bœsch <u@pkh.me> | 2015-08-10 21:03:11 +0200 |
---|---|---|
committer | Clément Bœsch <u@pkh.me> | 2015-09-06 15:28:21 +0200 |
commit | a388ca359d78c6fa00c75b326ada11048b1226ba (patch) | |
tree | f7f8db350504ad1bf74cf8f2d20611a4e800d9d8 /libavfilter/asrc_sine.c | |
parent | db18b3d6e6fa83eef862023d4c18bbe1113df075 (diff) | |
download | ffmpeg-a388ca359d78c6fa00c75b326ada11048b1226ba.tar.gz |
avfilter/sine: support expression in the number of output samples
Diffstat (limited to 'libavfilter/asrc_sine.c')
-rw-r--r-- | libavfilter/asrc_sine.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c index 6aa01d5ec5..cd43ae444e 100644 --- a/libavfilter/asrc_sine.c +++ b/libavfilter/asrc_sine.c @@ -22,6 +22,7 @@ #include "libavutil/avassert.h" #include "libavutil/channel_layout.h" +#include "libavutil/eval.h" #include "libavutil/opt.h" #include "audio.h" #include "avfilter.h" @@ -31,7 +32,8 @@ typedef struct { const AVClass *class; double frequency; double beep_factor; - int samples_per_frame; + char *samples_per_frame; + AVExpr *samples_per_frame_expr; int sample_rate; int64_t duration; int16_t *sin; @@ -61,6 +63,9 @@ typedef struct { #define OPT_DUR(name, field, def, min, max, descr, ...) \ OPT_GENERIC(name, field, def, min, max, descr, DURATION, str, __VA_ARGS__) +#define OPT_STR(name, field, def, min, max, descr, ...) \ + OPT_GENERIC(name, field, def, min, max, descr, STRING, str, __VA_ARGS__) + static const AVOption sine_options[] = { OPT_DBL("frequency", frequency, 440, 0, DBL_MAX, "set the sine frequency"), OPT_DBL("f", frequency, 440, 0, DBL_MAX, "set the sine frequency"), @@ -70,7 +75,7 @@ static const AVOption sine_options[] = { OPT_INT("r", sample_rate, 44100, 1, INT_MAX, "set the sample rate"), OPT_DUR("duration", duration, 0, 0, INT64_MAX, "set the audio duration"), OPT_DUR("d", duration, 0, 0, INT64_MAX, "set the audio duration"), - OPT_INT("samples_per_frame", samples_per_frame, 1024, 0, INT_MAX, "set the number of samples per frame"), + OPT_STR("samples_per_frame", samples_per_frame, "1024", 0, 0, "set the number of samples per frame"), {NULL} }; @@ -120,8 +125,25 @@ static void make_sin_table(int16_t *sin) sin[i + 2 * half_pi] = -sin[i]; } +static const char *const var_names[] = { + "n", + "pts", + "t", + "TB", + NULL +}; + +enum { + VAR_N, + VAR_PTS, + VAR_T, + VAR_TB, + VAR_VARS_NB +}; + static av_cold int init(AVFilterContext *ctx) { + int ret; SineContext *sine = ctx->priv; if (!(sine->sin = av_malloc(sizeof(*sine->sin) << LOG_PERIOD))) @@ -136,6 +158,12 @@ static av_cold int init(AVFilterContext *ctx) sine->sample_rate + 0.5; } + ret = av_expr_parse(&sine->samples_per_frame_expr, + sine->samples_per_frame, var_names, + NULL, NULL, NULL, NULL, 0, sine); + if (ret < 0) + return ret; + return 0; } @@ -143,6 +171,8 @@ static av_cold void uninit(AVFilterContext *ctx) { SineContext *sine = ctx->priv; + av_expr_free(sine->samples_per_frame_expr); + sine->samples_per_frame_expr = NULL; av_freep(&sine->sin); } @@ -188,9 +218,21 @@ static int request_frame(AVFilterLink *outlink) { SineContext *sine = outlink->src->priv; AVFrame *frame; - int i, nb_samples = sine->samples_per_frame; + double values[VAR_VARS_NB] = { + [VAR_N] = outlink->frame_count, + [VAR_PTS] = sine->pts, + [VAR_T] = sine->pts * av_q2d(outlink->time_base), + [VAR_TB] = av_q2d(outlink->time_base), + }; + int i, nb_samples = lrint(av_expr_eval(sine->samples_per_frame_expr, values, sine)); int16_t *samples; + if (nb_samples <= 0) { + av_log(sine, AV_LOG_WARNING, "nb samples expression evaluated to %d, " + "defaulting to 1024\n", nb_samples); + nb_samples = 1024; + } + if (sine->duration) { nb_samples = FFMIN(nb_samples, sine->duration - sine->pts); av_assert1(nb_samples >= 0); |