Go to the documentation of this file.
105 int slice_start,
int slice_end,
int jobnr);
110 static const char *
const var_names[] = {
"X",
"Y",
"W",
"H",
"A",
"B",
"PLANE",
"P",
NULL };
153 #define OFFSET(x) offsetof(XFadeContext, x)
154 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
210 #define CUSTOM_TRANSITION(name, type, div) \
211 static void custom##name##_transition(AVFilterContext *ctx, \
212 const AVFrame *a, const AVFrame *b, AVFrame *out, \
214 int slice_start, int slice_end, int jobnr) \
216 XFadeContext *s = ctx->priv; \
217 const int height = slice_end - slice_start; \
219 double values[VAR_VARS_NB]; \
220 values[VAR_W] = out->width; \
221 values[VAR_H] = out->height; \
222 values[VAR_PROGRESS] = progress; \
224 for (int p = 0; p < s->nb_planes; p++) { \
225 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
226 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
227 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
229 values[VAR_PLANE] = p; \
231 for (int y = 0; y < height; y++) { \
232 values[VAR_Y] = slice_start + y; \
233 for (int x = 0; x < out->width; x++) { \
235 values[VAR_A] = xf0[x]; \
236 values[VAR_B] = xf1[x]; \
237 dst[x] = av_expr_eval(s->e, values, s); \
240 dst += out->linesize[p] / div; \
241 xf0 += a->linesize[p] / div; \
242 xf1 += b->linesize[p] / div; \
250 static inline
float mix(
float a,
float b,
float mix)
260 static inline float smoothstep(
float edge0,
float edge1,
float x)
264 t =
av_clipf((x - edge0) / (edge1 - edge0), 0.
f, 1.
f);
266 return t * t * (3.f - 2.f * t);
269 #define FADE_TRANSITION(name, type, div) \
270 static void fade##name##_transition(AVFilterContext *ctx, \
271 const AVFrame *a, const AVFrame *b, AVFrame *out, \
273 int slice_start, int slice_end, int jobnr) \
275 XFadeContext *s = ctx->priv; \
276 const int height = slice_end - slice_start; \
278 for (int p = 0; p < s->nb_planes; p++) { \
279 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
280 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
281 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
283 for (int y = 0; y < height; y++) { \
284 for (int x = 0; x < out->width; x++) { \
285 dst[x] = mix(xf0[x], xf1[x], progress); \
288 dst += out->linesize[p] / div; \
289 xf0 += a->linesize[p] / div; \
290 xf1 += b->linesize[p] / div; \
298 #define WIPELEFT_TRANSITION(name, type, div) \
299 static void wipeleft##name##_transition(AVFilterContext *ctx, \
300 const AVFrame *a, const AVFrame *b, AVFrame *out, \
302 int slice_start, int slice_end, int jobnr) \
304 XFadeContext *s = ctx->priv; \
305 const int height = slice_end - slice_start; \
306 const int z = out->width * progress; \
308 for (int p = 0; p < s->nb_planes; p++) { \
309 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
310 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
311 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
313 for (int y = 0; y < height; y++) { \
314 for (int x = 0; x < out->width; x++) { \
315 dst[x] = x > z ? xf1[x] : xf0[x]; \
318 dst += out->linesize[p] / div; \
319 xf0 += a->linesize[p] / div; \
320 xf1 += b->linesize[p] / div; \
328 #define WIPERIGHT_TRANSITION(name, type, div) \
329 static void wiperight##name##_transition(AVFilterContext *ctx, \
330 const AVFrame *a, const AVFrame *b, AVFrame *out, \
332 int slice_start, int slice_end, int jobnr) \
334 XFadeContext *s = ctx->priv; \
335 const int height = slice_end - slice_start; \
336 const int z = out->width * (1.f - progress); \
338 for (int p = 0; p < s->nb_planes; p++) { \
339 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
340 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
341 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
343 for (int y = 0; y < height; y++) { \
344 for (int x = 0; x < out->width; x++) { \
345 dst[x] = x > z ? xf0[x] : xf1[x]; \
348 dst += out->linesize[p] / div; \
349 xf0 += a->linesize[p] / div; \
350 xf1 += b->linesize[p] / div; \
358 #define WIPEUP_TRANSITION(name, type, div) \
359 static void wipeup##name##_transition(AVFilterContext *ctx, \
360 const AVFrame *a, const AVFrame *b, AVFrame *out, \
362 int slice_start, int slice_end, int jobnr) \
364 XFadeContext *s = ctx->priv; \
365 const int height = slice_end - slice_start; \
366 const int z = out->height * progress; \
368 for (int p = 0; p < s->nb_planes; p++) { \
369 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
370 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
371 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
373 for (int y = 0; y < height; y++) { \
374 for (int x = 0; x < out->width; x++) { \
375 dst[x] = slice_start + y > z ? xf1[x] : xf0[x]; \
378 dst += out->linesize[p] / div; \
379 xf0 += a->linesize[p] / div; \
380 xf1 += b->linesize[p] / div; \
388 #define WIPEDOWN_TRANSITION(name, type, div) \
389 static void wipedown##name##_transition(AVFilterContext *ctx, \
390 const AVFrame *a, const AVFrame *b, AVFrame *out, \
392 int slice_start, int slice_end, int jobnr) \
394 XFadeContext *s = ctx->priv; \
395 const int height = slice_end - slice_start; \
396 const int z = out->height * (1.f - progress); \
398 for (int p = 0; p < s->nb_planes; p++) { \
399 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
400 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
401 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
403 for (int y = 0; y < height; y++) { \
404 for (int x = 0; x < out->width; x++) { \
405 dst[x] = slice_start + y > z ? xf0[x] : xf1[x]; \
408 dst += out->linesize[p] / div; \
409 xf0 += a->linesize[p] / div; \
410 xf1 += b->linesize[p] / div; \
418 #define SLIDELEFT_TRANSITION(name, type, div) \
419 static void slideleft##name##_transition(AVFilterContext *ctx, \
420 const AVFrame *a, const AVFrame *b, AVFrame *out, \
422 int slice_start, int slice_end, int jobnr) \
424 XFadeContext *s = ctx->priv; \
425 const int height = slice_end - slice_start; \
426 const int width = out->width; \
427 const int z = -progress * width; \
429 for (int p = 0; p < s->nb_planes; p++) { \
430 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
431 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
432 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
434 for (int y = 0; y < height; y++) { \
435 for (int x = 0; x < width; x++) { \
436 const int zx = z + x; \
437 const int zz = zx % width + width * (zx < 0); \
438 dst[x] = (zx > 0) && (zx < width) ? xf1[zz] : xf0[zz]; \
441 dst += out->linesize[p] / div; \
442 xf0 += a->linesize[p] / div; \
443 xf1 += b->linesize[p] / div; \
451 #define SLIDERIGHT_TRANSITION(name, type, div) \
452 static void slideright##name##_transition(AVFilterContext *ctx, \
453 const AVFrame *a, const AVFrame *b, AVFrame *out, \
455 int slice_start, int slice_end, int jobnr) \
457 XFadeContext *s = ctx->priv; \
458 const int height = slice_end - slice_start; \
459 const int width = out->width; \
460 const int z = progress * width; \
462 for (int p = 0; p < s->nb_planes; p++) { \
463 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
464 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
465 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
467 for (int y = 0; y < height; y++) { \
468 for (int x = 0; x < out->width; x++) { \
469 const int zx = z + x; \
470 const int zz = zx % width + width * (zx < 0); \
471 dst[x] = (zx > 0) && (zx < width) ? xf1[zz] : xf0[zz]; \
474 dst += out->linesize[p] / div; \
475 xf0 += a->linesize[p] / div; \
476 xf1 += b->linesize[p] / div; \
484 #define SLIDEUP_TRANSITION(name, type, div) \
485 static void slideup##name##_transition(AVFilterContext *ctx, \
486 const AVFrame *a, const AVFrame *b, AVFrame *out, \
488 int slice_start, int slice_end, int jobnr) \
490 XFadeContext *s = ctx->priv; \
491 const int height = out->height; \
492 const int z = -progress * height; \
494 for (int p = 0; p < s->nb_planes; p++) { \
495 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
497 for (int y = slice_start; y < slice_end; y++) { \
498 const int zy = z + y; \
499 const int zz = zy % height + height * (zy < 0); \
500 const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]); \
501 const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]); \
503 for (int x = 0; x < out->width; x++) { \
504 dst[x] = (zy > 0) && (zy < height) ? xf1[x] : xf0[x]; \
507 dst += out->linesize[p] / div; \
515 #define SLIDEDOWN_TRANSITION(name, type, div) \
516 static void slidedown##name##_transition(AVFilterContext *ctx, \
517 const AVFrame *a, const AVFrame *b, AVFrame *out, \
519 int slice_start, int slice_end, int jobnr) \
521 XFadeContext *s = ctx->priv; \
522 const int height = out->height; \
523 const int z = progress * height; \
525 for (int p = 0; p < s->nb_planes; p++) { \
526 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
528 for (int y = slice_start; y < slice_end; y++) { \
529 const int zy = z + y; \
530 const int zz = zy % height + height * (zy < 0); \
531 const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]); \
532 const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]); \
534 for (int x = 0; x < out->width; x++) { \
535 dst[x] = (zy > 0) && (zy < height) ? xf1[x] : xf0[x]; \
538 dst += out->linesize[p] / div; \
546 #define CIRCLECROP_TRANSITION(name, type, div) \
547 static void circlecrop##name##_transition(AVFilterContext *ctx, \
548 const AVFrame *a, const AVFrame *b, AVFrame *out, \
550 int slice_start, int slice_end, int jobnr) \
552 XFadeContext *s = ctx->priv; \
553 const int width = out->width; \
554 const int height = out->height; \
555 float z = powf(2.f * fabsf(progress - 0.5f), 3.f) * hypotf(width/2, height/2); \
557 for (int p = 0; p < s->nb_planes; p++) { \
558 const int bg = s->black[p]; \
559 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
561 for (int y = slice_start; y < slice_end; y++) { \
562 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
563 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
565 for (int x = 0; x < width; x++) { \
566 float dist = hypotf(x - width / 2, y - height / 2); \
567 int val = progress < 0.5f ? xf1[x] : xf0[x]; \
568 dst[x] = (z < dist) ? bg : val; \
571 dst += out->linesize[p] / div; \
579 #define RECTCROP_TRANSITION(name, type, div) \
580 static void rectcrop##name##_transition(AVFilterContext *ctx, \
581 const AVFrame *a, const AVFrame *b, AVFrame *out, \
583 int slice_start, int slice_end, int jobnr) \
585 XFadeContext *s = ctx->priv; \
586 const int width = out->width; \
587 const int height = out->height; \
588 int zh = fabsf(progress - 0.5f) * height; \
589 int zw = fabsf(progress - 0.5f) * width; \
591 for (int p = 0; p < s->nb_planes; p++) { \
592 const int bg = s->black[p]; \
593 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
595 for (int y = slice_start; y < slice_end; y++) { \
596 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
597 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
599 for (int x = 0; x < width; x++) { \
600 int dist = FFABS(x - width / 2) < zw && \
601 FFABS(y - height / 2) < zh; \
602 int val = progress < 0.5f ? xf1[x] : xf0[x]; \
603 dst[x] = !dist ? bg : val; \
606 dst += out->linesize[p] / div; \
614 #define DISTANCE_TRANSITION(name, type, div) \
615 static void distance##name##_transition(AVFilterContext *ctx, \
616 const AVFrame *a, const AVFrame *b, AVFrame *out, \
618 int slice_start, int slice_end, int jobnr) \
620 XFadeContext *s = ctx->priv; \
621 const int width = out->width; \
622 const float max = s->max_value; \
624 for (int y = slice_start; y < slice_end; y++) { \
625 for (int x = 0; x < width; x++) { \
627 for (int p = 0; p < s->nb_planes; p++) { \
628 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
629 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
631 dist += (xf0[x] / max - xf1[x] / max) * \
632 (xf0[x] / max - xf1[x] / max); \
635 dist = sqrtf(dist) <= progress; \
636 for (int p = 0; p < s->nb_planes; p++) { \
637 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
638 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
639 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
640 dst[x] = mix(mix(xf0[x], xf1[x], dist), xf1[x], progress); \
649 #define FADEBLACK_TRANSITION(name, type, div) \
650 static void fadeblack##name##_transition(AVFilterContext *ctx, \
651 const AVFrame *a, const AVFrame *b, AVFrame *out, \
653 int slice_start, int slice_end, int jobnr) \
655 XFadeContext *s = ctx->priv; \
656 const int height = slice_end - slice_start; \
657 const float phase = 0.2f; \
659 for (int p = 0; p < s->nb_planes; p++) { \
660 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
661 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
662 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
663 const int bg = s->black[p]; \
665 for (int y = 0; y < height; y++) { \
666 for (int x = 0; x < out->width; x++) { \
667 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)), \
668 mix(bg, xf1[x], smoothstep(phase, 1.f, progress)), \
672 dst += out->linesize[p] / div; \
673 xf0 += a->linesize[p] / div; \
674 xf1 += b->linesize[p] / div; \
682 #define FADEWHITE_TRANSITION(name, type, div) \
683 static void fadewhite##name##_transition(AVFilterContext *ctx, \
684 const AVFrame *a, const AVFrame *b, AVFrame *out, \
686 int slice_start, int slice_end, int jobnr) \
688 XFadeContext *s = ctx->priv; \
689 const int height = slice_end - slice_start; \
690 const float phase = 0.2f; \
692 for (int p = 0; p < s->nb_planes; p++) { \
693 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
694 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
695 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
696 const int bg = s->white[p]; \
698 for (int y = 0; y < height; y++) { \
699 for (int x = 0; x < out->width; x++) { \
700 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)), \
701 mix(bg, xf1[x], smoothstep(phase, 1.f, progress)), \
705 dst += out->linesize[p] / div; \
706 xf0 += a->linesize[p] / div; \
707 xf1 += b->linesize[p] / div; \
715 #define RADIAL_TRANSITION(name, type, div) \
716 static void radial##name##_transition(AVFilterContext *ctx, \
717 const AVFrame *a, const AVFrame *b, AVFrame *out, \
719 int slice_start, int slice_end, int jobnr) \
721 XFadeContext *s = ctx->priv; \
722 const int width = out->width; \
723 const int height = out->height; \
725 for (int y = slice_start; y < slice_end; y++) { \
726 for (int x = 0; x < width; x++) { \
727 const float smooth = atan2f(x - width / 2, y - height / 2) - \
728 (progress - 0.5f) * (M_PI * 2.5f); \
729 for (int p = 0; p < s->nb_planes; p++) { \
730 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
731 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
732 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
734 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
743 #define SMOOTHLEFT_TRANSITION(name, type, div) \
744 static void smoothleft##name##_transition(AVFilterContext *ctx, \
745 const AVFrame *a, const AVFrame *b, AVFrame *out, \
747 int slice_start, int slice_end, int jobnr) \
749 XFadeContext *s = ctx->priv; \
750 const int width = out->width; \
751 const float w = width; \
753 for (int y = slice_start; y < slice_end; y++) { \
754 for (int x = 0; x < width; x++) { \
755 const float smooth = 1.f + x / w - progress * 2.f; \
757 for (int p = 0; p < s->nb_planes; p++) { \
758 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
759 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
760 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
762 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
771 #define SMOOTHRIGHT_TRANSITION(name, type, div) \
772 static void smoothright##name##_transition(AVFilterContext *ctx, \
773 const AVFrame *a, const AVFrame *b, AVFrame *out, \
775 int slice_start, int slice_end, int jobnr) \
777 XFadeContext *s = ctx->priv; \
778 const int width = out->width; \
779 const float w = width; \
781 for (int y = slice_start; y < slice_end; y++) { \
782 for (int x = 0; x < width; x++) { \
783 const float smooth = 1.f + (w - 1 - x) / w - progress * 2.f; \
785 for (int p = 0; p < s->nb_planes; p++) { \
786 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
787 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
788 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
790 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
799 #define SMOOTHUP_TRANSITION(name, type, div) \
800 static void smoothup##name##_transition(AVFilterContext *ctx, \
801 const AVFrame *a, const AVFrame *b, AVFrame *out, \
803 int slice_start, int slice_end, int jobnr) \
805 XFadeContext *s = ctx->priv; \
806 const int width = out->width; \
807 const float h = out->height; \
809 for (int y = slice_start; y < slice_end; y++) { \
810 const float smooth = 1.f + y / h - progress * 2.f; \
811 for (int x = 0; x < width; x++) { \
812 for (int p = 0; p < s->nb_planes; p++) { \
813 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
814 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
815 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
817 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
826 #define SMOOTHDOWN_TRANSITION(name, type, div) \
827 static void smoothdown##name##_transition(AVFilterContext *ctx, \
828 const AVFrame *a, const AVFrame *b, AVFrame *out, \
830 int slice_start, int slice_end, int jobnr) \
832 XFadeContext *s = ctx->priv; \
833 const int width = out->width; \
834 const float h = out->height; \
836 for (int y = slice_start; y < slice_end; y++) { \
837 const float smooth = 1.f + (h - 1 - y) / h - progress * 2.f; \
838 for (int x = 0; x < width; x++) { \
839 for (int p = 0; p < s->nb_planes; p++) { \
840 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
841 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
842 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
844 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
853 #define CIRCLEOPEN_TRANSITION(name, type, div) \
854 static void circleopen##name##_transition(AVFilterContext *ctx, \
855 const AVFrame *a, const AVFrame *b, AVFrame *out, \
857 int slice_start, int slice_end, int jobnr) \
859 XFadeContext *s = ctx->priv; \
860 const int width = out->width; \
861 const int height = out->height; \
862 const float z = hypotf(width / 2, height / 2); \
863 const float p = (progress - 0.5f) * 3.f; \
865 for (int y = slice_start; y < slice_end; y++) { \
866 for (int x = 0; x < width; x++) { \
867 const float smooth = hypotf(x - width / 2, y - height / 2) / z + p; \
868 for (int p = 0; p < s->nb_planes; p++) { \
869 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
870 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
871 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
873 dst[x] = mix(xf0[x], xf1[x], smoothstep(0.f, 1.f, smooth)); \
882 #define CIRCLECLOSE_TRANSITION(name, type, div) \
883 static void circleclose##name##_transition(AVFilterContext *ctx, \
884 const AVFrame *a, const AVFrame *b, AVFrame *out, \
886 int slice_start, int slice_end, int jobnr) \
888 XFadeContext *s = ctx->priv; \
889 const int width = out->width; \
890 const int height = out->height; \
891 const float z = hypotf(width / 2, height / 2); \
892 const float p = (1.f - progress - 0.5f) * 3.f; \
894 for (int y = slice_start; y < slice_end; y++) { \
895 for (int x = 0; x < width; x++) { \
896 const float smooth = hypotf(x - width / 2, y - height / 2) / z + p; \
897 for (int p = 0; p < s->nb_planes; p++) { \
898 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
899 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
900 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
902 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
911 #define VERTOPEN_TRANSITION(name, type, div) \
912 static void vertopen##name##_transition(AVFilterContext *ctx, \
913 const AVFrame *a, const AVFrame *b, AVFrame *out, \
915 int slice_start, int slice_end, int jobnr) \
917 XFadeContext *s = ctx->priv; \
918 const int width = out->width; \
919 const float w2 = out->width / 2; \
921 for (int y = slice_start; y < slice_end; y++) { \
922 for (int x = 0; x < width; x++) { \
923 const float smooth = 2.f - fabsf((x - w2) / w2) - progress * 2.f; \
924 for (int p = 0; p < s->nb_planes; p++) { \
925 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
926 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
927 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
929 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
938 #define VERTCLOSE_TRANSITION(name, type, div) \
939 static void vertclose##name##_transition(AVFilterContext *ctx, \
940 const AVFrame *a, const AVFrame *b, AVFrame *out, \
942 int slice_start, int slice_end, int jobnr) \
944 XFadeContext *s = ctx->priv; \
945 const int width = out->width; \
946 const float w2 = out->width / 2; \
948 for (int y = slice_start; y < slice_end; y++) { \
949 for (int x = 0; x < width; x++) { \
950 const float smooth = 1.f + fabsf((x - w2) / w2) - progress * 2.f; \
951 for (int p = 0; p < s->nb_planes; p++) { \
952 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
953 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
954 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
956 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
965 #define HORZOPEN_TRANSITION(name, type, div) \
966 static void horzopen##name##_transition(AVFilterContext *ctx, \
967 const AVFrame *a, const AVFrame *b, AVFrame *out, \
969 int slice_start, int slice_end, int jobnr) \
971 XFadeContext *s = ctx->priv; \
972 const int width = out->width; \
973 const float h2 = out->height / 2; \
975 for (int y = slice_start; y < slice_end; y++) { \
976 const float smooth = 2.f - fabsf((y - h2) / h2) - progress * 2.f; \
977 for (int x = 0; x < width; x++) { \
978 for (int p = 0; p < s->nb_planes; p++) { \
979 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
980 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
981 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
983 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
992 #define HORZCLOSE_TRANSITION(name, type, div) \
993 static void horzclose##name##_transition(AVFilterContext *ctx, \
994 const AVFrame *a, const AVFrame *b, AVFrame *out, \
996 int slice_start, int slice_end, int jobnr) \
998 XFadeContext *s = ctx->priv; \
999 const int width = out->width; \
1000 const float h2 = out->height / 2; \
1002 for (int y = slice_start; y < slice_end; y++) { \
1003 const float smooth = 1.f + fabsf((y - h2) / h2) - progress * 2.f; \
1004 for (int x = 0; x < width; x++) { \
1005 for (int p = 0; p < s->nb_planes; p++) { \
1006 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1007 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1008 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1010 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1021 const float r =
sinf(x * 12.9898
f + y * 78.233
f) * 43758.545f;
1026 #define DISSOLVE_TRANSITION(name, type, div) \
1027 static void dissolve##name##_transition(AVFilterContext *ctx, \
1028 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1030 int slice_start, int slice_end, int jobnr) \
1032 XFadeContext *s = ctx->priv; \
1033 const int width = out->width; \
1035 for (int y = slice_start; y < slice_end; y++) { \
1036 for (int x = 0; x < width; x++) { \
1037 const float smooth = frand(x, y) * 2.f + progress * 2.f - 1.5f; \
1038 for (int p = 0; p < s->nb_planes; p++) { \
1039 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1040 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1041 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1043 dst[x] = smooth >= 0.5f ? xf0[x] : xf1[x]; \
1052 #define PIXELIZE_TRANSITION(name, type, div) \
1053 static void pixelize##name##_transition(AVFilterContext *ctx, \
1054 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1056 int slice_start, int slice_end, int jobnr) \
1058 XFadeContext *s = ctx->priv; \
1059 const int w = out->width; \
1060 const int h = out->height; \
1061 const float d = fminf(progress, 1.f - progress); \
1062 const float dist = ceilf(d * 50.f) / 50.f; \
1063 const float sqx = 2.f * dist * FFMIN(w, h) / 20.f; \
1064 const float sqy = 2.f * dist * FFMIN(w, h) / 20.f; \
1066 for (int y = slice_start; y < slice_end; y++) { \
1067 for (int x = 0; x < w; x++) { \
1068 int sx = dist > 0.f ? FFMIN((floorf(x / sqx) + .5f) * sqx, w - 1) : x; \
1069 int sy = dist > 0.f ? FFMIN((floorf(y / sqy) + .5f) * sqy, h - 1) : y; \
1070 for (int p = 0; p < s->nb_planes; p++) { \
1071 const type *xf0 = (const type *)(a->data[p] + sy * a->linesize[p]); \
1072 const type *xf1 = (const type *)(b->data[p] + sy * b->linesize[p]); \
1073 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1075 dst[x] = mix(xf0[sx], xf1[sx], progress); \
1084 #define DIAGTL_TRANSITION(name, type, div) \
1085 static void diagtl##name##_transition(AVFilterContext *ctx, \
1086 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1088 int slice_start, int slice_end, int jobnr) \
1090 XFadeContext *s = ctx->priv; \
1091 const int width = out->width; \
1092 const float w = width; \
1093 const float h = out->height; \
1095 for (int y = slice_start; y < slice_end; y++) { \
1096 for (int x = 0; x < width; x++) { \
1097 const float smooth = 1.f + x / w * y / h - progress * 2.f; \
1099 for (int p = 0; p < s->nb_planes; p++) { \
1100 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1101 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1102 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1104 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1113 #define DIAGTR_TRANSITION(name, type, div) \
1114 static void diagtr##name##_transition(AVFilterContext *ctx, \
1115 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1117 int slice_start, int slice_end, int jobnr) \
1119 XFadeContext *s = ctx->priv; \
1120 const int width = out->width; \
1121 const float w = width; \
1122 const float h = out->height; \
1124 for (int y = slice_start; y < slice_end; y++) { \
1125 for (int x = 0; x < width; x++) { \
1126 const float smooth = 1.f + (w - 1 - x) / w * y / h - progress * 2.f; \
1128 for (int p = 0; p < s->nb_planes; p++) { \
1129 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1130 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1131 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1133 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1142 #define DIAGBL_TRANSITION(name, type, div) \
1143 static void diagbl##name##_transition(AVFilterContext *ctx, \
1144 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1146 int slice_start, int slice_end, int jobnr) \
1148 XFadeContext *s = ctx->priv; \
1149 const int width = out->width; \
1150 const float w = width; \
1151 const float h = out->height; \
1153 for (int y = slice_start; y < slice_end; y++) { \
1154 for (int x = 0; x < width; x++) { \
1155 const float smooth = 1.f + x / w * (h - 1 - y) / h - progress * 2.f; \
1157 for (int p = 0; p < s->nb_planes; p++) { \
1158 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1159 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1160 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1162 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1171 #define DIAGBR_TRANSITION(name, type, div) \
1172 static void diagbr##name##_transition(AVFilterContext *ctx, \
1173 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1175 int slice_start, int slice_end, int jobnr) \
1177 XFadeContext *s = ctx->priv; \
1178 const int width = out->width; \
1179 const float w = width; \
1180 const float h = out->height; \
1182 for (int y = slice_start; y < slice_end; y++) { \
1183 for (int x = 0; x < width; x++) { \
1184 const float smooth = 1.f + (w - 1 - x) / w * (h - 1 - y) / h - \
1187 for (int p = 0; p < s->nb_planes; p++) { \
1188 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1189 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1190 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1192 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \
1201 #define HLSLICE_TRANSITION(name, type, div) \
1202 static void hlslice##name##_transition(AVFilterContext *ctx, \
1203 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1205 int slice_start, int slice_end, int jobnr) \
1207 XFadeContext *s = ctx->priv; \
1208 const int width = out->width; \
1209 const float w = width; \
1211 for (int y = slice_start; y < slice_end; y++) { \
1212 for (int x = 0; x < width; x++) { \
1213 const float smooth = smoothstep(-0.5f, 0.f, x / w - progress * 1.5f); \
1214 const float ss = smooth <= fract(10.f * x / w) ? 0.f : 1.f; \
1216 for (int p = 0; p < s->nb_planes; p++) { \
1217 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1218 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1219 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1221 dst[x] = mix(xf1[x], xf0[x], ss); \
1230 #define HRSLICE_TRANSITION(name, type, div) \
1231 static void hrslice##name##_transition(AVFilterContext *ctx, \
1232 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1234 int slice_start, int slice_end, int jobnr) \
1236 XFadeContext *s = ctx->priv; \
1237 const int width = out->width; \
1238 const float w = width; \
1240 for (int y = slice_start; y < slice_end; y++) { \
1241 for (int x = 0; x < width; x++) { \
1242 const float xx = (w - 1 - x) / w; \
1243 const float smooth = smoothstep(-0.5f, 0.f, xx - progress * 1.5f); \
1244 const float ss = smooth <= fract(10.f * xx) ? 0.f : 1.f; \
1246 for (int p = 0; p < s->nb_planes; p++) { \
1247 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1248 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1249 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1251 dst[x] = mix(xf1[x], xf0[x], ss); \
1260 #define VUSLICE_TRANSITION(name, type, div) \
1261 static void vuslice##name##_transition(AVFilterContext *ctx, \
1262 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1264 int slice_start, int slice_end, int jobnr) \
1266 XFadeContext *s = ctx->priv; \
1267 const int width = out->width; \
1268 const float h = out->height; \
1270 for (int y = slice_start; y < slice_end; y++) { \
1271 const float smooth = smoothstep(-0.5f, 0.f, y / h - progress * 1.5f); \
1272 const float ss = smooth <= fract(10.f * y / h) ? 0.f : 1.f; \
1274 for (int x = 0; x < width; x++) { \
1275 for (int p = 0; p < s->nb_planes; p++) { \
1276 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1277 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1278 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1280 dst[x] = mix(xf1[x], xf0[x], ss); \
1289 #define VDSLICE_TRANSITION(name, type, div) \
1290 static void vdslice##name##_transition(AVFilterContext *ctx, \
1291 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1293 int slice_start, int slice_end, int jobnr) \
1295 XFadeContext *s = ctx->priv; \
1296 const int width = out->width; \
1297 const float h = out->height; \
1299 for (int y = slice_start; y < slice_end; y++) { \
1300 const float yy = (h - 1 - y) / h; \
1301 const float smooth = smoothstep(-0.5f, 0.f, yy - progress * 1.5f); \
1302 const float ss = smooth <= fract(10.f * yy) ? 0.f : 1.f; \
1304 for (int x = 0; x < width; x++) { \
1305 for (int p = 0; p < s->nb_planes; p++) { \
1306 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1307 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1308 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1310 dst[x] = mix(xf1[x], xf0[x], ss); \
1319 #define HBLUR_TRANSITION(name, type, div) \
1320 static void hblur##name##_transition(AVFilterContext *ctx, \
1321 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1323 int slice_start, int slice_end, int jobnr) \
1325 XFadeContext *s = ctx->priv; \
1326 const int width = out->width; \
1327 const float prog = progress <= 0.5f ? progress * 2.f : (1.f - progress) * 2.f; \
1328 const int size = 1 + (width / 2) * prog; \
1330 for (int y = slice_start; y < slice_end; y++) { \
1331 for (int p = 0; p < s->nb_planes; p++) { \
1332 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1333 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1334 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1339 for (int x = 0; x < size; x++) { \
1344 for (int x = 0; x < width; x++) { \
1345 dst[x] = mix(sum0 / cnt, sum1 / cnt, progress); \
1347 if (x + size < width) { \
1348 sum0 += xf0[x + size] - xf0[x]; \
1349 sum1 += xf1[x + size] - xf1[x]; \
1363 #define FADEGRAYS_TRANSITION(name, type, div) \
1364 static void fadegrays##name##_transition(AVFilterContext *ctx, \
1365 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1367 int slice_start, int slice_end, int jobnr) \
1369 XFadeContext *s = ctx->priv; \
1370 const int width = out->width; \
1371 const int is_rgb = s->is_rgb; \
1372 const int mid = (s->max_value + 1) / 2; \
1373 const float phase = 0.2f; \
1375 for (int y = slice_start; y < slice_end; y++) { \
1376 for (int x = 0; x < width; x++) { \
1379 for (int p = 0; p < s->nb_planes; p++) { \
1380 const type *xf0 = (const type *)(a->data[p] + \
1381 y * a->linesize[p]); \
1382 const type *xf1 = (const type *)(b->data[p] + \
1383 y * b->linesize[p]); \
1385 bg[0][3] = xf0[x]; \
1386 bg[1][3] = xf1[x]; \
1388 bg[0][0] += xf0[x]; \
1389 bg[1][0] += xf1[x]; \
1392 bg[0][0] = bg[0][0] / 3; \
1393 bg[1][0] = bg[1][0] / 3; \
1394 bg[0][1] = bg[0][2] = bg[0][0]; \
1395 bg[1][1] = bg[1][2] = bg[1][0]; \
1397 const type *yf0 = (const type *)(a->data[0] + \
1398 y * a->linesize[0]); \
1399 const type *yf1 = (const type *)(b->data[0] + \
1400 y * a->linesize[0]); \
1401 bg[0][0] = yf0[x]; \
1402 bg[1][0] = yf1[x]; \
1403 if (s->nb_planes == 4) { \
1404 const type *af0 = (const type *)(a->data[3] + \
1405 y * a->linesize[3]); \
1406 const type *af1 = (const type *)(b->data[3] + \
1407 y * a->linesize[3]); \
1408 bg[0][3] = af0[x]; \
1409 bg[1][3] = af1[x]; \
1411 bg[0][1] = bg[1][1] = mid; \
1412 bg[0][2] = bg[1][2] = mid; \
1415 for (int p = 0; p < s->nb_planes; p++) { \
1416 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \
1417 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \
1418 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \
1420 dst[x] = mix(mix(xf0[x], bg[0][p], \
1421 smoothstep(1.f-phase, 1.f, progress)), \
1422 mix(bg[1][p], xf1[x], smoothstep(phase, 1.f, progress)), \
1432 #define WIPETL_TRANSITION(name, type, div) \
1433 static void wipetl##name##_transition(AVFilterContext *ctx, \
1434 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1436 int slice_start, int slice_end, int jobnr) \
1438 XFadeContext *s = ctx->priv; \
1439 const int height = slice_end - slice_start; \
1440 const int zw = out->width * progress; \
1441 const int zh = out->height * progress; \
1443 for (int p = 0; p < s->nb_planes; p++) { \
1444 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1445 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1446 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1448 for (int y = 0; y < height; y++) { \
1449 for (int x = 0; x < out->width; x++) { \
1450 dst[x] = slice_start + y <= zh && \
1451 x <= zw ? xf0[x] : xf1[x]; \
1454 dst += out->linesize[p] / div; \
1455 xf0 += a->linesize[p] / div; \
1456 xf1 += b->linesize[p] / div; \
1464 #define WIPETR_TRANSITION(name, type, div) \
1465 static void wipetr##name##_transition(AVFilterContext *ctx, \
1466 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1468 int slice_start, int slice_end, int jobnr) \
1470 XFadeContext *s = ctx->priv; \
1471 const int height = slice_end - slice_start; \
1472 const int zw = out->width * (1.f - progress); \
1473 const int zh = out->height * progress; \
1475 for (int p = 0; p < s->nb_planes; p++) { \
1476 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1477 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1478 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1480 for (int y = 0; y < height; y++) { \
1481 for (int x = 0; x < out->width; x++) { \
1482 dst[x] = slice_start + y <= zh && \
1483 x > zw ? xf0[x] : xf1[x]; \
1486 dst += out->linesize[p] / div; \
1487 xf0 += a->linesize[p] / div; \
1488 xf1 += b->linesize[p] / div; \
1496 #define WIPEBL_TRANSITION(name, type, div) \
1497 static void wipebl##name##_transition(AVFilterContext *ctx, \
1498 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1500 int slice_start, int slice_end, int jobnr) \
1502 XFadeContext *s = ctx->priv; \
1503 const int height = slice_end - slice_start; \
1504 const int zw = out->width * progress; \
1505 const int zh = out->height * (1.f - progress); \
1507 for (int p = 0; p < s->nb_planes; p++) { \
1508 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1509 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1510 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1512 for (int y = 0; y < height; y++) { \
1513 for (int x = 0; x < out->width; x++) { \
1514 dst[x] = slice_start + y > zh && \
1515 x <= zw ? xf0[x] : xf1[x]; \
1518 dst += out->linesize[p] / div; \
1519 xf0 += a->linesize[p] / div; \
1520 xf1 += b->linesize[p] / div; \
1528 #define WIPEBR_TRANSITION(name, type, div) \
1529 static void wipebr##name##_transition(AVFilterContext *ctx, \
1530 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1532 int slice_start, int slice_end, int jobnr) \
1534 XFadeContext *s = ctx->priv; \
1535 const int height = slice_end - slice_start; \
1536 const int zh = out->height * (1.f - progress); \
1537 const int zw = out->width * (1.f - progress); \
1539 for (int p = 0; p < s->nb_planes; p++) { \
1540 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1541 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1542 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1544 for (int y = 0; y < height; y++) { \
1545 for (int x = 0; x < out->width; x++) { \
1546 dst[x] = slice_start + y > zh && \
1547 x > zw ? xf0[x] : xf1[x]; \
1550 dst += out->linesize[p] / div; \
1551 xf0 += a->linesize[p] / div; \
1552 xf1 += b->linesize[p] / div; \
1560 #define SQUEEZEH_TRANSITION(name, type, div) \
1561 static void squeezeh##name##_transition(AVFilterContext *ctx, \
1562 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1564 int slice_start, int slice_end, int jobnr) \
1566 XFadeContext *s = ctx->priv; \
1567 const float h = out->height; \
1568 const int height = slice_end - slice_start; \
1570 for (int p = 0; p < s->nb_planes; p++) { \
1571 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1572 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1574 for (int y = 0; y < height; y++) { \
1575 const float z = .5f + ((slice_start + y) / h - .5f) / progress; \
1577 if (z < 0.f || z > 1.f) { \
1578 for (int x = 0; x < out->width; x++) \
1581 const int yy = lrintf(z * (h - 1.f)); \
1582 const type *xf0 = (const type *)(a->data[p] + yy * a->linesize[p]); \
1584 for (int x = 0; x < out->width; x++) \
1588 dst += out->linesize[p] / div; \
1589 xf1 += b->linesize[p] / div; \
1597 #define SQUEEZEV_TRANSITION(name, type, div) \
1598 static void squeezev##name##_transition(AVFilterContext *ctx, \
1599 const AVFrame *a, const AVFrame *b, AVFrame *out, \
1601 int slice_start, int slice_end, int jobnr) \
1603 XFadeContext *s = ctx->priv; \
1604 const float w = out->width; \
1605 const int height = slice_end - slice_start; \
1607 for (int p = 0; p < s->nb_planes; p++) { \
1608 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \
1609 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \
1610 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
1612 for (int y = 0; y < height; y++) { \
1613 for (int x = 0; x < out->width; x++) { \
1614 const float z = .5f + (x / w - .5f) / progress; \
1616 if (z < 0.f || z > 1.f) { \
1619 const int xx = lrintf(z * (w - 1.f)); \
1625 dst += out->linesize[p] / div; \
1626 xf0 += a->linesize[p] / div; \
1627 xf1 += b->linesize[p] / div; \
1635 static inline
double getpix(
void *priv,
double x,
double y,
int plane,
int nb)
1640 int linesize =
in->linesize[
FFMIN(plane,
s->nb_planes - 1)];
1641 const int w =
in->width;
1642 const int h =
in->height;
1650 const uint16_t *src16 = (
const uint16_t*)
src;
1653 return src16[
xi + yi * linesize];
1655 return src[
xi + yi * linesize];
1659 static double a0(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 0, 0); }
1660 static double a1(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 1, 0); }
1661 static double a2(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 2, 0); }
1662 static double a3(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 3, 0); }
1664 static double b0(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 0, 1); }
1665 static double b1(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 1, 1); }
1666 static double b2(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 2, 1); }
1667 static double b3(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 3, 1); }
1681 if (inlink0->
w != inlink1->
w || inlink0->
h != inlink1->
h) {
1683 "(size %dx%d) do not match the corresponding "
1684 "second input link %s parameters (size %dx%d)\n",
1685 ctx->input_pads[0].name, inlink0->
w, inlink0->
h,
1686 ctx->input_pads[1].name, inlink1->
w, inlink1->
h);
1693 "(%d/%d) do not match the corresponding "
1694 "second input link %s timebase (%d/%d)\n",
1709 "(%d/%d) do not match the corresponding "
1710 "second input link %s frame rate (%d/%d)\n",
1716 outlink->
w = inlink0->
w;
1717 outlink->
h = inlink0->
h;
1725 s->max_value = (1 <<
s->depth) - 1;
1727 s->black[1] =
s->black[2] =
s->is_rgb ? 0 :
s->max_value / 2;
1728 s->black[3] =
s->max_value;
1729 s->white[0] =
s->white[3] =
s->max_value;
1730 s->white[1] =
s->white[2] =
s->is_rgb ?
s->max_value :
s->max_value / 2;
1739 switch (
s->transition) {
1740 case CUSTOM:
s->transitionf =
s->depth <= 8 ? custom8_transition : custom16_transition;
break;
1741 case FADE:
s->transitionf =
s->depth <= 8 ? fade8_transition : fade16_transition;
break;
1742 case WIPELEFT:
s->transitionf =
s->depth <= 8 ? wipeleft8_transition : wipeleft16_transition;
break;
1743 case WIPERIGHT:
s->transitionf =
s->depth <= 8 ? wiperight8_transition : wiperight16_transition;
break;
1744 case WIPEUP:
s->transitionf =
s->depth <= 8 ? wipeup8_transition : wipeup16_transition;
break;
1745 case WIPEDOWN:
s->transitionf =
s->depth <= 8 ? wipedown8_transition : wipedown16_transition;
break;
1746 case SLIDELEFT:
s->transitionf =
s->depth <= 8 ? slideleft8_transition : slideleft16_transition;
break;
1747 case SLIDERIGHT:
s->transitionf =
s->depth <= 8 ? slideright8_transition : slideright16_transition;
break;
1748 case SLIDEUP:
s->transitionf =
s->depth <= 8 ? slideup8_transition : slideup16_transition;
break;
1749 case SLIDEDOWN:
s->transitionf =
s->depth <= 8 ? slidedown8_transition : slidedown16_transition;
break;
1750 case CIRCLECROP:
s->transitionf =
s->depth <= 8 ? circlecrop8_transition : circlecrop16_transition;
break;
1751 case RECTCROP:
s->transitionf =
s->depth <= 8 ? rectcrop8_transition : rectcrop16_transition;
break;
1752 case DISTANCE:
s->transitionf =
s->depth <= 8 ? distance8_transition : distance16_transition;
break;
1753 case FADEBLACK:
s->transitionf =
s->depth <= 8 ? fadeblack8_transition : fadeblack16_transition;
break;
1754 case FADEWHITE:
s->transitionf =
s->depth <= 8 ? fadewhite8_transition : fadewhite16_transition;
break;
1755 case RADIAL:
s->transitionf =
s->depth <= 8 ? radial8_transition : radial16_transition;
break;
1756 case SMOOTHLEFT:
s->transitionf =
s->depth <= 8 ? smoothleft8_transition : smoothleft16_transition;
break;
1757 case SMOOTHRIGHT:
s->transitionf =
s->depth <= 8 ? smoothright8_transition: smoothright16_transition;
break;
1758 case SMOOTHUP:
s->transitionf =
s->depth <= 8 ? smoothup8_transition : smoothup16_transition;
break;
1759 case SMOOTHDOWN:
s->transitionf =
s->depth <= 8 ? smoothdown8_transition : smoothdown16_transition;
break;
1760 case CIRCLEOPEN:
s->transitionf =
s->depth <= 8 ? circleopen8_transition : circleopen16_transition;
break;
1761 case CIRCLECLOSE:
s->transitionf =
s->depth <= 8 ? circleclose8_transition: circleclose16_transition;
break;
1762 case VERTOPEN:
s->transitionf =
s->depth <= 8 ? vertopen8_transition : vertopen16_transition;
break;
1763 case VERTCLOSE:
s->transitionf =
s->depth <= 8 ? vertclose8_transition : vertclose16_transition;
break;
1764 case HORZOPEN:
s->transitionf =
s->depth <= 8 ? horzopen8_transition : horzopen16_transition;
break;
1765 case HORZCLOSE:
s->transitionf =
s->depth <= 8 ? horzclose8_transition : horzclose16_transition;
break;
1766 case DISSOLVE:
s->transitionf =
s->depth <= 8 ? dissolve8_transition : dissolve16_transition;
break;
1767 case PIXELIZE:
s->transitionf =
s->depth <= 8 ? pixelize8_transition : pixelize16_transition;
break;
1768 case DIAGTL:
s->transitionf =
s->depth <= 8 ? diagtl8_transition : diagtl16_transition;
break;
1769 case DIAGTR:
s->transitionf =
s->depth <= 8 ? diagtr8_transition : diagtr16_transition;
break;
1770 case DIAGBL:
s->transitionf =
s->depth <= 8 ? diagbl8_transition : diagbl16_transition;
break;
1771 case DIAGBR:
s->transitionf =
s->depth <= 8 ? diagbr8_transition : diagbr16_transition;
break;
1772 case HLSLICE:
s->transitionf =
s->depth <= 8 ? hlslice8_transition : hlslice16_transition;
break;
1773 case HRSLICE:
s->transitionf =
s->depth <= 8 ? hrslice8_transition : hrslice16_transition;
break;
1774 case VUSLICE:
s->transitionf =
s->depth <= 8 ? vuslice8_transition : vuslice16_transition;
break;
1775 case VDSLICE:
s->transitionf =
s->depth <= 8 ? vdslice8_transition : vdslice16_transition;
break;
1776 case HBLUR:
s->transitionf =
s->depth <= 8 ? hblur8_transition : hblur16_transition;
break;
1777 case FADEGRAYS:
s->transitionf =
s->depth <= 8 ? fadegrays8_transition : fadegrays16_transition;
break;
1778 case WIPETL:
s->transitionf =
s->depth <= 8 ? wipetl8_transition : wipetl16_transition;
break;
1779 case WIPETR:
s->transitionf =
s->depth <= 8 ? wipetr8_transition : wipetr16_transition;
break;
1780 case WIPEBL:
s->transitionf =
s->depth <= 8 ? wipebl8_transition : wipebl16_transition;
break;
1781 case WIPEBR:
s->transitionf =
s->depth <= 8 ? wipebr8_transition : wipebr16_transition;
break;
1782 case SQUEEZEH:
s->transitionf =
s->depth <= 8 ? squeezeh8_transition : squeezeh16_transition;
break;
1783 case SQUEEZEV:
s->transitionf =
s->depth <= 8 ? squeezev8_transition : squeezev16_transition;
break;
1786 if (
s->transition ==
CUSTOM) {
1788 "a0",
"a1",
"a2",
"a3",
1789 "b0",
"b1",
"b2",
"b3",
1792 double (*
func2[])(
void *, double, double) = {
1814 int slice_start = (outlink->
h * jobnr ) / nb_jobs;
1815 int slice_end = (outlink->
h * (jobnr+1)) / nb_jobs;
1826 float progress =
av_clipf(1.
f - ((
float)(
s->pts -
s->first_pts -
s->offset_pts) /
s->duration_pts), 0.f, 1.f);
1835 td.xf[0] =
a,
td.xf[1] =
b,
td.out =
out,
td.progress = progress;
1853 if (
s->xfade_is_over) {
1862 }
else if (
ret > 0) {
1863 in->pts = (
in->pts -
s->last_pts) +
s->pts;
1879 s->first_pts =
s->xf[0]->pts;
1881 s->pts =
s->xf[0]->pts;
1882 if (
s->first_pts +
s->offset_pts >
s->xf[0]->pts) {
1897 s->last_pts =
s->xf[1]->pts;
1898 s->pts =
s->xf[0]->pts;
1899 if (
s->xf[0]->pts - (
s->first_pts +
s->offset_pts) >
s->duration_pts)
1900 s->xfade_is_over = 1;
1916 s->xfade_is_over = 1;
1925 if (
s->eof[0] &&
s->eof[1] && (
1929 }
else if (
s->xfade_is_over) {
1963 .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[]
static __device__ float floorf(float a)
#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)
#define WIPEBL_TRANSITION(name, type, div)
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 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 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)
#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[]
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 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)
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 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.
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)
#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 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)