| @@ -26,48 +26,42 @@ · 25 unmodified lines |
| 26 | */ | 26 | */ |
| 27 | | 27 | |
| 28 | #include "libavutil/common.h" | 28 | #include "libavutil/common.h" |
| | 29 | #include "libavutil/opt.h" |
| 29 | #include "libavutil/pixdesc.h" | 30 | #include "libavutil/pixdesc.h" |
| 30 | #include "avfilter.h" | 31 | #include "avfilter.h" |
| 31 | #include "formats.h" | 32 | #include "formats.h" |
| 32 | #include "internal.h" | 33 | #include "internal.h" |
| 33 | #include "video.h" | 34 | #include "video.h" |
| 34 | | 35 | |
| | 36 | #define FADE_IN 0 |
| | 37 | #define FADE_OUT 1 |
| | 38 | |
| 35 | typedef struct { | 39 | typedef struct { |
| | 40 | const AVClass *class; |
| | 41 | int type; |
| 36 | int factor, fade_per_frame; | 42 | int factor, fade_per_frame; |
| 37 | unsigned int frame_index, start_frame, stop_frame; | 43 | int start_frame, nb_frames; |
| | 44 | unsigned int frame_index, stop_frame; |
| 38 | int hsub, vsub, bpp; | 45 | int hsub, vsub, bpp; |
| 39 | } FadeContext; | 46 | } FadeContext; |
| 40 | | 47 | |
| 41 | static av_cold int init(AVFilterContext *ctx, const char *args) | 48 | static av_cold int init(AVFilterContext *ctx, const char *args) |
| 42 | { | 49 | { |
| 43 | FadeContext *fade = ctx->priv; | 50 | FadeContext *fade = ctx->priv; |
| 44 | unsigned int nb_frames; | | |
| 45 | char in_out[4]; | | |
| 46 | | | |
| 47 | if (!args || | | |
| 48 | sscanf(args, " %3[^:]:%u:%u", in_out, &fade->start_frame, &nb_frames) != 3) { | | |
| 49 | av_log(ctx, AV_LOG_ERROR, | | |
| 50 | "Expected 3 arguments '(in|out):#:#':'%s'\n", args); | | |
| 51 | return AVERROR(EINVAL); | | |
| 52 | } | | |
| 53 | | 51 | |
| 54 | nb_frames = nb_frames ? nb_frames : 1; | 52 | fade->fade_per_frame = (1 << 16) / fade->nb_frames; |
| 55 | fade->fade_per_frame = (1 << 16) / nb_frames; | 53 | if (fade->type == FADE_IN) { |
| 56 | if (!strcmp(in_out, "in")) | | |
| 57 | fade->factor = 0; | 54 | fade->factor = 0; |
| 58 | else if (!strcmp(in_out, "out")) { | 55 | } else if (fade->type == FADE_OUT) { |
| 59 | fade->fade_per_frame = -fade->fade_per_frame; | 56 | fade->fade_per_frame = -fade->fade_per_frame; |
| 60 | fade->factor = (1 << 16); | 57 | fade->factor = (1 << 16); |
| 61 | } else { | | |
| 62 | av_log(ctx, AV_LOG_ERROR, | | |
| 63 | "first argument must be 'in' or 'out':'%s'\n", in_out); | | |
| 64 | return AVERROR(EINVAL); | | |
| 65 | } | 58 | } |
| 66 | fade->stop_frame = fade->start_frame + nb_frames; | 59 | fade->stop_frame = fade->start_frame + fade->nb_frames; |
| 67 | | 60 | |
| 68 | av_log(ctx, AV_LOG_VERBOSE, | 61 | av_log(ctx, AV_LOG_VERBOSE, |
| 69 | "type:%s start_frame:%d nb_frames:%d\n", | 62 | "type:%s start_frame:%d nb_frames:%d\n", |
| 70 | in_out, fade->start_frame, nb_frames); | 63 | fade->type == FADE_IN ? "in" : "out", fade->start_frame, |
| | 64 | fade->nb_frames); |
| 71 | return 0; | 65 | return 0; |
| 72 | } | 66 | } |
| 73 | | 67 | |
| @@ -143,6 +137,26 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) · 69 unmodified lines |
| 143 | return ff_filter_frame(inlink->dst->outputs[0], frame); | 137 | return ff_filter_frame(inlink->dst->outputs[0], frame); |
| 144 | } | 138 | } |
| 145 | | 139 | |
| | 140 | #define OFFSET(x) offsetof(FadeContext, x) |
| | 141 | #define FLAGS AV_OPT_FLAG_VIDEO_PARAM |
| | 142 | static const AVOption options[] = { |
| | 143 | { "type", "'in' or 'out' for fade-in/fade-out", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = FADE_IN }, FADE_IN, FADE_OUT, FLAGS, "type" }, |
| | 144 | { "in", "fade-in", 0, AV_OPT_TYPE_CONST, { .i64 = FADE_IN }, .unit = "type" }, |
| | 145 | { "out", "fade-out", 0, AV_OPT_TYPE_CONST, { .i64 = FADE_OUT }, .unit = "type" }, |
| | 146 | { "start_frame", "Number of the first frame to which to apply the effect.", |
| | 147 | OFFSET(start_frame), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, |
| | 148 | { "nb_frames", "Number of frames to which the effect should be applied.", |
| | 149 | OFFSET(nb_frames), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, FLAGS }, |
| | 150 | { NULL }, |
| | 151 | }; |
| | 152 | |
| | 153 | static const AVClass fade_class = { |
| | 154 | .class_name = "fade", |
| | 155 | .item_name = av_default_item_name, |
| | 156 | .option = options, |
| | 157 | .version = LIBAVUTIL_VERSION_INT, |
| | 158 | }; |
| | 159 | |
| 146 | static const AVFilterPad avfilter_vf_fade_inputs[] = { | 160 | static const AVFilterPad avfilter_vf_fade_inputs[] = { |
| 147 | { | 161 | { |
| 148 | .name = "default", | 162 | .name = "default", |
| @@ -168,6 +182,7 @@ AVFilter avfilter_vf_fade = { · 19 unmodified lines |
| 168 | .description = NULL_IF_CONFIG_SMALL("Fade in/out input video"), | 182 | .description = NULL_IF_CONFIG_SMALL("Fade in/out input video"), |
| 169 | .init = init, | 183 | .init = init, |
| 170 | .priv_size = sizeof(FadeContext), | 184 | .priv_size = sizeof(FadeContext), |
| | 185 | .priv_class = &fade_class, |
| 171 | .query_formats = query_formats, | 186 | .query_formats = query_formats, |
| 172 | | 187 | |
| 173 | .inputs = avfilter_vf_fade_inputs, | 188 | .inputs = avfilter_vf_fade_inputs, |