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

Stefano Sabatini stefasab at gmail.com
Sat Nov 5 15:39:21 CET 2011


On date Saturday 2011-11-05 14:11:54 +0000, Mark Himsley encoded:
> 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.

Fine, just please mention it in the docs.
 
> > BTW this is also missing non-negativity checks.
> 
> Just like the current implementation. Ok to fix that with a later patch?

Yes.
 
> > [...]
> > 
> > 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.

I ended implementing a new filter (multifade), sharing code with fade,
I'll post it in a day or so as a proof of concept.
-- 
FFmpeg = Fancy and Fanciful Murdering Perennial Enlightened Guru


More information about the ffmpeg-devel mailing list