Go to the documentation of this file.
108 int slice_start,
int slice_end,
int jobnr);
113 static const char *
const var_names[] = {
"X",
"Y",
"W",
"H",
"A",
"B",
"PLANE",
"P",
NULL };
148 #define OFFSET(x) offsetof(XFadeContext, x)
149 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
208 #define CUSTOM_TRANSITION(name, type, div) \
209 static void custom##name##_transition(AVFilterContext *ctx, \
210 const AVFrame *a, const AVFrame *b, AVFrame *out, \
212 int slice_start, int slice_end, int jobnr) \
214 XFadeContext *s = ctx->priv; \
215 const int height = slice_end - slice_start; \
217 double values[VAR_VARS_NB]; \
218 values[VAR_W] = out->width; \
219 values[VAR_H] = out->height; \
220 values[VAR_PROGRESS] = progress; \
222 for (int p = 0; p < s->nb_planes; p++) { \
223 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
224 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
225 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
227 values[VAR_PLANE] = p; \
229 for (int y = 0; y < height; y++) { \
230 values[VAR_Y] = slice_start + y; \
231 for (int x = 0; x < out->width; x++) { \
233 values[VAR_A] = xf0[x]; \
234 values[VAR_B] = xf1[x]; \
235 dst[x] = av_expr_eval(s->e, values, s); \
238 dst += out->linesize[p] / div; \
239 xf0 += a->linesize[p] / div; \
240 xf1 += b->linesize[p] / div; \
248 static inline
float mix(
float a,
float b,
float mix)
258 static inline float smoothstep(
float edge0,
float edge1,
float x)
262 t =
av_clipf((x - edge0) / (edge1 - edge0), 0.
f, 1.
f);
264 return t * t * (3.f - 2.f * t);
267 #define FADE_TRANSITION(name, type, div) \
268 static void fade##name##_transition(AVFilterContext *ctx, \
269 const AVFrame *a, const AVFrame *b, AVFrame *out, \
271 int slice_start, int slice_end, int jobnr) \
273 XFadeContext *s = ctx->priv; \
274 const int height = slice_end - slice_start; \
276 for (int p = 0; p < s->nb_planes; p++) { \
277 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
278 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
279 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
281 for (int y = 0; y < height; y++) { \
282 for (int x = 0; x < out->width; x++) { \
283 dst[x] = mix(xf0[x], xf1[x], progress); \
286 dst += out->linesize[p] / div; \
287 xf0 += a->linesize[p] / div; \
288 xf1 += b->linesize[p] / div; \
296 #define WIPELEFT_TRANSITION(name, type, div) \
297 static void wipeleft##name##_transition(AVFilterContext *ctx, \
298 const AVFrame *a, const AVFrame *b, AVFrame *out, \
300 int slice_start, int slice_end, int jobnr) \
302 XFadeContext *s = ctx->priv; \
303 const int height = slice_end - slice_start; \
304 const int z = out->width * progress; \
306 for (int p = 0; p < s->nb_planes; p++) { \
307 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
308 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
309 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
311 for (int y = 0; y < height; y++) { \
312 for (int x = 0; x < out->width; x++) { \
313 dst[x] = x > z ? xf1[x] : xf0[x]; \
316 dst += out->linesize[p] / div; \
317 xf0 += a->linesize[p] / div; \
318 xf1 += b->linesize[p] / div; \
326 #define WIPERIGHT_TRANSITION(name, type, div) \
327 static void wiperight##name##_transition(AVFilterContext *ctx, \
328 const AVFrame *a, const AVFrame *b, AVFrame *out, \
330 int slice_start, int slice_end, int jobnr) \
332 XFadeContext *s = ctx->priv; \
333 const int height = slice_end - slice_start; \
334 const int z = out->width * (1.f - progress); \
336 for (int p = 0; p < s->nb_planes; p++) { \
337 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
338 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
339 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
341 for (int y = 0; y < height; y++) { \
342 for (int x = 0; x < out->width; x++) { \
343 dst[x] = x > z ? xf0[x] : xf1[x]; \
346 dst += out->linesize[p] / div; \
347 xf0 += a->linesize[p] / div; \
348 xf1 += b->linesize[p] / div; \
356 #define WIPEUP_TRANSITION(name, type, div) \
357 static void wipeup##name##_transition(AVFilterContext *ctx, \
358 const AVFrame *a, const AVFrame *b, AVFrame *out, \
360 int slice_start, int slice_end, int jobnr) \
362 XFadeContext *s = ctx->priv; \
363 const int height = slice_end - slice_start; \
364 const int z = out->height * progress; \
366 for (int p = 0; p < s->nb_planes; p++) { \
367 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
368 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
369 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
371 for (int y = 0; y < height; y++) { \
372 for (int x = 0; x < out->width; x++) { \
373 dst[x] = slice_start + y > z ? xf1[x] : xf0[x]; \
376 dst += out->linesize[p] / div; \
377 xf0 += a->linesize[p] / div; \
378 xf1 += b->linesize[p] / div; \
386 #define WIPEDOWN_TRANSITION(name, type, div) \
387 static void wipedown##name##_transition(AVFilterContext *ctx, \
388 const AVFrame *a, const AVFrame *b, AVFrame *out, \
390 int slice_start, int slice_end, int jobnr) \
392 XFadeContext *s = ctx->priv; \
393 const int height = slice_end - slice_start; \
394 const int z = out->height * (1.f - progress); \
396 for (int p = 0; p < s->nb_planes; p++) { \
397 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
398 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
399 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
401 for (int y = 0; y < height; y++) { \
402 for (int x = 0; x < out->width; x++) { \
403 dst[x] = slice_start + y > z ? xf0[x] : xf1[x]; \
406 dst += out->linesize[p] / div; \
407 xf0 += a->linesize[p] / div; \
408 xf1 += b->linesize[p] / div; \
416 #define SLIDELEFT_TRANSITION(name, type, div) \
417 static void slideleft##name##_transition(AVFilterContext *ctx, \
418 const AVFrame *a, const AVFrame *b, AVFrame *out, \
420 int slice_start, int slice_end, int jobnr) \
422 XFadeContext *s = ctx->priv; \
423 const int height = slice_end - slice_start; \
424 const int width = out->width; \
425 const int z = -progress * width; \
427 for (int p = 0; p < s->nb_planes; p++) { \
428 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
429 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
430 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
432 for (int y = 0; y < height; y++) { \
433 for (int x = 0; x < width; x++) { \
434 const int zx = z + x; \
435 const int zz = zx % width + width * (zx < 0); \
436 dst[x] = (zx >= 0) && (zx < width) ? xf1[zz] : xf0[zz]; \
439 dst += out->linesize[p] / div; \
440 xf0 += a->linesize[p] / div; \
441 xf1 += b->linesize[p] / div; \
449 #define SLIDERIGHT_TRANSITION(name, type, div) \
450 static void slideright##name##_transition(AVFilterContext *ctx, \
451 const AVFrame *a, const AVFrame *b, AVFrame *out, \
453 int slice_start, int slice_end, int jobnr) \
455 XFadeContext *s = ctx->priv; \
456 const int height = slice_end - slice_start; \
457 const int width = out->width; \
458 const int z = progress * width; \
460 for (int p = 0; p < s->nb_planes; p++) { \
461 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
462 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
463 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
465 for (int y = 0; y < height; y++) { \
466 for (int x = 0; x < out->width; x++) { \
467 const int zx = z + x; \
468 const int zz = zx % width + width * (zx < 0); \
469 dst[x] = (zx >= 0) && (zx < width) ? xf1[zz] : xf0[zz]; \
472 dst += out->linesize[p] / div; \
473 xf0 += a->linesize[p] / div; \
474 xf1 += b->linesize[p] / div; \
482 #define SLIDEUP_TRANSITION(name, type, div) \
483 static void slideup##name##_transition(AVFilterContext *ctx, \
484 const AVFrame *a, const AVFrame *b, AVFrame *out, \
486 int slice_start, int slice_end, int jobnr) \
488 XFadeContext *s = ctx->priv; \
489 const int height = out->height; \
490 const int z = -progress * height; \
492 for (int p = 0; p < s->nb_planes; p++) { \
493 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
495 for (int y = slice_start; y < slice_end; y++) { \
496 const int zy = z + y; \
497 const int zz = zy % height + height * (zy < 0); \
498 const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]); \
499 const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]); \
501 for (int x = 0; x < out->width; x++) { \
502 dst[x] = (zy >= 0) && (zy < height) ? xf1[x] : xf0[x]; \
505 dst += out->linesize[p] / div; \
513 #define SLIDEDOWN_TRANSITION(name, type, div) \
514 static void slidedown##name##_transition(AVFilterContext *ctx, \
515 const AVFrame *a, const AVFrame *b, AVFrame *out, \
517 int slice_start, int slice_end, int jobnr) \
519 XFadeContext *s = ctx->priv; \
520 const int height = out->height; \
521 const int z = progress * height; \
523 for (int p = 0; p < s->nb_planes; p++) { \
524 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
526 for (int y = slice_start; y < slice_end; y++) { \
527 const int zy = z + y; \
528 const int zz = zy % height + height * (zy < 0); \
529 const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]); \
530 const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]); \
532 for (int x = 0; x < out->width; x++) { \
533 dst[x] = (zy >= 0) && (zy < height) ? xf1[x] : xf0[x]; \
536 dst += out->linesize[p] / div; \
544 #define CIRCLECROP_TRANSITION(name, type, div) \
545 static void circlecrop##name##_transition(AVFilterContext *ctx, \
546 const AVFrame *a, const AVFrame *b, AVFrame *out, \
548 int slice_start, int slice_end, int jobnr) \
550 XFadeContext *s = ctx->priv; \
551 const int width = out->width; \
552 const int height = out->height; \
553 float z = powf(2.f * fabsf(progress - 0.5f), 3.f) * hypotf(width/2, height/2); \
555 for (int p = 0; p < s->nb_planes; p++) { \
556 const int bg = s->black[p]; \
557 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
559 for (int y = slice_start; y < slice_end; y++) { \
560 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
561 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
563 for (int x = 0; x < width; x++) { \
564 float dist = hypotf(x - width / 2, y - height / 2); \
565 int val = progress < 0.5f ? xf1[x] : xf0[x]; \
566 dst[x] = (z < dist) ? bg : val; \
569 dst += out->linesize[p] / div; \
577 #define RECTCROP_TRANSITION(name, type, div) \
578 static void rectcrop##name##_transition(AVFilterContext *ctx, \
579 const AVFrame *a, const AVFrame *b, AVFrame *out, \
581 int slice_start, int slice_end, int jobnr) \
583 XFadeContext *s = ctx->priv; \
584 const int width = out->width; \
585 const int height = out->height; \
586 int zh = fabsf(progress - 0.5f) * height; \
587 int zw = fabsf(progress - 0.5f) * width; \
589 for (int p = 0; p < s->nb_planes; p++) { \
590 const int bg = s->black[p]; \
591 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
593 for (int y = slice_start; y < slice_end; y++) { \
594 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
595 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
597 for (int x = 0; x < width; x++) { \
598 int dist = FFABS(x - width / 2) < zw && \
599 FFABS(y - height / 2) < zh; \
600 int val = progress < 0.5f ? xf1[x] : xf0[x]; \
601 dst[x] = !dist ? bg : val; \
604 dst += out->linesize[p] / div; \
612 #define DISTANCE_TRANSITION(name, type, div) \
613 static void distance##name##_transition(AVFilterContext *ctx, \
614 const AVFrame *a, const AVFrame *b, AVFrame *out, \
616 int slice_start, int slice_end, int jobnr) \
618 XFadeContext *s = ctx->priv; \
619 const int width = out->width; \
620 const float max = s->max_value; \
622 for (int y = slice_start; y < slice_end; y++) { \
623 for (int x = 0; x < width; x++) { \
625 for (int p = 0; p < s->nb_planes; p++) { \
626 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
627 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
629 dist += (xf0[x] / max - xf1[x] / max) * \
630 (xf0[x] / max - xf1[x] / max); \
633 dist = sqrtf(dist) <= progress; \
634 for (int p = 0; p < s->nb_planes; p++) { \
635 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
636 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
637 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
638 dst[x] = mix(mix(xf0[x], xf1[x], dist), xf1[x], progress); \
647 #define FADEBLACK_TRANSITION(name, type, div) \
648 static void fadeblack##name##_transition(AVFilterContext *ctx, \
649 const AVFrame *a, const AVFrame *b, AVFrame *out, \
651 int slice_start, int slice_end, int jobnr) \
653 XFadeContext *s = ctx->priv; \
654 const int height = slice_end - slice_start; \
655 const float phase = 0.2f; \
657 for (int p = 0; p < s->nb_planes; p++) { \
658 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
659 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
660 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
661 const int bg = s->black[p]; \
663 for (int y = 0; y < height; y++) { \
664 for (int x = 0; x < out->width; x++) { \
665 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)), \
666 mix(bg, xf1[x], smoothstep(phase, 1.f, progress)), \
670 dst += out->linesize[p] / div; \
671 xf0 += a->linesize[p] / div; \
672 xf1 += b->linesize[p] / div; \
680 #define FADEWHITE_TRANSITION(name, type, div) \
681 static void fadewhite##name##_transition(AVFilterContext *ctx, \
682 const AVFrame *a, const AVFrame *b, AVFrame *out, \
684 int slice_start, int slice_end, int jobnr) \
686 XFadeContext *s = ctx->priv; \
687 const int height = slice_end - slice_start; \
688 const float phase = 0.2f; \
690 for (int p = 0; p < s->nb_planes; p++) { \
691 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
692 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
693 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
694 const int bg = s->white[p]; \
696 for (int y = 0; y < height; y++) { \
697 for (int x = 0; x < out->width; x++) { \
698 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)), \
699 mix(bg, xf1[x], smoothstep(phase, 1.f, progress)), \
703 dst += out->linesize[p] / div; \
704 xf0 += a->linesize[p] / div; \
705 xf1 += b->linesize[p] / div; \
713 #define RADIAL_TRANSITION(name, type, div) \
714 static void radial##name##_transition(AVFilterContext *ctx, \
715 const AVFrame *a, const AVFrame *b, AVFrame *out, \
717 int slice_start, int slice_end, int jobnr) \
719 XFadeContext *s = ctx->priv; \
720 const int width = out->width; \
721 const int height = out->height; \
723 for (int y = slice_start; y < slice_end; y++) { \
724 for (int x = 0; x < width; x++) { \
725 const float smooth = atan2f(x - width / 2, y - height / 2) - \
726 (progress - 0.5f) * (M_PI * 2.5f); \
727 for (int p = 0; p < s->nb_planes; p++) { \
728 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
729 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
730 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
732 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
741 #define SMOOTHLEFT_TRANSITION(name, type, div) \
742 static void smoothleft##name##_transition(AVFilterContext *ctx, \
743 const AVFrame *a, const AVFrame *b, AVFrame *out, \
745 int slice_start, int slice_end, int jobnr) \
747 XFadeContext *s = ctx->priv; \
748 const int width = out->width; \
749 const float w = width; \
751 for (int y = slice_start; y < slice_end; y++) { \
752 for (int x = 0; x < width; x++) { \
753 const float smooth = 1.f + x / w - progress * 2.f; \
755 for (int p = 0; p < s->nb_planes; p++) { \
756 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
757 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
758 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
760 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
769 #define SMOOTHRIGHT_TRANSITION(name, type, div) \
770 static void smoothright##name##_transition(AVFilterContext *ctx, \
771 const AVFrame *a, const AVFrame *b, AVFrame *out, \
773 int slice_start, int slice_end, int jobnr) \
775 XFadeContext *s = ctx->priv; \
776 const int width = out->width; \
777 const float w = width; \
779 for (int y = slice_start; y < slice_end; y++) { \
780 for (int x = 0; x < width; x++) { \
781 const float smooth = 1.f + (w - 1 - x) / w - progress * 2.f; \
783 for (int p = 0; p < s->nb_planes; p++) { \
784 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
785 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
786 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
788 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
797 #define SMOOTHUP_TRANSITION(name, type, div) \
798 static void smoothup##name##_transition(AVFilterContext *ctx, \
799 const AVFrame *a, const AVFrame *b, AVFrame *out, \
801 int slice_start, int slice_end, int jobnr) \
803 XFadeContext *s = ctx->priv; \
804 const int width = out->width; \
805 const float h = out->height; \
807 for (int y = slice_start; y < slice_end; y++) { \
808 const float smooth = 1.f + y / h - progress * 2.f; \
809 for (int x = 0; x < width; x++) { \
810 for (int p = 0; p < s->nb_planes; p++) { \
811 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
812 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
813 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
815 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
824 #define SMOOTHDOWN_TRANSITION(name, type, div) \
825 static void smoothdown##name##_transition(AVFilterContext *ctx, \
826 const AVFrame *a, const AVFrame *b, AVFrame *out, \
828 int slice_start, int slice_end, int jobnr) \
830 XFadeContext *s = ctx->priv; \
831 const int width = out->width; \
832 const float h = out->height; \
834 for (int y = slice_start; y < slice_end; y++) { \
835 const float smooth = 1.f + (h - 1 - y) / h - progress * 2.f; \
836 for (int x = 0; x < width; x++) { \
837 for (int p = 0; p < s->nb_planes; p++) { \
838 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
839 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
840 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
842 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
851 #define CIRCLEOPEN_TRANSITION(name, type, div) \
852 static void circleopen##name##_transition(AVFilterContext *ctx, \
853 const AVFrame *a, const AVFrame *b, AVFrame *out, \
855 int slice_start, int slice_end, int jobnr) \
857 XFadeContext *s = ctx->priv; \
858 const int width = out->width; \
859 const int height = out->height; \
860 const float z = hypotf(width / 2, height / 2); \
861 const float p = (progress - 0.5f) * 3.f; \
863 for (int y = slice_start; y < slice_end; y++) { \
864 for (int x = 0; x < width; x++) { \
865 const float smooth = hypotf(x - width / 2, y - height / 2) / z + p; \
866 for (int p = 0; p < s->nb_planes; p++) { \
867 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
868 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
869 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
871 dst[x] = mix(xf0[x], xf1[x], smoothstep(0.f, 1.f, smooth)); \
880 #define CIRCLECLOSE_TRANSITION(name, type, div) \
881 static void circleclose##name##_transition(AVFilterContext *ctx, \
882 const AVFrame *a, const AVFrame *b, AVFrame *out, \
884 int slice_start, int slice_end, int jobnr) \
886 XFadeContext *s = ctx->priv; \
887 const int width = out->width; \
888 const int height = out->height; \
889 const float z = hypotf(width / 2, height / 2); \
890 const float p = (1.f - progress - 0.5f) * 3.f; \
892 for (int y = slice_start; y < slice_end; y++) { \
893 for (int x = 0; x < width; x++) { \
894 const float smooth = hypotf(x - width / 2, y - height / 2) / z + p; \
895 for (int p = 0; p < s->nb_planes; p++) { \
896 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
897 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
898 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
900 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
909 #define VERTOPEN_TRANSITION(name, type, div) \
910 static void vertopen##name##_transition(AVFilterContext *ctx, \
911 const AVFrame *a, const AVFrame *b, AVFrame *out, \
913 int slice_start, int slice_end, int jobnr) \
915 XFadeContext *s = ctx->priv; \
916 const int width = out->width; \
917 const float w2 = out->width / 2; \
919 for (int y = slice_start; y < slice_end; y++) { \
920 for (int x = 0; x < width; x++) { \
921 const float smooth = 2.f - fabsf((x - w2) / w2) - progress * 2.f; \
922 for (int p = 0; p < s->nb_planes; p++) { \
923 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
924 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
925 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
927 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
936 #define VERTCLOSE_TRANSITION(name, type, div) \
937 static void vertclose##name##_transition(AVFilterContext *ctx, \
938 const AVFrame *a, const AVFrame *b, AVFrame *out, \
940 int slice_start, int slice_end, int jobnr) \
942 XFadeContext *s = ctx->priv; \
943 const int width = out->width; \
944 const float w2 = out->width / 2; \
946 for (int y = slice_start; y < slice_end; y++) { \
947 for (int x = 0; x < width; x++) { \
948 const float smooth = 1.f + fabsf((x - w2) / w2) - progress * 2.f; \
949 for (int p = 0; p < s->nb_planes; p++) { \
950 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
951 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
952 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
954 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
963 #define HORZOPEN_TRANSITION(name, type, div) \
964 static void horzopen##name##_transition(AVFilterContext *ctx, \
965 const AVFrame *a, const AVFrame *b, AVFrame *out, \
967 int slice_start, int slice_end, int jobnr) \
969 XFadeContext *s = ctx->priv; \
970 const int width = out->width; \
971 const float h2 = out->height / 2; \
973 for (int y = slice_start; y < slice_end; y++) { \
974 const float smooth = 2.f - fabsf((y - h2) / h2) - progress * 2.f; \
975 for (int x = 0; x < width; x++) { \
976 for (int p = 0; p < s->nb_planes; p++) { \
977 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
978 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
979 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
981 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
990 #define HORZCLOSE_TRANSITION(name, type, div) \
991 static void horzclose##name##_transition(AVFilterContext *ctx, \
992 const AVFrame *a, const AVFrame *b, AVFrame *out, \
994 int slice_start, int slice_end, int jobnr) \
996 XFadeContext *s = ctx->priv; \
997 const int width = out->width; \
998 const float h2 = out->height / 2; \
1000 for (int y = slice_start; y < slice_end; y++) { \
1001 const float smooth = 1.f + fabsf((y - h2) / h2) - progress * 2.f; \
1002 for (int x = 0; x < width; x++) { \
1003 for (int p = 0; p < s->nb_planes; p++) { \
1004 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1005 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1006 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1008 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1019 const float r =
sinf(x * 12.9898
f + y * 78.233
f) * 43758.545f;
1024 #define DISSOLVE_TRANSITION(name, type, div) \
1025 static void dissolve##name##_transition(AVFilterContext *ctx, \
1026 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1028 int slice_start, int slice_end, int jobnr) \
1030 XFadeContext *s = ctx->priv; \
1031 const int width = out->width; \
1033 for (int y = slice_start; y < slice_end; y++) { \
1034 for (int x = 0; x < width; x++) { \
1035 const float smooth = frand(x, y) * 2.f + progress * 2.f - 1.5f; \
1036 for (int p = 0; p < s->nb_planes; p++) { \
1037 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1038 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1039 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1041 dst[x] = smooth >= 0.5f ? xf0[x] : xf1[x]; \
1050 #define PIXELIZE_TRANSITION(name, type, div) \
1051 static void pixelize##name##_transition(AVFilterContext *ctx, \
1052 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1054 int slice_start, int slice_end, int jobnr) \
1056 XFadeContext *s = ctx->priv; \
1057 const int w = out->width; \
1058 const int h = out->height; \
1059 const float d = fminf(progress, 1.f - progress); \
1060 const float dist = ceilf(d * 50.f) / 50.f; \
1061 const float sqx = 2.f * dist * FFMIN(w, h) / 20.f; \
1062 const float sqy = 2.f * dist * FFMIN(w, h) / 20.f; \
1064 for (int y = slice_start; y < slice_end; y++) { \
1065 for (int x = 0; x < w; x++) { \
1066 int sx = dist > 0.f ? FFMIN((floorf(x / sqx) + .5f) * sqx, w - 1) : x; \
1067 int sy = dist > 0.f ? FFMIN((floorf(y / sqy) + .5f) * sqy, h - 1) : y; \
1068 for (int p = 0; p < s->nb_planes; p++) { \
1069 const type *xf0 = (const type *)(a->data[p] + sy * a->linesize[p]); \
1070 const type *xf1 = (const type *)(b->data[p] + sy * b->linesize[p]); \
1071 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1073 dst[x] = mix(xf0[sx], xf1[sx], progress); \
1082 #define DIAGTL_TRANSITION(name, type, div) \
1083 static void diagtl##name##_transition(AVFilterContext *ctx, \
1084 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1086 int slice_start, int slice_end, int jobnr) \
1088 XFadeContext *s = ctx->priv; \
1089 const int width = out->width; \
1090 const float w = width; \
1091 const float h = out->height; \
1093 for (int y = slice_start; y < slice_end; y++) { \
1094 for (int x = 0; x < width; x++) { \
1095 const float smooth = 1.f + x / w * y / h - progress * 2.f; \
1097 for (int p = 0; p < s->nb_planes; p++) { \
1098 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1099 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1100 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1102 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1111 #define DIAGTR_TRANSITION(name, type, div) \
1112 static void diagtr##name##_transition(AVFilterContext *ctx, \
1113 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1115 int slice_start, int slice_end, int jobnr) \
1117 XFadeContext *s = ctx->priv; \
1118 const int width = out->width; \
1119 const float w = width; \
1120 const float h = out->height; \
1122 for (int y = slice_start; y < slice_end; y++) { \
1123 for (int x = 0; x < width; x++) { \
1124 const float smooth = 1.f + (w - 1 - x) / w * y / h - progress * 2.f; \
1126 for (int p = 0; p < s->nb_planes; p++) { \
1127 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1128 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1129 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1131 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1140 #define DIAGBL_TRANSITION(name, type, div) \
1141 static void diagbl##name##_transition(AVFilterContext *ctx, \
1142 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1144 int slice_start, int slice_end, int jobnr) \
1146 XFadeContext *s = ctx->priv; \
1147 const int width = out->width; \
1148 const float w = width; \
1149 const float h = out->height; \
1151 for (int y = slice_start; y < slice_end; y++) { \
1152 for (int x = 0; x < width; x++) { \
1153 const float smooth = 1.f + x / w * (h - 1 - y) / h - progress * 2.f; \
1155 for (int p = 0; p < s->nb_planes; p++) { \
1156 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1157 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1158 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1160 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1169 #define DIAGBR_TRANSITION(name, type, div) \
1170 static void diagbr##name##_transition(AVFilterContext *ctx, \
1171 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1173 int slice_start, int slice_end, int jobnr) \
1175 XFadeContext *s = ctx->priv; \
1176 const int width = out->width; \
1177 const float w = width; \
1178 const float h = out->height; \
1180 for (int y = slice_start; y < slice_end; y++) { \
1181 for (int x = 0; x < width; x++) { \
1182 const float smooth = 1.f + (w - 1 - x) / w * (h - 1 - y) / h - \
1185 for (int p = 0; p < s->nb_planes; p++) { \
1186 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1187 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1188 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1190 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1199 #define HLSLICE_TRANSITION(name, type, div) \
1200 static void hlslice##name##_transition(AVFilterContext *ctx, \
1201 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1203 int slice_start, int slice_end, int jobnr) \
1205 XFadeContext *s = ctx->priv; \
1206 const int width = out->width; \
1207 const float w = width; \
1209 for (int y = slice_start; y < slice_end; y++) { \
1210 for (int x = 0; x < width; x++) { \
1211 const float smooth = smoothstep(-0.5f, 0.f, x / w - progress * 1.5f); \
1212 const float ss = smooth <= fract(10.f * x / w) ? 0.f : 1.f; \
1214 for (int p = 0; p < s->nb_planes; p++) { \
1215 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1216 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1217 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1219 dst[x] = mix(xf1[x], xf0[x], ss); \
1228 #define HRSLICE_TRANSITION(name, type, div) \
1229 static void hrslice##name##_transition(AVFilterContext *ctx, \
1230 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1232 int slice_start, int slice_end, int jobnr) \
1234 XFadeContext *s = ctx->priv; \
1235 const int width = out->width; \
1236 const float w = width; \
1238 for (int y = slice_start; y < slice_end; y++) { \
1239 for (int x = 0; x < width; x++) { \
1240 const float xx = (w - 1 - x) / w; \
1241 const float smooth = smoothstep(-0.5f, 0.f, xx - progress * 1.5f); \
1242 const float ss = smooth <= fract(10.f * xx) ? 0.f : 1.f; \
1244 for (int p = 0; p < s->nb_planes; p++) { \
1245 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1246 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1247 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1249 dst[x] = mix(xf1[x], xf0[x], ss); \
1258 #define VUSLICE_TRANSITION(name, type, div) \
1259 static void vuslice##name##_transition(AVFilterContext *ctx, \
1260 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1262 int slice_start, int slice_end, int jobnr) \
1264 XFadeContext *s = ctx->priv; \
1265 const int width = out->width; \
1266 const float h = out->height; \
1268 for (int y = slice_start; y < slice_end; y++) { \
1269 const float smooth = smoothstep(-0.5f, 0.f, y / h - progress * 1.5f); \
1270 const float ss = smooth <= fract(10.f * y / h) ? 0.f : 1.f; \
1272 for (int x = 0; x < width; x++) { \
1273 for (int p = 0; p < s->nb_planes; p++) { \
1274 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1275 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1276 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1278 dst[x] = mix(xf1[x], xf0[x], ss); \
1287 #define VDSLICE_TRANSITION(name, type, div) \
1288 static void vdslice##name##_transition(AVFilterContext *ctx, \
1289 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1291 int slice_start, int slice_end, int jobnr) \
1293 XFadeContext *s = ctx->priv; \
1294 const int width = out->width; \
1295 const float h = out->height; \
1297 for (int y = slice_start; y < slice_end; y++) { \
1298 const float yy = (h - 1 - y) / h; \
1299 const float smooth = smoothstep(-0.5f, 0.f, yy - progress * 1.5f); \
1300 const float ss = smooth <= fract(10.f * yy) ? 0.f : 1.f; \
1302 for (int x = 0; x < width; x++) { \
1303 for (int p = 0; p < s->nb_planes; p++) { \
1304 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1305 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1306 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1308 dst[x] = mix(xf1[x], xf0[x], ss); \
1317 #define HBLUR_TRANSITION(name, type, div) \
1318 static void hblur##name##_transition(AVFilterContext *ctx, \
1319 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1321 int slice_start, int slice_end, int jobnr) \
1323 XFadeContext *s = ctx->priv; \
1324 const int width = out->width; \
1325 const float prog = progress <= 0.5f ? progress * 2.f : (1.f - progress) * 2.f; \
1326 const int size = 1 + (width / 2) * prog; \
1328 for (int y = slice_start; y < slice_end; y++) { \
1329 for (int p = 0; p < s->nb_planes; p++) { \
1330 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1331 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1332 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1337 for (int x = 0; x < size; x++) { \
1342 for (int x = 0; x < width; x++) { \
1343 dst[x] = mix(sum0 / cnt, sum1 / cnt, progress); \
1345 if (x + size < width) { \
1346 sum0 += xf0[x + size] - xf0[x]; \
1347 sum1 += xf1[x + size] - xf1[x]; \
1361 #define FADEGRAYS_TRANSITION(name, type, div) \
1362 static void fadegrays##name##_transition(AVFilterContext *ctx, \
1363 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1365 int slice_start, int slice_end, int jobnr) \
1367 XFadeContext *s = ctx->priv; \
1368 const int width = out->width; \
1369 const int is_rgb = s->is_rgb; \
1370 const int mid = (s->max_value + 1) / 2; \
1371 const float phase = 0.2f; \
1373 for (int y = slice_start; y < slice_end; y++) { \
1374 for (int x = 0; x < width; x++) { \
1377 for (int p = 0; p < s->nb_planes; p++) { \
1378 const type *xf0 = (const type *)(a->data[p] + \
1379 y * a->linesize[p]); \
1380 const type *xf1 = (const type *)(b->data[p] + \
1381 y * b->linesize[p]); \
1383 bg[0][3] = xf0[x]; \
1384 bg[1][3] = xf1[x]; \
1386 bg[0][0] += xf0[x]; \
1387 bg[1][0] += xf1[x]; \
1390 bg[0][0] = bg[0][0] / 3; \
1391 bg[1][0] = bg[1][0] / 3; \
1392 bg[0][1] = bg[0][2] = bg[0][0]; \
1393 bg[1][1] = bg[1][2] = bg[1][0]; \
1395 const type *yf0 = (const type *)(a->data[0] + \
1396 y * a->linesize[0]); \
1397 const type *yf1 = (const type *)(b->data[0] + \
1398 y * a->linesize[0]); \
1399 bg[0][0] = yf0[x]; \
1400 bg[1][0] = yf1[x]; \
1401 if (s->nb_planes == 4) { \
1402 const type *af0 = (const type *)(a->data[3] + \
1403 y * a->linesize[3]); \
1404 const type *af1 = (const type *)(b->data[3] + \
1405 y * a->linesize[3]); \
1406 bg[0][3] = af0[x]; \
1407 bg[1][3] = af1[x]; \
1409 bg[0][1] = bg[1][1] = mid; \
1410 bg[0][2] = bg[1][2] = mid; \
1413 for (int p = 0; p < s->nb_planes; p++) { \
1414 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1415 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1416 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1418 dst[x] = mix(mix(xf0[x], bg[0][p], \
1419 smoothstep(1.f-phase, 1.f, progress)), \
1420 mix(bg[1][p], xf1[x], smoothstep(phase, 1.f, progress)), \
1430 #define WIPETL_TRANSITION(name, type, div) \
1431 static void wipetl##name##_transition(AVFilterContext *ctx, \
1432 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1434 int slice_start, int slice_end, int jobnr) \
1436 XFadeContext *s = ctx->priv; \
1437 const int height = slice_end - slice_start; \
1438 const int zw = out->width * progress; \
1439 const int zh = out->height * progress; \
1441 for (int p = 0; p < s->nb_planes; p++) { \
1442 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1443 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1444 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1446 for (int y = 0; y < height; y++) { \
1447 for (int x = 0; x < out->width; x++) { \
1448 dst[x] = slice_start + y <= zh && \
1449 x <= zw ? xf0[x] : xf1[x]; \
1452 dst += out->linesize[p] / div; \
1453 xf0 += a->linesize[p] / div; \
1454 xf1 += b->linesize[p] / div; \
1462 #define WIPETR_TRANSITION(name, type, div) \
1463 static void wipetr##name##_transition(AVFilterContext *ctx, \
1464 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1466 int slice_start, int slice_end, int jobnr) \
1468 XFadeContext *s = ctx->priv; \
1469 const int height = slice_end - slice_start; \
1470 const int zw = out->width * (1.f - progress); \
1471 const int zh = out->height * progress; \
1473 for (int p = 0; p < s->nb_planes; p++) { \
1474 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1475 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1476 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1478 for (int y = 0; y < height; y++) { \
1479 for (int x = 0; x < out->width; x++) { \
1480 dst[x] = slice_start + y <= zh && \
1481 x > zw ? xf0[x] : xf1[x]; \
1484 dst += out->linesize[p] / div; \
1485 xf0 += a->linesize[p] / div; \
1486 xf1 += b->linesize[p] / div; \
1494 #define WIPEBL_TRANSITION(name, type, div) \
1495 static void wipebl##name##_transition(AVFilterContext *ctx, \
1496 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1498 int slice_start, int slice_end, int jobnr) \
1500 XFadeContext *s = ctx->priv; \
1501 const int height = slice_end - slice_start; \
1502 const int zw = out->width * progress; \
1503 const int zh = out->height * (1.f - progress); \
1505 for (int p = 0; p < s->nb_planes; p++) { \
1506 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1507 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1508 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1510 for (int y = 0; y < height; y++) { \
1511 for (int x = 0; x < out->width; x++) { \
1512 dst[x] = slice_start + y > zh && \
1513 x <= zw ? xf0[x] : xf1[x]; \
1516 dst += out->linesize[p] / div; \
1517 xf0 += a->linesize[p] / div; \
1518 xf1 += b->linesize[p] / div; \
1526 #define WIPEBR_TRANSITION(name, type, div) \
1527 static void wipebr##name##_transition(AVFilterContext *ctx, \
1528 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1530 int slice_start, int slice_end, int jobnr) \
1532 XFadeContext *s = ctx->priv; \
1533 const int height = slice_end - slice_start; \
1534 const int zh = out->height * (1.f - progress); \
1535 const int zw = out->width * (1.f - progress); \
1537 for (int p = 0; p < s->nb_planes; p++) { \
1538 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1539 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1540 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1542 for (int y = 0; y < height; y++) { \
1543 for (int x = 0; x < out->width; x++) { \
1544 dst[x] = slice_start + y > zh && \
1545 x > zw ? xf0[x] : xf1[x]; \
1548 dst += out->linesize[p] / div; \
1549 xf0 += a->linesize[p] / div; \
1550 xf1 += b->linesize[p] / div; \
1558 #define SQUEEZEH_TRANSITION(name, type, div) \
1559 static void squeezeh##name##_transition(AVFilterContext *ctx, \
1560 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1562 int slice_start, int slice_end, int jobnr) \
1564 XFadeContext *s = ctx->priv; \
1565 const float h = out->height; \
1566 const int height = slice_end - slice_start; \
1568 for (int p = 0; p < s->nb_planes; p++) { \
1569 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1570 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1572 for (int y = 0; y < height; y++) { \
1573 const float z = .5f + ((slice_start + y) / h - .5f) / progress; \
1575 if (z < 0.f || z > 1.f) { \
1576 for (int x = 0; x < out->width; x++) \
1579 const int yy = lrintf(z * (h - 1.f)); \
1580 const type *xf0 = (const type *)(a->data[p] + yy * a->linesize[p]); \
1582 for (int x = 0; x < out->width; x++) \
1586 dst += out->linesize[p] / div; \
1587 xf1 += b->linesize[p] / div; \
1595 #define SQUEEZEV_TRANSITION(name, type, div) \
1596 static void squeezev##name##_transition(AVFilterContext *ctx, \
1597 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1599 int slice_start, int slice_end, int jobnr) \
1601 XFadeContext *s = ctx->priv; \
1602 const float w = out->width; \
1603 const int height = slice_end - slice_start; \
1605 for (int p = 0; p < s->nb_planes; p++) { \
1606 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1607 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1608 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1610 for (int y = 0; y < height; y++) { \
1611 for (int x = 0; x < out->width; x++) { \
1612 const float z = .5f + (x / w - .5f) / progress; \
1614 if (z < 0.f || z > 1.f) { \
1617 const int xx = lrintf(z * (w - 1.f)); \
1623 dst += out->linesize[p] / div; \
1624 xf0 += a->linesize[p] / div; \
1625 xf1 += b->linesize[p] / div; \
1633 static
void zoom(
float *
u,
float *v,
float amount)
1635 *
u = 0.5f + ((*
u - 0.5f) * amount);
1636 *v = 0.5f + ((*v - 0.5f) * amount);
1639 #define ZOOMIN_TRANSITION(name, type, div) \
1640 static void zoomin##name##_transition(AVFilterContext *ctx, \
1641 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1643 int slice_start, int slice_end, int jobnr) \
1645 XFadeContext *s = ctx->priv; \
1646 const float w = out->width; \
1647 const float h = out->height; \
1648 const float zf = smoothstep(0.5f, 1.f, progress); \
1650 for (int p = 0; p < s->nb_planes; p++) { \
1651 const type *xf0 = (const type *)(a->data[p]); \
1652 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1653 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1655 for (int y = slice_start; y < slice_end; y++) { \
1656 for (int x = 0; x < w; x++) { \
1663 iu = ceilf(u * (w - 1)); \
1664 iv = ceilf(v * (h - 1)); \
1665 zv = xf0[iu + iv * a->linesize[p] / div]; \
1666 dst[x] = mix(zv, xf1[x], smoothstep(0.f, 0.5f, progress)); \
1668 dst += out->linesize[p] / div; \
1669 xf1 += b->linesize[p] / div; \
1677 #define FADEFAST_TRANSITION(name, type, div) \
1678 static void fadefast##name##_transition(AVFilterContext *ctx, \
1679 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1681 int slice_start, int slice_end, int jobnr) \
1683 XFadeContext *s = ctx->priv; \
1684 const int height = slice_end - slice_start; \
1685 const float imax = 1.f / s->max_value; \
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]); \
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)\
1699 dst += out->linesize[p] / div; \
1700 xf0 += a->linesize[p] / div; \
1701 xf1 += b->linesize[p] / div; \
1709 #define FADESLOW_TRANSITION(name, type, div) \
1710 static void fadeslow##name##_transition(AVFilterContext *ctx, \
1711 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1713 int slice_start, int slice_end, int jobnr) \
1715 XFadeContext *s = ctx->priv; \
1716 const int height = slice_end - slice_start; \
1717 const float imax = 1.f / s->max_value; \
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]); \
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)\
1731 dst += out->linesize[p] / div; \
1732 xf0 += a->linesize[p] / div; \
1733 xf1 += b->linesize[p] / div; \
1741 static inline
double getpix(
void *priv,
double x,
double y,
int plane,
int nb)
1745 const uint8_t *
src = in->
data[
FFMIN(plane,
s->nb_planes - 1)];
1756 const uint16_t *src16 = (
const uint16_t*)
src;
1759 return src16[
xi + yi * linesize];
1761 return src[
xi + yi * linesize];
1765 static double a0(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 0, 0); }
1766 static double a1(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 1, 0); }
1767 static double a2(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 2, 0); }
1768 static double a3(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 3, 0); }
1770 static double b0(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 0, 1); }
1771 static double b1(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 1, 1); }
1772 static double b2(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 2, 1); }
1773 static double b3(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 3, 1); }
1783 if (inlink0->
w != inlink1->
w || inlink0->
h != inlink1->
h) {
1785 "(size %dx%d) do not match the corresponding "
1786 "second input link %s parameters (size %dx%d)\n",
1787 ctx->input_pads[0].name, inlink0->
w, inlink0->
h,
1788 ctx->input_pads[1].name, inlink1->
w, inlink1->
h);
1795 "(%d/%d) do not match the corresponding "
1796 "second input link %s timebase (%d/%d)\n",
1811 "(%d/%d) do not match the corresponding "
1812 "second input link %s frame rate (%d/%d)\n",
1818 outlink->
w = inlink0->
w;
1819 outlink->
h = inlink0->
h;
1827 s->max_value = (1 <<
s->depth) - 1;
1829 s->black[1] =
s->black[2] =
s->is_rgb ? 0 :
s->max_value / 2;
1830 s->black[3] =
s->max_value;
1831 s->white[0] =
s->white[3] =
s->max_value;
1832 s->white[1] =
s->white[2] =
s->is_rgb ?
s->max_value :
s->max_value / 2;
1841 switch (
s->transition) {
1842 case CUSTOM:
s->transitionf =
s->depth <= 8 ? custom8_transition : custom16_transition;
break;
1843 case FADE:
s->transitionf =
s->depth <= 8 ? fade8_transition : fade16_transition;
break;
1844 case WIPELEFT:
s->transitionf =
s->depth <= 8 ? wipeleft8_transition : wipeleft16_transition;
break;
1845 case WIPERIGHT:
s->transitionf =
s->depth <= 8 ? wiperight8_transition : wiperight16_transition;
break;
1846 case WIPEUP:
s->transitionf =
s->depth <= 8 ? wipeup8_transition : wipeup16_transition;
break;
1847 case WIPEDOWN:
s->transitionf =
s->depth <= 8 ? wipedown8_transition : wipedown16_transition;
break;
1848 case SLIDELEFT:
s->transitionf =
s->depth <= 8 ? slideleft8_transition : slideleft16_transition;
break;
1849 case SLIDERIGHT:
s->transitionf =
s->depth <= 8 ? slideright8_transition : slideright16_transition;
break;
1850 case SLIDEUP:
s->transitionf =
s->depth <= 8 ? slideup8_transition : slideup16_transition;
break;
1851 case SLIDEDOWN:
s->transitionf =
s->depth <= 8 ? slidedown8_transition : slidedown16_transition;
break;
1852 case CIRCLECROP:
s->transitionf =
s->depth <= 8 ? circlecrop8_transition : circlecrop16_transition;
break;
1853 case RECTCROP:
s->transitionf =
s->depth <= 8 ? rectcrop8_transition : rectcrop16_transition;
break;
1854 case DISTANCE:
s->transitionf =
s->depth <= 8 ? distance8_transition : distance16_transition;
break;
1855 case FADEBLACK:
s->transitionf =
s->depth <= 8 ? fadeblack8_transition : fadeblack16_transition;
break;
1856 case FADEWHITE:
s->transitionf =
s->depth <= 8 ? fadewhite8_transition : fadewhite16_transition;
break;
1857 case RADIAL:
s->transitionf =
s->depth <= 8 ? radial8_transition : radial16_transition;
break;
1858 case SMOOTHLEFT:
s->transitionf =
s->depth <= 8 ? smoothleft8_transition : smoothleft16_transition;
break;
1859 case SMOOTHRIGHT:
s->transitionf =
s->depth <= 8 ? smoothright8_transition: smoothright16_transition;
break;
1860 case SMOOTHUP:
s->transitionf =
s->depth <= 8 ? smoothup8_transition : smoothup16_transition;
break;
1861 case SMOOTHDOWN:
s->transitionf =
s->depth <= 8 ? smoothdown8_transition : smoothdown16_transition;
break;
1862 case CIRCLEOPEN:
s->transitionf =
s->depth <= 8 ? circleopen8_transition : circleopen16_transition;
break;
1863 case CIRCLECLOSE:
s->transitionf =
s->depth <= 8 ? circleclose8_transition: circleclose16_transition;
break;
1864 case VERTOPEN:
s->transitionf =
s->depth <= 8 ? vertopen8_transition : vertopen16_transition;
break;
1865 case VERTCLOSE:
s->transitionf =
s->depth <= 8 ? vertclose8_transition : vertclose16_transition;
break;
1866 case HORZOPEN:
s->transitionf =
s->depth <= 8 ? horzopen8_transition : horzopen16_transition;
break;
1867 case HORZCLOSE:
s->transitionf =
s->depth <= 8 ? horzclose8_transition : horzclose16_transition;
break;
1868 case DISSOLVE:
s->transitionf =
s->depth <= 8 ? dissolve8_transition : dissolve16_transition;
break;
1869 case PIXELIZE:
s->transitionf =
s->depth <= 8 ? pixelize8_transition : pixelize16_transition;
break;
1870 case DIAGTL:
s->transitionf =
s->depth <= 8 ? diagtl8_transition : diagtl16_transition;
break;
1871 case DIAGTR:
s->transitionf =
s->depth <= 8 ? diagtr8_transition : diagtr16_transition;
break;
1872 case DIAGBL:
s->transitionf =
s->depth <= 8 ? diagbl8_transition : diagbl16_transition;
break;
1873 case DIAGBR:
s->transitionf =
s->depth <= 8 ? diagbr8_transition : diagbr16_transition;
break;
1874 case HLSLICE:
s->transitionf =
s->depth <= 8 ? hlslice8_transition : hlslice16_transition;
break;
1875 case HRSLICE:
s->transitionf =
s->depth <= 8 ? hrslice8_transition : hrslice16_transition;
break;
1876 case VUSLICE:
s->transitionf =
s->depth <= 8 ? vuslice8_transition : vuslice16_transition;
break;
1877 case VDSLICE:
s->transitionf =
s->depth <= 8 ? vdslice8_transition : vdslice16_transition;
break;
1878 case HBLUR:
s->transitionf =
s->depth <= 8 ? hblur8_transition : hblur16_transition;
break;
1879 case FADEGRAYS:
s->transitionf =
s->depth <= 8 ? fadegrays8_transition : fadegrays16_transition;
break;
1880 case WIPETL:
s->transitionf =
s->depth <= 8 ? wipetl8_transition : wipetl16_transition;
break;
1881 case WIPETR:
s->transitionf =
s->depth <= 8 ? wipetr8_transition : wipetr16_transition;
break;
1882 case WIPEBL:
s->transitionf =
s->depth <= 8 ? wipebl8_transition : wipebl16_transition;
break;
1883 case WIPEBR:
s->transitionf =
s->depth <= 8 ? wipebr8_transition : wipebr16_transition;
break;
1884 case SQUEEZEH:
s->transitionf =
s->depth <= 8 ? squeezeh8_transition : squeezeh16_transition;
break;
1885 case SQUEEZEV:
s->transitionf =
s->depth <= 8 ? squeezev8_transition : squeezev16_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;
1892 if (
s->transition ==
CUSTOM) {
1894 "a0",
"a1",
"a2",
"a3",
1895 "b0",
"b1",
"b2",
"b3",
1920 int slice_start = (outlink->
h * jobnr ) / nb_jobs;
1921 int slice_end = (outlink->
h * (jobnr+1)) / nb_jobs;
1932 float progress =
av_clipf(1.
f - ((
float)(
s->pts -
s->first_pts -
s->offset_pts) /
s->duration_pts), 0.f, 1.f);
1941 td.xf[0] =
a,
td.xf[1] =
b,
td.out =
out,
td.progress = progress;
1960 if (
s->xfade_is_over) {
1969 }
else if (
ret > 0) {
1970 in->
pts = (in->
pts -
s->last_pts) +
s->pts;
1986 s->first_pts =
s->xf[0]->pts;
1988 s->pts =
s->xf[0]->pts;
1989 if (
s->first_pts +
s->offset_pts >
s->xf[0]->pts) {
2004 s->last_pts =
s->xf[1]->pts;
2005 s->pts =
s->xf[0]->pts;
2006 if (
s->xf[0]->pts - (
s->first_pts +
s->offset_pts) >
s->duration_pts)
2007 s->xfade_is_over = 1;
2023 s->xfade_is_over = 1;
2032 if (
s->eof[0] &&
s->eof[1] && (
2036 }
else if (
s->xfade_is_over) {
2068 .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.
static enum AVPixelFormat pix_fmts[]
#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)
#define u(width, name, range_min, range_max)
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 FILTER_PIXFMTS_ARRAY(array)
static __device__ float floorf(float a)
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
#define WIPEDOWN_TRANSITION(name, type, div)
static void zoom(float *u, float *v, float amount)
#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)
#define WIPEBL_TRANSITION(name, type, div)
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
#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)
A link between two filters.
static float mix(float a, float b, float mix)
static const char *const func2_names[]
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
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 FADEGRAYS_TRANSITION(name, type, div)
#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
static double(*const func2[])(void *, double, double)
#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 ZOOMIN_TRANSITION(name, type, div)
#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[]
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
#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)
#define FILTER_INPUTS(array)
#define WIPETR_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.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
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[]
const AVFilter ff_vf_xfade
@ 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 FADESLOW_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 HBLUR_TRANSITION(name, type, div)
#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)
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 WIPETL_TRANSITION(name, type, div)
#define DIAGTL_TRANSITION(name, type, div)
const char * name
Pad name.
static float fract(float a)
#define SQUEEZEH_TRANSITION(name, type, div)
#define CIRCLEOPEN_TRANSITION(name, type, div)
#define AV_PIX_FMT_YUVA444P9
#define SQUEEZEV_TRANSITION(name, type, div)
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.
#define FADEFAST_TRANSITION(name, type, div)
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 FILTER_OUTPUTS(array)
#define DIAGBR_TRANSITION(name, type, div)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
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 av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
#define WIPEBR_TRANSITION(name, type, div)
#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)