On 04/21/2010 03:35 PM, Stefano Sabatini wrote:
[...]
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc
Hi,
Attached is the vf_drawtext.c and changes to libavfilter.texi (both are
patches against libavfilter soc like you asked for)
Following is the list of changes :
1. Using a single context structure now. Descriptive variable names.
2. Input parameters also are descriptive now, but sometimes different
from the corresponding context variable where the context variable name
is too long.
3. Using macro instead of function to parse libfreetype messages now.
4. Changed warning messages to AV_LOG_WARNINGS.
4. User now needs to provide only one of text or file, if both are given
then file is used.
5. Made color string to YUV conversion separate function called for both
fg and bg color.
6. Alignments, indents, description of filter and redundant '!='s fixed.
7. Reading file only once now in init.
8. Using re-entrant localtime_r now.
9. The documentation now uses $var{x} instead of ``x''. Made these
changes throughout the libavfilter doc, not just drawtext. Is that ok?
10. Updated documentation with new parameter names, strftime behavior
and the file/text requirement.
As for the alpha channel support in drawbox function, do we need to
update the alpha values? Should the caller be allowed to specify bgcolor
or fgcolor in #RRGGBBAA format?
Please review and let me know if there's anything else that needs to be
fixed.
Regards,
Hemanth
Index: vf_drawtext.c
===================================================================
--- vf_drawtext.c (revision 0)
+++ vf_drawtext.c (revision 0)
@@ -0,0 +1,476 @@
+/*
+ * copyright (c) 2010 S.N. Hemanth Meenakshisundaram
+ * Original vhook author: Gustavo Sverzut Barbieri <[email protected]>
+ * Libavfilter version : S.N. Hemanth Meenakshisundaram <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Drawtext Filter
+ */
+
+#include "avfilter.h"
+#include "parseutils.h"
+#include "libavcodec/colorspace.h"
+#include "libavutil/pixdesc.h"
+
+#undef time
+#include <sys/time.h>
+#include <time.h>
+
+#include <ft2build.h>
+#include <freetype/config/ftheader.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+typedef struct {
+ const AVClass *class;
+ unsigned char *font;
+ unsigned char *text; ///< text to be drawn
+ char *file; ///< file with text to be drawn
+ unsigned int x; ///< x position to start drawing text
+ unsigned int y; ///< y position to start drawing text
+ unsigned int size; ///< font size to use
+ char *fgcolor_string; ///< foreground color as string
+ char *bgcolor_string; ///< background color as string
+ unsigned char fgcolor[3]; ///< foreground color in YUV
+ unsigned char bgcolor[3]; ///< background/Box color in YUV
+ short int draw_box; ///< draw box around text - true or false
+ short int outline; ///< draw outline in bg color around text
+ int text_height; ///< height of a font symbol
+ int baseline; ///< baseline to draw fonts from
+ int use_kerning; ///< font kerning is used - true/false
+ FT_Library library; ///< freetype font library handle
+ FT_Face face; ///< freetype font face handle
+ FT_Glyph glyphs[256]; ///< array holding glyphs of font
+ FT_Bitmap bitmaps[256]; ///< array holding bitmaps of font
+ int advance[256];
+ int bitmap_left[256];
+ int bitmap_top[256];
+ unsigned int glyphs_index[256];
+ int hsub, vsub; ///< chroma subsampling values
+} DrawTextContext;
+
+#define OFFSET(x) offsetof(DrawTextContext, x)
+
+static const AVOption drawtext_options[]= {
+{"font", "set font", OFFSET(font), FF_OPT_TYPE_STRING, 0,
CHAR_MIN, CHAR_MAX },
+{"text", "set text", OFFSET(text), FF_OPT_TYPE_STRING, 0,
CHAR_MIN, CHAR_MAX },
+{"file", "set file", OFFSET(file), FF_OPT_TYPE_STRING, 0,
CHAR_MIN, CHAR_MAX },
+{"fgcolor", "set fgcolor", OFFSET(fgcolor_string), FF_OPT_TYPE_STRING, 0,
CHAR_MIN, CHAR_MAX },
+{"bgcolor", "set bgcolor", OFFSET(bgcolor_string), FF_OPT_TYPE_STRING, 0,
CHAR_MIN, CHAR_MAX },
+{"box", "set box", OFFSET(draw_box), FF_OPT_TYPE_INT, 0,
0, 1 },
+{"outline", "set outline", OFFSET(outline), FF_OPT_TYPE_INT, 0,
0, 1 },
+{"size", "set size", OFFSET(size), FF_OPT_TYPE_INT, 16,
1, 72 },
+{"x", "set x", OFFSET(x), FF_OPT_TYPE_INT, 0,
0, INT_MAX },
+{"y", "set y", OFFSET(y), FF_OPT_TYPE_INT, 0,
0, INT_MAX },
+{NULL},
+};
+
+static const char *drawtext_get_name(void *ctx)
+{
+ return "drawtext";
+}
+
+static const AVClass drawtext_class = {
+ "DrawTextContext",
+ drawtext_get_name,
+ drawtext_options
+};
+
+static int query_formats(AVFilterContext *ctx)
+{
+ /* FIXME : Add support for other formats */
+ enum PixelFormat pix_fmts[] = {
+ PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P,
+ PIX_FMT_YUV411P, PIX_FMT_YUV410P,
+ PIX_FMT_YUV440P, PIX_FMT_NONE
+ };
+
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ return 0;
+}
+
+#undef __FTERRORS_H__
+#define FT_ERROR_START_LIST {
+#define FT_ERRORDEF(e, v, s) { (e), (s) },
+#define FT_ERROR_END_LIST { 0, NULL } };
+
+struct ft_error
+{
+ int err;
+ char *err_msg;
+} ft_errors[] =
+#include FT_ERRORS_H
+
+#define FT_ERRMSG(e) ft_errors[e].err_msg
+
+#define MAX_TEXT_SIZE 1024
+
+static inline int extract_color(AVFilterContext *ctx, char *color_str,
unsigned char *color)
+{
+ uint8_t rgba[4];
+ if (color_str && (av_parse_color(rgba, color_str, ctx))) {
+ return -1;
+ }
+ color[0] = RGB_TO_Y(rgba[0], rgba[1], rgba[2]);
+ color[1] = RGB_TO_U(rgba[0], rgba[1], rgba[2], 0);
+ color[2] = RGB_TO_V(rgba[0], rgba[1], rgba[2], 0);
+ return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ unsigned short int c;
+ uint8_t err, file_valid = 0;
+ int y_max, y_min;
+ FT_BBox bbox;
+ DrawTextContext *dtext = ctx->priv;
+
+ dtext->class = &drawtext_class;
+ av_opt_set_defaults2(dtext, 0, 0);
+ dtext->fgcolor_string = av_strdup("black");
+ dtext->bgcolor_string = av_strdup("white");
+
+ if (av_set_options_string(dtext, args, "=", ":") < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n",
args);
+ return AVERROR(EINVAL);
+ }
+
+ if (!dtext->font || *(dtext->font) == 0) {
+ av_log(ctx, AV_LOG_ERROR, "No font file provided! (=f:filename)\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (dtext->file && *(dtext->file)) {
+ FILE *fp;
+ if (!(fp = fopen(dtext->file, "r"))) {
+ av_log(ctx, AV_LOG_WARNING, "WARNING: The file could not be
opened.\n");
+ } else {
+ uint16_t read_bytes;
+ char *tbuff = av_malloc(MAX_TEXT_SIZE);
+ read_bytes = fread(tbuff, sizeof(char), MAX_TEXT_SIZE-1, fp);
+ if (read_bytes > 0) {
+ tbuff[read_bytes] = 0;
+ av_free(dtext->text);
+ dtext->text = tbuff;
+ } else {
+ av_log(ctx, AV_LOG_WARNING, "WARNING: The file could not be
read or\
+ is empty.\n");
+ av_free(tbuff);
+ }
+ fclose(fp);
+ file_valid = 1;
+ }
+ }
+
+ if (!dtext->text || *(dtext->text) == 0) {
+ av_log(ctx, AV_LOG_ERROR, "Either text or a valid file must be
provided (=t:text or =f:file)\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (extract_color(ctx, dtext->fgcolor_string, dtext->fgcolor)) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid foreground color: '%s'.\n",
dtext->fgcolor_string);
+ return AVERROR(EINVAL);
+ }
+
+ if (extract_color(ctx, dtext->bgcolor_string, dtext->bgcolor)) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid foreground color: '%s'.\n",
dtext->fgcolor_string);
+ return AVERROR(EINVAL);
+ }
+
+ if ((err = FT_Init_FreeType(&(dtext->library)))) {
+ av_log(ctx, AV_LOG_ERROR, "Could not load FreeType (%s).\n",
FT_ERRMSG(err));
+ return AVERROR(EINVAL);
+ }
+
+ if ((err = FT_New_Face( dtext->library, dtext->font, 0, &(dtext->face)))) {
+ av_log(ctx, AV_LOG_ERROR, "Could not load face: %s (%s).\n",
dtext->font, FT_ERRMSG(err));
+ return AVERROR(EINVAL);
+ }
+ if ((err = FT_Set_Pixel_Sizes( dtext->face, 0, dtext->size))) {
+ av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels
(%s).\n", dtext->size, FT_ERRMSG(err));
+ return AVERROR(EINVAL);
+ }
+
+ dtext->use_kerning = FT_HAS_KERNING(dtext->face);
+
+ /* load and cache glyphs */
+ y_max = -32000;
+ y_min = 32000;
+ /* FIXME : Supports only ASCII text now. Add Unicode support */
+ for (c=0; c <= 255; c++) {
+
+ if (!file_valid && !strrchr(dtext->text,(unsigned char)c))
+ continue;
+
+ /* Load char */
+ err = FT_Load_Char( dtext->face, (unsigned char) c, FT_LOAD_RENDER |
FT_LOAD_MONOCHROME );
+ if (err) continue; /* ignore errors */
+
+ dtext->bitmaps[c] = dtext->face->glyph->bitmap;
+ dtext->bitmap_left[c] = dtext->face->glyph->bitmap_left;
+ dtext->bitmap_top[c] = dtext->face->glyph->bitmap_top;
+ dtext->advance[c] = dtext->face->glyph->advance.x >> 6;
+
+ err = FT_Get_Glyph( dtext->face->glyph, &(dtext->glyphs[c]) );
+ if (err) continue; /* ignore errors */
+ dtext->glyphs_index[c] = FT_Get_Char_Index( dtext->face, (unsigned
char) c );
+
+ /* Measure text height to calculate text_height (or the maximum text
height) */
+ FT_Glyph_Get_CBox( dtext->glyphs[ c ], ft_glyph_bbox_pixels, &bbox );
+ if (bbox.yMax > y_max)
+ y_max = bbox.yMax;
+ if (bbox.yMin < y_min)
+ y_min = bbox.yMin;
+ }
+
+ dtext->text_height = y_max - y_min;
+ dtext->baseline = y_max;
+
+ return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ DrawTextContext *dtext = ctx->priv;
+ av_free(dtext->font);
+ av_free(dtext->text);
+ av_free(dtext->file);
+ av_free(dtext->fgcolor_string);
+ av_free(dtext->bgcolor_string);
+ FT_Done_Face(dtext->face);
+ FT_Done_FreeType(dtext->library);
+}
+
+static int config_input(AVFilterLink *link)
+{
+ DrawTextContext *dtext = link->dst->priv;
+ const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[link->format];
+ dtext->hsub = pix_desc->log2_chroma_w;
+ dtext->vsub = pix_desc->log2_chroma_h;
+ return 0;
+}
+
+#define SET_PIXEL(pic_ref, yuv_color, x, y, hsub, vsub) { \
+ pic_ref->data[0][ (x ) + (y )*pic_ref->linesize[0] ] =
yuv_color[0]; \
+ pic_ref->data[1][ (x >> hsub) + (y >> vsub)*pic_ref->linesize[1] ] =
yuv_color[1]; \
+ pic_ref->data[2][ (x >> hsub) + (y >> vsub)*pic_ref->linesize[2] ] =
yuv_color[2]; \
+}
+
+#define GET_PIXEL(pic_ref, yuv_color, x, y, hsub, vsub) { \
+ yuv_color[0] = pic_ref->data[0][ (x ) + (y
)*pic_ref->linesize[0] ]; \
+ yuv_color[1] = pic_ref->data[1][ (x >> hsub) + (y >>
vsub)*pic_ref->linesize[1] ]; \
+ yuv_color[2] = pic_ref->data[2][ (x >> hsub) + (y >>
vsub)*pic_ref->linesize[2] ]; \
+}
+
+static inline void draw_glyph(AVFilterPicRef *pic_ref, FT_Bitmap *bitmap,
unsigned int x,
+ unsigned int y, unsigned int width, unsigned int
height,
+ unsigned char yuv_fgcolor[3], unsigned char
yuv_color[3],
+ short int outline, int hsub, int vsub)
+{
+ int r, c;
+ uint8_t spixel, dpixel[3], in_glyph=0;
+
+ if (bitmap->pixel_mode == ft_pixel_mode_mono) {
+ in_glyph = 0;
+ for (r=0; (r < bitmap->rows) && (r+y < height); r++) {
+ for (c=0; (c < bitmap->width) && (c+x < width); c++) {
+ /* pixel in the pic_ref (destination) */
+ GET_PIXEL(pic_ref, dpixel, (c+x), (y+r), hsub, vsub);
+
+ /* pixel in the glyph bitmap (source) */
+ spixel = bitmap->buffer[r*bitmap->pitch +c/8] & (0x80>>(c%8));
+
+ if (spixel)
+ memcpy(dpixel, yuv_fgcolor, 3);
+
+ if (outline) {
+ /* border detection: */
+ if ( !in_glyph && spixel ) {
+ /* left border detected */
+ in_glyph = 1;
+ /* draw left pixel border */
+ if (c-1 >= 0)
+ SET_PIXEL(pic_ref, yuv_color, (c+x-1), (y+r),
hsub, vsub);
+ } else if ( in_glyph && !spixel ) {
+ /* right border detected */
+ in_glyph = 0;
+ /* 'draw' right pixel border */
+ memcpy(dpixel, yuv_color, 3);
+ }
+
+ if (in_glyph) {
+ /* see if we have a top/bottom border */
+ /* top */
+ if ((r-1 >= 0) && (!
bitmap->buffer[(r-1)*bitmap->pitch +c/8] & (0x80>>(c%8))))
+ /* we have a top border */
+ SET_PIXEL(pic_ref, yuv_color, (c+x), (y+r-1),
hsub, vsub);
+
+ /* bottom border detection */
+ if ((r+1 < height) && (!
bitmap->buffer[(r+1)*bitmap->pitch +c/8] & (0x80>>(c%8))))
+ /* draw bottom border */
+ SET_PIXEL(pic_ref, yuv_color, (c+x), (y+r+1),
hsub, vsub);
+ }
+ }
+ SET_PIXEL(pic_ref, dpixel, (c+x), (y+r), hsub, vsub);
+ }
+ }
+ }
+}
+
+static inline void drawbox(AVFilterPicRef *pic_ref, unsigned int x, unsigned
int y,
+ unsigned int width, unsigned int height,
+ unsigned char yuv_color[3], int hsub, int vsub)
+{
+ int i, plane;
+ uint8_t *p;
+
+ for (plane = 0; plane < 3 && pic_ref->data[plane]; plane++) {
+ int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
+ int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
+
+ p = pic_ref->data[plane] + (y >> vsub1) * pic_ref->linesize[plane] +
(x >> hsub1);
+ for (i = 0; i < (height >> vsub1); i++) {
+ memset(p, yuv_color[plane], (width >> hsub1));
+ p += pic_ref->linesize[plane];
+ }
+ }
+}
+
+static void draw_text(AVFilterContext *ctx, AVFilterPicRef *pic_ref, int
width, int height)
+{
+ DrawTextContext *dtext = ctx->priv;
+ FT_Face face = dtext->face;
+ FT_GlyphSlot slot = face->glyph;
+ unsigned char *text = dtext->text;
+ unsigned char c;
+ unsigned char buff[MAX_TEXT_SIZE];
+ int x = 0, y = 0, i = 0, size = 0;
+ time_t now = time(0);
+ int str_w, str_w_max;
+ FT_Vector pos[MAX_TEXT_SIZE];
+ FT_Vector delta;
+ struct tm ltime;
+
+ strftime(buff, sizeof(buff), text, localtime_r(&now, <ime));
+ text = buff;
+ size = strlen(text);
+
+ /* measure text size and save glyphs position*/
+ str_w = str_w_max = 0;
+ x = dtext->x;
+ y = dtext->y;
+ for (i=0; i < size; i++) {
+ c = text[i];
+ /* kerning */
+ if ( (dtext->use_kerning) && (i > 0) && (dtext->glyphs_index[c]) ) {
+ FT_Get_Kerning(dtext->face, dtext->glyphs_index[text[i-1]],
+ dtext->glyphs_index[c], ft_kerning_default, &delta);
+ x += delta.x >> 6;
+ }
+
+ if (( (x + dtext->advance[ c ]) >= width ) || ( c == '\n' )) {
+ if (c != '\n')
+ str_w_max = width - dtext->x - 1;
+ y += dtext->text_height;
+ x = dtext->x;
+ }
+
+ /* save position */
+ pos[i].x = x + dtext->bitmap_left[c];
+ pos[i].y = y - dtext->bitmap_top[c] + dtext->baseline;
+ x += dtext->advance[c];
+ str_w += dtext->advance[c];
+ }
+ y += dtext->text_height;
+ if (str_w_max == 0)
+ str_w_max = str_w;
+ if (dtext->draw_box) {
+ /* Check if it doesn't pass the limits */
+ if ( str_w_max + dtext->x >= width )
+ str_w_max = width - dtext->x - 1;
+ if ( y >= height )
+ y = height - 1;
+
+ /* Draw Background */
+ drawbox( pic_ref, dtext->x, dtext->y, str_w_max, y-dtext->y,
+ dtext->bgcolor, dtext->hsub, dtext->vsub );
+ }
+
+ /* Draw Glyphs */
+ for (i=0; i < size; i++) {
+ c = text[i];
+
+ /* skip '_' (consider as space) if text was specified in cmd line and
+ * skip new line char, just go to new line */
+ if (( (c == '_') && (text == dtext->text) ) || ( c == '\n' ) )
+ continue;
+
+ /* now, draw to our target surface */
+ draw_glyph( pic_ref,
+ &(dtext->bitmaps[ c ]),
+ pos[i].x,
+ pos[i].y,
+ width,
+ height,
+ dtext->fgcolor,
+ dtext->bgcolor,
+ dtext->outline,
+ dtext->hsub,
+ dtext->vsub );
+
+ /* increment pen position */
+ x += slot->advance.x >> 6;
+ }
+}
+
+static void end_frame(AVFilterLink *link)
+{
+ AVFilterLink *output = link->dst->outputs[0];
+ AVFilterPicRef *pic_ref = link->cur_pic;
+
+ draw_text(link->dst, pic_ref, pic_ref->w, pic_ref->h);
+
+ avfilter_draw_slice(output, 0, pic_ref->h, 1);
+ avfilter_end_frame(output);
+}
+
+AVFilter avfilter_vf_drawtext = {
+ .name = "drawtext",
+ .description = "Draw text on top of video frames using libfreetype
library.",
+ .priv_size = sizeof(DrawTextContext),
+ .init = init,
+ .uninit = uninit,
+
+ .query_formats = query_formats,
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .get_video_buffer=
avfilter_null_get_video_buffer,
+ .start_frame =
avfilter_null_start_frame,
+ .end_frame = end_frame,
+ .config_props = config_input,
+ .min_perms = AV_PERM_WRITE |
+ AV_PERM_READ,
+ .rej_perms = AV_PERM_PRESERVE },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO, },
+ { .name = NULL}},
+};
--- ../../../ffmpeg_soc/libavfilter/ffmpeg/doc/libavfilter.texi 2010-04-04
02:11:17.144045518 -0700
+++ libavfilter.texi 2010-04-22 15:07:08.367807862 -0700
@@ -116,12 +116,12 @@
./ffmpeg -i in.avi -vfilters "crop=0:0:0:240" out.avi
@end example
-``x'' and ``y'' specify the position of the top-left corner of the
+$var{x} and $var{y} specify the position of the top-left corner of the
output (non-cropped) area.
-The default value of ``x'' and ``y'' is 0.
+The default value of $var{x} and $var{y} is 0.
-The ``width'' and ``height'' parameters specify the width and height
+The $var{width} and $var{height} parameters specify the width and height
of the output (non-cropped) area.
A value of 0 is interpreted as the maximum possible size contained in
@@ -137,7 +137,7 @@
100:100 and the right-bottom corner corresponding to the right-bottom
corner of the input image.
-The default value of ``width'' and ``height'' is 0.
+The default value of $var{width} and $var{height} is 0.
@section drawbox
@@ -147,6 +147,95 @@
Draw a box with x:y:width:height dimensions in a chosen color.
+...@section drawtext
+
+Draws text string or text from specified file on top of video.
+
+It accepts the following parameters:
+font=<font file>:text=<text>:file=<text file>:x=<x offset>:y=<y offset>:
+fgcolor=<foreground color>:bgcolor=<background color>:size=<font
size>:box=<draw box>:
+outline=<draw outline>
+
+font and at least one of text and file are mandatory parameters.
+
+If a date/time format string is passed in place of text, the current
+date and time are drawn in the specified format.
+
+The description of the accepted parameters follows.
+
+...@table @option
+...@item font
+
+Specifies the font file to be used for drawing text. Path must be included.
+This parameter is mandatory.
+
+...@item text
+
+Specifies the text string to be drawn.
+This parameter is mandatory if no file is specified and also serves as the
+fallback text if any file specified fails to open.
+
+...@item file
+
+Specifies a text file containing text to be drawn. Max of 1024 characters are
+read from the file. Any text string provided is ignored if file text is valid.
+
+This parameter is mandatory if no text string is specified.
+
+...@item x, y
+
+Specify the offsets where text will be drawn within the video
+frame. Relative to the top/left border of the output image.
+
+The default value of $var{x} and $var{y} is 0.
+
+...@item size
+
+Specifies the font size to be used for drawing text.
+
+The default value of $var{size} is 16.
+
+...@item fgcolor
+
+Specifies the foreground color to be used for drawing text.
+Specify either as a string (e.g. black or as a hex value e.g. FF0000)
+
+The default value of $var{fgcolor} is black.
+
+...@item bgcolor
+
+Specifies the background color to be used for drawing box around text
+or drawing text outline based on option selected.
+Specify either as a string (e.g. black or as a 0xRRGGBB e.g. 0xFF0000)
+
+The default value of $var{bgcolor} is white.
+
+...@item box
+
+Specifies whether to draw a box around text using background color.
+Value should be either 1(enable) or 0(disable).
+
+The default value of $var{box} is 0.
+
+...@item outline
+
+Specifies whether to draw an outline around text using background color.
+Value should be either 1(enable) or 0(disable).
+
+The default value of $var{outline} is 0.
+
+...@end table
+...@example
+drawtext="font=FreeSerif.ttf: text=TestText: x=100: y=50: size=24:
+ fgcolor=Yellow: bgcolor=Red: b=1"
+...@end example
+
+Draw 'TestText' with font FreeSerif of size 24 at (100,50), text color is
yellow,
+background color is red, draw a box around text.
+
+Note that the double quotes are not necessary if spaces are not used in
specifying
+the parameter list.
+
@section fifo
@example
@@ -278,24 +367,24 @@
@item width, height
Specify the size of the output image with the paddings added. If the
-value for ``width'' or ``height'' is 0, the corresponding input size
+value for $var{width} or $var{height} is 0, the corresponding input size
is used for the output.
-The default value of ``width'' and ``height'' is 0.
+The default value of $var{width} and $var{height} is 0.
@item x, y
Specify the offsets where to place the input image in the padded area
with respect to the top/left border of the output image.
-The default value of ``x'' and ``y'' is 0.
+The default value of $var{x} and $var{y} is 0.
@item color
Specify the color of the padded area, it can be the name of a color
(case insensitive match) or a 0xRRGGBB[AA] sequence.
-The default value of ``color'' is ``black''.
+The default value of $var{color} is ``black''.
@end table
@@ -323,14 +412,14 @@
the next filter, the scale filter will convert the input to the
requested format.
-If the value for ``width'' or ``height'' is 0, the respective input
+If the value for $var{width} or $var{height} is 0, the respective input
size is used for the output.
-If the value for ``width'' or ``height'' is -1, the scale filter will
+If the value for $var{width} or $var{height} is -1, the scale filter will
use, for the respective output size, a value that maintains the aspect
ratio of the input image.
-The default value of ``width'' and ``height'' is 0.
+The default value of $var{width} and $var{height} is 0.
@section setpts
@@ -422,10 +511,10 @@
template and to be employed in analysis / debugging tools.
It accepts as optional parameter a string of the form
-``width:height'', where ``width'' and ``height'' specify the size of
+``width:height'', where $var{width} and $var{height} specify the size of
the configured source.
-The default values of ``width'' and ``height'' are respectively 352
+The default values of $var{width} and $var{height} are respectively 352
and 288 (corresponding to the CIF size format).
@chapter Available video sinks
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc