[FFmpeg-soc] vf_overlay with transparancy

Vitor Sessak vitor1001 at gmail.com
Thu May 28 23:44:06 CEST 2009


Zeger Knops wrote:
> On Wed, 2009-05-27 at 21:52 +0200, Vitor Sessak wrote:
>>> +           //TODO rgb conversion if user is using rgb in alpha function
>>> +            alpha->values[POV_cyuv] = (outrow_0[j]<<16) + (outrow_1[j_sub]<<8) + outrow_2[j_sub];
>>> +            alpharow[j] = ff_parse_eval(alpha->value, alpha->values, alpha);
>> If you are using ff_parse_eval() here, this filter have no advantage 
>> comparing to vf_applyfn. In the other hand, if you accept only YUVA420 
>> as input and if you call ff_parse_eval() at most once per frame, this 
>> filter can be _much_ faster (and no memcpy(), just modifying the buffer, 
>> see vf_drawbox).
> 
> Compared to vf_applyfn this filter is faster since there is only a
> single call to ff_parse_eval instead of 6, that could be an advantage.

You can make vf_applyfn equally fast to set alpha channel by replacing 
lines like

> +            outrow_0[j]     = ff_parse_eval(applyfn->Y_evalexpr, applyfn->var_values, applyfn);

by

if(applyfn->Y_evalexpr)
    outrow_0[j] = ff_parse_eval(applyfn->Y_evalexpr, 
applyfn->var_values, applyfn);
else
    outrow_0[j] = applyfn->var_values[Y];

(making of course in the init applyfn->Y_evalexpr null is the user does 
not specify "Y=...").

> Would this filter still be a nice addition to libavfilter if it is
> fully replaceable by vf_applyfn?

FFmpeg is as a rule of thumb speed-obsessed. It is only ok to do 6 
ff_eval_parse() operations per pixel in vf_applyfn because of all the 
nifty tricks it allows. So, if you submit a vf_alpha filter that is 
fast, it is _very_ welcome (and the vf_alpha code you submitted can 
easily be modified to be very fast). What I suggest to you is:

In init():

for (i=0; i < height; i++)
     for (j=0; j < width; j++) {
         var_values[x] = i;
         var_values[y] = j;
         ctx->alpha_vals[i*width + j] = ff_parse_eval(ctx->evalexpr, 
var_values, ctx);
     }

In draw_slice(), instead of

> alpharow[j] = ff_parse_eval(alpha->value, alpha->values, alpha);

do

alpharow[j] = ctx->alpha_vals[i*width+j];

It should allow do set the alpha channel depending on the (x,y) coords, 
but with very little speed loss.

-Vitor


More information about the FFmpeg-soc mailing list