mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-26 04:50:25 +00:00
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@gmail.com>
This commit is contained in:
parent
f3e886c7df
commit
dec87454de
@ -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.
|
||||
|
||||
@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.
|
||||
|
@ -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, \
|
||||
|
@ -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 },
|
||||
|
Loading…
Reference in New Issue
Block a user