Go to the documentation of this file.
   96                         int slice_start, 
int slice_end, 
int jobnr);
 
  101 static const char *
const var_names[] = {   
"X",   
"Y",   
"W",   
"H",   
"A",   
"B",   
"PLANE",          
"P",        
NULL };
 
  144 #define OFFSET(x) offsetof(XFadeContext, x) 
  145 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) 
  193 #define CUSTOM_TRANSITION(name, type, div)                                           \ 
  194 static void custom##name##_transition(AVFilterContext *ctx,                          \ 
  195                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  197                             int slice_start, int slice_end, int jobnr)               \ 
  199     XFadeContext *s = ctx->priv;                                                     \ 
  200     const int height = slice_end - slice_start;                                      \ 
  202     double values[VAR_VARS_NB];                                                      \ 
  203     values[VAR_W] = out->width;                                                      \ 
  204     values[VAR_H] = out->height;                                                     \ 
  205     values[VAR_PROGRESS] = progress;                                                 \ 
  207     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  208         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  209         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  210         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  212         values[VAR_PLANE] = p;                                                       \ 
  214         for (int y = 0; y < height; y++) {                                           \ 
  215             values[VAR_Y] = slice_start + y;                                         \ 
  216             for (int x = 0; x < out->width; x++) {                                   \ 
  218                 values[VAR_A] = xf0[x];                                              \ 
  219                 values[VAR_B] = xf1[x];                                              \ 
  220                 dst[x] = av_expr_eval(s->e, values, s);                              \ 
  223             dst += out->linesize[p] / div;                                           \ 
  224             xf0 += a->linesize[p] / div;                                             \ 
  225             xf1 += b->linesize[p] / div;                                             \ 
  233 static inline 
float mix(
float a, 
float b, 
float mix)
 
  240     return a - floorf(
a);
 
  243 static inline float smoothstep(
float edge0, 
float edge1, 
float x)
 
  247     t = av_clipf((x - edge0) / (edge1 - edge0), 0.
f, 1.
f);
 
  249     return t * t * (3.f - 2.f * t);
 
  252 #define FADE_TRANSITION(name, type, div)                                             \ 
  253 static void fade##name##_transition(AVFilterContext *ctx,                            \ 
  254                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  256                             int slice_start, int slice_end, int jobnr)               \ 
  258     XFadeContext *s = ctx->priv;                                                     \ 
  259     const int height = slice_end - slice_start;                                      \ 
  261     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  262         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  263         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  264         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  266         for (int y = 0; y < height; y++) {                                           \ 
  267             for (int x = 0; x < out->width; x++) {                                   \ 
  268                 dst[x] = mix(xf0[x], xf1[x], progress);                              \ 
  271             dst += out->linesize[p] / div;                                           \ 
  272             xf0 += a->linesize[p] / div;                                             \ 
  273             xf1 += b->linesize[p] / div;                                             \ 
  281 #define WIPELEFT_TRANSITION(name, type, div)                                         \ 
  282 static void wipeleft##name##_transition(AVFilterContext *ctx,                        \ 
  283                                 const AVFrame *a, const AVFrame *b, AVFrame *out,    \ 
  285                                 int slice_start, int slice_end, int jobnr)           \ 
  287     XFadeContext *s = ctx->priv;                                                     \ 
  288     const int height = slice_end - slice_start;                                      \ 
  289     const int z = out->width * progress;                                             \ 
  291     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  292         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  293         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  294         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  296         for (int y = 0; y < height; y++) {                                           \ 
  297             for (int x = 0; x < out->width; x++) {                                   \ 
  298                 dst[x] = x > z ? xf1[x] : xf0[x];                                    \ 
  301             dst += out->linesize[p] / div;                                           \ 
  302             xf0 += a->linesize[p] / div;                                             \ 
  303             xf1 += b->linesize[p] / div;                                             \ 
  311 #define WIPERIGHT_TRANSITION(name, type, div)                                        \ 
  312 static void wiperight##name##_transition(AVFilterContext *ctx,                       \ 
  313                                  const AVFrame *a, const AVFrame *b, AVFrame *out,   \ 
  315                                  int slice_start, int slice_end, int jobnr)          \ 
  317     XFadeContext *s = ctx->priv;                                                     \ 
  318     const int height = slice_end - slice_start;                                      \ 
  319     const int z = out->width * (1.f - progress);                                     \ 
  321     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  322         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  323         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  324         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  326         for (int y = 0; y < height; y++) {                                           \ 
  327             for (int x = 0; x < out->width; x++) {                                   \ 
  328                 dst[x] = x > z ? xf0[x] : xf1[x];                                    \ 
  331             dst += out->linesize[p] / div;                                           \ 
  332             xf0 += a->linesize[p] / div;                                             \ 
  333             xf1 += b->linesize[p] / div;                                             \ 
  341 #define WIPEUP_TRANSITION(name, type, div)                                           \ 
  342 static void wipeup##name##_transition(AVFilterContext *ctx,                          \ 
  343                               const AVFrame *a, const AVFrame *b, AVFrame *out,      \ 
  345                               int slice_start, int slice_end, int jobnr)             \ 
  347     XFadeContext *s = ctx->priv;                                                     \ 
  348     const int height = slice_end - slice_start;                                      \ 
  349     const int z = out->height * progress;                                            \ 
  351     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  352         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  353         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  354         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  356         for (int y = 0; y < height; y++) {                                           \ 
  357             for (int x = 0; x < out->width; x++) {                                   \ 
  358                 dst[x] = slice_start + y > z ? xf1[x] : xf0[x];                      \ 
  361             dst += out->linesize[p] / div;                                           \ 
  362             xf0 += a->linesize[p] / div;                                             \ 
  363             xf1 += b->linesize[p] / div;                                             \ 
  371 #define WIPEDOWN_TRANSITION(name, type, div)                                         \ 
  372 static void wipedown##name##_transition(AVFilterContext *ctx,                        \ 
  373                                 const AVFrame *a, const AVFrame *b, AVFrame *out,    \ 
  375                                 int slice_start, int slice_end, int jobnr)           \ 
  377     XFadeContext *s = ctx->priv;                                                     \ 
  378     const int height = slice_end - slice_start;                                      \ 
  379     const int z = out->height * (1.f - progress);                                    \ 
  381     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  382         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  383         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  384         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  386         for (int y = 0; y < height; y++) {                                           \ 
  387             for (int x = 0; x < out->width; x++) {                                   \ 
  388                 dst[x] = slice_start + y > z ? xf0[x] : xf1[x];                      \ 
  391             dst += out->linesize[p] / div;                                           \ 
  392             xf0 += a->linesize[p] / div;                                             \ 
  393             xf1 += b->linesize[p] / div;                                             \ 
  401 #define SLIDELEFT_TRANSITION(name, type, div)                                        \ 
  402 static void slideleft##name##_transition(AVFilterContext *ctx,                       \ 
  403                                  const AVFrame *a, const AVFrame *b, AVFrame *out,   \ 
  405                                  int slice_start, int slice_end, int jobnr)          \ 
  407     XFadeContext *s = ctx->priv;                                                     \ 
  408     const int height = slice_end - slice_start;                                      \ 
  409     const int width = out->width;                                                    \ 
  410     const int z = -progress * width;                                                 \ 
  412     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  413         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  414         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  415         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  417         for (int y = 0; y < height; y++) {                                           \ 
  418             for (int x = 0; x < width; x++) {                                        \ 
  419                 const int zx = z + x;                                                \ 
  420                 const int zz = zx % width + width * (zx < 0);                        \ 
  421                 dst[x] = (zx > 0) && (zx < width) ? xf1[zz] : xf0[zz];               \ 
  424             dst += out->linesize[p] / div;                                           \ 
  425             xf0 += a->linesize[p] / div;                                             \ 
  426             xf1 += b->linesize[p] / div;                                             \ 
  434 #define SLIDERIGHT_TRANSITION(name, type, div)                                       \ 
  435 static void slideright##name##_transition(AVFilterContext *ctx,                      \ 
  436                                   const AVFrame *a, const AVFrame *b, AVFrame *out,  \ 
  438                                   int slice_start, int slice_end, int jobnr)         \ 
  440     XFadeContext *s = ctx->priv;                                                     \ 
  441     const int height = slice_end - slice_start;                                      \ 
  442     const int width = out->width;                                                    \ 
  443     const int z = progress * width;                                                  \ 
  445     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  446         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  447         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  448         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  450         for (int y = 0; y < height; y++) {                                           \ 
  451             for (int x = 0; x < out->width; x++) {                                   \ 
  452                 const int zx = z + x;                                                \ 
  453                 const int zz = zx % width + width * (zx < 0);                        \ 
  454                 dst[x] = (zx > 0) && (zx < width) ? xf1[zz] : xf0[zz];               \ 
  457             dst += out->linesize[p] / div;                                           \ 
  458             xf0 += a->linesize[p] / div;                                             \ 
  459             xf1 += b->linesize[p] / div;                                             \ 
  467 #define SLIDEUP_TRANSITION(name, type, div)                                         \ 
  468 static void slideup##name##_transition(AVFilterContext *ctx,                        \ 
  469                                const AVFrame *a, const AVFrame *b, AVFrame *out,    \ 
  471                                int slice_start, int slice_end, int jobnr)           \ 
  473     XFadeContext *s = ctx->priv;                                                    \ 
  474     const int height = out->height;                                                 \ 
  475     const int z = -progress * height;                                               \ 
  477     for (int p = 0; p < s->nb_planes; p++) {                                        \ 
  478         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);        \ 
  480         for (int y = slice_start; y < slice_end; y++) {                             \ 
  481             const int zy = z + y;                                                   \ 
  482             const int zz = zy % height + height * (zy < 0);                         \ 
  483             const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]);     \ 
  484             const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]);     \ 
  486             for (int x = 0; x < out->width; x++) {                                  \ 
  487                 dst[x] = (zy > 0) && (zy < height) ? xf1[x] : xf0[x];               \ 
  490             dst += out->linesize[p] / div;                                          \ 
  498 #define SLIDEDOWN_TRANSITION(name, type, div)                                       \ 
  499 static void slidedown##name##_transition(AVFilterContext *ctx,                      \ 
  500                                  const AVFrame *a, const AVFrame *b, AVFrame *out,  \ 
  502                                  int slice_start, int slice_end, int jobnr)         \ 
  504     XFadeContext *s = ctx->priv;                                                    \ 
  505     const int height = out->height;                                                 \ 
  506     const int z = progress * height;                                                \ 
  508     for (int p = 0; p < s->nb_planes; p++) {                                        \ 
  509         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);        \ 
  511         for (int y = slice_start; y < slice_end; y++) {                             \ 
  512             const int zy = z + y;                                                   \ 
  513             const int zz = zy % height + height * (zy < 0);                         \ 
  514             const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]);     \ 
  515             const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]);     \ 
  517             for (int x = 0; x < out->width; x++) {                                  \ 
  518                 dst[x] = (zy > 0) && (zy < height) ? xf1[x] : xf0[x];               \ 
  521             dst += out->linesize[p] / div;                                          \ 
  529 #define CIRCLECROP_TRANSITION(name, type, div)                                      \ 
  530 static void circlecrop##name##_transition(AVFilterContext *ctx,                     \ 
  531                                  const AVFrame *a, const AVFrame *b, AVFrame *out,  \ 
  533                                  int slice_start, int slice_end, int jobnr)         \ 
  535     XFadeContext *s = ctx->priv;                                                    \ 
  536     const int width = out->width;                                                   \ 
  537     const int height = out->height;                                                 \ 
  538     float z = powf(2.f * fabsf(progress - 0.5f), 3.f) * hypotf(width/2, height/2);  \ 
  540     for (int p = 0; p < s->nb_planes; p++) {                                        \ 
  541         const int bg = s->black[p];                                                 \ 
  542         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);        \ 
  544         for (int y = slice_start; y < slice_end; y++) {                             \ 
  545             const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);      \ 
  546             const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);      \ 
  548             for (int x = 0; x < width; x++) {                                       \ 
  549                 float dist = hypotf(x - width / 2, y - height / 2);                 \ 
  550                 int val = progress < 0.5f ? xf1[x] : xf0[x];                        \ 
  551                 dst[x] = (z < dist) ? bg : val;                                     \ 
  554             dst += out->linesize[p] / div;                                          \ 
  562 #define RECTCROP_TRANSITION(name, type, div)                                        \ 
  563 static void rectcrop##name##_transition(AVFilterContext *ctx,                       \ 
  564                                  const AVFrame *a, const AVFrame *b, AVFrame *out,  \ 
  566                                  int slice_start, int slice_end, int jobnr)         \ 
  568     XFadeContext *s = ctx->priv;                                                    \ 
  569     const int width = out->width;                                                   \ 
  570     const int height = out->height;                                                 \ 
  571     int zh = fabsf(progress - 0.5f) * height;                                       \ 
  572     int zw = fabsf(progress - 0.5f) * width;                                        \ 
  574     for (int p = 0; p < s->nb_planes; p++) {                                        \ 
  575         const int bg = s->black[p];                                                 \ 
  576         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);        \ 
  578         for (int y = slice_start; y < slice_end; y++) {                             \ 
  579             const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);      \ 
  580             const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);      \ 
  582             for (int x = 0; x < width; x++) {                                       \ 
  583                 int dist = FFABS(x - width  / 2) < zw &&                            \ 
  584                            FFABS(y - height / 2) < zh;                              \ 
  585                 int val = progress < 0.5f ? xf1[x] : xf0[x];                        \ 
  586                 dst[x] = !dist ? bg : val;                                          \ 
  589             dst += out->linesize[p] / div;                                          \ 
  597 #define DISTANCE_TRANSITION(name, type, div)                                        \ 
  598 static void distance##name##_transition(AVFilterContext *ctx,                       \ 
  599                                  const AVFrame *a, const AVFrame *b, AVFrame *out,  \ 
  601                                  int slice_start, int slice_end, int jobnr)         \ 
  603     XFadeContext *s = ctx->priv;                                                    \ 
  604     const int width = out->width;                                                   \ 
  605     const float max = s->max_value;                                                 \ 
  607     for (int y = slice_start; y < slice_end; y++) {                                 \ 
  608         for (int x = 0; x < width; x++) {                                           \ 
  610             for (int p = 0; p < s->nb_planes; p++) {                                \ 
  611                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);  \ 
  612                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);  \ 
  614                 dist += (xf0[x] / max - xf1[x] / max) *                             \ 
  615                         (xf0[x] / max - xf1[x] / max);                              \ 
  618             dist = sqrtf(dist) <= progress;                                         \ 
  619             for (int p = 0; p < s->nb_planes; p++) {                                \ 
  620                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);  \ 
  621                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);  \ 
  622                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);          \ 
  623                 dst[x] = mix(mix(xf0[x], xf1[x], dist), xf1[x], progress);          \ 
  632 #define FADEBLACK_TRANSITION(name, type, div)                                        \ 
  633 static void fadeblack##name##_transition(AVFilterContext *ctx,                       \ 
  634                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  636                             int slice_start, int slice_end, int jobnr)               \ 
  638     XFadeContext *s = ctx->priv;                                                     \ 
  639     const int height = slice_end - slice_start;                                      \ 
  640     const float phase = 0.2f;                                                        \ 
  642     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  643         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  644         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  645         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  646         const int bg = s->black[p];                                                  \ 
  648         for (int y = 0; y < height; y++) {                                           \ 
  649             for (int x = 0; x < out->width; x++) {                                   \ 
  650                 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)),  \ 
  651                          mix(bg, xf1[x], smoothstep(phase, 1.f, progress)),          \ 
  655             dst += out->linesize[p] / div;                                           \ 
  656             xf0 += a->linesize[p] / div;                                             \ 
  657             xf1 += b->linesize[p] / div;                                             \ 
  665 #define FADEWHITE_TRANSITION(name, type, div)                                        \ 
  666 static void fadewhite##name##_transition(AVFilterContext *ctx,                       \ 
  667                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  669                             int slice_start, int slice_end, int jobnr)               \ 
  671     XFadeContext *s = ctx->priv;                                                     \ 
  672     const int height = slice_end - slice_start;                                      \ 
  673     const float phase = 0.2f;                                                        \ 
  675     for (int p = 0; p < s->nb_planes; p++) {                                         \ 
  676         const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 
  677         const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 
  678         type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]);         \ 
  679         const int bg = s->white[p];                                                  \ 
  681         for (int y = 0; y < height; y++) {                                           \ 
  682             for (int x = 0; x < out->width; x++) {                                   \ 
  683                 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)),  \ 
  684                          mix(bg, xf1[x], smoothstep(phase, 1.f, progress)),          \ 
  688             dst += out->linesize[p] / div;                                           \ 
  689             xf0 += a->linesize[p] / div;                                             \ 
  690             xf1 += b->linesize[p] / div;                                             \ 
  698 #define RADIAL_TRANSITION(name, type, div)                                           \ 
  699 static void radial##name##_transition(AVFilterContext *ctx,                          \ 
  700                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  702                             int slice_start, int slice_end, int jobnr)               \ 
  704     XFadeContext *s = ctx->priv;                                                     \ 
  705     const int width = out->width;                                                    \ 
  706     const int height = out->height;                                                  \ 
  708     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  709         for (int x = 0; x < width; x++) {                                            \ 
  710             const float smooth = atan2f(x - width / 2, y - height / 2) -             \ 
  711                                  (progress - 0.5f) * (M_PI * 2.5f);                  \ 
  712             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  713                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  714                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  715                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  717                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  726 #define SMOOTHLEFT_TRANSITION(name, type, div)                                       \ 
  727 static void smoothleft##name##_transition(AVFilterContext *ctx,                      \ 
  728                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  730                             int slice_start, int slice_end, int jobnr)               \ 
  732     XFadeContext *s = ctx->priv;                                                     \ 
  733     const int width = out->width;                                                    \ 
  734     const float w = width;                                                           \ 
  736     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  737         for (int x = 0; x < width; x++) {                                            \ 
  738             const float smooth = 1.f + x / w - progress * 2.f;                       \ 
  740             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  741                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  742                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  743                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  745                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  754 #define SMOOTHRIGHT_TRANSITION(name, type, div)                                      \ 
  755 static void smoothright##name##_transition(AVFilterContext *ctx,                     \ 
  756                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  758                             int slice_start, int slice_end, int jobnr)               \ 
  760     XFadeContext *s = ctx->priv;                                                     \ 
  761     const int width = out->width;                                                    \ 
  762     const float w = width;                                                           \ 
  764     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  765         for (int x = 0; x < width; x++) {                                            \ 
  766             const float smooth = 1.f + (w - 1 - x) / w - progress * 2.f;             \ 
  768             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  769                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  770                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  771                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  773                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  782 #define SMOOTHUP_TRANSITION(name, type, div)                                         \ 
  783 static void smoothup##name##_transition(AVFilterContext *ctx,                        \ 
  784                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  786                             int slice_start, int slice_end, int jobnr)               \ 
  788     XFadeContext *s = ctx->priv;                                                     \ 
  789     const int width = out->width;                                                    \ 
  790     const float h = out->height;                                                     \ 
  792     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  793         const float smooth = 1.f + y / h - progress * 2.f;                           \ 
  794         for (int x = 0; x < width; x++) {                                            \ 
  795             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  796                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  797                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  798                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  800                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  809 #define SMOOTHDOWN_TRANSITION(name, type, div)                                       \ 
  810 static void smoothdown##name##_transition(AVFilterContext *ctx,                      \ 
  811                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  813                             int slice_start, int slice_end, int jobnr)               \ 
  815     XFadeContext *s = ctx->priv;                                                     \ 
  816     const int width = out->width;                                                    \ 
  817     const float h = out->height;                                                     \ 
  819     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  820         const float smooth = 1.f + (h - 1 - y) / h - progress * 2.f;                 \ 
  821         for (int x = 0; x < width; x++) {                                            \ 
  822             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  823                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  824                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  825                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  827                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  836 #define CIRCLEOPEN_TRANSITION(name, type, div)                                       \ 
  837 static void circleopen##name##_transition(AVFilterContext *ctx,                      \ 
  838                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  840                             int slice_start, int slice_end, int jobnr)               \ 
  842     XFadeContext *s = ctx->priv;                                                     \ 
  843     const int width = out->width;                                                    \ 
  844     const int height = out->height;                                                  \ 
  845     const float z = hypotf(width / 2, height / 2);                                   \ 
  846     const float p = (progress - 0.5f) * 3.f;                                         \ 
  848     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  849         for (int x = 0; x < width; x++) {                                            \ 
  850             const float smooth = hypotf(x - width / 2, y - height / 2) / z + p;      \ 
  851             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  852                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  853                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  854                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  856                 dst[x] = mix(xf0[x], xf1[x], smoothstep(0.f, 1.f, smooth));          \ 
  865 #define CIRCLECLOSE_TRANSITION(name, type, div)                                      \ 
  866 static void circleclose##name##_transition(AVFilterContext *ctx,                     \ 
  867                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  869                             int slice_start, int slice_end, int jobnr)               \ 
  871     XFadeContext *s = ctx->priv;                                                     \ 
  872     const int width = out->width;                                                    \ 
  873     const int height = out->height;                                                  \ 
  874     const float z = hypotf(width / 2, height / 2);                                   \ 
  875     const float p = (1.f - progress - 0.5f) * 3.f;                                   \ 
  877     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  878         for (int x = 0; x < width; x++) {                                            \ 
  879             const float smooth = hypotf(x - width / 2, y - height / 2) / z + p;      \ 
  880             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  881                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  882                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  883                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  885                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  894 #define VERTOPEN_TRANSITION(name, type, div)                                         \ 
  895 static void vertopen##name##_transition(AVFilterContext *ctx,                        \ 
  896                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  898                             int slice_start, int slice_end, int jobnr)               \ 
  900     XFadeContext *s = ctx->priv;                                                     \ 
  901     const int width = out->width;                                                    \ 
  902     const float w2 = out->width / 2;                                                 \ 
  904     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  905         for (int x = 0; x < width; x++) {                                            \ 
  906             const float smooth = 2.f - fabsf((x - w2) / w2) - progress * 2.f;        \ 
  907             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  908                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  909                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  910                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  912                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  921 #define VERTCLOSE_TRANSITION(name, type, div)                                        \ 
  922 static void vertclose##name##_transition(AVFilterContext *ctx,                       \ 
  923                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  925                             int slice_start, int slice_end, int jobnr)               \ 
  927     XFadeContext *s = ctx->priv;                                                     \ 
  928     const int width = out->width;                                                    \ 
  929     const float w2 = out->width / 2;                                                 \ 
  931     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  932         for (int x = 0; x < width; x++) {                                            \ 
  933             const float smooth = 1.f + fabsf((x - w2) / w2) - progress * 2.f;        \ 
  934             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  935                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  936                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  937                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  939                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  948 #define HORZOPEN_TRANSITION(name, type, div)                                         \ 
  949 static void horzopen##name##_transition(AVFilterContext *ctx,                        \ 
  950                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  952                             int slice_start, int slice_end, int jobnr)               \ 
  954     XFadeContext *s = ctx->priv;                                                     \ 
  955     const int width = out->width;                                                    \ 
  956     const float h2 = out->height / 2;                                                \ 
  958     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  959         const float smooth = 2.f - fabsf((y - h2) / h2) - progress * 2.f;            \ 
  960         for (int x = 0; x < width; x++) {                                            \ 
  961             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  962                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  963                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  964                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  966                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
  975 #define HORZCLOSE_TRANSITION(name, type, div)                                        \ 
  976 static void horzclose##name##_transition(AVFilterContext *ctx,                       \ 
  977                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
  979                             int slice_start, int slice_end, int jobnr)               \ 
  981     XFadeContext *s = ctx->priv;                                                     \ 
  982     const int width = out->width;                                                    \ 
  983     const float h2 = out->height / 2;                                                \ 
  985     for (int y = slice_start; y < slice_end; y++) {                                  \ 
  986         const float smooth = 1.f + fabsf((y - h2) / h2) - progress * 2.f;            \ 
  987         for (int x = 0; x < width; x++) {                                            \ 
  988             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
  989                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
  990                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
  991                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
  993                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
 1004     const float r = 
sinf(x * 12.9898
f + y * 78.233
f) * 43758.545f;
 
 1006     return r - floorf(
r);
 
 1009 #define DISSOLVE_TRANSITION(name, type, div)                                         \ 
 1010 static void dissolve##name##_transition(AVFilterContext *ctx,                        \ 
 1011                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1013                             int slice_start, int slice_end, int jobnr)               \ 
 1015     XFadeContext *s = ctx->priv;                                                     \ 
 1016     const int width = out->width;                                                    \ 
 1018     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1019         for (int x = 0; x < width; x++) {                                            \ 
 1020             const float smooth = frand(x, y) * 2.f + progress * 2.f - 1.5f;          \ 
 1021             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1022                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1023                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1024                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1026                 dst[x] = smooth >= 0.5f ? xf0[x] : xf1[x];                           \ 
 1035 #define PIXELIZE_TRANSITION(name, type, div)                                         \ 
 1036 static void pixelize##name##_transition(AVFilterContext *ctx,                        \ 
 1037                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1039                             int slice_start, int slice_end, int jobnr)               \ 
 1041     XFadeContext *s = ctx->priv;                                                     \ 
 1042     const int w = out->width;                                                        \ 
 1043     const int h = out->height;                                                       \ 
 1044     const float d = fminf(progress, 1.f - progress);                                 \ 
 1045     const float dist = ceilf(d * 50.f) / 50.f;                                       \ 
 1046     const float sqx = 2.f * dist * FFMIN(w, h) / 20.f;                               \ 
 1047     const float sqy = 2.f * dist * FFMIN(w, h) / 20.f;                               \ 
 1049     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1050         for (int x = 0; x < w; x++) {                                                \ 
 1051             int sx = dist > 0.f ? FFMIN((floorf(x / sqx) + .5f) * sqx, w - 1) : x;   \ 
 1052             int sy = dist > 0.f ? FFMIN((floorf(y / sqy) + .5f) * sqy, h - 1) : y;   \ 
 1053             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1054                 const type *xf0 = (const type *)(a->data[p] + sy * a->linesize[p]);  \ 
 1055                 const type *xf1 = (const type *)(b->data[p] + sy * b->linesize[p]);  \ 
 1056                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1058                 dst[x] = mix(xf0[sx], xf1[sx], progress);                            \ 
 1067 #define DIAGTL_TRANSITION(name, type, div)                                           \ 
 1068 static void diagtl##name##_transition(AVFilterContext *ctx,                          \ 
 1069                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1071                             int slice_start, int slice_end, int jobnr)               \ 
 1073     XFadeContext *s = ctx->priv;                                                     \ 
 1074     const int width = out->width;                                                    \ 
 1075     const float w = width;                                                           \ 
 1076     const float h = out->height;                                                     \ 
 1078     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1079         for (int x = 0; x < width; x++) {                                            \ 
 1080             const float smooth = 1.f + x / w * y / h - progress * 2.f;               \ 
 1082             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1083                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1084                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1085                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1087                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
 1096 #define DIAGTR_TRANSITION(name, type, div)                                           \ 
 1097 static void diagtr##name##_transition(AVFilterContext *ctx,                          \ 
 1098                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1100                             int slice_start, int slice_end, int jobnr)               \ 
 1102     XFadeContext *s = ctx->priv;                                                     \ 
 1103     const int width = out->width;                                                    \ 
 1104     const float w = width;                                                           \ 
 1105     const float h = out->height;                                                     \ 
 1107     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1108         for (int x = 0; x < width; x++) {                                            \ 
 1109             const float smooth = 1.f + (w - 1 - x) / w * y / h - progress * 2.f;     \ 
 1111             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1112                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1113                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1114                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1116                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
 1125 #define DIAGBL_TRANSITION(name, type, div)                                           \ 
 1126 static void diagbl##name##_transition(AVFilterContext *ctx,                          \ 
 1127                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1129                             int slice_start, int slice_end, int jobnr)               \ 
 1131     XFadeContext *s = ctx->priv;                                                     \ 
 1132     const int width = out->width;                                                    \ 
 1133     const float w = width;                                                           \ 
 1134     const float h = out->height;                                                     \ 
 1136     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1137         for (int x = 0; x < width; x++) {                                            \ 
 1138             const float smooth = 1.f + x / w * (h - 1 - y) / h - progress * 2.f;     \ 
 1140             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1141                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1142                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1143                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1145                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
 1154 #define DIAGBR_TRANSITION(name, type, div)                                           \ 
 1155 static void diagbr##name##_transition(AVFilterContext *ctx,                          \ 
 1156                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1158                             int slice_start, int slice_end, int jobnr)               \ 
 1160     XFadeContext *s = ctx->priv;                                                     \ 
 1161     const int width = out->width;                                                    \ 
 1162     const float w = width;                                                           \ 
 1163     const float h = out->height;                                                     \ 
 1165     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1166         for (int x = 0; x < width; x++) {                                            \ 
 1167             const float smooth = 1.f + (w - 1 - x) / w * (h - 1 - y) / h -           \ 
 1170             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1171                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1172                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1173                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1175                 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth));          \ 
 1184 #define HLSLICE_TRANSITION(name, type, div)                                          \ 
 1185 static void hlslice##name##_transition(AVFilterContext *ctx,                         \ 
 1186                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1188                             int slice_start, int slice_end, int jobnr)               \ 
 1190     XFadeContext *s = ctx->priv;                                                     \ 
 1191     const int width = out->width;                                                    \ 
 1192     const float w = width;                                                           \ 
 1194     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1195         for (int x = 0; x < width; x++) {                                            \ 
 1196             const float smooth = smoothstep(-0.5f, 0.f, x / w - progress * 1.5f);    \ 
 1197             const float ss = smooth <= fract(10.f * x / w) ? 0.f : 1.f;              \ 
 1199             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1200                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1201                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1202                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1204                 dst[x] = mix(xf1[x], xf0[x], ss);                                    \ 
 1213 #define HRSLICE_TRANSITION(name, type, div)                                          \ 
 1214 static void hrslice##name##_transition(AVFilterContext *ctx,                         \ 
 1215                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1217                             int slice_start, int slice_end, int jobnr)               \ 
 1219     XFadeContext *s = ctx->priv;                                                     \ 
 1220     const int width = out->width;                                                    \ 
 1221     const float w = width;                                                           \ 
 1223     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1224         for (int x = 0; x < width; x++) {                                            \ 
 1225             const float xx = (w - 1 - x) / w;                                        \ 
 1226             const float smooth = smoothstep(-0.5f, 0.f, xx - progress * 1.5f);       \ 
 1227             const float ss = smooth <= fract(10.f * xx) ? 0.f : 1.f;                 \ 
 1229             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1230                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1231                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1232                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1234                 dst[x] = mix(xf1[x], xf0[x], ss);                                    \ 
 1243 #define VUSLICE_TRANSITION(name, type, div)                                          \ 
 1244 static void vuslice##name##_transition(AVFilterContext *ctx,                         \ 
 1245                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1247                             int slice_start, int slice_end, int jobnr)               \ 
 1249     XFadeContext *s = ctx->priv;                                                     \ 
 1250     const int width = out->width;                                                    \ 
 1251     const float h = out->height;                                                     \ 
 1253     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1254          const float smooth = smoothstep(-0.5f, 0.f, y / h - progress * 1.5f);       \ 
 1255          const float ss = smooth <= fract(10.f * y / h) ? 0.f : 1.f;                 \ 
 1257          for (int x = 0; x < width; x++) {                                           \ 
 1258             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1259                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1260                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1261                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1263                 dst[x] = mix(xf1[x], xf0[x], ss);                                    \ 
 1272 #define VDSLICE_TRANSITION(name, type, div)                                          \ 
 1273 static void vdslice##name##_transition(AVFilterContext *ctx,                         \ 
 1274                             const AVFrame *a, const AVFrame *b, AVFrame *out,        \ 
 1276                             int slice_start, int slice_end, int jobnr)               \ 
 1278     XFadeContext *s = ctx->priv;                                                     \ 
 1279     const int width = out->width;                                                    \ 
 1280     const float h = out->height;                                                     \ 
 1282     for (int y = slice_start; y < slice_end; y++) {                                  \ 
 1283          const float yy = (h - 1 - y) / h;                                           \ 
 1284          const float smooth = smoothstep(-0.5f, 0.f, yy - progress * 1.5f);          \ 
 1285          const float ss = smooth <= fract(10.f * yy) ? 0.f : 1.f;                    \ 
 1287          for (int x = 0; x < width; x++) {                                           \ 
 1288             for (int p = 0; p < s->nb_planes; p++) {                                 \ 
 1289                 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]);   \ 
 1290                 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]);   \ 
 1291                 type *dst = (type *)(out->data[p] + y * out->linesize[p]);           \ 
 1293                 dst[x] = mix(xf1[x], xf0[x], ss);                                    \ 
 1302 static inline 
