[FFmpeg-devel] [PATCH] lavfi/setpts: add stp and ldp functions
Stefano Sabatini
stefasab at gmail.com
Tue Sep 9 11:54:44 CEST 2014
TODO: bump micro version
---
doc/filters.texi | 18 +++++++++++++++++-
libavfilter/setpts.c | 33 ++++++++++++++++++++++++++++++---
2 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index bb486ea..4338a3e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10528,7 +10528,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
@@ -10589,6 +10589,14 @@ The wallclock (RTC) time at the start of the movie in microseconds.
@item TB
The timebase of the input timestamps.
+ at item ldp(idx)
+Load the persistent variable loaded in register @var{idx}, which was
+filled with the @code{stp} function.
+
+ at item stp(idx, val)
+Store the value @var{val} in the persistent register with index
+ at var{idx}, which must be a value from 0 to 9. The register can then be
+loaded with @code{ldp}.
@end table
@subsection Examples
@@ -10642,6 +10650,14 @@ Generate timestamps by counting samples:
asetpts=N/SR/TB
@end example
+ at item
+Remove timestamp gaps greater than 60 seconds, and avoid non
+monotically increasing timestamps setting an arbitrary constant frame
+duration of 0.05 seconds:
+ at example
+setpts='st(0,(T-PREV_INT));if(gt(ld(0),60),stp(0,PTS-PREV_INPTS));st(1,PTS-ldp(0));if(lte(ld(1),PREV_OUTPTS),PREV_OUTPTS+0.05/TB,ld(1))'
+ at end example
+
@end itemize
@section settb, asettb
diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
index 92b07fb..873d987 100644
--- a/libavfilter/setpts.c
+++ b/libavfilter/setpts.c
@@ -84,21 +84,48 @@ enum var_name {
VAR_VARS_NB
};
+#define PERSISTENT_VARS_NB 10
typedef struct SetPTSContext {
const AVClass *class;
char *expr_str;
AVExpr *expr;
double var_values[VAR_VARS_NB];
enum AVMediaType type;
+ double persistent_vars[PERSISTENT_VARS_NB];
} SetPTSContext;
+static double ldp(void *opaque, double var_idx)
+{
+ SetPTSContext *s = opaque;
+ int var_idxi = var_idx;
+ if ((unsigned)var_idxi >= PERSISTENT_VARS_NB)
+ return NAN;
+ return s->persistent_vars[var_idxi];
+}
+
+static double stp(void *opaque, double var_idx, double val)
+{
+ SetPTSContext *s = opaque;
+ int var_idxi = var_idx;
+ if ((unsigned)var_idxi >= PERSISTENT_VARS_NB)
+ return NAN;
+ s->persistent_vars[var_idxi] = val;
+ return val;
+}
+
+static double (* const funcs1[])(void *, double) = { (void *)ldp, NULL };
+static double (* const funcs2[])(void *, double, double) = { (void *)stp, NULL };
+
+static const char * const funcs1_names[] = { "ldp", NULL };
+static const char * const funcs2_names[] = { "stp", NULL };
+
static av_cold int init(AVFilterContext *ctx)
{
SetPTSContext *setpts = ctx->priv;
int ret;
- if ((ret = av_expr_parse(&setpts->expr, setpts->expr_str,
- var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
+ if ((ret = av_expr_parse(&setpts->expr, setpts->expr_str, var_names,
+ funcs1_names, funcs1, funcs2_names, funcs2, 0, ctx)) < 0) {
av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", setpts->expr_str);
return ret;
}
@@ -174,7 +201,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
setpts->var_values[VAR_NB_SAMPLES] = frame->nb_samples;
}
- d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
+ d = av_expr_eval(setpts->expr, setpts->var_values, setpts);
frame->pts = D2TS(d);
av_dlog(inlink->dst,
--
1.8.3.2
More information about the ffmpeg-devel
mailing list