| @@ -74,6 +74,8 @@ enum XFadeTransitions { · 73 unmodified lines |
| 74 | SQUEEZEH, | 74 | SQUEEZEH, |
| 75 | SQUEEZEV, | 75 | SQUEEZEV, |
| 76 | ZOOMIN, | 76 | ZOOMIN, |
| | 77 | FADEFAST, |
| | 78 | FADESLOW, |
| 77 | NB_TRANSITIONS, | 79 | NB_TRANSITIONS, |
| 78 | }; | 80 | }; |
| 79 | | 81 | |
| @@ -193,6 +195,8 @@ static const AVOption xfade_options[] = { · 113 unmodified lines |
| 193 | { "squeezeh", "squeeze h transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEH}, 0, 0, FLAGS, "transition" }, | 195 | { "squeezeh", "squeeze h transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEH}, 0, 0, FLAGS, "transition" }, |
| 194 | { "squeezev", "squeeze v transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEV}, 0, 0, FLAGS, "transition" }, | 196 | { "squeezev", "squeeze v transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEV}, 0, 0, FLAGS, "transition" }, |
| 195 | { "zoomin", "zoom in transition", 0, AV_OPT_TYPE_CONST, {.i64=ZOOMIN}, 0, 0, FLAGS, "transition" }, | 197 | { "zoomin", "zoom in transition", 0, AV_OPT_TYPE_CONST, {.i64=ZOOMIN}, 0, 0, FLAGS, "transition" }, |
| | 198 | { "fadefast", "fast fade transition", 0, AV_OPT_TYPE_CONST, {.i64=FADEFAST}, 0, 0, FLAGS, "transition" }, |
| | 199 | { "fadeslow", "slow fade transition", 0, AV_OPT_TYPE_CONST, {.i64=FADESLOW}, 0, 0, FLAGS, "transition" }, |
| 196 | { "duration", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=1000000}, 0, 60000000, FLAGS }, | 200 | { "duration", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=1000000}, 0, 60000000, FLAGS }, |
| 197 | { "offset", "set cross fade start relative to first input stream", OFFSET(offset), AV_OPT_TYPE_DURATION, {.i64=0}, INT64_MIN, INT64_MAX, FLAGS }, | 201 | { "offset", "set cross fade start relative to first input stream", OFFSET(offset), AV_OPT_TYPE_DURATION, {.i64=0}, INT64_MIN, INT64_MAX, FLAGS }, |
| 198 | { "expr", "set expression for custom transition", OFFSET(custom_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, | 202 | { "expr", "set expression for custom transition", OFFSET(custom_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, |
| @@ -1670,6 +1674,70 @@ static void zoomin##name##_transition(AVFilterContext *ctx, · 1471 unmodified lines |
| 1670 | ZOOMIN_TRANSITION(8, uint8_t, 1) | 1674 | ZOOMIN_TRANSITION(8, uint8_t, 1) |
| 1671 | ZOOMIN_TRANSITION(16, uint16_t, 2) | 1675 | ZOOMIN_TRANSITION(16, uint16_t, 2) |
| 1672 | | 1676 | |
| | 1677 | #define FADEFAST_TRANSITION(name, type, div) \ |
| | 1678 | static void fadefast##name##_transition(AVFilterContext *ctx, \ |
| | 1679 | const AVFrame *a, const AVFrame *b, AVFrame *out, \ |
| | 1680 | float progress, \ |
| | 1681 | int slice_start, int slice_end, int jobnr) \ |
| | 1682 | { \ |
| | 1683 | XFadeContext *s = ctx->priv; \ |
| | 1684 | const int height = slice_end - slice_start; \ |
| | 1685 | const float imax = 1.f / s->max_value; \ |
| | 1686 | \ |
| | 1687 | for (int p = 0; p < s->nb_planes; p++) { \ |
| | 1688 | const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ |
| | 1689 | const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ |
| | 1690 | type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ |
| | 1691 | \ |
| | 1692 | for (int y = 0; y < height; y++) { \ |
| | 1693 | for (int x = 0; x < out->width; x++) { \ |
| | 1694 | dst[x] = mix(xf0[x], xf1[x], powf(progress, 1.f + \ |
| | 1695 | logf(1.f+FFABS(xf0[x]-xf1[x])*imax)\ |
| | 1696 | )); \ |
| | 1697 | } \ |
| | 1698 | \ |
| | 1699 | dst += out->linesize[p] / div; \ |
| | 1700 | xf0 += a->linesize[p] / div; \ |
| | 1701 | xf1 += b->linesize[p] / div; \ |
| | 1702 | } \ |
| | 1703 | } \ |
| | 1704 | } |
| | 1705 | |
| | 1706 | FADEFAST_TRANSITION(8, uint8_t, 1) |
| | 1707 | FADEFAST_TRANSITION(16, uint16_t, 2) |
| | 1708 | |
| | 1709 | #define FADESLOW_TRANSITION(name, type, div) \ |
| | 1710 | static void fadeslow##name##_transition(AVFilterContext *ctx, \ |
| | 1711 | const AVFrame *a, const AVFrame *b, AVFrame *out, \ |
| | 1712 | float progress, \ |
| | 1713 | int slice_start, int slice_end, int jobnr) \ |
| | 1714 | { \ |
| | 1715 | XFadeContext *s = ctx->priv; \ |
| | 1716 | const int height = slice_end - slice_start; \ |
| | 1717 | const float imax = 1.f / s->max_value; \ |
| | 1718 | \ |
| | 1719 | for (int p = 0; p < s->nb_planes; p++) { \ |
| | 1720 | const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ |
| | 1721 | const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ |
| | 1722 | type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ |
| | 1723 | \ |
| | 1724 | for (int y = 0; y < height; y++) { \ |
| | 1725 | for (int x = 0; x < out->width; x++) { \ |
| | 1726 | dst[x] = mix(xf0[x], xf1[x], powf(progress, 1.f + \ |
| | 1727 | logf(2.f-FFABS(xf0[x]-xf1[x])*imax)\ |
| | 1728 | )); \ |
| | 1729 | } \ |
| | 1730 | \ |
| | 1731 | dst += out->linesize[p] / div; \ |
| | 1732 | xf0 += a->linesize[p] / div; \ |
| | 1733 | xf1 += b->linesize[p] / div; \ |
| | 1734 | } \ |
| | 1735 | } \ |
| | 1736 | } |
| | 1737 | |
| | 1738 | FADESLOW_TRANSITION(8, uint8_t, 1) |
| | 1739 | FADESLOW_TRANSITION(16, uint16_t, 2) |
| | 1740 | |
| 1673 | static inline double getpix(void *priv, double x, double y, int plane, int nb) | 1741 | static inline double getpix(void *priv, double x, double y, int plane, int nb) |
| 1674 | { | 1742 | { |
| 1675 | XFadeContext *s = priv; | 1743 | XFadeContext *s = priv; |
| @@ -1816,6 +1884,8 @@ static int config_output(AVFilterLink *outlink) · 140 unmodified lines |
| 1816 | case SQUEEZEH: s->transitionf = s->depth <= 8 ? squeezeh8_transition : squeezeh16_transition; break; | 1884 | case SQUEEZEH: s->transitionf = s->depth <= 8 ? squeezeh8_transition : squeezeh16_transition; break; |
| 1817 | case SQUEEZEV: s->transitionf = s->depth <= 8 ? squeezev8_transition : squeezev16_transition; break; | 1885 | case SQUEEZEV: s->transitionf = s->depth <= 8 ? squeezev8_transition : squeezev16_transition; break; |
| 1818 | case ZOOMIN: s->transitionf = s->depth <= 8 ? zoomin8_transition : zoomin16_transition; break; | 1886 | case ZOOMIN: s->transitionf = s->depth <= 8 ? zoomin8_transition : zoomin16_transition; break; |
| | 1887 | case FADEFAST: s->transitionf = s->depth <= 8 ? fadefast8_transition : fadefast16_transition; break; |
| | 1888 | case FADESLOW: s->transitionf = s->depth <= 8 ? fadeslow8_transition : fadeslow16_transition; break; |
| 1819 | default: return AVERROR_BUG; | 1889 | default: return AVERROR_BUG; |
| 1820 | } | 1890 | } |
| 1821 | | 1891 | |