double getpix(
void *priv, 
double x, 
double y, 
int plane, 
int nb)
 
 1307     int linesize = 
in->linesize[
FFMIN(plane, 
s->nb_planes - 1)];
 
 1308     const int w = 
in->width;
 
 1309     const int h = 
in->height;
 
 1313     xi = av_clipd(x, 0, 
w - 1);
 
 1314     yi = av_clipd(y, 0, 
h - 1);
 
 1317         const uint16_t *src16 = (
const uint16_t*)
src;
 
 1320         return src16[
xi + yi * linesize];
 
 1322         return src[
xi + yi * linesize];
 
 1326 static double a0(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 0, 0); }
 
 1327 static double a1(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 1, 0); }
 
 1328 static double a2(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 2, 0); }
 
 1329 static double a3(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 3, 0); }
 
 1331 static double b0(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 0, 1); }
 
 1332 static double b1(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 1, 1); }
 
 1333 static double b2(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 2, 1); }
 
 1334 static double b3(
void *priv, 
double x, 
double y) { 
return getpix(priv, x, y, 3, 1); }
 
 1349     if (inlink0->
w != inlink1->
w || inlink0->
h != inlink1->
h) {
 
 1351                "(size %dx%d) do not match the corresponding " 
 1352                "second input link %s parameters (size %dx%d)\n",
 
 1353                ctx->input_pads[0].name, inlink0->
w, inlink0->
h,
 
 1354                ctx->input_pads[1].name, inlink1->
w, inlink1->
h);
 
 1361                "(%d/%d) do not match the corresponding " 
 1362                "second input link %s timebase (%d/%d)\n",
 
 1368     outlink->
