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 250 #if CONFIG_LIBFRIBIDI 251 {
"text_shaping",
"attempt to shape text before drawing",
OFFSET(text_shaping),
AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, 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;
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;
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))) {
423 double size, roundedsize;
433 roundedsize =
round(size);
435 if (!(roundedsize > INT_MIN && roundedsize < INT_MAX)) {
440 fontsize = roundedsize;
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();
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) {
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';
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);
705 if (!s->
fontfile && !CONFIG_LIBFONTCONFIG) {
713 "Both text and text file provided. Please provide only one\n");
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));
763 FT_Stroker_Set(s->
stroker, s->
borderw << 6, FT_STROKER_LINECAP_ROUND,
764 FT_STROKER_LINEJOIN_ROUND, 0);
773 if ((err =
load_glyph(ctx, &glyph,
' ')) < 0) {
780 (strchr(s->
text,
'%') || strchr(s->
text,
'\\')))
798 FT_Done_Glyph(glyph->glyph);
799 FT_Done_Glyph(glyph->border_glyph);
822 FT_Done_Face(s->
face);
879 if (!strcmp(cmd,
"reinit")) {
884 new->class = &drawtext_class;
915 av_log(ctx,
AV_LOG_ERROR,
"Failed to process command. Continuing with existing parameters.\n");
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")) {
952 int64_t ms =
llrint(pts * 1000);
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);
1098 av_strlcatf(fmt_str,
sizeof(fmt_str),
"0%u", positions);
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;
1184 if ((ret =
eval_function(ctx, bp, argv[0], argc - 1, argv + 1)) < 0)
1187 *rtext = (
char *)text + 1;
1190 for (
i = 0;
i < argc;
i++)
1201 if (*text ==
'\\' && text[1]) {
1204 }
else if (*text ==
'%') {
1227 Glyph *glyph =
NULL;
1229 for (i = 0, p = text; *p; i++) {
1231 Glyph
dummy = { 0 };
1232 GET_UTF8(code, *p ? *p++ : 0, code = 0xfffd;
goto continue_on_invalid;);
1233 continue_on_invalid:
1236 if (code ==
'\n' || code ==
'\r' || code ==
'\t')
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)
1254 bitmap.buffer, bitmap.pitch,
1255 bitmap.width, bitmap.rows,
1256 bitmap.pixel_mode == FT_PIXEL_MODE_MONO ? 0 : 3,
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);
1370 for (
i = 0, p = text; *p;
i++) {
1371 GET_UTF8(code, *p ? *p++ : 0, code = 0xfffd;
goto continue_on_invalid;);
1372 continue_on_invalid:
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);
1394 for (
i = 0, p = text; *p;
i++) {
1395 GET_UTF8(code, *p ? *p++ : 0, code = 0xfffd;
goto continue_on_invalid2;);
1396 continue_on_invalid2:
1399 if (prev_code ==
'\r' && code ==
'\n')
1405 max_text_line_w =
FFMAX(max_text_line_w, x);
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);
1426 s->
positions[
i].y =
y - glyph->bitmap_top + y_max;
1428 else x += glyph->advance;
1431 max_text_line_w =
FFMAX(x, max_text_line_w);
1454 box_w = max_text_line_w;
1463 int offsetleft =
FFMAX3(boxoffset, borderoffset,
1465 int offsettop =
FFMAX3(boxoffset, borderoffset,
1468 int offsetright =
FFMAX3(boxoffset, borderoffset,
1470 int offsetbottom =
FFMAX3(boxoffset, borderoffset,
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)
1478 s->
x =
FFMAX(width - box_w - offsetright, 0);
1479 if (s->
y + box_h + offsetbottom > height)
1480 s->
y =
FFMAX(height - box_h - offsetbottom, 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,
1576 .
inputs = avfilter_vf_drawtext_inputs,
1577 .
outputs = avfilter_vf_drawtext_outputs,
Context structure for the Lagged Fibonacci PRNG.
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
static int func_frame_num(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
char * y_expr
expression for y position
void av_bprintf(AVBPrint *buf, const char *fmt,...)
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
int tc24hmax
1 if timecode is wrapped to 24 hours, 0 otherwise
This structure describes decoded (raw) audio or video data.
uint8_t * fontcolor_expr
fontcolor expression to evaluate
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
int x
x position to start drawing text
static double drand(void *opaque, double min, double max)
static int func_metadata(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
static const AVOption drawtext_options[]
unsigned int fontsize
font size to use
FFDrawColor boxcolor
background color
#define AV_LOG_WARNING
Something somehow does not look correct.
static av_cold int parse_fontsize(AVFilterContext *ctx)
char * x_expr
expression for x position
Main libavfilter public API header.
uint8_t * fontfile
font to be used
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
int h
agreed upon image height
static const struct drawtext_function functions[]
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.
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
static int draw_text(AVFilterContext *ctx, AVFrame *frame, int width, int height)
uint8_t * text
text to be drawn
void * av_tree_find(const AVTreeNode *t, void *key, int(*cmp)(const void *key, const void *b), void *next[2])
#define FF_ARRAY_ELEMS(a)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
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.
char * tc_opt_string
specified timecode option string
static void error(const char *err)
static int draw_glyphs(DrawTextContext *s, AVFrame *frame, int width, int height, FFDrawColor *color, int x, int y, int borderw)
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
int boxborderw
box border width
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
struct AVTreeNode * av_tree_node_alloc(void)
Allocate an AVTreeNode.
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
Parse timecode representation (hh:mm:ss[:;.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
FT_Stroker stroker
freetype stroker handle
static int glyph_enu_free(void *opaque, void *elem)
static int func_pict_type(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
AVExpr * fontsize_pexpr
parsed expressions for fontsize
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
FT_Face face
freetype font face handle
static int glyph_cmp(const void *key, const void *b)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
static av_cold int init(AVFilterContext *ctx)
int start_number
starting frame number for n/frame_num var
static int load_font_file(AVFilterContext *ctx, const char *path, int index)
static const AVFilterPad avfilter_vf_drawtext_inputs[]
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
char av_get_picture_type_char(enum AVPictureType pict_type)
Return a single letter to describe the given picture type pict_type.
AVDictionary * metadata
metadata.
static av_cold void uninit(AVFilterContext *ctx)
FT_Vector * positions
positions for each element in the text
void av_tree_destroy(AVTreeNode *t)
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.
A filter pad used for either input or output.
A link between two filters.
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.
double var_values[VAR_VARS_NB]
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
AVBPrint expanded_text
used to contain the expanded text
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...
#define AV_BPRINT_SIZE_UNLIMITED
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVExpr * y_pexpr
parsed expressions for x and y
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
void * priv
private data for use by the filter
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
int y
y position to start drawing text
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
static int expand_function(AVFilterContext *ctx, AVBPrint *bp, char **rtext)
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link...
static av_always_inline av_const double round(double x)
FFDrawColor fontcolor
foreground color
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...
static const char *const fun2_names[]
int reload
reload text file for each frame
AVBPrint expanded_fontcolor
used to contain the expanded fontcolor spec
int w
agreed upon image width
#define FFDIFFSIGN(x, y)
Comparator.
static const struct ft_error ft_errors[]
enum AVPictureType pict_type
Picture type of the frame.
#define FF_DRAW_PROCESS_ALPHA
Process alpha pixel component.
#define AV_TIME_BASE
Internal time base represented as integer.
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
int64_t basetime
base pts time in the real world for display
char * fontsize_expr
expression for fontsize
int max_glyph_h
max glyph height
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
AVRational tc_rate
frame rate for timecode
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
static int func_eval_expr(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
static const AVFilterPad outputs[]
int format
agreed upon media format
AVTimecode tc
timecode context
static void update_color_with_alpha(DrawTextContext *s, FFDrawColor *color, const FFDrawColor incolor)
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.
#define AV_LOG_INFO
Standard information.
char * av_strdup(const char *s)
Duplicate a string.
int64_t pkt_duration
duration of the corresponding packet, expressed in AVStream->time_base units, 0 if unknown...
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static int load_font(AVFilterContext *ctx)
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
timecode wraps after 24 hours
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Describe the class of an AVClass context structure.
static int func_strftime(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
Rational number (pair of numerator and denominator).
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.
struct AVTreeNode * glyphs
rendered glyphs, stored using the UTF-32 char code
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
static int is_newline(uint32_t c)
const char * name
Filter name.
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
static int expand_text(AVFilterContext *ctx, char *text, AVBPrint *bp)
AVFilterLink ** outputs
array of pointers to output links
int tag
opaque argument to func
short int draw_box
draw box around text - true or false
static int config_input(AVFilterLink *inlink)
#define flags(name, subs,...)
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm)
Append a formatted date and time to a print buffer.
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
Load timecode string in buf.
AVFILTER_DEFINE_CLASS(drawtext)
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
static void update_alpha(DrawTextContext *s)
int(* func)(AVFilterContext *, AVBPrint *, char *, unsigned, char **, int)
static const char *const var_names[]
int use_kerning
font kerning is used - true/false
common internal and external API header
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
static int query_formats(AVFilterContext *ctx)
FT_Library library
freetype font library handle
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
double(* eval_func2)(void *, double a, double b)
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
static const AVFilterPad avfilter_vf_drawtext_outputs[]
static av_always_inline int diff(const uint32_t a, const uint32_t b)
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
AVFilterContext * dst
dest filter
int reinit
tells if the filter is being reinited
FFDrawColor shadowcolor
shadow color
static av_cold int update_fontsize(AVFilterContext *ctx)
void * av_tree_insert(AVTreeNode **tp, void *key, int(*cmp)(const void *key, const void *b), AVTreeNode **next)
Insert or remove an element.
int line_spacing
lines spacing in pixels
int max_glyph_w
max glyph width
static const eval_func2 fun2[]
and forward the result(frame or status change) to the corresponding input.If nothing is possible
static int func_pts(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
unsigned int default_fontsize
default font size to use
int fix_bounds
do we let it go out of frame bounds - t/f
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
#define av_malloc_array(a, b)
char * textfile
file with text to be drawn
static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code)
Load glyphs corresponding to the UTF-32 codepoint code.
static int load_textfile(AVFilterContext *ctx)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
static int eval_function(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv)
int ft_load_flags
flags used for loading fonts, see FT_LOAD_*
int pkt_size
size of the corresponding packet containing the compressed frame.
int exp_mode
expansion mode to use for the text
uint32_t flags
flags such as drop frame, +24 hours support, ...
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.
#define AVERROR_EXTERNAL
Generic error in an external library.
size_t nb_positions
number of elements of positions array
FFDrawColor bordercolor
border color
#define AV_NOPTS_VALUE
Undefined timestamp value.
static av_cold int set_fontsize(AVFilterContext *ctx, unsigned int fontsize)
#define AV_TIMECODE_STR_SIZE
simple arithmetic expression evaluator
static int func_eval_expr_int_format(AVFilterContext *ctx, AVBPrint *bp, char *fct, unsigned argc, char **argv, int tag)
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.