[FFmpeg-devel] [PATCH] drawtext: Allow textfile path to be expanded per frame

David Andreoletti david at andreoletti.net
Tue May 19 06:43:12 EEST 2020


Hi ffmpeg maintainers / community,
New contributor here. The patch [0] for the drawtext filter was submitted some
time ago now but has been reviewed yet. It seems there is no official maintainer
for this filter (as per the MAINTAINERS file)
What should be done to have it reviewed ?

[0]
https://patchwork.ffmpeg.org/project/ffmpeg/patch/20200511143159.19390-1-david@andreoletti.net/

Regards,
David Andreoletti  





On Mon, May 11, 2020 2:31 PM, David Andreoletti david at andreoletti.net  wrote:
drawtext allows a file to be reloaded per frame. However,

the file to be reloaded is constant across frame. With

textfile now supporting text expansion, a different file can

be reloaded per frame. Eg: textfile=/path/fo/file{frame_num}.txt




Signed-off-by: David Andreoletti <david at andreoletti.net>

---

  doc/filters.texi | 16 +++++++++++++---

  libavfilter/vf_drawtext.c | 19 ++++++++++++++++---

  2 files changed, 29 insertions(+), 6 deletions(-)




diff --git a/doc/filters.texi b/doc/filters.texi

index d19fd346ae..460d65dd88 100644

--- a/doc/filters.texi

+++ b/doc/filters.texi

@@ -9659,13 +9659,13 @@ The default value of @var{borderw} is 0.

  Set the color to be used for drawing border around text. For the syntax of
this

  option, check the @ref{color syntax,,"Color" section in the ffmpeg-utils
manual,ffmpeg-utils}.

  

  The default value of @var{bordercolor} is "black".

  

  @item expansion

-Select how the @var{text} is expanded. Can be either @code{none},

+Select how the @var{text} and @var{textfile} are expanded. Can be either
@code{none},

  @code{strftime} (deprecated) or

  @code{normal} (default). See the @ref{drawtext_expansion, Text expansion}
section

  below for details.

  

  @item basetime

  Set a start time for the count. Value is in microseconds. Only applied

@@ -9786,15 +9786,19 @@ of UTF-8 encoded characters.

  

  This parameter is mandatory if no text string is specified with the

  parameter @var{text}.

  

  If both @var{text} and @var{textfile} are specified, an error is thrown.

  

+This parameter supports (per frame) variable expansion. Per frame variable 

+expansion requires @code{reload=1}. See @var{expansion} for details.

+

+

  @item reload

-If set to 1, the @var{textfile} will be reloaded before each frame.

-Be sure to update it atomically, or it may be read partially, or even fail.

+If set to 1, then before each frame, @var{textfile} file path will be expanded
and then the file at said path will be reloaded.

+Be sure to update the file atomically, or it may be read partially, or even
fail.

  

  @item x

  @item y

  The expressions which specify the offsets where text will be drawn

  within the video frame. They are relative to the top/left border of the

  output image.

@@ -10060,12 +10064,18 @@
drawtext="fontsize=15:fontfile=FreeSerif.ttf:text=LONG_LINE:y=h-line_h:x=-50*t"

  @item

  Show the content of file @file{CREDITS} off the bottom of the frame and scroll
up.

  @example

  drawtext="fontsize=20:fontfile=FreeSerif.ttf:textfile=CREDITS:y=h-20*t"

  @end example

  

+ at item

+Each frame, reload a different text file at /path/to/frameX.txt, where X is
replaced with the frame number being processed by the filter

+ at example

+drawtext="expansion:normal:textfile=/path/to/frame%@{frame_num@}.txt:reload=1"

+ at end example

+

  @item

  Draw a single green letter "g", at the center of the input video.

  The glyph baseline is placed at half screen height.

  @example

 
drawtext="fontsize=60:fontfile=FreeSerif.ttf:fontcolor=green:text=g:x=(w-max_glyph_w)/2:y=h/2-ascent"

  @end example

diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c

index abe1ca6c35..ffb1ff2330 100644

--- a/libavfilter/vf_drawtext.c

+++ b/libavfilter/vf_drawtext.c

@@ -152,13 +152,14 @@ typedef struct DrawTextContext {

  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

- char *textfile; ///< file with text to be drawn

+ char *textfile; ///< filename with text to be drawn

+ AVBPrint expanded_textfile; ///< Same as textfile, except the filename can be
expanded

  int x; ///< x position to start drawing text

  int y; ///< y position to start drawing text

  int max_glyph_w; ///< max glyph width

  int max_glyph_h; ///< max glyph height

  int shadowx, shadowy;

  int borderw; ///< border width

@@ -565,24 +566,33 @@ static int load_font(AVFilterContext *ctx)

  if (!err)

  return 0;

  #endif

  return err;

  }

  

+static int expand_text(AVFilterContext *ctx, char *text, AVBPrint *bp);

  static int load_textfile(AVFilterContext *ctx)

  {

  DrawTextContext *s = ctx->priv;

  int err;

  uint8_t *textbuf;

  uint8_t *tmp;

  size_t textbuf_size;

  

- if ((err = av_file_map(s->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {

+ if ((err = expand_text(ctx, s->textfile, &s->expanded_textfile)) < 0) {

+ av_log(ctx, AV_LOG_ERROR, "The text file path '%s' is not expandable\n",

+ s->textfile);

+ return err;

+ }

+

+ av_log(ctx, AV_LOG_DEBUG, "expanded_textfile:%s\n", s->expanded_textfile.str);

+

+ if ((err = av_file_map(s->expanded_textfile.str, &textbuf, &textbuf_size, 0,
ctx)) < 0) {

  av_log(ctx, AV_LOG_ERROR,

  "The text file '%s' could not be read or is empty\n",

- s->textfile);

+ s->expanded_textfile.str);

  return err;

  }

  

  if (textbuf_size > SIZE_MAX - 1 || !(tmp = av_realloc(s->text, textbuf_size +
1))) {

  av_file_unmap(textbuf, textbuf_size);

  return AVERROR(ENOMEM);

@@ -702,12 +712,14 @@ static av_cold int init(AVFilterContext *ctx)

  

  if (!s->fontfile && !CONFIG_LIBFONTCONFIG) {

  av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");

  return AVERROR(EINVAL);

  }

  

+ av_bprint_init(&s->expanded_textfile, 0, AV_BPRINT_SIZE_UNLIMITED);

+

  if (s->textfile) {

  if (s->text) {

  av_log(ctx, AV_LOG_ERROR,

  "Both text and text file provided. Please provide only one\n");

  return AVERROR(EINVAL);

  }

@@ -820,12 +832,13 @@ static av_cold void uninit(AVFilterContext *ctx)

  FT_Done_Face(s->face);

  FT_Stroker_Done(s->stroker);

  FT_Done_FreeType(s->library);

  

  av_bprint_finalize(&s->expanded_text, NULL);

  av_bprint_finalize(&s->expanded_fontcolor, NULL);

+ av_bprint_finalize(&s->expanded_textfile, NULL);

  }

  

  static int config_input(AVFilterLink *inlink)

  {

  AVFilterContext *ctx = inlink->dst;

  DrawTextContext *s = ctx->priv;

-- 

2.26.2


More information about the ffmpeg-devel mailing list