[FFmpeg-devel] [PATCH] vf_fade: fade alpha

Mark Himsley mark at mdsh.com
Sat Nov 5 15:11:54 CET 2011


On 05/11/2011 13:31, Stefano Sabatini wrote:
> On date Saturday 2011-11-05 02:00:22 +0000, Mark Himsley encoded:
>> use options framework
>>
>> -- 
>> Mark
> 
>> diff --git a/doc/filters.texi b/doc/filters.texi
>> index 0da5702..a6110e4 100644
>> --- a/doc/filters.texi
>> +++ b/doc/filters.texi
>> @@ -1078,7 +1078,7 @@ For more information about libfreetype, check:
>>  Apply fade-in/out effect to input video.
>>  
>>  It accepts the parameters:
>> - at var{type}:@var{start_frame}:@var{nb_frames}
>> + at var{type}:@var{start_frame}:@var{nb_frames}[:@var{options}]
>>  
>>  @var{type} specifies if the effect type, can be either "in" for
>>  fade-in, or "out" for a fade-out effect.
>> @@ -1091,6 +1091,22 @@ effect has to last. At the end of the fade-in effect the output video
>>  will have the same intensity as the input video, at the end of the
>>  fade-out transition the output video will be completely black.
>>  
>> +This source accepts an optional sequence of @var{key}=@var{value} pairs,
>> +separated by ":". The description of the accepted options follows.
>> +
>> + at table @option
>> +
>> + at item type, t
>> +See @var{type}
>> +
>> + at item in_point, i
>> +See @var{start_frame}
>> +
>> + at item duration, d
>> +See @var{nb_frames}
>> +
>> + at end table
>> +
>>  A few usage examples follow, usable too as test scenarios.
>>  @example
>>  # fade in first 30 frames of video
>> diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
>> index 5032019..6f750b4 100644
>> --- a/libavfilter/vf_fade.c
>> +++ b/libavfilter/vf_fade.c
>> @@ -25,48 +25,130 @@
>>   * based heavily on vf_negate.c by Bobby Bingham
>>   */
>>  
>> +#include "libavutil/avstring.h"
>> +#include "libavutil/eval.h"
>> +#include "libavutil/opt.h"
>>  #include "libavutil/pixdesc.h"
>>  #include "avfilter.h"
> 
>> +#include "drawutils.h"
> 
> This looks spurious.
> 
>>  #include "internal.h"
>>  
>>  typedef struct {
>> +    const AVClass *class;
>>      int factor, fade_per_frame;
>>      unsigned int frame_index, start_frame, stop_frame;
>>      int hsub, vsub, bpp;
>>      unsigned int black_level, black_level_scaled;
>> +
>> +    char *type, *start_expr, *count_expr;
>>  } FadeContext;
>>  
>> +#define OFFSET(x) offsetof(FadeContext, x)
>> +
>> +static const AVOption fade_options[] = {
>> +    { "type",     "set the fade direction",                     OFFSET(type),       AV_OPT_TYPE_STRING, {.str = "in" }, CHAR_MIN, CHAR_MAX },
>> +    { "t",        "set the fade direction",                     OFFSET(type),       AV_OPT_TYPE_STRING, {.str = "in" }, CHAR_MIN, CHAR_MAX },
>> +    { "in_point", "set expression of frame to start fading",    OFFSET(start_expr), AV_OPT_TYPE_STRING, {.str = "0"  }, CHAR_MIN, CHAR_MAX },
>> +    { "i",        "set expression of frame to start fading",    OFFSET(start_expr), AV_OPT_TYPE_STRING, {.str = "0"  }, CHAR_MIN, CHAR_MAX },
>> +    { "duration", "set expression for fade duration in frames", OFFSET(count_expr), AV_OPT_TYPE_STRING, {.str = "25" }, CHAR_MIN, CHAR_MAX },
>> +    { "d",        "set expression for fade duration in frames", OFFSET(count_expr), AV_OPT_TYPE_STRING, {.str = "25" }, CHAR_MIN, CHAR_MAX },
>> +    {NULL},
>> +};
>> +
>> +static const char *fade_get_name(void *ctx)
>> +{
>> +    return "fade";
>> +}
>> +
>> +static const AVClass fade_class = {
>> +    "FadeContext",
>> +    fade_get_name,
>> +    fade_options
>> +};
>> +
>>  static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
>>  {
>>      FadeContext *fade = ctx->priv;
>>      unsigned int nb_frames;
>> -    char in_out[4];
>> +    double res;
>> +    int ret = 0;
>> +    char *args1, *expr, *bufptr = NULL;
>>  
>> -    if (!args ||
>> -        sscanf(args, " %3[^:]:%u:%u", in_out, &fade->start_frame, &nb_frames) != 3) {
>> -        av_log(ctx, AV_LOG_ERROR,
>> -               "Expected 3 arguments '(in|out):#:#':'%s'\n", args);
>> -        return AVERROR(EINVAL);
>> +    fade->class = &fade_class;
>> +    av_opt_set_defaults(fade);
>> +
>> +    if (!(args1 = av_strdup(args))) {
>> +        ret = AVERROR(ENOMEM);
>> +        goto end;
>> +    }
>> +
>> +    if (expr = av_strtok(args1, ":", &bufptr)) {
>> +        if (!(fade->type = av_strdup(expr))) {
>> +            ret = AVERROR(ENOMEM);
>> +            goto end;
>> +        }
>> +    }
>> +    if (expr = av_strtok(NULL, ":", &bufptr)) {
>> +        if (!(fade->start_expr = av_strdup(expr))) {
>> +            ret = AVERROR(ENOMEM);
>> +            goto end;
>> +        }
>> +    }
>> +    if (expr = av_strtok(NULL, ":", &bufptr)) {
>> +        if (!(fade->count_expr = av_strdup(expr))) {
>> +            ret = AVERROR(ENOMEM);
>> +            goto end;
>> +        }
>>      }
>>  
>> -    nb_frames = nb_frames ? nb_frames : 1;
>> +    if (bufptr && (ret = av_set_options_string(fade, bufptr, "=", ":")) < 0)
>> +        goto end;
>> +
> 
>> +    if ((ret = av_expr_parse_and_eval(&res, (expr = fade->start_expr), NULL, NULL,
>> +                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
>> +        goto fail;
>> +    fade->start_frame = res;
>> +    if ((ret = av_expr_parse_and_eval(&res, (expr = fade->count_expr), NULL, NULL,
>> +                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
>> +        goto fail;
>> +    nb_frames = res;
> 
> Do you have a specific reason for preferring expressions over plain
> ints?

No specific reason, I thought it would be useful.

> BTW this is also missing non-negativity checks.

Just like the current implementation. Ok to fix that with a later patch?

> [...]
> 
> Side note: I always hated the fade syntax, I had a local fade version
> rotting in my local repo which supports times and duration expressed
> in seconds (and allow to specify for multiple fade effects), I can
> post it if you want to hack on it.

I was wondering how far I could extend the current fade filter, or
whether a wholly new filter should be written. Multiple fade ups and
downs would be nice for use cases that are coming up.

-- 
Mark


More information about the ffmpeg-devel mailing list