You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
lavfi/drawtext: add generic timeline interface and deprecate "draw".
This commit is contained in:
@@ -3239,16 +3239,6 @@ Either a string (e.g. "yellow") or in 0xRRGGBB[AA] format
|
|||||||
(e.g. "0xff00ff"), possibly followed by an alpha specifier.
|
(e.g. "0xff00ff"), possibly followed by an alpha specifier.
|
||||||
The default value of @var{boxcolor} is "white".
|
The default value of @var{boxcolor} is "white".
|
||||||
|
|
||||||
@item draw
|
|
||||||
Set an expression which specifies if the text should be drawn. If the
|
|
||||||
expression evaluates to 0, the text is not drawn. This is useful for
|
|
||||||
specifying that the text should be drawn only when specific conditions
|
|
||||||
are met.
|
|
||||||
|
|
||||||
Default value is "1".
|
|
||||||
|
|
||||||
See below for the list of accepted constants and functions.
|
|
||||||
|
|
||||||
@item expansion
|
@item expansion
|
||||||
Select how the @var{text} is expanded. Can be either @code{none},
|
Select how the @var{text} is expanded. Can be either @code{none},
|
||||||
@code{strftime} (deprecated) or
|
@code{strftime} (deprecated) or
|
||||||
@@ -3548,7 +3538,7 @@ drawtext="fontsize=60:fontfile=FreeSerif.ttf:fontcolor=green:text=g:x=(w-max_gly
|
|||||||
@item
|
@item
|
||||||
Show text for 1 second every 3 seconds:
|
Show text for 1 second every 3 seconds:
|
||||||
@example
|
@example
|
||||||
drawtext="fontfile=FreeSerif.ttf:fontcolor=white:x=100:y=x/dar:draw=lt(mod(t\,3)\,1):text='blink'"
|
drawtext="fontfile=FreeSerif.ttf:fontcolor=white:x=100:y=x/dar:enable=lt(mod(t\,3)\,1):text='blink'"
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item
|
@item
|
||||||
|
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#define LIBAVFILTER_VERSION_MAJOR 3
|
#define LIBAVFILTER_VERSION_MAJOR 3
|
||||||
#define LIBAVFILTER_VERSION_MINOR 83
|
#define LIBAVFILTER_VERSION_MINOR 83
|
||||||
#define LIBAVFILTER_VERSION_MICRO 101
|
#define LIBAVFILTER_VERSION_MICRO 102
|
||||||
|
|
||||||
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
||||||
LIBAVFILTER_VERSION_MINOR, \
|
LIBAVFILTER_VERSION_MINOR, \
|
||||||
@@ -82,5 +82,8 @@
|
|||||||
#ifndef FF_API_OLD_GRAPH_PARSE
|
#ifndef FF_API_OLD_GRAPH_PARSE
|
||||||
#define FF_API_OLD_GRAPH_PARSE (LIBAVFILTER_VERSION_MAJOR < 4)
|
#define FF_API_OLD_GRAPH_PARSE (LIBAVFILTER_VERSION_MAJOR < 4)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
|
#define FF_API_DRAWTEXT_OLD_TIMELINE (LIBAVFILTER_VERSION_MAJOR < 4)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* AVFILTER_VERSION_H */
|
#endif /* AVFILTER_VERSION_H */
|
||||||
|
@@ -155,9 +155,11 @@ typedef struct {
|
|||||||
AVExpr *x_pexpr, *y_pexpr; ///< parsed expressions for x and y
|
AVExpr *x_pexpr, *y_pexpr; ///< parsed expressions for x and y
|
||||||
int64_t basetime; ///< base pts time in the real world for display
|
int64_t basetime; ///< base pts time in the real world for display
|
||||||
double var_values[VAR_VARS_NB];
|
double var_values[VAR_VARS_NB];
|
||||||
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
char *draw_expr; ///< expression for draw
|
char *draw_expr; ///< expression for draw
|
||||||
AVExpr *draw_pexpr; ///< parsed expression for draw
|
AVExpr *draw_pexpr; ///< parsed expression for draw
|
||||||
int draw; ///< set to zero to prevent drawing
|
int draw; ///< set to zero to prevent drawing
|
||||||
|
#endif
|
||||||
AVLFG prng; ///< random
|
AVLFG prng; ///< random
|
||||||
char *tc_opt_string; ///< specified timecode option string
|
char *tc_opt_string; ///< specified timecode option string
|
||||||
AVRational tc_rate; ///< frame rate for timecode
|
AVRational tc_rate; ///< frame rate for timecode
|
||||||
@@ -186,7 +188,9 @@ static const AVOption drawtext_options[]= {
|
|||||||
{"shadowy", "set y", OFFSET(shadowy), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX , FLAGS},
|
{"shadowy", "set y", OFFSET(shadowy), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX , FLAGS},
|
||||||
{"tabsize", "set tab size", OFFSET(tabsize), AV_OPT_TYPE_INT, {.i64=4}, 0, INT_MAX , FLAGS},
|
{"tabsize", "set tab size", OFFSET(tabsize), AV_OPT_TYPE_INT, {.i64=4}, 0, INT_MAX , FLAGS},
|
||||||
{"basetime", "set base time", OFFSET(basetime), AV_OPT_TYPE_INT64, {.i64=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX , FLAGS},
|
{"basetime", "set base time", OFFSET(basetime), AV_OPT_TYPE_INT64, {.i64=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX , FLAGS},
|
||||||
{"draw", "if false do not draw", OFFSET(draw_expr), AV_OPT_TYPE_STRING, {.str="1"}, CHAR_MIN, CHAR_MAX, FLAGS},
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
|
{"draw", "if false do not draw (deprecated)", OFFSET(draw_expr), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS},
|
||||||
|
#endif
|
||||||
|
|
||||||
{"expansion", "set the expansion mode", OFFSET(exp_mode), AV_OPT_TYPE_INT, {.i64=EXP_NORMAL}, 0, 2, FLAGS, "expansion"},
|
{"expansion", "set the expansion mode", OFFSET(exp_mode), AV_OPT_TYPE_INT, {.i64=EXP_NORMAL}, 0, 2, FLAGS, "expansion"},
|
||||||
{"none", "set no expansion", OFFSET(exp_mode), AV_OPT_TYPE_CONST, {.i64=EXP_NONE}, 0, 0, FLAGS, "expansion"},
|
{"none", "set no expansion", OFFSET(exp_mode), AV_OPT_TYPE_CONST, {.i64=EXP_NONE}, 0, 0, FLAGS, "expansion"},
|
||||||
@@ -423,6 +427,12 @@ static av_cold int init(AVFilterContext *ctx)
|
|||||||
DrawTextContext *s = ctx->priv;
|
DrawTextContext *s = ctx->priv;
|
||||||
Glyph *glyph;
|
Glyph *glyph;
|
||||||
|
|
||||||
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
|
if (s->draw_expr)
|
||||||
|
av_log(ctx, AV_LOG_WARNING, "'draw' option is deprecated and will be removed soon, "
|
||||||
|
"you are encouraged to use the generic timeline support through the 'enable' option\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!s->fontfile && !CONFIG_FONTCONFIG) {
|
if (!s->fontfile && !CONFIG_FONTCONFIG) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
|
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
@@ -518,8 +528,10 @@ static av_cold void uninit(AVFilterContext *ctx)
|
|||||||
|
|
||||||
av_expr_free(s->x_pexpr);
|
av_expr_free(s->x_pexpr);
|
||||||
av_expr_free(s->y_pexpr);
|
av_expr_free(s->y_pexpr);
|
||||||
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
av_expr_free(s->draw_pexpr);
|
av_expr_free(s->draw_pexpr);
|
||||||
s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
|
s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
|
||||||
|
#endif
|
||||||
av_freep(&s->positions);
|
av_freep(&s->positions);
|
||||||
s->nb_positions = 0;
|
s->nb_positions = 0;
|
||||||
|
|
||||||
@@ -564,16 +576,25 @@ static int config_input(AVFilterLink *inlink)
|
|||||||
|
|
||||||
av_expr_free(s->x_pexpr);
|
av_expr_free(s->x_pexpr);
|
||||||
av_expr_free(s->y_pexpr);
|
av_expr_free(s->y_pexpr);
|
||||||
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
av_expr_free(s->draw_pexpr);
|
av_expr_free(s->draw_pexpr);
|
||||||
s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
|
s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
|
||||||
|
#else
|
||||||
|
s->x_pexpr = s->y_pexpr = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,
|
if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,
|
||||||
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
|
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
|
||||||
(ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names,
|
(ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names,
|
||||||
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
|
|
||||||
(ret = av_expr_parse(&s->draw_pexpr, s->draw_expr, var_names,
|
|
||||||
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
|
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
|
||||||
|
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
|
if (s->draw_expr &&
|
||||||
|
(ret = av_expr_parse(&s->draw_pexpr, s->draw_expr, var_names,
|
||||||
|
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -955,10 +976,16 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame,
|
|||||||
s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
|
s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
|
||||||
s->y = s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, &s->prng);
|
s->y = s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, &s->prng);
|
||||||
s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
|
s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
|
||||||
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
|
if (s->draw_pexpr){
|
||||||
s->draw = av_expr_eval(s->draw_pexpr, s->var_values, &s->prng);
|
s->draw = av_expr_eval(s->draw_pexpr, s->var_values, &s->prng);
|
||||||
|
|
||||||
if(!s->draw)
|
if(!s->draw)
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
if (ctx->is_disabled)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
box_w = FFMIN(width - 1 , max_text_line_w);
|
box_w = FFMIN(width - 1 , max_text_line_w);
|
||||||
box_h = FFMIN(height - 1, y + s->max_glyph_h);
|
box_h = FFMIN(height - 1, y + s->max_glyph_h);
|
||||||
@@ -1042,4 +1069,9 @@ AVFilter avfilter_vf_drawtext = {
|
|||||||
.inputs = avfilter_vf_drawtext_inputs,
|
.inputs = avfilter_vf_drawtext_inputs,
|
||||||
.outputs = avfilter_vf_drawtext_outputs,
|
.outputs = avfilter_vf_drawtext_outputs,
|
||||||
.process_command = command,
|
.process_command = command,
|
||||||
|
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||||
|
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
|
||||||
|
#else
|
||||||
|
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user