[FFmpeg-devel] [PATCH 4/4] lavfi/drawtext: implement more generic expansion.

Stefano Sabatini stefasab at gmail.com
Thu Nov 15 02:12:33 CET 2012


On date Sunday 2012-11-11 18:56:45 +0100, Nicolas George encoded:
> The new expansion mechanism uses the %{...} notation.
> For compatibility reasons, it must be enabled explicitly,
> but a warning is printed if a change is likely to happen.
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>

Reminder: bump micro.

> ---
>  doc/filters.texi          |   50 ++++++++++++++-
>  libavfilter/vf_drawtext.c |  149 +++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 192 insertions(+), 7 deletions(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index eaf0f42..973573e 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -1844,8 +1844,7 @@ libfreetype library.
>  To enable compilation of this filter you need to configure FFmpeg with
>  @code{--enable-libfreetype}.
>  
> -The filter also recognizes strftime() sequences in the provided text
> -and expands them accordingly. Check the documentation of strftime().

> + at subsection Syntax

Nit: this is a bit weird since it will result the only filter with
that section (syntax is usually described just after the description).  

>  The filter accepts parameters as a list of @var{key}=@var{value} pairs,
>  separated by ":".
> @@ -1865,6 +1864,10 @@ Either a string (e.g. "yellow") or in 0xRRGGBB[AA] format
>  (e.g. "0xff00ff"), possibly followed by an alpha specifier.
>  The default value of @var{boxcolor} is "white".
>  
> + at item compat_expand (or old)
> +Use the old strftime-style expansion for the text. It is enabled by default
> +for now.
> +
>  @item draw
>  Set an expression which specifies if the text should be drawn. If the
>  expression evaluates to 0, the text is not drawn. This is useful for
> @@ -2039,6 +2042,43 @@ each other, so you can for example specify @code{y=x/dar}.
>  If libavfilter was built with @code{--enable-fontconfig}, then
>  @option{fontfile} can be a fontconfig pattern or omitted.
>  
> + at subsection Text expansion
> +
> +If @option{compat_expand} is enabled (which is the default for now),
> +the filter also recognizes strftime() sequences in the provided text
> +and expands them accordingly. Check the documentation of strftime().
> +This feature is deprecated.
> +
> +If @option{compat_expand} is not enabled, a more general expansion mechanism
> +is used.
> +
> +The backslash character '\', followed by any character, always expand to the
> +second character.
> +
> +Sequence of the form @code{%@{...@}} are expanded. The text between the
> +braces is a function name, possibly followed by arguments separated by ':'.
> +If the arguments contain special characters or delimiters (':' or '@{'),
                                                                      ^^
Should be "@}" ?

> +they should be escaped. Note that they probably must also be escaped as the
> +value for the @option{text} option in the filter argument string and as the
> +filter argument in the filter graph description, and possibly also for the
> +shell, that makes up to four levels of escaping; using a text file avoids
> +these problems.

Add something along the lines: "and thus is strongly encouraged" so
you get less users running and crying in the night because of escaping
madness.

> +
> +The following functions exist:
> +
> + at table @command

Note: from my local texinfo manual:

|Use the `@commannd' command to indicate command names, such as `ls' or
|`cc'.

(The typo is in the manual.) On the other hand same ad-hocity can be
found in the definition of @option (Use the `@option' command to
indicate a command-line option; for example, `-l' or `--version' or
`--output=FILENAME') so this might be a valid choice and equivalent
from the rendering point of view.

> +
> + at item localtime
> +The time at which the filter is running, expressed in the local time zone.
> +It can accept an argument: a strftime() format string.
> +

> + at item pts
> +The timestamp of the current frame, in seconds, with microsecond accuracy.

Maybe "time" or "pts_time" would be more appropriate, so it is still
possible to use "pts" for indicating the actual timestamp (the PTS
integer value), which might be useful for several (mostly debugging)
reasons.

> +
> + at end table
> +
> + at subsection Examples
> +
>  Some examples follow.
>  
>  @itemize
> @@ -2104,6 +2144,12 @@ Use fontconfig to set the font. Note that the colons need to be escaped.
>  drawtext='fontfile=Linux Libertine O-40\:style=Semibold:text=FFmpeg'
>  @end example
>  
> + at item
> +Print the date of a real-time encoding (see strftime(3)):
> + at example
> +drawtext='fontfile=FreeSans.ttf:compat_expand=0:text=%@{localtime:%a %b %d %Y@}'
> + at end example
> +
>  @end itemize
>  
>  For more information about libfreetype, check:
> diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
> index f9c69ae..e359793 100644
> --- a/libavfilter/vf_drawtext.c
> +++ b/libavfilter/vf_drawtext.c
> @@ -115,6 +115,7 @@ enum var_name {
>  
>  typedef struct {
>      const AVClass *class;
> +    int compat_expand;              ///< use old strftime-style expand
>      int reinit;                     ///< tells if the filter is being reinited
>      uint8_t *fontfile;              ///< font to be used
>      uint8_t *text;                  ///< text to be drawn
> @@ -181,6 +182,8 @@ static const AVOption drawtext_options[]= {
>  {"tabsize",  "set tab size",         OFFSET(tabsize),            AV_OPT_TYPE_INT,    {.i64=4},     0,        INT_MAX , FLAGS},
>  {"basetime", "set base time",        OFFSET(basetime),           AV_OPT_TYPE_INT64,  {.i64=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX , FLAGS},
>  {"draw",     "if false do not draw", OFFSET(draw_expr),          AV_OPT_TYPE_STRING, {.str="1"},   CHAR_MIN, CHAR_MAX, FLAGS},

> +{"compat_expand", "use old strftime-style expand", OFFSET(compat_expand), AV_OPT_TYPE_INT, {.i64=1},      0,        1, FLAGS},
> +{"old",           "use old strftime-style expand", OFFSET(compat_expand), AV_OPT_TYPE_INT, {.i64=1},      0,        1, FLAGS},

What about to introduce an expansion_mode for this? So we could have:
expansion=strftime -> deprecated, enabled by default for the moment
expansion=extended
expansion=literal

The latter would save jumps in the hoops when scripting.

>  {"timecode", "set initial timecode", OFFSET(tc_opt_string),      AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
>  {"tc24hmax", "set 24 hours max (timecode only)", OFFSET(tc24hmax), AV_OPT_TYPE_INT,  {.i64=0},            0,        1, FLAGS},
>  {"timecode_rate", "set rate (timecode only)", OFFSET(tc_rate),   AV_OPT_TYPE_RATIONAL, {.dbl=0},          0,  INT_MAX, FLAGS},
> @@ -484,6 +487,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
>      }
>      dtext->tabsize *= glyph->advance;
>  
> +    if (dtext->compat_expand &&
> +        (strchr(dtext->text, '%') || strchr(dtext->text, '\\')))
> +        av_log(ctx, AV_LOG_WARNING, "Compat expand is deprecated.\n");
> +
>      av_bprint_init(&dtext->expanded_text, 0, AV_BPRINT_SIZE_UNLIMITED);
>  
>      return 0;
> @@ -585,6 +592,138 @@ static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char
>      return AVERROR(ENOSYS);
>  }
[...]

Thanks for working on this, this was on my todo since a long time but
I couldn't find the motivation to find a proper and extensible design.
-- 
FFmpeg = Fantastic & Freak Monstrous Peaceless Erroneous Gnome


More information about the ffmpeg-devel mailing list