[FFmpeg-cvslog] lavfi/drawtext: add expansion function eif()
Andrey Utkin
git at videolan.org
Thu Jul 17 13:27:12 CEST 2014
ffmpeg | branch: master | Andrey Utkin <andrey.krieger.utkin at gmail.com> | Fri Jul 4 12:16:16 2014 +0300| [dec87454deb2f2a314f309cd6c1fa636503a70ae] | committer: Stefano Sabatini
lavfi/drawtext: add expansion function eif()
It evaluates expression and outputs it as integer value, using specified
format.
Address trac ticket #3699.
Signed-off-by: Stefano Sabatini <stefasab at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dec87454deb2f2a314f309cd6c1fa636503a70ae
---
doc/filters.texi | 9 +++++++
libavfilter/version.h | 2 +-
libavfilter/vf_drawtext.c | 62 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index 0f73314..6bea105 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -3911,6 +3911,15 @@ example the text size is not known when evaluating the expression, so
the constants @var{text_w} and @var{text_h} will have an undefined
value.
+ at item eif
+Evaluate the expression's value and output as formatted integer.
+
+First argument is expression to be evaluated, same as for @var{expr} function.
+Second argument specifies output format. Allowed values are 'x', 'X', 'd' and
+'u', they are treated exactly as in printf function.
+Third parameter is optional and sets the number of positions taken by output.
+Effectively this allows to add padding with zeros from the left.
+
@item gmtime
The time at which the filter is running, expressed in UTC.
It can accept an argument: a strftime() format string.
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 227d320..8f47a96 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -31,7 +31,7 @@
#define LIBAVFILTER_VERSION_MAJOR 4
#define LIBAVFILTER_VERSION_MINOR 11
-#define LIBAVFILTER_VERSION_MICRO 100
+#define LIBAVFILTER_VERSION_MICRO 101
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 0b93d14..3336eb2 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -37,6 +37,7 @@
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
+#include <fenv.h>
#if CONFIG_LIBFONTCONFIG
#include <fontconfig/fontconfig.h>
@@ -908,6 +909,66 @@ static int func_eval_expr(AVFilterContext *ctx, AVBPrint *bp,
return ret;
}
+static int func_eval_expr_int_format(AVFilterContext *ctx, AVBPrint *bp,
+ char *fct, unsigned argc, char **argv, int tag)
+{
+ DrawTextContext *s = ctx->priv;
+ double res;
+ int intval;
+ int ret;
+ unsigned int positions = 0;
+ char fmt_str[30] = "%";
+
+ /*
+ * argv[0] expression to be converted to `int`
+ * argv[1] format: 'x', 'X', 'd' or 'u'
+ * argv[2] positions printed (optional)
+ */
+
+ ret = av_expr_parse_and_eval(&res, argv[0], var_names, s->var_values,
+ NULL, NULL, fun2_names, fun2,
+ &s->prng, 0, ctx);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Expression '%s' for the expr text expansion function is not valid\n",
+ argv[0]);
+ return ret;
+ }
+
+ if (!strchr("xXdu", argv[1][0])) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid format '%c' specified,"
+ " allowed values: 'x', 'X', 'd', 'u'\n", argv[1][0]);
+ return AVERROR(EINVAL);
+ }
+
+ if (argc == 3) {
+ ret = sscanf(argv[2], "%u", &positions);
+ if (ret != 1) {
+ av_log(ctx, AV_LOG_ERROR, "eif(): Invalid number of positions"
+ " to print: '%s'\n", argv[2]);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ feclearexcept(FE_ALL_EXCEPT);
+ intval = res;
+ if ((ret = fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW))) {
+ av_log(ctx, AV_LOG_ERROR, "Conversion of floating-point result to int failed. Control register: 0x%08x. Conversion result: %d\n", ret, intval);
+ return AVERROR(EINVAL);
+ }
+
+ if (argc == 3)
+ av_strlcatf(fmt_str, sizeof(fmt_str), "0%u", positions);
+ av_strlcatf(fmt_str, sizeof(fmt_str), "%c", argv[1][0]);
+
+ av_log(ctx, AV_LOG_DEBUG, "Formatting value %f (expr '%s') with spec '%s'\n",
+ res, argv[0], fmt_str);
+
+ av_bprintf(bp, fmt_str, intval);
+
+ return 0;
+}
+
static const struct drawtext_function {
const char *name;
unsigned argc_min, argc_max;
@@ -916,6 +977,7 @@ static const struct drawtext_function {
} functions[] = {
{ "expr", 1, 1, 0, func_eval_expr },
{ "e", 1, 1, 0, func_eval_expr },
+ { "eif", 2, 3, 0, func_eval_expr_int_format },
{ "pict_type", 0, 0, 0, func_pict_type },
{ "pts", 0, 2, 0, func_pts },
{ "gmtime", 0, 1, 'G', func_strftime },
More information about the ffmpeg-cvslog
mailing list