w = inlink0->
w;
 
 1369     outlink->
h = inlink0->
h;
 
 1377     s->max_value = (1 << 
s->depth) - 1;
 
 1379     s->black[1] = 
s->black[2] = is_rgb ? 0 : 
s->max_value / 2;
 
 1380     s->black[3] = 
s->max_value;
 
 1381     s->white[0] = 
s->white[3] = 
s->max_value;
 
 1382     s->white[1] = 
s->white[2] = is_rgb ? 
s->max_value : 
s->max_value / 2;
 
 1391     switch (
s->transition) {
 
 1392     case CUSTOM:     
s->transitionf = 
s->depth <= 8 ? custom8_transition     : custom16_transition;     
break;
 
 1393     case FADE:       
s->transitionf = 
s->depth <= 8 ? fade8_transition       : fade16_transition;       
break;
 
 1394     case WIPELEFT:   
s->transitionf = 
s->depth <= 8 ? wipeleft8_transition   : wipeleft16_transition;   
break;
 
 1395     case WIPERIGHT:  
s->transitionf = 
s->depth <= 8 ? wiperight8_transition  : wiperight16_transition;  
break;
 
 1396     case WIPEUP:     
s->transitionf = 
s->depth <= 8 ? wipeup8_transition     : wipeup16_transition;     
break;
 
 1397     case WIPEDOWN:   
s->transitionf = 
s->depth <= 8 ? wipedown8_transition   : wipedown16_transition;   
break;
 
 1398     case SLIDELEFT:  
s->transitionf = 
s->depth <= 8 ? slideleft8_transition  : slideleft16_transition;  
break;
 
 1399     case SLIDERIGHT: 
s->transitionf = 
s->depth <= 8 ? slideright8_transition : slideright16_transition; 
break;
 
 1400     case SLIDEUP:    
s->transitionf = 
s->depth <= 8 ? slideup8_transition    : slideup16_transition;    
break;
 
 1401     case SLIDEDOWN:  
s->transitionf = 
s->depth <= 8 ? slidedown8_transition  : slidedown16_transition;  
break;
 
 1402     case CIRCLECROP: 
s->transitionf = 
s->depth <= 8 ? circlecrop8_transition : circlecrop16_transition; 
break;
 
 1403     case RECTCROP:   
s->transitionf = 
s->depth <= 8 ? rectcrop8_transition   : rectcrop16_transition;   
break;
 
 1404     case DISTANCE:   
s->transitionf = 
s->depth <= 8 ? distance8_transition   : distance16_transition;   
break;
 
 1405     case FADEBLACK:  
s->transitionf = 
s->depth <= 8 ? fadeblack8_transition  : fadeblack16_transition;  
break;
 
 1406     case FADEWHITE:  
s->transitionf = 
s->depth <= 8 ? fadewhite8_transition  : fadewhite16_transition;  
break;
 
 1407     case RADIAL:     
s->transitionf = 
s->depth <= 8 ? radial8_transition     : radial16_transition;     
break;
 
 1408     case SMOOTHLEFT: 
s->transitionf = 
s->depth <= 8 ? smoothleft8_transition : smoothleft16_transition; 
break;
 
 1409     case SMOOTHRIGHT:
s->transitionf = 
s->depth <= 8 ? smoothright8_transition: smoothright16_transition;
break;
 
 1410     case SMOOTHUP:   
s->transitionf = 
s->depth <= 8 ? smoothup8_transition   : smoothup16_transition;   
break;
 
 1411     case SMOOTHDOWN: 
s->transitionf = 
s->depth <= 8 ? smoothdown8_transition : smoothdown16_transition; 
break;
 
 1412     case CIRCLEOPEN: 
s->transitionf = 
s->depth <= 8 ? circleopen8_transition : circleopen16_transition; 
break;
 
 1413     case CIRCLECLOSE:
s->transitionf = 
s->depth <= 8 ? circleclose8_transition: circleclose16_transition;
break;
 
 1414     case VERTOPEN:   
s->transitionf = 
s->depth <= 8 ? vertopen8_transition   : vertopen16_transition;   
break;
 
 1415     case VERTCLOSE:  
s->transitionf = 
s->depth <= 8 ? vertclose8_transition  : vertclose16_transition;  
break;
 
 1416     case HORZOPEN:   
s->transitionf = 
s->depth <= 8 ? horzopen8_transition   : horzopen16_transition;   
break;
 
 1417     case HORZCLOSE:  
s->transitionf = 
s->depth <= 8 ? horzclose8_transition  : horzclose16_transition;  
break;
 
 1418     case DISSOLVE:   
s->transitionf = 
s->depth <= 8 ? dissolve8_transition   : dissolve16_transition;   
break;
 
 1419     case PIXELIZE:   
s->transitionf = 
s->depth <= 8 ? pixelize8_transition   : pixelize16_transition;   
break;
 
 1420     case DIAGTL:     
s->transitionf = 
s->depth <= 8 ? diagtl8_transition     : diagtl16_transition;     
break;
 
 1421     case DIAGTR:     
s->transitionf = 
s->depth <= 8 ? diagtr8_transition     : diagtr16_transition;     
break;
 
 1422     case DIAGBL:     
s->transitionf = 
s->depth <= 8 ? diagbl8_transition     : diagbl16_transition;     
break;
 
 1423     case DIAGBR:     
s->transitionf = 
s->depth <= 8 ? diagbr8_transition     : diagbr16_transition;     
break;
 
 1424     case HLSLICE:    
s->transitionf = 
s->depth <= 8 ? hlslice8_transition    : hlslice16_transition;    
break;
 
 1425     case HRSLICE:    
s->transitionf = 
s->depth <= 8 ? hrslice8_transition    : hrslice16_transition;    
break;
 
 1426     case VUSLICE:    
s->transitionf = 
s->depth <= 8 ? vuslice8_transition    : vuslice16_transition;    
break;
 
 1427     case VDSLICE:    
s->transitionf = 
s->depth <= 8 ? vdslice8_transition    : vdslice16_transition;    
break;
 
 1430     if (
s->transition == 
CUSTOM) {
 
 1432             "a0", 
"a1", 
"a2", 
"a3",
 
 1433             "b0", 
"b1", 
"b2", 
"b3",
 
 1436         double (*
func2[])(
void *, double, double) = {
 
 1458     int slice_start = (outlink->
h *  jobnr   ) / nb_jobs;
 
 1459     int slice_end   = (outlink->
h * (jobnr+1)) / nb_jobs;
 
 1470     float progress = av_clipf(1.
f - ((
float)(
s->pts - 
s->first_pts - 
s->offset_pts) / 
s->duration_pts), 0.f, 1.f);
 
 1478     td.xf[0] = 
a, 
td.xf[1] = 
b, 
td.out = 
out, 
td.progress = progress;
 
 1496     if (
s->xfade_is_over) {
 
 1500         } 
else if (
ret > 0) {
 
 1501             in->pts = (
in->pts - 
s->last_pts) + 
s->pts;
 
 1518                 s->first_pts = 
s->xf[0]->pts;
 
 1520             s->pts = 
s->xf[0]->pts;
 
 1521             if (
s->first_pts + 
s->offset_pts > 
s->xf[0]->pts) {
 
 1536         s->last_pts = 
s->xf[1]->pts;
 
 1537         s->pts = 
s->xf[0]->pts;
 
 1538         if (
s->xf[0]->pts - (
s->first_pts + 
s->offset_pts) > 
s->duration_pts)
 
 1539             s->xfade_is_over = 1;
 
 1555             s->xfade_is_over = 1;
 
 1560         if (!
s->eof[0] && !
s->xf[0])
 
 1562         if (!
s->eof[1] && (
s->need_second || 
s->eof[0]))
 
 1564         if (
s->eof[0] && 
s->eof[1] && (
 
 1599     .priv_class    = &xfade_class,
 
  
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
#define AV_PIX_FMT_GBRAP16
AVPixelFormat
Pixel format.
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
#define HORZOPEN_TRANSITION(name, type, div)
#define FADEBLACK_TRANSITION(name, type, div)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
#define SLIDERIGHT_TRANSITION(name, type, div)
static int xfade_activate(AVFilterContext *ctx)
#define CIRCLECROP_TRANSITION(name, type, div)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AVERROR_EOF
End of file.
static const AVOption xfade_options[]
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
#define WIPEDOWN_TRANSITION(name, type, div)
#define RECTCROP_TRANSITION(name, type, div)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFILTER_DEFINE_CLASS(xfade)
This structure describes decoded (raw) audio or video data.
#define SLIDELEFT_TRANSITION(name, type, div)
int depth
Number of bits in the component.
#define VDSLICE_TRANSITION(name, type, div)
#define WIPERIGHT_TRANSITION(name, type, div)
const char * name
Filter name.
#define SMOOTHDOWN_TRANSITION(name, type, div)
AVFormatInternal * internal
An opaque field for libavformat internal usage.
A link between two filters.
static float mix(float a, float b, float mix)
static const char *const func2_names[]
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
#define AV_PIX_FMT_GBRP14
static double b1(void *priv, double x, double y)
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
#define AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_YUVA444P16
#define VERTOPEN_TRANSITION(name, type, div)
static int xfade_frame(AVFilterContext *ctx, AVFrame *a, AVFrame *b)
#define SLIDEDOWN_TRANSITION(name, type, div)
#define PIXELIZE_TRANSITION(name, type, div)
#define AV_PIX_FMT_GRAY16
static double a2(void *priv, double x, double y)
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
#define HLSLICE_TRANSITION(name, type, div)
A filter pad used for either input or output.
#define AV_PIX_FMT_YUV444P10
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define DIAGTR_TRANSITION(name, type, div)
#define SMOOTHLEFT_TRANSITION(name, type, div)
#define AV_PIX_FMT_GBRAP10
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
static double b3(void *priv, double x, double y)
#define AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_YUV444P16
static float smoothstep(float edge0, float edge1, float x)
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
static const char *const var_names[]
static const AVFilterPad outputs[]
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
static enum AVPixelFormat pix_fmts[]
#define AV_PIX_FMT_YUVA444P12
#define xi(width, name, var, range_min, range_max, subs,...)
static double getpix(void *priv, double x, double y, int plane, int nb)
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
#define CIRCLECLOSE_TRANSITION(name, type, div)
#define DIAGBL_TRANSITION(name, type, div)
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
#define AV_PIX_FMT_GRAY10
AVFrame * ff_inlink_peek_frame(AVFilterLink *link, size_t idx)
Access a frame in the link fifo without consuming it.
#define AV_PIX_FMT_GBRP16
#define SLIDEUP_TRANSITION(name, type, div)
Describe the class of an AVClass context structure.
static double a3(void *priv, double x, double y)
#define FADE_TRANSITION(name, type, div)
filter_frame For filters that do not use the activate() callback
static const AVFilterPad xfade_inputs[]
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
#define DISTANCE_TRANSITION(name, type, div)
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
static const AVFilterPad xfade_outputs[]
size_t ff_inlink_queued_frames(AVFilterLink *link)
Get the number of frames available on the link.
#define RADIAL_TRANSITION(name, type, div)
#define WIPELEFT_TRANSITION(name, type, div)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#define CUSTOM_TRANSITION(name, type, div)
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
#define HORZCLOSE_TRANSITION(name, type, div)
int format
agreed upon media format
static av_cold void uninit(AVFilterContext *ctx)
#define AV_NOPTS_VALUE
Undefined timestamp value.
#define AV_PIX_FMT_YUV444P12
AVFilterContext * src
source filter
#define VUSLICE_TRANSITION(name, type, div)
static double b2(void *priv, double x, double y)
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
static double a0(void *priv, double x, double y)
#define AV_PIX_FMT_YUVA444P10
static float frand(int x, int y)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
#define WIPEUP_TRANSITION(name, type, div)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static int config_output(AVFilterLink *outlink)
#define SMOOTHRIGHT_TRANSITION(name, type, div)
int w
agreed upon image width
#define AV_PIX_FMT_GBRP12
#define VERTCLOSE_TRANSITION(name, type, div)
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Used for passing data between threads.
#define DIAGTL_TRANSITION(name, type, div)
const char * name
Pad name.
static float fract(float a)
#define CIRCLEOPEN_TRANSITION(name, type, div)
#define AV_PIX_FMT_YUVA444P9
static int xfade_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
int h
agreed upon image height
#define FADEWHITE_TRANSITION(name, type, div)
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
int ff_outlink_get_status(AVFilterLink *link)
Get the status on an output link.
#define SMOOTHUP_TRANSITION(name, type, div)
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
void(* transitionf)(AVFilterContext *ctx, const AVFrame *a, const AVFrame *b, AVFrame *out, float progress, int slice_start, int slice_end, int jobnr)
#define DIAGBR_TRANSITION(name, type, div)
double(* func2[])(void *, double, double)
#define flags(name, subs,...)
static double b0(void *priv, double x, double y)
static double a1(void *priv, double x, double y)
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
#define AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_GRAY12
static int query_formats(AVFilterContext *ctx)
#define DISSOLVE_TRANSITION(name, type, div)
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
#define HRSLICE_TRANSITION(name, type, div)