[FFmpeg-devel] [PATCH 2/2] drawtext: add fontcolor_expr

Stefano Sabatini stefasab at gmail.com
Fri Jul 4 15:23:36 CEST 2014


On date Friday 2014-07-04 12:16:17 +0300, Andrey Utkin encoded:
> An option for fontcolor, dynamically evaluated
> ---
>  doc/filters.texi          | 16 ++++++++++++++++
>  libavfilter/vf_drawtext.c | 27 ++++++++++++++++++++++-----
>  2 files changed, 38 insertions(+), 5 deletions(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 3ed28a0..c42bfcf 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -3660,6 +3660,11 @@ the "Color" section in the ffmpeg-utils manual.
>  
>  The default value of @var{fontcolor} is "black".
>  
> + at item fontcolor_expr
> +String which is expanded the same way as @var{text} to obtain dynamic
> + at var{fontcolor} value. By default this option has empty value and is not
> +processed. When this option is set, it overrides @var{fontcolor} option.
> +
>  @item font
>  The font family to be used for drawing text. By default Sans.
>  
> @@ -3975,6 +3980,17 @@ Print the date of a real-time encoding (see strftime(3)):
>  drawtext='fontfile=FreeSans.ttf:text=%@{localtime:%a %b %d %Y@}'
>  @end example
>  
> + at item
> +Text fading in and out (appearing/disappearing).
> + at example
> +#!/bin/sh
> +DS=1.0 # display start
> +DE=10.0 # display end
> +FID=1.5 # fade in duration
> +FOD=5 # fade out duration

> +ffplay -f lavfi -i "drawtext=text=TEST:fontsize=50:fontfile=FreeSerif.ttf:fontcolor_expr=ff0000%@{eif\\\\: max(0\\, min(255\\, 255*(1*between(t\\, $DS + $FID\\, $DE - $FOD) + ((t - $DS)/$FID)*between(t\\, $DS\\, $DS + $FID) + (-(t - $DE)/$FOD)*between(t\\, $DE - $FOD\\, $DE) ) )) \\\\: x\\\\: 2 @}"
> + at end example

probably it would be simpler to use fontcolor_expr=red@{e:...}. Also
see my clip patch, it will simplify this a bit further.

> +
>  @end itemize
>  
>  For more information about libfreetype, check:
> diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
> index 305e00f..4f4354e 100644
> --- a/libavfilter/vf_drawtext.c
> +++ b/libavfilter/vf_drawtext.c
> @@ -137,6 +137,8 @@ typedef struct DrawTextContext {
>      uint8_t *fontfile;              ///< font to be usedgit
>      uint8_t *text;                  ///< text to be drawn
>      AVBPrint expanded_text;         ///< used to contain the expanded text
> +    uint8_t *fontcolor_expr;        ///< fontcolor expression to evaluate
> +    AVBPrint expanded_fontcolor;    ///< used to contain the expanded fontcolor spec
>      int ft_load_flags;              ///< flags used for loading fonts, see FT_LOAD_*
>      FT_Vector *positions;           ///< positions for each element in the text
>      size_t nb_positions;            ///< number of elements of positions array
> @@ -192,6 +194,7 @@ static const AVOption drawtext_options[]= {
>      {"text",        "set text",             OFFSET(text),               AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
>      {"textfile",    "set text file",        OFFSET(textfile),           AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
>      {"fontcolor",   "set foreground color", OFFSET(fontcolor.rgba),     AV_OPT_TYPE_COLOR,  {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
> +    {"fontcolor_expr", "set foreground color expression", OFFSET(fontcolor_expr), AV_OPT_TYPE_STRING, {.str=""}, CHAR_MIN, CHAR_MAX, FLAGS},
>      {"boxcolor",    "set box color",        OFFSET(boxcolor.rgba),      AV_OPT_TYPE_COLOR,  {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS},
>      {"bordercolor", "set border color",     OFFSET(bordercolor.rgba),   AV_OPT_TYPE_COLOR,  {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
>      {"shadowcolor", "set shadow color",     OFFSET(shadowcolor.rgba),   AV_OPT_TYPE_COLOR,  {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
> @@ -570,6 +573,7 @@ static av_cold int init(AVFilterContext *ctx)
>          av_log(ctx, AV_LOG_WARNING, "expansion=strftime is deprecated.\n");
>  
>      av_bprint_init(&s->expanded_text, 0, AV_BPRINT_SIZE_UNLIMITED);
> +    av_bprint_init(&s->expanded_fontcolor, 0, AV_BPRINT_SIZE_UNLIMITED);
>  
>      return 0;
>  }
> @@ -613,6 +617,7 @@ static av_cold void uninit(AVFilterContext *ctx)
>      FT_Done_FreeType(s->library);
>  
>      av_bprint_finalize(&s->expanded_text, NULL);
> +    av_bprint_finalize(&s->expanded_fontcolor, NULL);
>  }
>  
>  static inline int is_newline(uint32_t c)
> @@ -946,11 +951,8 @@ end:
>      return ret;
>  }
>  
> -static int expand_text(AVFilterContext *ctx)
> +static int expand_text(AVFilterContext *ctx, char *text, AVBPrint *bp)
>  {
> -    DrawTextContext *s = ctx->priv;
> -    char *text = s->text;
> -    AVBPrint *bp = &s->expanded_text;
>      int ret;
>  
>      av_bprint_clear(bp);
> @@ -1046,7 +1048,7 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame,
>          av_bprintf(bp, "%s", s->text);
>          break;
>      case EXP_NORMAL:
> -        if ((ret = expand_text(ctx)) < 0)
> +        if ((ret = expand_text(ctx, s->text, &s->expanded_text)) < 0)
>              return ret;
>          break;
>      case EXP_STRFTIME:
> @@ -1072,6 +1074,21 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame,
>          s->nb_positions = len;
>      }
>  
> +    if (s->fontcolor_expr[0]) {
> +        /* If expression is set, evaluate and replace the static value */
> +        av_bprint_clear(&s->expanded_fontcolor);
> +        if ((ret = expand_text(ctx, s->fontcolor_expr, &s->expanded_fontcolor)) < 0)
> +            return ret;
> +        if (!av_bprint_is_complete(&s->expanded_fontcolor))
> +            return AVERROR(ENOMEM);
> +        av_log(s, AV_LOG_DEBUG, "Evaluated fontcolor is '%s'\n", s->expanded_fontcolor.str);
> +        ret = av_parse_color(s->fontcolor.rgba, s->expanded_fontcolor.str, -1, s);
> +        if (ret)
> +            return ret;
> +        ff_draw_color(&s->dc, &s->fontcolor, s->fontcolor.rgba);
> +    }

> +
> +

nit++: double newline

LGTM otherwise, thanks.
-- 
FFmpeg = Fierce Faithful Mastering Pitiful Evil Game


More information about the ffmpeg-devel mailing list