Skip to content
Snippets Groups Projects
Commit 1c76134f authored by Gyan Doshi's avatar Gyan Doshi Committed by Lou Logan
Browse files

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.
parent 980af9a8
No related branches found
No related tags found
No related merge requests found
...@@ -7146,6 +7146,11 @@ The expression which sets the thickness of the box edge. ...@@ -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}. A value of @code{fill} will create a filled box. Default value is @code{3}.
   
See below for the list of accepted constants. See below for the list of accepted constants.
@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 @end table
   
The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the 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. ...@@ -7243,6 +7248,11 @@ video with inverted luma.
The expression which sets the thickness of the grid line. Default value is @code{1}. The expression which sets the thickness of the grid line. Default value is @code{1}.
   
See below for the list of accepted constants. See below for the list of accepted constants.
@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 @end table
   
The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
......
...@@ -80,6 +80,7 @@ typedef struct DrawBoxContext { ...@@ -80,6 +80,7 @@ typedef struct DrawBoxContext {
char *w_expr, *h_expr; ///< expression for width and height char *w_expr, *h_expr; ///< expression for width and height
char *t_expr; ///< expression for thickness char *t_expr; ///< expression for thickness
int have_alpha; int have_alpha;
int replace;
} DrawBoxContext; } DrawBoxContext;
static const int NUM_EXPR_EVALS = 5; static const int NUM_EXPR_EVALS = 5;
...@@ -213,7 +214,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -213,7 +214,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
int plane, x, y, xb = s->x, yb = s->y; int plane, x, y, xb = s->x, yb = s->y;
unsigned char *row[4]; 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++) { for (y = FFMAX(yb, 0); y < frame->height && y < (yb + s->h); y++) {
row[0] = frame->data[0] + y * frame->linesize[0]; row[0] = frame->data[0] + y * frame->linesize[0];
row[3] = frame->data[3] + y * frame->linesize[3]; row[3] = frame->data[3] + y * frame->linesize[3];
...@@ -286,6 +287,7 @@ static const AVOption drawbox_options[] = { ...@@ -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 }, { "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 }, { "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 }, { "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 } { NULL }
}; };
...@@ -354,7 +356,7 @@ static int drawgrid_filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -354,7 +356,7 @@ static int drawgrid_filter_frame(AVFilterLink *inlink, AVFrame *frame)
int plane, x, y; int plane, x, y;
uint8_t *row[4]; uint8_t *row[4];
if (drawgrid->have_alpha) { if (drawgrid->have_alpha && drawgrid->replace) {
for (y = 0; y < frame->height; y++) { for (y = 0; y < frame->height; y++) {
row[0] = frame->data[0] + y * frame->linesize[0]; row[0] = frame->data[0] + y * frame->linesize[0];
row[3] = frame->data[3] + y * frame->linesize[3]; row[3] = frame->data[3] + y * frame->linesize[3];
...@@ -418,6 +420,7 @@ static const AVOption drawgrid_options[] = { ...@@ -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 }, { "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 }, { "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 }, { "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 } { NULL }
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment