On 11/04/15 19:04, Luca Barbato wrote:
> And document both `draw` and `alpha`.
> ---
> doc/filters.texi | 11 +++++++++++
> libavfilter/vf_drawtext.c | 48
> +++++++++++++++++++++++++++++++++++++----------
> 2 files changed, 49 insertions(+), 10 deletions(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 28e3292..e36f9a2 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -1209,6 +1209,17 @@ The timestamp, expressed in seconds. It's NAN if the
> input timestamp is unknown.
>
> The default value of @var{x} and @var{y} is 0.
>
> +@item draw
> +Draw the text only if the expression evaluates as non-zero.
> +The expression accepts the same variables @var{x, y} do.
> +The default value is 1.
> +
> +@item alpha
> +Draw the text applying alpha blending. The value can
> +be either a number between 0.0 and 1.0
> +The expression accepts the same variables @var{x, y} do.
> +The default value is 1.
> +
> @item fontsize
> The font size to be used for drawing text.
> The default value of @var{fontsize} is 16.
> diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
> index 0befb56..3464c6d 100644
> --- a/libavfilter/vf_drawtext.c
> +++ b/libavfilter/vf_drawtext.c
> @@ -152,6 +152,9 @@ typedef struct DrawTextContext {
> char *d_expr;
> AVExpr *d_pexpr;
> int draw; ///< set to zero to prevent drawing
> + char *a_expr;
> + AVExpr *a_pexpr;
> + int alpha;
> AVLFG prng; ///< random
> } DrawTextContext;
>
> @@ -176,6 +179,7 @@ static const AVOption drawtext_options[]= {
> { "shadowy", NULL, OFFSET(shadowy),
> AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
> { "tabsize", NULL, OFFSET(tabsize),
> AV_OPT_TYPE_INT, { .i64 = 4 }, 0, INT_MAX, FLAGS },
> { "draw", "if false do not draw", OFFSET(d_expr),
> AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS },
> + { "alpha", "apply alpha while rendering", OFFSET(a_expr),
> AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS },
> { "fix_bounds", "if true, check and fix text coords to avoid clipping",
> OFFSET(fix_bounds),
> AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS },
>
> @@ -678,6 +682,8 @@ static int config_input(AVFilterLink *inlink)
> (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->d_pexpr, s->d_expr, var_names,
> + NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
> + (ret = av_expr_parse(&s->a_pexpr, s->a_expr, var_names,
> NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
> return AVERROR(EINVAL);
>
> @@ -713,7 +719,7 @@ static int config_input(AVFilterLink *inlink)
>
> #define SET_PIXEL_YUV(frame, yuva_color, val, x, y, hsub, vsub) { \
> luma_pos = ((x) ) + ((y) ) * frame->linesize[0]; \
> - alpha = yuva_color[3] * (val) * 129; \
> + alpha = yuva_color[3] * alpha_mul * (val) * 129 / 255; \
> frame->data[0][luma_pos] = (alpha * yuva_color[0] + (255*255*129 -
> alpha) * frame->data[0][luma_pos] ) >> 23; \
> if (((x) & ((1<<(hsub)) - 1)) == 0 && ((y) & ((1<<(vsub)) - 1)) == 0) {\
> chroma_pos1 = ((x) >> (hsub)) + ((y) >> (vsub)) *
> frame->linesize[1]; \
> @@ -725,7 +731,8 @@ static int config_input(AVFilterLink *inlink)
>
> static inline int draw_glyph_yuv(AVFrame *frame, FT_Bitmap *bitmap, unsigned
> int x,
> unsigned int y, unsigned int width,
> unsigned int height,
> - const uint8_t yuva_color[4], int hsub, int
> vsub)
> + const uint8_t yuva_color[4], int hsub, int
> vsub,
> + int alpha_mul)
> {
> int r, c, alpha;
> unsigned int luma_pos, chroma_pos1, chroma_pos2;
> @@ -747,7 +754,7 @@ static inline int draw_glyph_yuv(AVFrame *frame,
> FT_Bitmap *bitmap, unsigned int
>
> #define SET_PIXEL_RGB(frame, rgba_color, val, x, y, pixel_step, r_off,
> g_off, b_off, a_off) { \
> p = frame->data[0] + (x) * pixel_step + ((y) * frame->linesize[0]); \
> - alpha = rgba_color[3] * (val) * 129; \
> + alpha = rgba_color[3] * alpha_mul * (val) * 129 / 255;
> \
> *(p+r_off) = (alpha * rgba_color[0] + (255*255*129 - alpha) *
> *(p+r_off)) >> 23; \
> *(p+g_off) = (alpha * rgba_color[1] + (255*255*129 - alpha) *
> *(p+g_off)) >> 23; \
> *(p+b_off) = (alpha * rgba_color[2] + (255*255*129 - alpha) *
> *(p+b_off)) >> 23; \
> @@ -756,7 +763,8 @@ static inline int draw_glyph_yuv(AVFrame *frame,
> FT_Bitmap *bitmap, unsigned int
> static inline int draw_glyph_rgb(AVFrame *frame, FT_Bitmap *bitmap,
> unsigned int x, unsigned int y,
> unsigned int width, unsigned int height,
> int pixel_step,
> - const uint8_t rgba_color[4], const uint8_t
> rgba_map[4])
> + const uint8_t rgba_color[4], const uint8_t
> rgba_map[4],
> + int alpha_mul)
> {
> int r, c, alpha;
> uint8_t *p;
> @@ -780,11 +788,12 @@ static inline int draw_glyph_rgb(AVFrame *frame,
> FT_Bitmap *bitmap,
> static inline void drawbox(AVFrame *frame, unsigned int x, unsigned int y,
> unsigned int width, unsigned int height,
> uint8_t *line[4], int pixel_step[4], uint8_t
> color[4],
> - int hsub, int vsub, int is_rgba_packed, uint8_t
> rgba_map[4])
> + int hsub, int vsub, int is_rgba_packed, uint8_t
> rgba_map[4],
> + int alpha_mul)
> {
> int i, j, alpha;
>
> - if (color[3] != 0xFF) {
> + if (color[3] != 0xFF || alpha_mul != 0xFF) {
> if (is_rgba_packed) {
> uint8_t *p;
> for (j = 0; j < height; j++)
> @@ -805,7 +814,9 @@ static inline void drawbox(AVFrame *frame, unsigned int
> x, unsigned int y,
> }
>
> static int draw_glyphs(DrawTextContext *s, AVFrame *frame,
> - int width, int height, const uint8_t rgbcolor[4],
> const uint8_t yuvcolor[4], int x, int y)
> + int width, int height,
> + const uint8_t rgbcolor[4], const uint8_t yuvcolor[4],
> + int x, int y)
> {
> char *text = HAVE_LOCALTIME_R ? s->expanded_text : s->text;
> uint32_t code = 0;
> @@ -831,11 +842,11 @@ static int draw_glyphs(DrawTextContext *s, AVFrame
> *frame,
> if (s->is_packed_rgb) {
> draw_glyph_rgb(frame, &glyph->bitmap,
> s->positions[i].x+x, s->positions[i].y+y, width,
> height,
> - s->pixel_step[0], rgbcolor, s->rgba_map);
> + s->pixel_step[0], rgbcolor, s->rgba_map,
> s->alpha);
> } else {
> draw_glyph_yuv(frame, &glyph->bitmap,
> s->positions[i].x+x, s->positions[i].y+y, width,
> height,
> - yuvcolor, s->hsub, s->vsub);
> + yuvcolor, s->hsub, s->vsub, s->alpha);
> }
> }
>
> @@ -853,7 +864,7 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame,
> drawbox(frame, s->x, s->y, s->w, s->h,
> s->box_line, s->pixel_step, s->boxcolor,
> s->hsub, s->vsub, s->is_packed_rgb,
> - s->rgba_map);
> + s->rgba_map, s->alpha);
>
> if (s->shadowx || s->shadowy) {
> if ((ret = draw_glyphs(s, frame, width, height,
> @@ -889,6 +900,21 @@ static inline int normalize_double(int *n, double d)
> return ret;
> }
>
> +static void update_alpha(DrawTextContext *s)
> +{
> + double alpha = av_expr_eval(s->a_pexpr, s->var_values, &s->prng);
> +
> + if (isnan(alpha))
> + return;
> +
> + if (alpha >= 1.0)
> + s->alpha = 255;
> + else if (alpha <= 0)
> + s->alpha = 0;
> + else
> + s->alpha = 256 * alpha;
> +}
> +
> static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> {
> AVFilterContext *ctx = inlink->dst;
> @@ -912,6 +938,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame
> *frame)
>
> s->draw = av_expr_eval(s->d_pexpr, s->var_values, &s->prng);
>
> + update_alpha(s);
> +
> normalize_double(&s->x, s->var_values[VAR_X]);
> normalize_double(&s->y, s->var_values[VAR_Y]);
>
>
Ping.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel