...
|
...
|
@@ -144,43 +144,44 @@ typedef struct {
|
144
|
144
|
} DrawTextContext;
|
145
|
145
|
|
146
|
146
|
#define OFFSET(x) offsetof(DrawTextContext, x)
|
|
147
|
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
|
147
|
148
|
|
148
|
149
|
static const AVOption drawtext_options[]= {
|
149
|
|
-{"fontfile", "set font file", OFFSET(fontfile), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
|
150
|
|
-{"text", "set text", OFFSET(text), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
|
151
|
|
-{"textfile", "set text file", OFFSET(textfile), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
|
152
|
|
-{"fontcolor","set foreground color", OFFSET(fontcolor_string), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
|
153
|
|
-{"boxcolor", "set box color", OFFSET(boxcolor_string), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
|
154
|
|
-{"shadowcolor", "set shadow color", OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
|
155
|
|
-{"box", "set box", OFFSET(draw_box), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
|
156
|
|
-{"fontsize", "set font size", OFFSET(fontsize), AV_OPT_TYPE_INT, {.i64=16}, 1, 72 },
|
157
|
|
-{"x", "set x", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX },
|
158
|
|
-{"y", "set y", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX },
|
159
|
|
-{"shadowx", "set x", OFFSET(shadowx), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX },
|
160
|
|
-{"shadowy", "set y", OFFSET(shadowy), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX },
|
161
|
|
-{"tabsize", "set tab size", OFFSET(tabsize), AV_OPT_TYPE_INT, {.i64=4}, 0, INT_MAX },
|
162
|
|
-{"draw", "if false do not draw", OFFSET(d_expr), AV_OPT_TYPE_STRING, {.str="1"}, CHAR_MIN, CHAR_MAX },
|
163
|
|
-{"fix_bounds", "if true, check and fix text coords to avoid clipping",
|
164
|
|
- OFFSET(fix_bounds), AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
|
165
|
|
-
|
166
|
|
-/* FT_LOAD_* flags */
|
167
|
|
-{"ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), AV_OPT_TYPE_FLAGS, {.i64=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, 0, "ft_load_flags" },
|
168
|
|
-{"default", "set default", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_DEFAULT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
169
|
|
-{"no_scale", "set no_scale", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_SCALE}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
170
|
|
-{"no_hinting", "set no_hinting", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_HINTING}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
171
|
|
-{"render", "set render", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_RENDER}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
172
|
|
-{"no_bitmap", "set no_bitmap", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
173
|
|
-{"vertical_layout", "set vertical_layout", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_VERTICAL_LAYOUT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
174
|
|
-{"force_autohint", "set force_autohint", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_FORCE_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
175
|
|
-{"crop_bitmap", "set crop_bitmap", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_CROP_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
176
|
|
-{"pedantic", "set pedantic", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_PEDANTIC}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
177
|
|
-{"ignore_global_advance_width", "set ignore_global_advance_width", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
178
|
|
-{"no_recurse", "set no_recurse", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_RECURSE}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
179
|
|
-{"ignore_transform", "set ignore_transform", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_IGNORE_TRANSFORM}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
180
|
|
-{"monochrome", "set monochrome", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_MONOCHROME}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
181
|
|
-{"linear_design", "set linear_design", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_LINEAR_DESIGN}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
182
|
|
-{"no_autohint", "set no_autohint", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
|
183
|
|
-{NULL},
|
|
150
|
+ { "fontfile", NULL, OFFSET(fontfile), AV_OPT_TYPE_STRING, .flags = FLAGS },
|
|
151
|
+ { "text", NULL, OFFSET(text), AV_OPT_TYPE_STRING, .flags = FLAGS },
|
|
152
|
+ { "textfile", NULL, OFFSET(textfile), AV_OPT_TYPE_STRING, .flags = FLAGS },
|
|
153
|
+ { "fontcolor", NULL, OFFSET(fontcolor_string), AV_OPT_TYPE_STRING, { .str = "black" }, .flags = FLAGS },
|
|
154
|
+ { "boxcolor", NULL, OFFSET(boxcolor_string), AV_OPT_TYPE_STRING, { .str = "white" }, .flags = FLAGS },
|
|
155
|
+ { "shadowcolor", NULL, OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, { .str = "black" }, .flags = FLAGS },
|
|
156
|
+ { "box", NULL, OFFSET(draw_box), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
|
|
157
|
+ { "fontsize", NULL, OFFSET(fontsize), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, 72, FLAGS },
|
|
158
|
+ { "x", NULL, OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
|
|
159
|
+ { "y", NULL, OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
|
|
160
|
+ { "shadowx", NULL, OFFSET(shadowx), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
|
|
161
|
+ { "shadowy", NULL, OFFSET(shadowy), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
|
|
162
|
+ { "tabsize", NULL, OFFSET(tabsize), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, INT_MAX, FLAGS },
|
|
163
|
+ { "draw", "if false do not draw", OFFSET(d_expr), AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS },
|
|
164
|
+ { "fix_bounds", "if true, check and fix text coords to avoid clipping",
|
|
165
|
+ OFFSET(fix_bounds), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS },
|
|
166
|
+
|
|
167
|
+ /* FT_LOAD_* flags */
|
|
168
|
+ { "ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), AV_OPT_TYPE_FLAGS, { .i64 = FT_LOAD_DEFAULT | FT_LOAD_RENDER}, 0, INT_MAX, FLAGS, "ft_load_flags" },
|
|
169
|
+ { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_DEFAULT }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
170
|
+ { "no_scale", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_SCALE }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
171
|
+ { "no_hinting", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_HINTING }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
172
|
+ { "render", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_RENDER }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
173
|
+ { "no_bitmap", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_BITMAP }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
174
|
+ { "vertical_layout", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_VERTICAL_LAYOUT }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
175
|
+ { "force_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_FORCE_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
176
|
+ { "crop_bitmap", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_CROP_BITMAP }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
177
|
+ { "pedantic", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_PEDANTIC }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
178
|
+ { "ignore_global_advance_width", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
179
|
+ { "no_recurse", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_RECURSE }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
180
|
+ { "ignore_transform", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_TRANSFORM }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
181
|
+ { "monochrome", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_MONOCHROME }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
182
|
+ { "linear_design", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_LINEAR_DESIGN }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
183
|
+ { "no_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" },
|
|
184
|
+ { NULL},
|
184
|
185
|
};
|
185
|
186
|
|
186
|
187
|
static const char *drawtext_get_name(void *ctx)
|
...
|
...
|
@@ -285,17 +286,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
|
285
|
285
|
DrawTextContext *dtext = ctx->priv;
|
286
|
286
|
Glyph *glyph;
|
287
|
287
|
|
288
|
|
- dtext->class = &drawtext_class;
|
289
|
|
- av_opt_set_defaults(dtext);
|
290
|
|
- dtext->fontcolor_string = av_strdup("black");
|
291
|
|
- dtext->boxcolor_string = av_strdup("white");
|
292
|
|
- dtext->shadowcolor_string = av_strdup("black");
|
293
|
|
-
|
294
|
|
- if ((err = (av_set_options_string(dtext, args, "=", ":"))) < 0) {
|
295
|
|
- av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
|
296
|
|
- return err;
|
297
|
|
- }
|
298
|
|
-
|
299
|
288
|
if (!dtext->fontfile) {
|
300
|
289
|
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
|
301
|
290
|
return AVERROR(EINVAL);
|
...
|
...
|
@@ -412,13 +402,8 @@ static av_cold void uninit(AVFilterContext *ctx)
|
412
|
412
|
DrawTextContext *dtext = ctx->priv;
|
413
|
413
|
int i;
|
414
|
414
|
|
415
|
|
- av_freep(&dtext->fontfile);
|
416
|
|
- av_freep(&dtext->text);
|
417
|
415
|
av_freep(&dtext->expanded_text);
|
418
|
|
- av_freep(&dtext->fontcolor_string);
|
419
|
|
- av_freep(&dtext->boxcolor_string);
|
420
|
416
|
av_freep(&dtext->positions);
|
421
|
|
- av_freep(&dtext->shadowcolor_string);
|
422
|
417
|
av_tree_enumerate(dtext->glyphs, NULL, NULL, glyph_enu_free);
|
423
|
418
|
av_tree_destroy(dtext->glyphs);
|
424
|
419
|
dtext->glyphs = 0;
|
...
|
...
|
@@ -879,6 +864,7 @@ AVFilter avfilter_vf_drawtext = {
|
879
|
879
|
.name = "drawtext",
|
880
|
880
|
.description = NULL_IF_CONFIG_SMALL("Draw text on top of video frames using libfreetype library."),
|
881
|
881
|
.priv_size = sizeof(DrawTextContext),
|
|
882
|
+ .priv_class = &drawtext_class,
|
882
|
883
|
.init = init,
|
883
|
884
|
.uninit = uninit,
|
884
|
885
|
.query_formats = query_formats,
|