Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2015-08-10 22:03:11 +0300
committerClément Bœsch <u@pkh.me>2015-09-06 16:28:21 +0300
commita388ca359d78c6fa00c75b326ada11048b1226ba (patch)
treef7f8db350504ad1bf74cf8f2d20611a4e800d9d8 /libavfilter/asrc_sine.c
parentdb18b3d6e6fa83eef862023d4c18bbe1113df075 (diff)
avfilter/sine: support expression in the number of output samples
Diffstat (limited to 'libavfilter/asrc_sine.c')
-rw-r--r--libavfilter/asrc_sine.c48
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);