Showing the changes to libavfilter (1 of 2 files). Show all
Unified · Split
| @@ -74,6 +74,8 @@ enum XFadeTransitions { · 73 unmodified lines | ||
| 74 | 74 | SQUEEZEH, |
| 75 | 75 | SQUEEZEV, |
| 76 | 76 | ZOOMIN, |
| 77 | + FADEFAST, | |
| 78 | + FADESLOW, | |
| 77 | 79 | NB_TRANSITIONS, |
| 78 | 80 | }; |
| 79 | 81 | |
| @@ -193,6 +195,8 @@ static const AVOption xfade_options[] = { · 113 unmodified lines | ||
| 193 | 195 | { "squeezeh", "squeeze h transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEH}, 0, 0, FLAGS, "transition" }, |
| 194 | 196 | { "squeezev", "squeeze v transition", 0, AV_OPT_TYPE_CONST, {.i64=SQUEEZEV}, 0, 0, FLAGS, "transition" }, |
| 195 | 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 | 200 | { "duration", "set cross fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=1000000}, 0, 60000000, FLAGS }, |
| 197 | 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 | 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 | 1674 | ZOOMIN_TRANSITION(8, uint8_t, 1) |
| 1671 | 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 | 1741 | static inline double getpix(void *priv, double x, double y, int plane, int nb) |
| 1674 | 1742 | { |
| 1675 | 1743 | XFadeContext *s = priv; |
| @@ -1816,6 +1884,8 @@ static int config_output(AVFilterLink *outlink) · 140 unmodified lines | ||
| 1816 | 1884 | case SQUEEZEH: s->transitionf = s->depth <= 8 ? squeezeh8_transition : squeezeh16_transition; break; |
| 1817 | 1885 | case SQUEEZEV: s->transitionf = s->depth <= 8 ? squeezev8_transition : squeezev16_transition; break; |
| 1818 | 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 | 1889 | default: return AVERROR_BUG; |
| 1820 | 1890 | } |
| 1821 | 1891 | |