[FFmpeg-devel] [PATCH] avfilter/drawbox+drawgrid - add option to prevent overwriting, of source pixels

Gyan Doshi gyandoshi at gmail.com
Tue Dec 12 15:06:29 EET 2017


As noted in ticket #6911, drawbox and drawgrids implement anomalous 
behaviour if the source or user-color has alpha - source pixels are 
destroyed. Patch introduces new boolean option, whose default value, 
allows both expected result and current behaviour.

Regards,
Gyan
-------------- next part --------------
From cc2979978a8c101588c237c0bc9b6c03731b10e9 Mon Sep 17 00:00:00 2001
From: Gyan Doshi <gyandoshi at gmail.com>
Date: Mon, 11 Dec 2017 22:35:18 +0530
Subject: [PATCH] avfilter/drawbox+drawgrid - add option to prevent overwriting
 of source pixels

If the user-supplied color in drawbox and drawgrid filters is non-opaque,
the box & grid painting overwrites the input's pixels (including alpha).
Users typically expect the alpha of the specified color to only act as a key
for compositing on top of the main input.

Added option allows users to select between replacement and composition.
Tested and documented.
---
 doc/filters.texi         | 10 ++++++++++
 libavfilter/vf_drawbox.c |  7 +++++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 3346438231..70105b928a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -7146,6 +7146,11 @@ The expression which sets the thickness of the box edge.
 A value of @code{fill} will create a filled box. Default value is @code{3}.
 
 See below for the list of accepted constants.
+
+ at item replace
+Applicable if the input has alpha. With value @code{1}, the pixels of the painted box
+will overwrite the video's color and alpha pixels.
+Default is @code{0}, which composites the box onto the input, leaving the video's alpha intact.
 @end table
 
 The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
@@ -7243,6 +7248,11 @@ video with inverted luma.
 The expression which sets the thickness of the grid line. Default value is @code{1}.
 
 See below for the list of accepted constants.
+
+ at item replace
+Applicable if the input has alpha. With @code{1} the pixels of the painted grid
+will overwrite the video's color and alpha pixels.
+Default is @code{0}, which composites the grid onto the input, leaving the video's alpha intact.
 @end table
 
 The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index d351846594..c9cb63dbd1 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -80,6 +80,7 @@ typedef struct DrawBoxContext {
     char *w_expr, *h_expr; ///< expression for width and height
     char *t_expr;          ///< expression for thickness
     int have_alpha;
+    int replace;
 } DrawBoxContext;
 
 static const int NUM_EXPR_EVALS = 5;
@@ -213,7 +214,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
     int plane, x, y, xb = s->x, yb = s->y;
     unsigned char *row[4];
 
-    if (s->have_alpha) {
+    if (s->have_alpha && s->replace) {
         for (y = FFMAX(yb, 0); y < frame->height && y < (yb + s->h); y++) {
             row[0] = frame->data[0] + y * frame->linesize[0];
             row[3] = frame->data[3] + y * frame->linesize[3];
@@ -286,6 +287,7 @@ static const AVOption drawbox_options[] = {
     { "c",         "set color of the box",                         OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS },
     { "thickness", "set the box thickness",                        OFFSET(t_expr),    AV_OPT_TYPE_STRING, { .str="3" },       CHAR_MIN, CHAR_MAX, FLAGS },
     { "t",         "set the box thickness",                        OFFSET(t_expr),    AV_OPT_TYPE_STRING, { .str="3" },       CHAR_MIN, CHAR_MAX, FLAGS },
+    { "replace",   "replace color & alpha",                        OFFSET(replace),   AV_OPT_TYPE_BOOL,   { .i64=0 },         0,        1,        FLAGS },
     { NULL }
 };
 
@@ -354,7 +356,7 @@ static int drawgrid_filter_frame(AVFilterLink *inlink, AVFrame *frame)
     int plane, x, y;
     uint8_t *row[4];
 
-    if (drawgrid->have_alpha) {
+    if (drawgrid->have_alpha && drawgrid->replace) {
         for (y = 0; y < frame->height; y++) {
             row[0] = frame->data[0] + y * frame->linesize[0];
             row[3] = frame->data[3] + y * frame->linesize[3];
@@ -418,6 +420,7 @@ static const AVOption drawgrid_options[] = {
     { "c",         "set color of the grid",   OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS },
     { "thickness", "set grid line thickness", OFFSET(t_expr),    AV_OPT_TYPE_STRING, {.str="1"},         CHAR_MIN, CHAR_MAX, FLAGS },
     { "t",         "set grid line thickness", OFFSET(t_expr),    AV_OPT_TYPE_STRING, {.str="1"},         CHAR_MIN, CHAR_MAX, FLAGS },
+    { "replace",   "replace color & alpha",   OFFSET(replace),   AV_OPT_TYPE_BOOL,   { .i64=0 },         0,        1,        FLAGS },
     { NULL }
 };
 
-- 
2.11.1.windows.1


More information about the ffmpeg-devel mailing list