| Original vf_xfade.c |
Amended vf_xfade.c |
|
127: void (*transitionf)(AVFilterContext *ctx, const AVFrame *a, const AVFrame *b, AVFrame *out, float progress, |
127: void (*transitionf)(AVFilterContext *ctx, const AVFrame *a, const AVFrame *b, AVFrame *out, float progress, |
|
128: int slice_start, int slice_end, int jobnr); |
128: int slice_start, int slice_end, int jobnr); |
| 129: |
129: |
| |
130: char *easing_str; // easing name with optional args |
| |
131: char *transition_str; // transition name with optional args |
| |
132: int reverse; // reverse option bit flags (enum ReverseOpts) |
| |
133: struct XFadeEasingContext *k; // xfade-easing data |
| |
134: |
| 130: AVExpr *e; |
135: AVExpr *e; |
| 131: } XFadeContext; |
136: } XFadeContext; |
| 132: |
137: |
| 158: AV_PIX_FMT_NONE |
163: AV_PIX_FMT_NONE |
| 159: }; |
164: }; |
| 160: |
165: |
| |
166: static void xe_data_free(struct XFadeEasingContext *k); |
| 161: static av_cold void uninit(AVFilterContext *ctx) |
167: static av_cold void uninit(AVFilterContext *ctx) |
| 162: { |
168: { |
| 163: XFadeContext *s = ctx->priv; |
169: XFadeContext *s = ctx->priv; |
| 164: |
170: |
| 165: av_expr_free(s->e); |
171: av_expr_free(s->e); |
| |
172: xe_data_free(s->k); |
| 166: } |
173: } |
| 167: |
174: |
| 168: #define OFFSET(x) offsetof(XFadeContext, x) |
175: #define OFFSET(x) offsetof(XFadeContext, x) |
|
169: #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) |
176: #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) |
| 170: |
177: |
| 171: static const AVOption xfade_options[] = { |
178: static const AVOption xfade_options[] = { |
|
172: { "transition", "set cross fade transition", OFFSET(transition), AV_OPT_TYPE_INT, {.i64=FADE}, -1, NB_TRANSITIONS-1, FLAGS, "transition" }, |
179: { "easing", "set cross fade easing", OFFSET(easing_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, |
| |
180: { "reverse", "reverse easing/transition", OFFSET(reverse), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, FLAGS }, |
| |
181: { "transition", "set cross fade transition", OFFSET(transition_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS, "transition" }, |
|
173: { "custom", "custom transition", 0, AV_OPT_TYPE_CONST, {.i64=CUSTOM}, 0, 0, FLAGS, "transition" }, |
182: { "custom", "custom transition", 0, AV_OPT_TYPE_CONST, {.i64=CUSTOM}, 0, 0, FLAGS, "transition" }, |
|
174: { "fade", "fade transition", 0, AV_OPT_TYPE_CONST, {.i64=FADE}, 0, 0, FLAGS, "transition" }, |
183: { "fade", "fade transition", 0, AV_OPT_TYPE_CONST, {.i64=FADE}, 0, 0, FLAGS, "transition" }, |
|
175: { "wipeleft", "wipe left transition", 0, AV_OPT_TYPE_CONST, {.i64=WIPELEFT}, 0, 0, FLAGS, "transition" }, |
184: { "wipeleft", "wipe left transition", 0, AV_OPT_TYPE_CONST, {.i64=WIPELEFT}, 0, 0, FLAGS, "transition" }, |
| 2002: REVEALV_TRANSITION(down, 8, uint8_t, 1, ) |
2011: REVEALV_TRANSITION(down, 8, uint8_t, 1, ) |
| 2003: REVEALV_TRANSITION(down, 16, uint16_t, 2, ) |
2012: REVEALV_TRANSITION(down, 16, uint16_t, 2, ) |
| 2004: |
2013: |
| |
2014: #include "xfade-easing.h" // easing & extended transitions |
| |
2015: |
|
2005: static inline double getpix(void *priv, double x, double y, int plane, int nb) |
2016: static inline double getpix(void *priv, double x, double y, int plane, int nb) |
| 2006: { |
2017: { |
| 2007: XFadeContext *s = priv; |
2018: XFadeContext *s = priv; |
|
2008: AVFrame *in = s->xf[nb]; |
2019: AVFrame *in = s->xf[nb ^ (s->reverse & REVERSE_TRANSITION)]; |
|
2009: const uint8_t *src = in->data[FFMIN(plane, s->nb_planes - 1)]; |
2020: const uint8_t *src = in->data[FFMIN(plane, s->nb_planes - 1)]; |
|
2010: int linesize = in->linesize[FFMIN(plane, s->nb_planes - 1)]; |
2021: int linesize = in->linesize[FFMIN(plane, s->nb_planes - 1)]; |
| 2011: const int w = in->width; |
2022: const int w = in->width; |
| 2100: if (s->duration) |
2111: if (s->duration) |
|
2101: s->duration_pts = av_rescale_q(s->duration, AV_TIME_BASE_Q, outlink->time_base); |
2112: s->duration_pts = av_rescale_q(s->duration, AV_TIME_BASE_Q, outlink->time_base); |
| 2102: |
2113: |
| |
2114: int ret = config_xfade_easing(ctx); |
| |
2115: if (ret <= 0) return ret; // error or extended transition |
| |
2116: |
| 2103: switch (s->transition) { |
2117: switch (s->transition) { |
|
2104: case CUSTOM: s->transitionf = s->depth <= 8 ? custom8_transition : custom16_transition; break; |
2118: case CUSTOM: s->transitionf = s->depth <= 8 ? custom8_transition : custom16_transition; break; |
|
2105: case FADE: s->transitionf = s->depth <= 8 ? fade8_transition : fade16_transition; break; |
2119: case FADE: s->transitionf = s->depth <= 8 ? fade8_transition : fade16_transition; break; |
| 2193: ThreadData *td = arg; |
2207: ThreadData *td = arg; |
|
2194: int slice_start = (outlink->h * jobnr ) / nb_jobs; |
2208: int slice_start = (outlink->h * jobnr ) / nb_jobs; |
|
2195: int slice_end = (outlink->h * (jobnr+1)) / nb_jobs; |
2209: int slice_end = (outlink->h * (jobnr+1)) / nb_jobs; |
| |
2210: int i = s->reverse & REVERSE_TRANSITION; // input 0 or 1 |
| |
2211: float p = td->progress; |
| 2196: |
2212: |
|
2197: s->transitionf(ctx, td->xf[0], td->xf[1], td->out, td->progress, slice_start, slice_end, jobnr); |
2213: p = (s->reverse & REVERSE_EASING) ? 1 - ease(s, 1 - p) : ease(s, p); // eased progress |
| |
2214: if (i) p = 1 - p; |
| |
2215: s->transitionf(ctx, td->xf[i], td->xf[i ^ 1], td->out, p, slice_start, slice_end, jobnr); |
| 2198: |
2216: |
| 2199: return 0; |
2217: return 0; |
| 2200: } |
2218: } |