It evaluates expression and outputs it as integer value, using specified
format.
Address trac ticket #3699.
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
... | ... |
@@ -3911,6 +3911,15 @@ example the text size is not known when evaluating the expression, so |
3911 | 3911 |
the constants @var{text_w} and @var{text_h} will have an undefined |
3912 | 3912 |
value. |
3913 | 3913 |
|
3914 |
+@item eif |
|
3915 |
+Evaluate the expression's value and output as formatted integer. |
|
3916 |
+ |
|
3917 |
+First argument is expression to be evaluated, same as for @var{expr} function. |
|
3918 |
+Second argument specifies output format. Allowed values are 'x', 'X', 'd' and |
|
3919 |
+'u', they are treated exactly as in printf function. |
|
3920 |
+Third parameter is optional and sets the number of positions taken by output. |
|
3921 |
+Effectively this allows to add padding with zeros from the left. |
|
3922 |
+ |
|
3914 | 3923 |
@item gmtime |
3915 | 3924 |
The time at which the filter is running, expressed in UTC. |
3916 | 3925 |
It can accept an argument: a strftime() format string. |
... | ... |
@@ -31,7 +31,7 @@ |
31 | 31 |
|
32 | 32 |
#define LIBAVFILTER_VERSION_MAJOR 4 |
33 | 33 |
#define LIBAVFILTER_VERSION_MINOR 11 |
34 |
-#define LIBAVFILTER_VERSION_MICRO 100 |
|
34 |
+#define LIBAVFILTER_VERSION_MICRO 101 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFILTER_VERSION_MINOR, \ |
... | ... |
@@ -37,6 +37,7 @@ |
37 | 37 |
#if HAVE_UNISTD_H |
38 | 38 |
#include <unistd.h> |
39 | 39 |
#endif |
40 |
+#include <fenv.h> |
|
40 | 41 |
|
41 | 42 |
#if CONFIG_LIBFONTCONFIG |
42 | 43 |
#include <fontconfig/fontconfig.h> |
... | ... |
@@ -908,6 +909,66 @@ static int func_eval_expr(AVFilterContext *ctx, AVBPrint *bp, |
908 | 908 |
return ret; |
909 | 909 |
} |
910 | 910 |
|
911 |
+static int func_eval_expr_int_format(AVFilterContext *ctx, AVBPrint *bp, |
|
912 |
+ char *fct, unsigned argc, char **argv, int tag) |
|
913 |
+{ |
|
914 |
+ DrawTextContext *s = ctx->priv; |
|
915 |
+ double res; |
|
916 |
+ int intval; |
|
917 |
+ int ret; |
|
918 |
+ unsigned int positions = 0; |
|
919 |
+ char fmt_str[30] = "%"; |
|
920 |
+ |
|
921 |
+ /* |
|
922 |
+ * argv[0] expression to be converted to `int` |
|
923 |
+ * argv[1] format: 'x', 'X', 'd' or 'u' |
|
924 |
+ * argv[2] positions printed (optional) |
|
925 |
+ */ |
|
926 |
+ |
|
927 |
+ ret = av_expr_parse_and_eval(&res, argv[0], var_names, s->var_values, |
|
928 |
+ NULL, NULL, fun2_names, fun2, |
|
929 |
+ &s->prng, 0, ctx); |
|
930 |
+ if (ret < 0) { |
|
931 |
+ av_log(ctx, AV_LOG_ERROR, |
|
932 |
+ "Expression '%s' for the expr text expansion function is not valid\n", |
|
933 |
+ argv[0]); |
|
934 |
+ return ret; |
|
935 |
+ } |
|
936 |
+ |
|
937 |
+ if (!strchr("xXdu", argv[1][0])) { |
|
938 |
+ av_log(ctx, AV_LOG_ERROR, "Invalid format '%c' specified," |
|
939 |
+ " allowed values: 'x', 'X', 'd', 'u'\n", argv[1][0]); |
|
940 |
+ return AVERROR(EINVAL); |
|
941 |
+ } |
|
942 |
+ |
|
943 |
+ if (argc == 3) { |
|
944 |
+ ret = sscanf(argv[2], "%u", &positions); |
|
945 |
+ if (ret != 1) { |
|
946 |
+ av_log(ctx, AV_LOG_ERROR, "eif(): Invalid number of positions" |
|
947 |
+ " to print: '%s'\n", argv[2]); |
|
948 |
+ return AVERROR(EINVAL); |
|
949 |
+ } |
|
950 |
+ } |
|
951 |
+ |
|
952 |
+ feclearexcept(FE_ALL_EXCEPT); |
|
953 |
+ intval = res; |
|
954 |
+ if ((ret = fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW))) { |
|
955 |
+ av_log(ctx, AV_LOG_ERROR, "Conversion of floating-point result to int failed. Control register: 0x%08x. Conversion result: %d\n", ret, intval); |
|
956 |
+ return AVERROR(EINVAL); |
|
957 |
+ } |
|
958 |
+ |
|
959 |
+ if (argc == 3) |
|
960 |
+ av_strlcatf(fmt_str, sizeof(fmt_str), "0%u", positions); |
|
961 |
+ av_strlcatf(fmt_str, sizeof(fmt_str), "%c", argv[1][0]); |
|
962 |
+ |
|
963 |
+ av_log(ctx, AV_LOG_DEBUG, "Formatting value %f (expr '%s') with spec '%s'\n", |
|
964 |
+ res, argv[0], fmt_str); |
|
965 |
+ |
|
966 |
+ av_bprintf(bp, fmt_str, intval); |
|
967 |
+ |
|
968 |
+ return 0; |
|
969 |
+} |
|
970 |
+ |
|
911 | 971 |
static const struct drawtext_function { |
912 | 972 |
const char *name; |
913 | 973 |
unsigned argc_min, argc_max; |
... | ... |
@@ -916,6 +977,7 @@ static const struct drawtext_function { |
916 | 916 |
} functions[] = { |
917 | 917 |
{ "expr", 1, 1, 0, func_eval_expr }, |
918 | 918 |
{ "e", 1, 1, 0, func_eval_expr }, |
919 |
+ { "eif", 2, 3, 0, func_eval_expr_int_format }, |
|
919 | 920 |
{ "pict_type", 0, 0, 0, func_pict_type }, |
920 | 921 |
{ "pts", 0, 2, 0, func_pts }, |
921 | 922 |
{ "gmtime", 0, 1, 'G', func_strftime }, |