[FFmpeg-devel] [PATCH] vf_fade: fade alpha
Stefano Sabatini
stefasab at gmail.com
Sat Nov 5 14:31:19 CET 2011
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? BTW this is also missing non-negativity checks.
[...]
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.
--
FFmpeg = Fundamentalist and Friendly Multipurpose Ponderous Ecumenical Gem
More information about the ffmpeg-devel
mailing list