34 #include <sys/types.h>
42 #if CONFIG_LIBFONTCONFIG
43 #include <fontconfig/fontconfig.h>
69 #include FT_FREETYPE_H
79 "max_glyph_a",
"ascent",
80 "max_glyph_d",
"descent",
147 #if CONFIG_LIBFONTCONFIG
202 #if CONFIG_LIBFRIBIDI
208 #define OFFSET(x) offsetof(DrawTextContext, x)
209 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
231 #if CONFIG_LIBFONTCONFIG
248 {
"start_number",
"start frame number for n/frame_num variable",
OFFSET(start_number),
AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX,
FLAGS},
250 #if CONFIG_LIBFRIBIDI
255 {
"ft_load_flags",
"set font loading flags for libfreetype",
OFFSET(ft_load_flags),
AV_OPT_TYPE_FLAGS, { .i64 = FT_LOAD_DEFAULT }, 0, INT_MAX,
FLAGS,
"ft_load_flags" },
261 {
"vertical_layout",
NULL, 0,
AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_VERTICAL_LAYOUT }, .flags =
FLAGS, .unit =
"ft_load_flags" },
265 {
"ignore_global_advance_width",
NULL, 0,
AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH }, .flags =
FLAGS, .unit =
"ft_load_flags" },
267 {
"ignore_transform",
NULL, 0,
AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_TRANSFORM }, .flags =
FLAGS, .unit =
"ft_load_flags" },
276 #undef __FTERRORS_H__
277 #define FT_ERROR_START_LIST {
278 #define FT_ERRORDEF(e, v, s) { (e), (s) },
279 #define FT_ERROR_END_LIST { 0, NULL } };
287 #define FT_ERRMSG(e) ft_errors[e].err_msg
289 typedef struct Glyph {
291 FT_Glyph border_glyph;
293 unsigned int fontsize;
295 FT_Bitmap border_bitmap;
304 const Glyph *
a =
key, *bb =
b;
305 int64_t
diff = (int64_t)
a->code - (int64_t)bb->code;
308 return diff > 0 ? 1 : -1;
310 return FFDIFFSIGN((int64_t)
a->fontsize, (int64_t)bb->fontsize);
319 FT_BitmapGlyph bitmapglyph;
325 if (FT_Load_Char(
s->face,
code,
s->ft_load_flags))
334 glyph->fontsize =
s->fontsize;
336 if (FT_Get_Glyph(
s->face->glyph, &glyph->glyph)) {
341 glyph->border_glyph = glyph->glyph;
342 if (FT_Glyph_StrokeBorder(&glyph->border_glyph,
s->stroker, 0, 0) ||
343 FT_Glyph_To_Bitmap(&glyph->border_glyph, FT_RENDER_MODE_NORMAL, 0, 1)) {
347 bitmapglyph = (FT_BitmapGlyph) glyph->border_glyph;
348 glyph->border_bitmap = bitmapglyph->bitmap;
350 if (FT_Glyph_To_Bitmap(&glyph->glyph, FT_RENDER_MODE_NORMAL, 0, 1)) {
354 bitmapglyph = (FT_BitmapGlyph) glyph->glyph;
356 glyph->bitmap = bitmapglyph->bitmap;
357 glyph->bitmap_left = bitmapglyph->left;
358 glyph->bitmap_top = bitmapglyph->top;
359 glyph->advance =
s->face->glyph->advance.x >> 6;
362 FT_Glyph_Get_CBox(glyph->glyph, ft_glyph_bbox_pixels, &glyph->bbox);
389 if ((err = FT_Set_Pixel_Sizes(
s->face, 0, fontsize))) {
395 s->fontsize = fontsize;
405 if (
s->fontsize_pexpr)
408 if (
s->fontsize_expr ==
NULL)
421 unsigned int fontsize =
s->default_fontsize;
423 double size, roundedsize;
426 if (
s->fontsize_expr !=
NULL) {
435 if (!(roundedsize > INT_MIN && roundedsize < INT_MAX)) {
440 fontsize = roundedsize;
448 if (fontsize ==
s->fontsize)
459 err = FT_New_Face(
s->library, path,
index, &
s->face);
461 #if !CONFIG_LIBFONTCONFIG
470 #if CONFIG_LIBFONTCONFIG
474 FcConfig *fontconfig;
475 FcPattern *pat, *best;
476 FcResult result = FcResultMatch;
483 fontconfig = FcInitLoadConfigAndFonts();
488 pat = FcNameParse(
s->fontfile ?
s->fontfile :
489 (
uint8_t *)(intptr_t)
"default");
495 FcPatternAddString(pat, FC_FAMILY,
s->font);
506 FcPatternAddDouble(pat, FC_SIZE,
size);
509 FcDefaultSubstitute(pat);
511 if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) {
513 FcPatternDestroy(pat);
517 best = FcFontMatch(fontconfig, pat, &result);
518 FcPatternDestroy(pat);
520 if (!best || result != FcResultMatch) {
522 "Cannot find a valid font for the family %s\n",
528 FcPatternGetInteger(best, FC_INDEX, 0, &
index ) != FcResultMatch ||
529 FcPatternGetDouble (best, FC_SIZE, 0, &
size ) != FcResultMatch) {
534 if (FcPatternGetString(best, FC_FILE, 0, &filename) != FcResultMatch) {
542 s->default_fontsize =
size + 0.5;
547 FcConfigDestroy(fontconfig);
549 FcPatternDestroy(best);
563 #if CONFIG_LIBFONTCONFIG
564 err = load_font_fontconfig(
ctx);
573 return c ==
'\n' ||
c ==
'\r' ||
c ==
'\f' ||
c ==
'\v';
584 if ((err =
av_file_map(
s->textfile, &textbuf, &textbuf_size, 0,
ctx)) < 0) {
586 "The text file '%s' could not be read or is empty\n",
591 if (textbuf_size > 0 &&
is_newline(textbuf[textbuf_size - 1]))
593 if (textbuf_size > SIZE_MAX - 1 || !(
tmp =
av_realloc(
s->text, textbuf_size + 1))) {
598 memcpy(
s->text, textbuf, textbuf_size);
599 s->text[textbuf_size] = 0;
605 #if CONFIG_LIBFRIBIDI
611 static const FriBidiFlags
flags = FRIBIDI_FLAGS_DEFAULT |
612 FRIBIDI_FLAGS_ARABIC;
613 FriBidiChar *unicodestr =
NULL;
615 FriBidiParType direction = FRIBIDI_PAR_LTR;
616 FriBidiStrIndex line_start = 0;
617 FriBidiStrIndex line_end = 0;
618 FriBidiLevel *embedding_levels =
NULL;
619 FriBidiArabicProp *ar_props =
NULL;
620 FriBidiCharType *bidi_types =
NULL;
623 len = strlen(
s->text);
627 len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
628 s->text,
len, unicodestr);
635 fribidi_get_bidi_types(unicodestr,
len, bidi_types);
638 if (!embedding_levels) {
642 if (!fribidi_get_par_embedding_levels(bidi_types,
len, &direction,
652 fribidi_get_joining_types(unicodestr,
len, ar_props);
653 fribidi_join_arabic(bidi_types,
len, embedding_levels, ar_props);
654 fribidi_shape(
flags, embedding_levels,
len, ar_props, unicodestr);
656 for (line_end = 0, line_start = 0; line_end <
len; line_end++) {
657 if (
is_newline(unicodestr[line_end]) || line_end ==
len - 1) {
658 if (!fribidi_reorder_line(
flags, bidi_types,
659 line_end - line_start + 1, line_start,
660 direction, embedding_levels, unicodestr,
664 line_start = line_end + 1;
669 for (
i = 0, j = 0;
i <
len;
i++)
670 if (unicodestr[
i] != FRIBIDI_CHAR_FILL)
671 unicodestr[j++] = unicodestr[
i];
680 len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8,
681 unicodestr,
len,
s->text);
700 s->fontsize_pexpr =
NULL;
703 s->default_fontsize = 16;
713 "Both text and text file provided. Please provide only one\n");
720 if (
s->reload && !
s->textfile)
723 if (
s->tc_opt_string) {
725 s->tc_opt_string,
ctx);
736 "Either text, a valid file or a timecode must be provided\n");
740 #if CONFIG_LIBFRIBIDI
742 if ((err = shape_text(
ctx)) < 0)
746 if ((err = FT_Init_FreeType(&(
s->library)))) {
748 "Could not load FreeType: %s\n",
FT_ERRMSG(err));
759 if (FT_Stroker_New(
s->library, &
s->stroker)) {
763 FT_Stroker_Set(
s->stroker,
s->borderw << 6, FT_STROKER_LINECAP_ROUND,
764 FT_STROKER_LINEJOIN_ROUND, 0);
767 s->use_kerning = FT_HAS_KERNING(
s->face);
777 s->tabsize *= glyph->advance;
780 (strchr(
s->text,
'%') || strchr(
s->text,
'\\')))
798 FT_Done_Glyph(glyph->glyph);
799 FT_Done_Glyph(glyph->border_glyph);
813 s->x_pexpr =
s->y_pexpr =
s->a_pexpr =
s->fontsize_pexpr =
NULL;
822 FT_Done_Face(
s->face);
823 FT_Stroker_Done(
s->stroker);
824 FT_Done_FreeType(
s->library);
847 s->var_values[
VAR_HSUB] = 1 <<
s->dc.hsub_max;
848 s->var_values[
VAR_VSUB] = 1 <<
s->dc.vsub_max;
858 s->x_pexpr =
s->y_pexpr =
s->a_pexpr =
NULL;
879 if (!strcmp(cmd,
"reinit")) {
884 new->class = &drawtext_class;
921 char *fct,
unsigned argc,
char **argv,
int tag)
930 char *fct,
unsigned argc,
char **argv,
int tag)
937 fmt = argc >= 1 ? argv[0] :
"flt";
946 if (!strcmp(fmt,
"flt")) {
948 }
else if (!strcmp(fmt,
"hms")) {
959 if (!strcmp(argv[2],
"24HH")) {
960 ms %= 24 * 60 * 60 * 1000;
967 (
int)(ms / (60 * 60 * 1000)),
968 (
int)(ms / (60 * 1000)) % 60,
969 (
int)(ms / 1000) % 60,
972 }
else if (!strcmp(fmt,
"localtime") ||
973 !strcmp(fmt,
"gmtime")) {
975 time_t ms = (time_t)
pts;
976 const char *timefmt = argc >= 3 ? argv[2] :
"%Y-%m-%d %H:%M:%S";
977 if (!strcmp(fmt,
"localtime"))
990 char *fct,
unsigned argc,
char **argv,
int tag)
999 char *fct,
unsigned argc,
char **argv,
int tag)
1012 char *fct,
unsigned argc,
char **argv,
int tag)
1014 const char *fmt = argc ? argv[0] :
"%Y-%m-%d %H:%M:%S";
1028 char *fct,
unsigned argc,
char **argv,
int tag)
1039 "Expression '%s' for the expr text expansion function is not valid\n",
1048 char *fct,
unsigned argc,
char **argv,
int tag)
1055 char fmt_str[30] =
"%";
1068 "Expression '%s' for the expr text expansion function is not valid\n",
1073 if (!strchr(
"xXdu", argv[1][0])) {
1075 " allowed values: 'x', 'X', 'd', 'u'\n", argv[1][0]);
1080 ret = sscanf(argv[2],
"%u", &
positions);
1083 " to print: '%s'\n", argv[2]);
1088 feclearexcept(FE_ALL_EXCEPT);
1090 #if defined(FE_INVALID) && defined(FE_OVERFLOW) && defined(FE_UNDERFLOW)
1091 if ((ret = fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW))) {
1092 av_log(
ctx,
AV_LOG_ERROR,
"Conversion of floating-point result to int failed. Control register: 0x%08x. Conversion result: %d\n", ret, intval);
1099 av_strlcatf(fmt_str,
sizeof(fmt_str),
"%c", argv[1][0]);
1102 res, argv[0], fmt_str);
1129 unsigned argc,
char **argv)
1157 const char *text = *rtext;
1158 char *argv[16] = {
NULL };
1159 unsigned argc = 0,
i;
1187 *rtext = (
char *)text + 1;
1190 for (
i = 0;
i < argc;
i++)
1201 if (*text ==
'\\' && text[1]) {
1204 }
else if (*text ==
'%') {
1221 int x,
int y,
int borderw)
1223 char *text =
s->expanded_text.str;
1227 Glyph *glyph =
NULL;
1229 for (
i = 0, p = text; *p;
i++) {
1231 Glyph
dummy = { 0 };
1233 continue_on_invalid:
1240 dummy.fontsize =
s->fontsize;
1243 bitmap = borderw ? glyph->border_bitmap : glyph->bitmap;
1245 if (glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO &&
1246 glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
1249 x1 =
s->positions[
i].x+
s->x+x - borderw;
1250 y1 =
s->positions[
i].y+
s->y+y - borderw;
1254 bitmap.buffer, bitmap.pitch,
1255 bitmap.width, bitmap.rows,
1256 bitmap.pixel_mode == FT_PIXEL_MODE_MONO ? 0 : 3,
1267 color->rgba[3] = (
color->rgba[3] *
s->alpha) / 255;
1280 else if (
alpha <= 0)
1292 uint32_t
code = 0, prev_code = 0;
1293 int x = 0, y = 0,
i = 0, ret;
1294 int max_text_line_w = 0,
len;
1298 int y_min = 32000, y_max = -32000;
1299 int x_min = 32000, x_max = -32000;
1301 Glyph *glyph =
NULL, *prev_glyph =
NULL;
1302 Glyph
dummy = { 0 };
1304 time_t now = time(0);
1306 AVBPrint *bp = &
s->expanded_text;
1318 switch (
s->exp_mode) {
1332 if (
s->tc_opt_string) {
1341 text =
s->expanded_text.str;
1342 if ((
len =
s->expanded_text.len) >
s->nb_positions) {
1343 if (!(
s->positions =
1346 s->nb_positions =
len;
1349 if (
s->fontcolor_expr[0]) {
1352 if ((ret =
expand_text(
ctx,
s->fontcolor_expr, &
s->expanded_fontcolor)) < 0)
1370 for (
i = 0, p = text; *p;
i++) {
1372 continue_on_invalid:
1376 dummy.fontsize =
s->fontsize;
1384 y_min =
FFMIN(glyph->bbox.yMin, y_min);
1385 y_max =
FFMAX(glyph->bbox.yMax, y_max);
1386 x_min =
FFMIN(glyph->bbox.xMin, x_min);
1387 x_max =
FFMAX(glyph->bbox.xMax, x_max);
1389 s->max_glyph_h = y_max - y_min;
1390 s->max_glyph_w = x_max - x_min;
1394 for (
i = 0, p = text; *p;
i++) {
1396 continue_on_invalid2:
1399 if (prev_code ==
'\r' &&
code ==
'\n')
1405 max_text_line_w =
FFMAX(max_text_line_w, x);
1406 y +=
s->max_glyph_h +
s->line_spacing;
1414 dummy.fontsize =
s->fontsize;
1418 if (
s->use_kerning && prev_glyph && glyph->code) {
1419 FT_Get_Kerning(
s->face, prev_glyph->code, glyph->code,
1420 ft_kerning_default, &
delta);
1425 s->positions[
i].x = x + glyph->bitmap_left;
1426 s->positions[
i].y = y - glyph->bitmap_top + y_max;
1427 if (
code ==
'\t') x = (x /
s->tabsize + 1)*
s->tabsize;
1428 else x += glyph->advance;
1431 max_text_line_w =
FFMAX(x, max_text_line_w);
1454 box_w = max_text_line_w;
1455 box_h = y +
s->max_glyph_h;
1457 if (
s->fix_bounds) {
1460 int boxoffset =
s->draw_box ?
FFMAX(
s->boxborderw, 0) : 0;
1461 int borderoffset =
s->borderw ?
FFMAX(
s->borderw, 0) : 0;
1463 int offsetleft =
FFMAX3(boxoffset, borderoffset,
1464 (
s->shadowx < 0 ?
FFABS(
s->shadowx) : 0));
1465 int offsettop =
FFMAX3(boxoffset, borderoffset,
1466 (
s->shadowy < 0 ?
FFABS(
s->shadowy) : 0));
1468 int offsetright =
FFMAX3(boxoffset, borderoffset,
1469 (
s->shadowx > 0 ?
s->shadowx : 0));
1470 int offsetbottom =
FFMAX3(boxoffset, borderoffset,
1471 (
s->shadowy > 0 ?
s->shadowy : 0));
1474 if (
s->x - offsetleft < 0)
s->x = offsetleft;
1475 if (
s->y - offsettop < 0)
s->y = offsettop;
1477 if (
s->x + box_w + offsetright >
width)
1479 if (
s->y + box_h + offsetbottom >
height)
1487 s->x -
s->boxborderw,
s->y -
s->boxborderw,
1488 box_w +
s->boxborderw * 2, box_h +
s->boxborderw * 2);
1490 if (
s->shadowx ||
s->shadowy) {
1492 &shadowcolor,
s->shadowx,
s->shadowy, 0)) < 0)
1498 &bordercolor, 0, 0,
s->borderw)) < 0)
1502 &fontcolor, 0, 0, 0)) < 0)
1520 #if CONFIG_LIBFRIBIDI
1521 if (
s->text_shaping)
1522 if ((ret = shape_text(
ctx)) < 0) {
1555 .needs_writable = 1,
1570 .description =
NULL_IF_CONFIG_SMALL(
"Draw text on top of video frames using libfreetype library."),
1572 .priv_class = &drawtext_class,
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Main libavfilter public API header.
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
void av_bprintf(AVBPrint *buf, const char *fmt,...)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm)
Append a formatted date and time to a print buffer.
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
#define AV_BPRINT_SIZE_UNLIMITED
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
#define flags(name, subs,...)
common internal and external API header
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
#define FFDIFFSIGN(x, y)
Comparator.
#define CONFIG_LIBFONTCONFIG
void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, int x0, int y0, int w, int h)
Blend a rectangle with an uniform color.
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, int l2depth, unsigned endianness, int x0, int y0)
Blend an alpha mask with an uniform color.
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
#define FF_DRAW_PROCESS_ALPHA
Process alpha pixel component.
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
simple arithmetic expression evaluator
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
int av_set_options_string(void *ctx, const char *opts, const char *key_val_sep, const char *pairs_sep)
Parse the key/value pairs list in opts.
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_EXTERNAL
Generic error in an external library.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
char * av_strdup(const char *s)
Duplicate a string.
char av_get_picture_type_char(enum AVPictureType pict_type)
Return a single letter to describe the given picture type pict_type.
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
#define AV_NOPTS_VALUE
Undefined timestamp value.
#define AV_TIME_BASE
Internal time base represented as integer.
void av_tree_enumerate(AVTreeNode *t, void *opaque, int(*cmp)(void *opaque, void *elem), int(*enu)(void *opaque, void *elem))
Apply enu(opaque, &elem) to all the elements in the tree in a given range.
void * av_tree_insert(AVTreeNode **tp, void *key, int(*cmp)(const void *key, const void *b), AVTreeNode **next)
Insert or remove an element.
struct AVTreeNode * av_tree_node_alloc(void)
Allocate an AVTreeNode.
void av_tree_destroy(AVTreeNode *t)
static const int16_t alpha[]
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, int log_offset, void *log_ctx)
Read the file with name filename, and put its content in a newly allocated buffer or map it with mmap...
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static av_always_inline av_const double round(double x)
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx)
Put the RGBA values that correspond to color_string in rgba_color.
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
#define FF_ARRAY_ELEMS(a)
Describe the class of an AVClass context structure.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
const char * name
Pad name.
const char * name
Filter name.
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int64_t pkt_duration
duration of the corresponding packet, expressed in AVStream->time_base units, 0 if unknown.
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
int pkt_size
size of the corresponding packet containing the compressed frame.
AVDictionary * metadata
metadata.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
enum AVPictureType pict_type
Picture type of the frame.
Context structure for the Lagged Fibonacci PRNG.
Rational number (pair of numerator and denominator).
int start_number
starting frame number for n/frame_num var
FFDrawColor shadowcolor
shadow color
int max_glyph_w
max glyph width
FT_Vector * positions
positions for each element in the text
int x
x position to start drawing text
AVRational tc_rate
frame rate for timecode
FT_Stroker stroker
freetype stroker handle
FFDrawColor bordercolor
border color
int reinit
tells if the filter is being reinited
int fix_bounds
do we let it go out of frame bounds - t/f
uint8_t * fontcolor_expr
fontcolor expression to evaluate
FFDrawColor boxcolor
background color
AVExpr * fontsize_pexpr
parsed expressions for fontsize
uint8_t * fontfile
font to be used
char * fontsize_expr
expression for fontsize
AVBPrint expanded_text
used to contain the expanded text
int max_glyph_h
max glyph height
double var_values[VAR_VARS_NB]
FFDrawColor fontcolor
foreground color
FT_Face face
freetype font face handle
short int draw_box
draw box around text - true or false
int use_kerning
font kerning is used - true/false
AVBPrint expanded_fontcolor
used to contain the expanded fontcolor spec
char * x_expr
expression for x position
struct AVTreeNode * glyphs
rendered glyphs, stored using the UTF-32 char code
char * textfile
file with text to be drawn
int ft_load_flags
flags used for loading fonts, see FT_LOAD_*
int exp_mode
expansion mode to use for the text
unsigned int default_fontsize
default font size to use
int line_spacing
lines spacing in pixels
int boxborderw
box border width
int y
y position to start drawing text
int reload
reload text file for each frame
char * y_expr
expression for y position
uint8_t * text
text to be drawn
unsigned int fontsize
font size to use
int64_t basetime
base pts time in the real world for display
size_t nb_positions
number of elements of positions array
char * tc_opt_string
specified timecode option string
int tc24hmax
1 if timecode is wrapped to 24 hours, 0 otherwise
AVExpr * y_pexpr
parsed expressions for x and y
AVTimecode tc
timecode context
FT_Library library
freetype font library handle
int tag
opaque argument to func
int(* func)(AVFilterContext *, AVBPrint *, char *, unsigned, char **, int)
#define av_malloc_array(a, b)
static void error(const char *err)
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
Parse timecode representation (hh:mm:ss[:;.
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
Load timecode string in buf.
#define AV_TIMECODE_STR_SIZE
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
void * av_tree_find(const AVTreeNode *t, void *key, int(*cmp)(const void *key, const void *b), void *next[2])
static const struct drawtext_function functions[]
AVFILTER_DEFINE_CLASS(drawtext)
static const AVFilterPad avfilter_vf_drawtext_outputs[]
static const AVFilterPad avfilter_vf_drawtext_inputs[]
double(* eval_func2)(void *, double a, double b)
static int load_font_file(AVFilterContext *ctx, const char *path, int index)
static av_cold int update_fontsize(AVFilterContext *ctx)
static int func_pict_type(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static int is_newline(uint32_t c)
static av_cold int set_fontsize(AVFilterContext *ctx, unsigned int fontsize)
static const eval_func2 fun2[]
static int load_textfile(AVFilterContext *ctx)
static int load_font(AVFilterContext *ctx)
static av_cold int parse_fontsize(AVFilterContext *ctx)
static const AVOption drawtext_options[]
static int query_formats(AVFilterContext *ctx)
static int draw_glyphs(DrawTextContext *s, AVFrame *frame, int width, int height, FFDrawColor *color, int x, int y, int borderw)
static int config_input(AVFilterLink *inlink)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
static void update_alpha(DrawTextContext *s)
static int func_metadata(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static int func_frame_num(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static int func_strftime(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static double drand(void *opaque, double min, double max)
static void update_color_with_alpha(DrawTextContext *s, FFDrawColor *color, const FFDrawColor incolor)
static const char *const var_names[]
static const char *const fun2_names[]
static int glyph_cmp(const void *key, const void *b)
static av_cold int init(AVFilterContext *ctx)
static int func_pts(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static av_cold void uninit(AVFilterContext *ctx)
static const struct ft_error ft_errors[]
static int func_eval_expr_int_format(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static int eval_function(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv)
static int expand_text(AVFilterContext *ctx, char *text, AVBPrint *bp)
static int func_eval_expr(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static int expand_function(AVFilterContext *ctx, AVBPrint *bp, char **rtext)
static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code)
Load glyphs corresponding to the UTF-32 codepoint code.
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
static int glyph_enu_free(void *opaque, void *elem)
static int draw_text(AVFilterContext *ctx, AVFrame *frame, int width, int height)
static av_always_inline int diff(const uint32_t a, const uint32_t b)
static const uint16_t positions[][14][3]