From: Stefano Sabatini <stefasab@gmail.com>
To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Cc: Stefano Sabatini <stefasab@gmail.com>
Subject: [FFmpeg-devel] [PATCH 2/2] lavfi/setpts: introduce rand() function in expression
Date: Thu, 28 Dec 2023 01:38:39 +0100
Message-ID: <20231228003839.860894-1-stefasab@gmail.com> (raw)
This is useful to simulate random jitter.
---
Changelog | 1 +
doc/filters.texi | 10 +++++++++-
libavfilter/setpts.c | 39 +++++++++++++++++++++++++++++++++------
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/Changelog b/Changelog
index 424bfc11af..ed01c53264 100644
--- a/Changelog
+++ b/Changelog
@@ -15,6 +15,7 @@ version <next>:
- tiltandshift filter
- qrencode filter and qrencodesrc source
- quirc filter
+- lavfi/setpts: introduce rand() function in expression
version 6.1:
- libaribcaption decoder
diff --git a/doc/filters.texi b/doc/filters.texi
index d1f95b9781..1d9a5d6c7d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -30946,7 +30946,7 @@ The expression which is evaluated for each frame to construct its timestamp.
@end table
The expression is evaluated through the eval API and can contain the following
-constants:
+constants and functions:
@table @option
@item FRAME_RATE, FR
@@ -31010,6 +31010,8 @@ The timebase of the input timestamps.
@item T_CHANGE
Time of the first frame after command was applied or time of the first frame if no commands.
+@item rand(min, max)
+a random number included between min and max
@end table
@subsection Examples
@@ -31021,6 +31023,12 @@ Start counting PTS from zero
setpts=PTS-STARTPTS
@end example
+@item
+Apply a random jitter effect of +/-100 TB units:
+@example
+setpts=PTS+100rand(-100\,100)
+@end example
+
@item
Apply fast motion effect:
@example
diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
index 88a8d6af86..0f24a900b3 100644
--- a/libavfilter/setpts.c
+++ b/libavfilter/setpts.c
@@ -32,6 +32,8 @@
#include "libavutil/internal.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
+#include "libavutil/lfg.h"
+#include "libavutil/random_seed.h"
#include "libavutil/time.h"
#include "audio.h"
#include "avfilter.h"
@@ -101,18 +103,39 @@ typedef struct SetPTSContext {
AVExpr *expr;
double var_values[VAR_VARS_NB];
enum AVMediaType type;
+ AVLFG lfg;
} SetPTSContext;
#define V(name_) \
setpts->var_values[VAR_##name_]
+static double drand(void *ctx, double min, double max)
+{
+ SetPTSContext *setpts = ((AVFilterContext *)ctx)->priv;
+
+ return min + (max-min) / UINT_MAX * av_lfg_get(&setpts->lfg);
+}
+
+typedef double (*eval_func2)(void *, double a, double b);
+
+static const eval_func2 fun2[] = {
+ drand,
+ NULL
+};
+
+static const char *const fun2_names[] = {
+ "rand"
+};
+
static av_cold int init(AVFilterContext *ctx)
{
SetPTSContext *setpts = ctx->priv;
int ret;
+ av_lfg_init(&setpts->lfg, av_get_random_seed());
+
if ((ret = av_expr_parse(&setpts->expr, setpts->expr_str,
- var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
+ var_names, NULL, NULL, fun2_names, fun2, 0, ctx)) < 0) {
av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", setpts->expr_str);
return ret;
}
@@ -126,6 +149,7 @@ static av_cold int init(AVFilterContext *ctx)
V(STARTPTS) = NAN;
V(STARTT) = NAN;
V(T_CHANGE) = NAN;
+
return 0;
}
@@ -159,8 +183,10 @@ static inline char *double2int64str(char *buf, double v)
return buf;
}
-static double eval_pts(SetPTSContext *setpts, AVFilterLink *inlink, AVFrame *frame, int64_t pts)
+static double eval_pts(AVFilterContext *ctx, AVFilterLink *inlink, AVFrame *frame, int64_t pts)
{
+ SetPTSContext *setpts = ctx->priv;
+
if (isnan(V(STARTPTS))) {
V(STARTPTS) = TS2D(pts);
V(STARTT ) = TS2T(pts, inlink->time_base);
@@ -186,17 +212,18 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
- return av_expr_eval(setpts->expr, setpts->var_values, NULL);
+ return av_expr_eval(setpts->expr, setpts->var_values, ctx);
}
#define d2istr(v) double2int64str((char[BUF_SIZE]){0}, v)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
- SetPTSContext *setpts = inlink->dst->priv;
+ AVFilterContext *ctx = inlink->dst;
+ SetPTSContext *setpts = ctx->priv;
int64_t in_pts = frame->pts;
double d;
- d = eval_pts(setpts, inlink, frame, frame->pts);
+ d = eval_pts(ctx, inlink, frame, frame->pts);
frame->pts = D2TS(d);
av_log(inlink->dst, AV_LOG_TRACE,
@@ -250,7 +277,7 @@ static int activate(AVFilterContext *ctx)
return filter_frame(inlink, in);
if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
- double d = eval_pts(setpts, inlink, NULL, pts);
+ double d = eval_pts(ctx, inlink, NULL, pts);
av_log(ctx, AV_LOG_TRACE, "N:EOF PTS:%s T:%f -> PTS:%s T:%f\n",
d2istr(V(PTS)), V(T), d2istr(d), TS2T(d, inlink->time_base));
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next reply other threads:[~2023-12-28 0:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-28 0:38 Stefano Sabatini [this message]
2023-12-28 11:02 ` Andreas Rheinhardt
2023-12-28 15:00 ` Stefano Sabatini
2023-12-28 18:49 ` Stefano Sabatini
2023-12-28 21:25 ` Michael Niedermayer
2023-12-29 11:51 ` Stefano Sabatini
2024-01-02 21:12 ` Stefano Sabatini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231228003839.860894-1-stefasab@gmail.com \
--to=stefasab@gmail.com \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git