[FFmpeg-cvslog] drawtext: refactor draw_text

Luca Barbato git at videolan.org
Sun Dec 4 01:09:26 CET 2011


ffmpeg | branch: master | Luca Barbato <lu_zero at gentoo.org> | Thu Dec  1 11:14:54 2011 +0100| [a2fb4bcb0189f6421608e0dec1a38c65910763f6] | committer: Luca Barbato

drawtext: refactor draw_text

Split the memory allocation from the actual drawing.

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

 libavfilter/vf_drawtext.c |   67 +++++++++++++++++++++++++++++++--------------
 1 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index c145874..3d6b7b0 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -55,8 +55,8 @@ typedef struct {
     FT_Vector *positions;           ///< positions for each element in the text
     size_t nb_positions;            ///< number of elements of positions array
     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 x, y;                       ///< position to start drawing text
+    int w, h;                       ///< dimension of the text block
     int shadowx, shadowy;
     unsigned int fontsize;          ///< font size to use
     char *fontcolor_string;         ///< font color as string
@@ -542,8 +542,7 @@ static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
     return 0;
 }
 
-static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
-                     int width, int height)
+static int dtext_prepare_text(AVFilterContext *ctx, int width, int height)
 {
     DrawTextContext *dtext = ctx->priv;
     uint32_t code = 0, prev_code = 0;
@@ -582,16 +581,20 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
     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))))
+        FT_Vector *p = av_realloc(dtext->positions,
+                                  len * sizeof(*dtext->positions));
+        if (!p) {
+            av_freep(dtext->positions);
+            dtext->nb_positions = 0;
             return AVERROR(ENOMEM);
-        dtext->nb_positions = len;
+        } else {
+            dtext->positions = p;
+            dtext->nb_positions = len;
+        }
     }
 
-    x = dtext->x;
-    y = dtext->y;
-
     /* load and cache glyphs */
     for (i = 0, p = text; *p; i++) {
         GET_UTF8(code, *p++, continue;);
@@ -600,7 +603,8 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
         dummy.code = code;
         glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
         if (!glyph)
-            load_glyph(ctx, &glyph, code);
+            ret = load_glyph(ctx, &glyph, code);
+        if (ret) return ret;
 
         y_min = FFMIN(glyph->bbox.yMin, y_min);
         y_max = FFMAX(glyph->bbox.yMax, y_max);
@@ -621,7 +625,7 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
         if (is_newline(code)) {
             str_w = FFMAX(str_w, x - dtext->x);
             y += text_height;
-            x = dtext->x;
+            x = 0;
             continue;
         }
 
@@ -638,9 +642,9 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
         }
 
         if (x + glyph->bbox.xMax >= width) {
-            str_w = FFMAX(str_w, x - dtext->x);
+            str_w = FFMAX(str_w, x);
             y += text_height;
-            x = dtext->x;
+            x = 0;
         }
 
         /* save position */
@@ -650,23 +654,43 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
         else              x += glyph->advance;
     }
 
-    str_w = FFMIN(width - dtext->x - 1, FFMAX(str_w, x - dtext->x));
+    str_w = FFMIN(width - 1, FFMAX(str_w, x));
     y     = FFMIN(y + text_height, height - 1);
 
+    dtext->w = str_w;
+    dtext->h = y;
+
+    return 0;
+}
+
+
+static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
+                     int width, int height)
+{
+    DrawTextContext *dtext = ctx->priv;
+    int ret;
+
     /* draw box */
     if (dtext->draw_box)
-        drawbox(picref, dtext->x, dtext->y, str_w, y-dtext->y,
+        drawbox(picref, dtext->x, dtext->y, dtext->w, dtext->h,
                 dtext->box_line, dtext->pixel_step, dtext->boxcolor,
-                dtext->hsub, dtext->vsub, dtext->is_packed_rgb, dtext->rgba_map);
+                dtext->hsub, dtext->vsub, dtext->is_packed_rgb,
+                dtext->rgba_map);
 
     if (dtext->shadowx || dtext->shadowy) {
-        if ((ret = draw_glyphs(dtext, picref, width, height, dtext->shadowcolor_rgba,
-                               dtext->shadowcolor, dtext->shadowx, dtext->shadowy)) < 0)
+        if ((ret = draw_glyphs(dtext, picref, width, height,
+                               dtext->shadowcolor_rgba,
+                               dtext->shadowcolor,
+                               dtext->x + dtext->shadowx,
+                               dtext->y + dtext->shadowy)) < 0)
             return ret;
     }
 
-    if ((ret = draw_glyphs(dtext, picref, width, height, dtext->fontcolor_rgba,
-                           dtext->fontcolor, 0, 0)) < 0)
+    if ((ret = draw_glyphs(dtext, picref, width, height,
+                           dtext->fontcolor_rgba,
+                           dtext->fontcolor,
+                           dtext->x,
+                           dtext->y)) < 0)
         return ret;
 
     return 0;
@@ -679,6 +703,7 @@ static void end_frame(AVFilterLink *inlink)
     AVFilterLink *outlink = inlink->dst->outputs[0];
     AVFilterBufferRef *picref = inlink->cur_buf;
 
+    dtext_prepare_text(inlink->dst, picref->video->w, picref->video->h);
     draw_text(inlink->dst, picref, picref->video->w, picref->video->h);
 
     avfilter_draw_slice(outlink, 0, picref->video->h, 1);



More information about the ffmpeg-cvslog mailing list