[FFmpeg-devel] [PATCH 3/3] drawtext: allow burning the timecode.
Clément Bœsch
ubitux at gmail.com
Tue Dec 6 11:37:39 CET 2011
From: Clément Bœsch <clement.boesch at smartjog.com>
---
doc/filters.texi | 7 +++++++
libavfilter/vf_drawtext.c | 23 ++++++++++++++++++++++-
2 files changed, 29 insertions(+), 1 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index eb1a4df..667decb 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1148,6 +1148,13 @@ the number of input frame, starting from 0
@item t
timestamp expressed in seconds, NAN if the input timestamp is unknown
+
+ at item timecode
+initial timecode representation in "hh:mm:ss[:;.]ff" format. It can be used
+with or without text parameter. @var{rate} option must be specified
+
+ at item r, rate
+frame rate (timecode only)
@end table
Some examples follow.
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 900c803..ba3c01b 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -29,6 +29,8 @@
#include <sys/time.h>
#include <time.h>
+#include "libavcodec/timecode.h"
+#include "libavutil/avstring.h"
#include "libavutil/colorspace.h"
#include "libavutil/file.h"
#include "libavutil/eval.h"
@@ -132,6 +134,8 @@ typedef struct {
AVExpr *x_pexpr, *y_pexpr; ///< parsed expressions for x and y
int64_t basetime; ///< base pts time in the real world for display
double var_values[VAR_VARS_NB];
+ struct ff_timecode tc;
+ int frame_id;
} DrawTextContext;
#define OFFSET(x) offsetof(DrawTextContext, x)
@@ -151,6 +155,9 @@ static const AVOption drawtext_options[]= {
{"shadowy", "set y", OFFSET(shadowy), AV_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX },
{"tabsize", "set tab size", OFFSET(tabsize), AV_OPT_TYPE_INT, {.dbl=4}, 0, INT_MAX },
{"basetime", "set base time", OFFSET(basetime), AV_OPT_TYPE_INT64, {.dbl=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX },
+{"timecode", "set initial timecode", OFFSET(tc.str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
+{"r", "set rate (timecode only)", OFFSET(tc.rate), AV_OPT_TYPE_RATIONAL, {.dbl=0}, 0, INT_MAX },
+{"rate", "set rate (timecode only)", OFFSET(tc.rate), AV_OPT_TYPE_RATIONAL, {.dbl=0}, 0, INT_MAX },
/* FT_LOAD_* flags */
@@ -311,9 +318,16 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
av_file_unmap(textbuf, textbuf_size);
}
+ if (dtext->tc.str) {
+ if (ff_init_smtpe_timecode(ctx, &dtext->tc) < 0)
+ return AVERROR(EINVAL);
+ if (!dtext->text)
+ dtext->text = av_strdup("");
+ }
+
if (!dtext->text) {
av_log(ctx, AV_LOG_ERROR,
- "Either text or a valid file must be provided\n");
+ "Either text, a valid file or a timecode must be provided\n");
return AVERROR(EINVAL);
}
@@ -659,6 +673,8 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
uint8_t *buf = dtext->expanded_text;
int buf_size = dtext->expanded_text_size;
+ char tcbuf[sizeof("hh:mm:ss.ff")];
+
if(dtext->basetime != AV_NOPTS_VALUE)
now= picref->pts*av_q2d(ctx->inputs[0]->time_base) + dtext->basetime/1000000;
@@ -681,6 +697,11 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
buf_size *= 2;
} while ((buf = av_realloc(buf, buf_size)));
+ if (dtext->tc.str) {
+ ff_timecode_to_string(tcbuf, &dtext->tc, dtext->frame_id++);
+ buf = av_asprintf("%s%s", dtext->text, tcbuf);
+ }
+
if (!buf)
return AVERROR(ENOMEM);
text = dtext->expanded_text = buf;
--
1.7.7.3
More information about the ffmpeg-devel
mailing list