From 0d602615ab58b14859dc915b94385cd79e21a87e Mon Sep 17 00:00:00 2001 From: Mark Himsley Date: Wed, 9 Nov 2011 01:17:55 +0100 Subject: [PATCH] vf_fade: add support to options parsing Extend fade syntax, required by a pending patch. Signed-off-by: Stefano Sabatini --- doc/filters.texi | 18 +++++++- libavfilter/avfilter.h | 2 +- libavfilter/vf_fade.c | 100 ++++++++++++++++++++++++++++++++++------- 3 files changed, 101 insertions(+), 19 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index f8a2d1b285..2741f96e4f 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1139,7 +1139,7 @@ For more information about libfreetype, check: Apply fade-in/out effect to input video. It accepts the parameters: -@var{type}:@var{start_frame}:@var{nb_frames} +@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. @@ -1152,6 +1152,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. +@var{options} is an optional sequence of @var{key}=@var{value} pairs, +separated by ":". The description of the accepted options follows. + +@table @option + +@item type, t +See @var{type}. + +@item start_frame, s +See @var{start_frame}. + +@item nb_frames, n +See @var{nb_frames}. + +@end table + A few usage examples follow, usable too as test scenarios. @example # fade in first 30 frames of video diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index b8205fd635..a65133026b 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -30,7 +30,7 @@ #define LIBAVFILTER_VERSION_MAJOR 2 #define LIBAVFILTER_VERSION_MINOR 47 -#define LIBAVFILTER_VERSION_MICRO 0 +#define LIBAVFILTER_VERSION_MICRO 1 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index be50eaa847..7252a1200b 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -25,48 +25,113 @@ * 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" #include "internal.h" typedef struct { + const AVClass *class; int factor, fade_per_frame; - unsigned int frame_index, start_frame, stop_frame; + unsigned int frame_index, start_frame, stop_frame, nb_frames; int hsub, vsub, bpp; unsigned int black_level, black_level_scaled; + + char *type; } 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 }, + { "start_frame", "set expression of frame to start fading", OFFSET(start_frame), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX }, + { "s", "set expression of frame to start fading", OFFSET(start_frame), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX }, + { "nb_frames", "set expression for fade duration in frames", OFFSET(nb_frames), AV_OPT_TYPE_INT, {.dbl = 25 }, 0, INT_MAX }, + { "n", "set expression for fade duration in frames", OFFSET(nb_frames), AV_OPT_TYPE_INT, {.dbl = 25 }, 0, INT_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]; + 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; } - nb_frames = nb_frames ? nb_frames : 1; - fade->fade_per_frame = (1 << 16) / nb_frames; - if (!strcmp(in_out, "in")) + if (expr = av_strtok(args1, ":", &bufptr)) { + if (!(fade->type = av_strdup(expr))) { + ret = AVERROR(ENOMEM); + goto end; + } + } + if (expr = av_strtok(NULL, ":", &bufptr)) { + if ((ret = av_opt_set(fade, "start_frame", expr, 0)) < 0) { + av_log(ctx, AV_LOG_ERROR, + "Invalid value '%s' for start_frame option\n", expr); + return ret; + } + } + if (expr = av_strtok(NULL, ":", &bufptr)) { + if ((ret = av_opt_set(fade, "nb_frames", expr, 0)) < 0) { + av_log(ctx, AV_LOG_ERROR, + "Invalid value '%s' for nb_frames option\n", expr); + return ret; + } + } + + if (bufptr && (ret = av_set_options_string(fade, bufptr, "=", ":")) < 0) + goto end; + + fade->fade_per_frame = (1 << 16) / fade->nb_frames; + if (!strcmp(fade->type, "in")) fade->factor = 0; - else if (!strcmp(in_out, "out")) { + else if (!strcmp(fade->type, "out")) { fade->fade_per_frame = -fade->fade_per_frame; fade->factor = (1 << 16); } else { av_log(ctx, AV_LOG_ERROR, - "first argument must be 'in' or 'out':'%s'\n", in_out); - return AVERROR(EINVAL); + "Type argument must be 'in' or 'out' but '%s' was specified\n", fade->type); + ret = AVERROR(EINVAL); + goto end; } - fade->stop_frame = fade->start_frame + nb_frames; + fade->stop_frame = fade->start_frame + fade->nb_frames; av_log(ctx, AV_LOG_INFO, "type:%s start_frame:%d nb_frames:%d\n", - in_out, fade->start_frame, nb_frames); - return 0; + fade->type, fade->start_frame, fade->nb_frames); + +end: + av_free(args1); + return ret; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + FadeContext *fade = ctx->priv; + + av_freep(&fade->type); } static int query_formats(AVFilterContext *ctx) @@ -163,6 +228,7 @@ AVFilter avfilter_vf_fade = { .name = "fade", .description = NULL_IF_CONFIG_SMALL("Fade in/out input video"), .init = init, + .uninit = uninit, .priv_size = sizeof(FadeContext), .query_formats = query_formats,