[FFmpeg-devel] [PATCH] blend filter

Paul B Mahol onemda at gmail.com
Mon Feb 18 11:07:12 CET 2013


On 2/17/13, Clement Boesch <ubitux at gmail.com> wrote:
> On Sun, Feb 17, 2013 at 06:59:21PM +0000, Paul B Mahol wrote:
>> Signed-off-by: Paul B Mahol <onemda at gmail.com>
>> ---
>>  doc/filters.texi         |  88 +++++++++
>>  libavfilter/Makefile     |   1 +
>>  libavfilter/allfilters.c |   1 +
>>  libavfilter/vf_blend.c   | 460
>> +++++++++++++++++++++++++++++++++++++++++++++++
>>  4 files changed, 550 insertions(+)
>>  create mode 100644 libavfilter/vf_blend.c
>>
>> diff --git a/doc/filters.texi b/doc/filters.texi
>> index a9ee7cb..231fcd3 100644
>> --- a/doc/filters.texi
>> +++ b/doc/filters.texi
>> @@ -1778,6 +1778,94 @@ threshold, and defaults to 98.
>>  @var{threshold} is the threshold below which a pixel value is
>>  considered black, and defaults to 32.
>>
>> + at section blend
>> +
>> +Blend two video frames into each other.
>> +
>> +It takes two inputs and one output, the first input is the "top" layer
>
> "and outputs one stream" (there is no verb for the "one output" so the
> mind fallbacks on "takes").

It was copied from overlay. Fixed.

[...]

> +
>> +static const AVOption blend_options[] = {
>> +    { "c0_mode", "set component #0 blend mode", OFFSET(params[0].mode),
>> AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
>> +    { "c1_mode", "set component #1 blend mode", OFFSET(params[1].mode),
>> AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
>> +    { "c2_mode", "set component #2 blend mode", OFFSET(params[2].mode),
>> AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
>> +    { "c3_mode", "set component #3 blend mode", OFFSET(params[3].mode),
>> AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},
>> +    { "all_mode", "set blend mode for all components", OFFSET(all_mode),
>> AV_OPT_TYPE_INT, {.i64=0},-1, BLEND_NB-1, FLAGS, "mode"},
>> +    { "addition",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION},   0,
>> 0, FLAGS, "mode" },
>> +    { "and",        "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AND},        0,
>> 0, FLAGS, "mode" },
>> +    { "average",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AVERAGE},    0,
>> 0, FLAGS, "mode" },
>> +    { "burn",       "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN},       0,
>> 0, FLAGS, "mode" },
>> +    { "darken",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN},     0,
>> 0, FLAGS, "mode" },
>> +    { "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0,
>> 0, FLAGS, "mode" },
>> +    { "divide",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE},     0,
>> 0, FLAGS, "mode" },
>> +    { "dodge",      "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE},      0,
>> 0, FLAGS, "mode" },
>> +    { "exclusion",  "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION},  0,
>> 0, FLAGS, "mode" },
>> +    { "hardlight",  "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDLIGHT},  0,
>> 0, FLAGS, "mode" },
>> +    { "lighten",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LIGHTEN},    0,
>> 0, FLAGS, "mode" },
>> +    { "multiply",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY},   0,
>> 0, FLAGS, "mode" },
>> +    { "negation",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NEGATION},   0,
>> 0, FLAGS, "mode" },
>> +    { "normal",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NORMAL},     0,
>> 0, FLAGS, "mode" },
>> +    { "or",         "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OR},         0,
>> 0, FLAGS, "mode" },
>> +    { "overlay",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OVERLAY},    0,
>> 0, FLAGS, "mode" },
>> +    { "phoenix",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PHOENIX},    0,
>> 0, FLAGS, "mode" },
>> +    { "reflect",    "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_REFLECT},    0,
>> 0, FLAGS, "mode" },
>> +    { "screen",     "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SCREEN},     0,
>> 0, FLAGS, "mode" },
>> +    { "softlight",  "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SOFTLIGHT},  0,
>> 0, FLAGS, "mode" },
>> +    { "subtract",   "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SUBTRACT},   0,
>> 0, FLAGS, "mode" },
>> +    { "xor",        "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_XOR},        0,
>> 0, FLAGS, "mode" },
>
> Note: I wonder how the AVOption API behaves when you do stuff like
> c0_mode=addition:c1_mode=and:c2_mode=average, does it really apply the
> good const to the option? (I'm asking because we got some surprise
> sometimes, and here the modes are commons between options).

It works after I changed default value for "all_mode" from 0 to -1.

>
> Also, doesn't it drives crazy ffmpeg -help full?

So?

[...]

> +    av_opt_set_defaults(b);
>> +
>> +    if ((ret = (av_set_options_string(b, args, "=", ":"))) < 0)
>> +        return ret;
>> +
>
> One level of ( ) is pointless.

Fixed.

[...]

> +    AVFilterLink *bottomlink = ctx->inputs[BOTTOM];
>> +
>> +    if (toplink->format != bottomlink->format) {
>> +        av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel
>> format\n");
>> +        return AVERROR(EINVAL);
>> +    }
>> +    if ((toplink->w != bottomlink->w) ||
>> +        (toplink->h != bottomlink->h)) {
>
> ditto ( )

Fixed.

[...]

Note that if both inputs are single image, ffmpeg returns nothing.

I thought copying rest of overlay convoluted code could fix it but I
would like to know is there nicer way.


More information about the ffmpeg-devel mailing list