[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