int pixel_step[4]; ///< distance in bytes between the component of each pixel
uint8_t rgba_map[4]; ///< map RGBA offsets to the positions in the packed RGBA format
uint8_t *box_line[4]; ///< line used for filling the box background
+ int64_t basetime; ///< base pts time in the real world for display
} DrawTextContext;
#define OFFSET(x) offsetof(DrawTextContext, x)
{"shadowx", "set x", OFFSET(shadowx), FF_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX },
{"shadowy", "set y", OFFSET(shadowy), FF_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX },
{"tabsize", "set tab size", OFFSET(tabsize), FF_OPT_TYPE_INT, {.dbl=4}, 0, INT_MAX },
+{"basetime", "set base time", OFFSET(basetime), FF_OPT_TYPE_INT64, {.dbl=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX },
+
/* FT_LOAD_* flags */
{"ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), FF_OPT_TYPE_FLAGS, {.dbl=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, 0, "ft_load_flags" },
Glyph *glyph;
dtext->class = &drawtext_class;
- av_opt_set_defaults2(dtext, 0, 0);
+ av_opt_set_defaults(dtext);
dtext->fontcolor_string = av_strdup("black");
dtext->boxcolor_string = av_strdup("white");
dtext->shadowcolor_string = av_strdup("black");
}
dtext->tabsize *= glyph->advance;
-#if !HAVE_LOCALTIME_R
- av_log(ctx, AV_LOG_WARNING, "strftime() expansion unavailable!\n");
-#endif
-
return 0;
}
av_freep(&dtext->fontcolor_string);
av_freep(&dtext->boxcolor_string);
av_freep(&dtext->positions);
+ dtext->nb_positions = 0;
av_freep(&dtext->shadowcolor_string);
av_tree_enumerate(dtext->glyphs, NULL, NULL, glyph_enu_free);
av_tree_destroy(dtext->glyphs);
return 0;
}
+static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
+{
+ if(!strcmp(cmd, "reinit")){
+ int ret;
+ uninit(ctx);
+ if((ret=init(ctx, arg, NULL)) < 0)
+ return ret;
+ return config_input(ctx->inputs[0]);
+ }
+
+ return AVERROR(ENOSYS);
+}
+
#define GET_BITMAP_VAL(r, c) \
bitmap->pixel_mode == FT_PIXEL_MODE_MONO ? \
(bitmap->buffer[(r) * bitmap->pitch + ((c)>>3)] & (0x80 >> ((c)&7))) * 255 : \
{
int r, c, alpha;
unsigned int luma_pos, chroma_pos1, chroma_pos2;
- uint8_t src_val, dst_pixel[4];
+ uint8_t src_val;
for (r = 0; r < bitmap->rows && r+y < height; r++) {
for (c = 0; c < bitmap->width && c+x < width; c++) {
- /* get pixel in the picref (destination) */
- dst_pixel[0] = picref->data[0][ c+x + (y+r) * picref->linesize[0]];
- dst_pixel[1] = picref->data[1][((c+x) >> hsub) + ((y+r) >> vsub) * picref->linesize[1]];
- dst_pixel[2] = picref->data[2][((c+x) >> hsub) + ((y+r) >> vsub) * picref->linesize[2]];
-
/* get intensity value in the glyph bitmap (source) */
src_val = GET_BITMAP_VAL(r, c);
if (!src_val)
{
int r, c, alpha;
uint8_t *p;
- uint8_t src_val, dst_pixel[4];
+ uint8_t src_val;
for (r = 0; r < bitmap->rows && r+y < height; r++) {
for (c = 0; c < bitmap->width && c+x < width; c++) {
- /* get pixel in the picref (destination) */
- dst_pixel[0] = picref->data[0][(c+x + rgba_map[0]) * pixel_step +
- (y+r) * picref->linesize[0]];
- dst_pixel[1] = picref->data[0][(c+x + rgba_map[1]) * pixel_step +
- (y+r) * picref->linesize[0]];
- dst_pixel[2] = picref->data[0][(c+x + rgba_map[2]) * pixel_step +
- (y+r) * picref->linesize[0]];
-
/* get intensity value in the glyph bitmap (source) */
src_val = GET_BITMAP_VAL(r, c);
if (!src_val)
static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
int width, int height, const uint8_t rgbcolor[4], const uint8_t yuvcolor[4], int x, int y)
{
- char *text = HAVE_LOCALTIME_R ? dtext->expanded_text : dtext->text;
+ char *text = dtext->expanded_text;
uint32_t code = 0;
int i;
uint8_t *p;
Glyph *glyph = NULL, *prev_glyph = NULL;
Glyph dummy = { 0 };
-#if HAVE_LOCALTIME_R
time_t now = time(0);
struct tm ltime;
uint8_t *buf = dtext->expanded_text;
int buf_size = dtext->expanded_text_size;
+ if(dtext->basetime != AV_NOPTS_VALUE)
+ now= picref->pts*av_q2d(ctx->inputs[0]->time_base) + dtext->basetime/1000000;
+
if (!buf) {
buf_size = 2*strlen(dtext->text)+1;
buf = av_malloc(buf_size);
}
+#if HAVE_LOCALTIME_R
localtime_r(&now, <ime);
+#else
+ if(strchr(dtext->text, '%'))
+ ltime= *localtime(&now);
+#endif
do {
*buf = 1;
return AVERROR(ENOMEM);
text = dtext->expanded_text = buf;
dtext->expanded_text_size = buf_size;
-#endif
if ((len = strlen(text)) > dtext->nb_positions) {
if (!(dtext->positions =
av_realloc(dtext->positions, len*sizeof(*dtext->positions))))
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, },
{ .name = NULL}},
+ .process_command = command,
};