From patchwork Mon May 11 14:31:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Andreoletti X-Patchwork-Id: 19626 X-Patchwork-Delegate: michael@niedermayer.cc Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id C0EE1449244 for ; Mon, 11 May 2020 17:32:48 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 98CA8687FBC; Mon, 11 May 2020 17:32:48 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from 3.mo6.mail-out.ovh.net (3.mo6.mail-out.ovh.net [178.33.253.26]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 14977687F31 for ; Mon, 11 May 2020 17:32:42 +0300 (EEST) Received: from player772.ha.ovh.net (unknown [10.110.208.202]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 36D2F20E22B for ; Mon, 11 May 2020 16:32:41 +0200 (CEST) Received: from andreoletti.net (114-45-55-50.dynamic-ip.hinet.net [114.45.55.50]) (Authenticated sender: david@andreoletti.net) by player772.ha.ovh.net (Postfix) with ESMTPSA id 34B31124BB208; Mon, 11 May 2020 14:32:37 +0000 (UTC) From: David Andreoletti To: ffmpeg-devel@ffmpeg.org Date: Mon, 11 May 2020 22:31:59 +0800 Message-Id: <20200511143159.19390-1-david@andreoletti.net> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 X-Ovh-Tracer-Id: 7063896019518716093 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduhedrledtgdejvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecunecujfgurhephffvufffkffoggfgsedtkeertdertddtnecuhfhrohhmpeffrghvihguucetnhgurhgvohhlvghtthhiuceouggrvhhiugesrghnughrvgholhgvthhtihdrnhgvtheqnecuggftrfgrthhtvghrnhepleeftdduheeghedufeejffefheduhfegheeuhfeltefgteeitdefgfdvfedtfedvnecukfhppedtrddtrddtrddtpdduudegrdeghedrheehrdehtdenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdqohhuthdphhgvlhhopehplhgrhigvrhejjedvrdhhrgdrohhvhhdrnhgvthdpihhnvghtpedtrddtrddtrddtpdhmrghilhhfrhhomhepuggrvhhiugesrghnughrvgholhgvthhtihdrnhgvthdprhgtphhtthhopehffhhmphgvghdquggvvhgvlhesfhhfmhhpvghgrdhorhhg Subject: [FFmpeg-devel] [PATCH] drawtext: Allow textfile path to be expanded per frame X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 Signed-off-by: David Andreoletti --- 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 +@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 +@example +drawtext="expansion:normal:textfile=/path/to/frame%@{frame_num@}.txt:reload=1" +@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;