[FFmpeg-cvslog] Add shadow support to the drawtext filter

Michael Niedermayer git
Tue Feb 22 01:51:47 CET 2011


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Tue Feb 22 01:41:52 2011 +0100| [f9c61974ae93258f78b9bb811476cad2062b9b76] | committer: Michael Niedermayer

Add shadow support to the drawtext filter

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f9c61974ae93258f78b9bb811476cad2062b9b76
---

 libavfilter/vf_drawtext.c |   37 +++++++++++++++++++++++++++++++------
 1 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 7802208..2751354 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -59,13 +59,17 @@ typedef struct {
     char *textfile;                 ///< file with text to be drawn
     unsigned int x;                 ///< x position to start drawing text
     unsigned int y;                 ///< y position to start drawing text
+    int shadowx, shadowy;
     unsigned int fontsize;          ///< font size to use
     char *fontcolor_string;         ///< font color as string
     char *boxcolor_string;          ///< box color as string
+    char *shadowcolor_string;       ///< shadow color as string
     uint8_t fontcolor[4];           ///< foreground color
     uint8_t boxcolor[4];            ///< background color
+    uint8_t shadowcolor[4];         ///< shadow color
     uint8_t fontcolor_rgba[4];      ///< foreground color in RGBA
     uint8_t boxcolor_rgba[4];       ///< background color in RGBA
+    uint8_t shadowcolor_rgba[4];    ///< shadow color in RGBA
 
     short int draw_box;             ///< draw box around text - true or false
     int use_kerning;                ///< font kerning is used - true/false
@@ -89,10 +93,13 @@ static const AVOption drawtext_options[]= {
 {"textfile", "set text file",        OFFSET(textfile),         FF_OPT_TYPE_STRING, 0,  CHAR_MIN, CHAR_MAX },
 {"fontcolor","set foreground color", OFFSET(fontcolor_string), FF_OPT_TYPE_STRING, 0,  CHAR_MIN, CHAR_MAX },
 {"boxcolor", "set box color",        OFFSET(boxcolor_string),  FF_OPT_TYPE_STRING, 0,  CHAR_MIN, CHAR_MAX },
+{"shadowcolor", "set shadow color",  OFFSET(shadowcolor_string),  FF_OPT_TYPE_STRING, 0,  CHAR_MIN, CHAR_MAX },
 {"box",      "set box",              OFFSET(draw_box),         FF_OPT_TYPE_INT,    0,         0,        1 },
 {"fontsize", "set font size",        OFFSET(fontsize),         FF_OPT_TYPE_INT,   16,         1,       72 },
 {"x",        "set x",                OFFSET(x),                FF_OPT_TYPE_INT,    0,         0,  INT_MAX },
 {"y",        "set y",                OFFSET(y),                FF_OPT_TYPE_INT,    0,         0,  INT_MAX },
+{"shadowx",  "set x",                OFFSET(shadowx),          FF_OPT_TYPE_INT,    0,         0,  INT_MAX },
+{"shadowy",  "set y",                OFFSET(shadowy),          FF_OPT_TYPE_INT,    0,         0,  INT_MAX },
 {"tabsize",  "set tab size",         OFFSET(tabsize),          FF_OPT_TYPE_INT,    4,         0,  INT_MAX },
 
 /* FT_LOAD_* flags */
@@ -205,6 +212,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
     av_opt_set_defaults2(dtext, 0, 0);
     dtext->fontcolor_string = av_strdup("black");
     dtext->boxcolor_string = av_strdup("white");
+    dtext->shadowcolor_string = av_strdup("black");
 
     if ((err = (av_set_options_string(dtext, args, "=", ":"))) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
@@ -257,6 +265,12 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
         return err;
     }
 
+    if ((err = av_parse_color(dtext->shadowcolor_rgba, dtext->shadowcolor_string, -1, ctx))) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Invalid shadow color '%s'\n", dtext->shadowcolor_string);
+        return err;
+    }
+
     if ((err = FT_Init_FreeType(&(dtext->library)))) {
         av_log(ctx, AV_LOG_ERROR,
                "Could not load FreeType: %s\n", FT_ERRMSG(err));
@@ -324,6 +338,7 @@ static av_cold void uninit(AVFilterContext *ctx)
     av_freep(&dtext->text);
     av_freep(&dtext->fontcolor_string);
     av_freep(&dtext->boxcolor_string);
+    av_freep(&dtext->shadowcolor_string);
     av_tree_enumerate(dtext->glyphs, NULL, NULL, glyph_enu_free);
     av_tree_destroy(dtext->glyphs);
     dtext->glyphs = 0;
@@ -359,6 +374,11 @@ static int config_input(AVFilterLink *inlink)
         dtext->fontcolor[1] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
         dtext->fontcolor[2] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
         dtext->fontcolor[3] = rgba[3];
+        rgba = dtext->shadowcolor_rgba;
+        dtext->shadowcolor[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
+        dtext->shadowcolor[1] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        dtext->shadowcolor[2] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        dtext->shadowcolor[3] = rgba[3];
     }
 
     return 0;
@@ -476,7 +496,7 @@ static inline void drawbox(AVFilterBufferRef *picref, unsigned int x, unsigned i
 }
 
 static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
-                        int width, int height)
+                       int width, int height, const uint8_t rgbcolor[4], const uint8_t yuvcolor[4], int x, int y)
 {
     char *text = dtext->text;
     uint32_t code = 0;
@@ -501,12 +521,12 @@ static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
 
         if (dtext->is_packed_rgb) {
             draw_glyph_rgb(picref, &glyph->bitmap,
-                           dtext->positions[i].x, dtext->positions[i].y, width, height,
-                           dtext->pixel_step[0], dtext->fontcolor_rgba, dtext->rgba_map);
+                           dtext->positions[i].x+x, dtext->positions[i].y+y, width, height,
+                           dtext->pixel_step[0], rgbcolor, dtext->rgba_map);
         } else {
             draw_glyph_yuv(picref, &glyph->bitmap,
-                           dtext->positions[i].x, dtext->positions[i].y, width, height,
-                           dtext->fontcolor, dtext->hsub, dtext->vsub);
+                           dtext->positions[i].x+x, dtext->positions[i].y+y, width, height,
+                           yuvcolor, dtext->hsub, dtext->vsub);
         }
     }
 
@@ -621,7 +641,12 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
                 dtext->hsub, dtext->vsub, dtext->is_packed_rgb, dtext->rgba_map);
     }
 
-    if((ret=draw_glyphs(dtext, picref, width, height))<0)
+    if(dtext->shadowx || dtext->shadowy){
+        if((ret=draw_glyphs(dtext, picref, width, height, dtext->shadowcolor_rgba, dtext->shadowcolor, dtext->shadowx, dtext->shadowy))<0)
+            return ret;
+    }
+
+    if((ret=draw_glyphs(dtext, picref, width, height, dtext->fontcolor_rgba, dtext->fontcolor, 0, 0))<0)
         return ret;
 
     return 0;




More information about the ffmpeg-cvslog mailing list