96 int slice_start,
int slice_end,
int jobnr);
101 static const char *
const var_names[] = {
"X",
"Y",
"W",
"H",
"A",
"B",
"PLANE",
"P",
NULL };
144 #define OFFSET(x) offsetof(XFadeContext, x) 145 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) 193 #define CUSTOM_TRANSITION(name, type, div) \ 194 static void custom##name##_transition(AVFilterContext *ctx, \ 195 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 197 int slice_start, int slice_end, int jobnr) \ 199 XFadeContext *s = ctx->priv; \ 200 const int height = slice_end - slice_start; \ 202 double values[VAR_VARS_NB]; \ 203 values[VAR_W] = out->width; \ 204 values[VAR_H] = out->height; \ 205 values[VAR_PROGRESS] = progress; \ 207 for (int p = 0; p < s->nb_planes; p++) { \ 208 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 209 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 210 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 212 values[VAR_PLANE] = p; \ 214 for (int y = 0; y < height; y++) { \ 215 values[VAR_Y] = slice_start + y; \ 216 for (int x = 0; x < out->width; x++) { \ 218 values[VAR_A] = xf0[x]; \ 219 values[VAR_B] = xf1[x]; \ 220 dst[x] = av_expr_eval(s->e, values, s); \ 223 dst += out->linesize[p] / div; \ 224 xf0 += a->linesize[p] / div; \ 225 xf1 += b->linesize[p] / div; \ 233 static inline
float mix(
float a,
float b,
float mix)
235 return a * mix + b * (1.f -
mix);
240 return a - floorf(a);
243 static inline float smoothstep(
float edge0,
float edge1,
float x)
247 t = av_clipf((x - edge0) / (edge1 - edge0), 0.
f, 1.
f);
249 return t * t * (3.f - 2.f * t);
252 #define FADE_TRANSITION(name, type, div) \ 253 static void fade##name##_transition(AVFilterContext *ctx, \ 254 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 256 int slice_start, int slice_end, int jobnr) \ 258 XFadeContext *s = ctx->priv; \ 259 const int height = slice_end - slice_start; \ 261 for (int p = 0; p < s->nb_planes; p++) { \ 262 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 263 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 264 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 266 for (int y = 0; y < height; y++) { \ 267 for (int x = 0; x < out->width; x++) { \ 268 dst[x] = mix(xf0[x], xf1[x], progress); \ 271 dst += out->linesize[p] / div; \ 272 xf0 += a->linesize[p] / div; \ 273 xf1 += b->linesize[p] / div; \ 281 #define WIPELEFT_TRANSITION(name, type, div) \ 282 static void wipeleft##name##_transition(AVFilterContext *ctx, \ 283 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 285 int slice_start, int slice_end, int jobnr) \ 287 XFadeContext *s = ctx->priv; \ 288 const int height = slice_end - slice_start; \ 289 const int z = out->width * progress; \ 291 for (int p = 0; p < s->nb_planes; p++) { \ 292 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 293 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 294 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 296 for (int y = 0; y < height; y++) { \ 297 for (int x = 0; x < out->width; x++) { \ 298 dst[x] = x > z ? xf1[x] : xf0[x]; \ 301 dst += out->linesize[p] / div; \ 302 xf0 += a->linesize[p] / div; \ 303 xf1 += b->linesize[p] / div; \ 311 #define WIPERIGHT_TRANSITION(name, type, div) \ 312 static void wiperight##name##_transition(AVFilterContext *ctx, \ 313 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 315 int slice_start, int slice_end, int jobnr) \ 317 XFadeContext *s = ctx->priv; \ 318 const int height = slice_end - slice_start; \ 319 const int z = out->width * (1.f - progress); \ 321 for (int p = 0; p < s->nb_planes; p++) { \ 322 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 323 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 324 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 326 for (int y = 0; y < height; y++) { \ 327 for (int x = 0; x < out->width; x++) { \ 328 dst[x] = x > z ? xf0[x] : xf1[x]; \ 331 dst += out->linesize[p] / div; \ 332 xf0 += a->linesize[p] / div; \ 333 xf1 += b->linesize[p] / div; \ 341 #define WIPEUP_TRANSITION(name, type, div) \ 342 static void wipeup##name##_transition(AVFilterContext *ctx, \ 343 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 345 int slice_start, int slice_end, int jobnr) \ 347 XFadeContext *s = ctx->priv; \ 348 const int height = slice_end - slice_start; \ 349 const int z = out->height * progress; \ 351 for (int p = 0; p < s->nb_planes; p++) { \ 352 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 353 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 354 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 356 for (int y = 0; y < height; y++) { \ 357 for (int x = 0; x < out->width; x++) { \ 358 dst[x] = slice_start + y > z ? xf1[x] : xf0[x]; \ 361 dst += out->linesize[p] / div; \ 362 xf0 += a->linesize[p] / div; \ 363 xf1 += b->linesize[p] / div; \ 371 #define WIPEDOWN_TRANSITION(name, type, div) \ 372 static void wipedown##name##_transition(AVFilterContext *ctx, \ 373 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 375 int slice_start, int slice_end, int jobnr) \ 377 XFadeContext *s = ctx->priv; \ 378 const int height = slice_end - slice_start; \ 379 const int z = out->height * (1.f - progress); \ 381 for (int p = 0; p < s->nb_planes; p++) { \ 382 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 383 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 384 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 386 for (int y = 0; y < height; y++) { \ 387 for (int x = 0; x < out->width; x++) { \ 388 dst[x] = slice_start + y > z ? xf0[x] : xf1[x]; \ 391 dst += out->linesize[p] / div; \ 392 xf0 += a->linesize[p] / div; \ 393 xf1 += b->linesize[p] / div; \ 401 #define SLIDELEFT_TRANSITION(name, type, div) \ 402 static void slideleft##name##_transition(AVFilterContext *ctx, \ 403 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 405 int slice_start, int slice_end, int jobnr) \ 407 XFadeContext *s = ctx->priv; \ 408 const int height = slice_end - slice_start; \ 409 const int width = out->width; \ 410 const int z = -progress * width; \ 412 for (int p = 0; p < s->nb_planes; p++) { \ 413 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 414 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 415 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 417 for (int y = 0; y < height; y++) { \ 418 for (int x = 0; x < width; x++) { \ 419 const int zx = z + x; \ 420 const int zz = zx % width + width * (zx < 0); \ 421 dst[x] = (zx > 0) && (zx < width) ? xf1[zz] : xf0[zz]; \ 424 dst += out->linesize[p] / div; \ 425 xf0 += a->linesize[p] / div; \ 426 xf1 += b->linesize[p] / div; \ 434 #define SLIDERIGHT_TRANSITION(name, type, div) \ 435 static void slideright##name##_transition(AVFilterContext *ctx, \ 436 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 438 int slice_start, int slice_end, int jobnr) \ 440 XFadeContext *s = ctx->priv; \ 441 const int height = slice_end - slice_start; \ 442 const int width = out->width; \ 443 const int z = progress * width; \ 445 for (int p = 0; p < s->nb_planes; p++) { \ 446 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 447 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 448 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 450 for (int y = 0; y < height; y++) { \ 451 for (int x = 0; x < out->width; x++) { \ 452 const int zx = z + x; \ 453 const int zz = zx % width + width * (zx < 0); \ 454 dst[x] = (zx > 0) && (zx < width) ? xf1[zz] : xf0[zz]; \ 457 dst += out->linesize[p] / div; \ 458 xf0 += a->linesize[p] / div; \ 459 xf1 += b->linesize[p] / div; \ 467 #define SLIDEUP_TRANSITION(name, type, div) \ 468 static void slideup##name##_transition(AVFilterContext *ctx, \ 469 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 471 int slice_start, int slice_end, int jobnr) \ 473 XFadeContext *s = ctx->priv; \ 474 const int height = out->height; \ 475 const int z = -progress * height; \ 477 for (int p = 0; p < s->nb_planes; p++) { \ 478 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 480 for (int y = slice_start; y < slice_end; y++) { \ 481 const int zy = z + y; \ 482 const int zz = zy % height + height * (zy < 0); \ 483 const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]); \ 484 const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]); \ 486 for (int x = 0; x < out->width; x++) { \ 487 dst[x] = (zy > 0) && (zy < height) ? xf1[x] : xf0[x]; \ 490 dst += out->linesize[p] / div; \ 498 #define SLIDEDOWN_TRANSITION(name, type, div) \ 499 static void slidedown##name##_transition(AVFilterContext *ctx, \ 500 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 502 int slice_start, int slice_end, int jobnr) \ 504 XFadeContext *s = ctx->priv; \ 505 const int height = out->height; \ 506 const int z = progress * height; \ 508 for (int p = 0; p < s->nb_planes; p++) { \ 509 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 511 for (int y = slice_start; y < slice_end; y++) { \ 512 const int zy = z + y; \ 513 const int zz = zy % height + height * (zy < 0); \ 514 const type *xf0 = (const type *)(a->data[p] + zz * a->linesize[p]); \ 515 const type *xf1 = (const type *)(b->data[p] + zz * b->linesize[p]); \ 517 for (int x = 0; x < out->width; x++) { \ 518 dst[x] = (zy > 0) && (zy < height) ? xf1[x] : xf0[x]; \ 521 dst += out->linesize[p] / div; \ 529 #define CIRCLECROP_TRANSITION(name, type, div) \ 530 static void circlecrop##name##_transition(AVFilterContext *ctx, \ 531 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 533 int slice_start, int slice_end, int jobnr) \ 535 XFadeContext *s = ctx->priv; \ 536 const int width = out->width; \ 537 const int height = out->height; \ 538 float z = powf(2.f * fabsf(progress - 0.5f), 3.f) * hypotf(width/2, height/2); \ 540 for (int p = 0; p < s->nb_planes; p++) { \ 541 const int bg = s->black[p]; \ 542 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 544 for (int y = slice_start; y < slice_end; y++) { \ 545 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 546 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 548 for (int x = 0; x < width; x++) { \ 549 float dist = hypotf(x - width / 2, y - height / 2); \ 550 int val = progress < 0.5f ? xf1[x] : xf0[x]; \ 551 dst[x] = (z < dist) ? bg : val; \ 554 dst += out->linesize[p] / div; \ 562 #define RECTCROP_TRANSITION(name, type, div) \ 563 static void rectcrop##name##_transition(AVFilterContext *ctx, \ 564 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 566 int slice_start, int slice_end, int jobnr) \ 568 XFadeContext *s = ctx->priv; \ 569 const int width = out->width; \ 570 const int height = out->height; \ 571 int zh = fabsf(progress - 0.5f) * height; \ 572 int zw = fabsf(progress - 0.5f) * width; \ 574 for (int p = 0; p < s->nb_planes; p++) { \ 575 const int bg = s->black[p]; \ 576 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 578 for (int y = slice_start; y < slice_end; y++) { \ 579 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 580 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 582 for (int x = 0; x < width; x++) { \ 583 int dist = FFABS(x - width / 2) < zw && \ 584 FFABS(y - height / 2) < zh; \ 585 int val = progress < 0.5f ? xf1[x] : xf0[x]; \ 586 dst[x] = !dist ? bg : val; \ 589 dst += out->linesize[p] / div; \ 597 #define DISTANCE_TRANSITION(name, type, div) \ 598 static void distance##name##_transition(AVFilterContext *ctx, \ 599 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 601 int slice_start, int slice_end, int jobnr) \ 603 XFadeContext *s = ctx->priv; \ 604 const int width = out->width; \ 605 const float max = s->max_value; \ 607 for (int y = slice_start; y < slice_end; y++) { \ 608 for (int x = 0; x < width; x++) { \ 610 for (int p = 0; p < s->nb_planes; p++) { \ 611 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 612 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 614 dist += (xf0[x] / max - xf1[x] / max) * \ 615 (xf0[x] / max - xf1[x] / max); \ 618 dist = sqrtf(dist) <= progress; \ 619 for (int p = 0; p < s->nb_planes; p++) { \ 620 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 621 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 622 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 623 dst[x] = mix(mix(xf0[x], xf1[x], dist), xf1[x], progress); \ 632 #define FADEBLACK_TRANSITION(name, type, div) \ 633 static void fadeblack##name##_transition(AVFilterContext *ctx, \ 634 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 636 int slice_start, int slice_end, int jobnr) \ 638 XFadeContext *s = ctx->priv; \ 639 const int height = slice_end - slice_start; \ 640 const float phase = 0.2f; \ 642 for (int p = 0; p < s->nb_planes; p++) { \ 643 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 644 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 645 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 646 const int bg = s->black[p]; \ 648 for (int y = 0; y < height; y++) { \ 649 for (int x = 0; x < out->width; x++) { \ 650 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)), \ 651 mix(bg, xf1[x], smoothstep(phase, 1.f, progress)), \ 655 dst += out->linesize[p] / div; \ 656 xf0 += a->linesize[p] / div; \ 657 xf1 += b->linesize[p] / div; \ 665 #define FADEWHITE_TRANSITION(name, type, div) \ 666 static void fadewhite##name##_transition(AVFilterContext *ctx, \ 667 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 669 int slice_start, int slice_end, int jobnr) \ 671 XFadeContext *s = ctx->priv; \ 672 const int height = slice_end - slice_start; \ 673 const float phase = 0.2f; \ 675 for (int p = 0; p < s->nb_planes; p++) { \ 676 const type *xf0 = (const type *)(a->data[p] + slice_start * a->linesize[p]); \ 677 const type *xf1 = (const type *)(b->data[p] + slice_start * b->linesize[p]); \ 678 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ 679 const int bg = s->white[p]; \ 681 for (int y = 0; y < height; y++) { \ 682 for (int x = 0; x < out->width; x++) { \ 683 dst[x] = mix(mix(xf0[x], bg, smoothstep(1.f-phase, 1.f, progress)), \ 684 mix(bg, xf1[x], smoothstep(phase, 1.f, progress)), \ 688 dst += out->linesize[p] / div; \ 689 xf0 += a->linesize[p] / div; \ 690 xf1 += b->linesize[p] / div; \ 698 #define RADIAL_TRANSITION(name, type, div) \ 699 static void radial##name##_transition(AVFilterContext *ctx, \ 700 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 702 int slice_start, int slice_end, int jobnr) \ 704 XFadeContext *s = ctx->priv; \ 705 const int width = out->width; \ 706 const int height = out->height; \ 708 for (int y = slice_start; y < slice_end; y++) { \ 709 for (int x = 0; x < width; x++) { \ 710 const float smooth = atan2f(x - width / 2, y - height / 2) - \ 711 (progress - 0.5f) * (M_PI * 2.5f); \ 712 for (int p = 0; p < s->nb_planes; p++) { \ 713 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 714 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 715 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 717 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 726 #define SMOOTHLEFT_TRANSITION(name, type, div) \ 727 static void smoothleft##name##_transition(AVFilterContext *ctx, \ 728 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 730 int slice_start, int slice_end, int jobnr) \ 732 XFadeContext *s = ctx->priv; \ 733 const int width = out->width; \ 734 const float w = width; \ 736 for (int y = slice_start; y < slice_end; y++) { \ 737 for (int x = 0; x < width; x++) { \ 738 const float smooth = 1.f + x / w - progress * 2.f; \ 740 for (int p = 0; p < s->nb_planes; p++) { \ 741 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 742 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 743 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 745 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 754 #define SMOOTHRIGHT_TRANSITION(name, type, div) \ 755 static void smoothright##name##_transition(AVFilterContext *ctx, \ 756 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 758 int slice_start, int slice_end, int jobnr) \ 760 XFadeContext *s = ctx->priv; \ 761 const int width = out->width; \ 762 const float w = width; \ 764 for (int y = slice_start; y < slice_end; y++) { \ 765 for (int x = 0; x < width; x++) { \ 766 const float smooth = 1.f + (w - 1 - x) / w - progress * 2.f; \ 768 for (int p = 0; p < s->nb_planes; p++) { \ 769 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 770 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 771 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 773 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 782 #define SMOOTHUP_TRANSITION(name, type, div) \ 783 static void smoothup##name##_transition(AVFilterContext *ctx, \ 784 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 786 int slice_start, int slice_end, int jobnr) \ 788 XFadeContext *s = ctx->priv; \ 789 const int width = out->width; \ 790 const float h = out->height; \ 792 for (int y = slice_start; y < slice_end; y++) { \ 793 const float smooth = 1.f + y / h - progress * 2.f; \ 794 for (int x = 0; x < width; x++) { \ 795 for (int p = 0; p < s->nb_planes; p++) { \ 796 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 797 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 798 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 800 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 809 #define SMOOTHDOWN_TRANSITION(name, type, div) \ 810 static void smoothdown##name##_transition(AVFilterContext *ctx, \ 811 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 813 int slice_start, int slice_end, int jobnr) \ 815 XFadeContext *s = ctx->priv; \ 816 const int width = out->width; \ 817 const float h = out->height; \ 819 for (int y = slice_start; y < slice_end; y++) { \ 820 const float smooth = 1.f + (h - 1 - y) / h - progress * 2.f; \ 821 for (int x = 0; x < width; x++) { \ 822 for (int p = 0; p < s->nb_planes; p++) { \ 823 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 824 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 825 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 827 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 836 #define CIRCLEOPEN_TRANSITION(name, type, div) \ 837 static void circleopen##name##_transition(AVFilterContext *ctx, \ 838 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 840 int slice_start, int slice_end, int jobnr) \ 842 XFadeContext *s = ctx->priv; \ 843 const int width = out->width; \ 844 const int height = out->height; \ 845 const float z = hypotf(width / 2, height / 2); \ 846 const float p = (progress - 0.5f) * 3.f; \ 848 for (int y = slice_start; y < slice_end; y++) { \ 849 for (int x = 0; x < width; x++) { \ 850 const float smooth = hypotf(x - width / 2, y - height / 2) / z + p; \ 851 for (int p = 0; p < s->nb_planes; p++) { \ 852 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 853 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 854 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 856 dst[x] = mix(xf0[x], xf1[x], smoothstep(0.f, 1.f, smooth)); \ 865 #define CIRCLECLOSE_TRANSITION(name, type, div) \ 866 static void circleclose##name##_transition(AVFilterContext *ctx, \ 867 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 869 int slice_start, int slice_end, int jobnr) \ 871 XFadeContext *s = ctx->priv; \ 872 const int width = out->width; \ 873 const int height = out->height; \ 874 const float z = hypotf(width / 2, height / 2); \ 875 const float p = (1.f - progress - 0.5f) * 3.f; \ 877 for (int y = slice_start; y < slice_end; y++) { \ 878 for (int x = 0; x < width; x++) { \ 879 const float smooth = hypotf(x - width / 2, y - height / 2) / z + p; \ 880 for (int p = 0; p < s->nb_planes; p++) { \ 881 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 882 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 883 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 885 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 894 #define VERTOPEN_TRANSITION(name, type, div) \ 895 static void vertopen##name##_transition(AVFilterContext *ctx, \ 896 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 898 int slice_start, int slice_end, int jobnr) \ 900 XFadeContext *s = ctx->priv; \ 901 const int width = out->width; \ 902 const float w2 = out->width / 2.0; \ 904 for (int y = slice_start; y < slice_end; y++) { \ 905 for (int x = 0; x < width; x++) { \ 906 const float smooth = 2.f - fabsf((x - w2) / w2) - progress * 2.f; \ 907 for (int p = 0; p < s->nb_planes; p++) { \ 908 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 909 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 910 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 912 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 921 #define VERTCLOSE_TRANSITION(name, type, div) \ 922 static void vertclose##name##_transition(AVFilterContext *ctx, \ 923 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 925 int slice_start, int slice_end, int jobnr) \ 927 XFadeContext *s = ctx->priv; \ 928 const int width = out->width; \ 929 const float w2 = out->width / 2.0; \ 931 for (int y = slice_start; y < slice_end; y++) { \ 932 for (int x = 0; x < width; x++) { \ 933 const float smooth = 1.f + fabsf((x - w2) / w2) - progress * 2.f; \ 934 for (int p = 0; p < s->nb_planes; p++) { \ 935 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 936 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 937 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 939 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 948 #define HORZOPEN_TRANSITION(name, type, div) \ 949 static void horzopen##name##_transition(AVFilterContext *ctx, \ 950 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 952 int slice_start, int slice_end, int jobnr) \ 954 XFadeContext *s = ctx->priv; \ 955 const int width = out->width; \ 956 const float h2 = out->height / 2.0; \ 958 for (int y = slice_start; y < slice_end; y++) { \ 959 const float smooth = 2.f - fabsf((y - h2) / h2) - progress * 2.f; \ 960 for (int x = 0; x < width; x++) { \ 961 for (int p = 0; p < s->nb_planes; p++) { \ 962 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 963 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 964 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 966 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 975 #define HORZCLOSE_TRANSITION(name, type, div) \ 976 static void horzclose##name##_transition(AVFilterContext *ctx, \ 977 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 979 int slice_start, int slice_end, int jobnr) \ 981 XFadeContext *s = ctx->priv; \ 982 const int width = out->width; \ 983 const float h2 = out->height / 2.0; \ 985 for (int y = slice_start; y < slice_end; y++) { \ 986 const float smooth = 1.f + fabsf((y - h2) / h2) - progress * 2.f; \ 987 for (int x = 0; x < width; x++) { \ 988 for (int p = 0; p < s->nb_planes; p++) { \ 989 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 990 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 991 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 993 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 1004 const float r =
sinf(x * 12.9898
f + y * 78.233
f) * 43758.545f;
1006 return r - floorf(r);
1009 #define DISSOLVE_TRANSITION(name, type, div) \ 1010 static void dissolve##name##_transition(AVFilterContext *ctx, \ 1011 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1013 int slice_start, int slice_end, int jobnr) \ 1015 XFadeContext *s = ctx->priv; \ 1016 const int width = out->width; \ 1018 for (int y = slice_start; y < slice_end; y++) { \ 1019 for (int x = 0; x < width; x++) { \ 1020 const float smooth = frand(x, y) * 2.f + progress * 2.f - 1.5f; \ 1021 for (int p = 0; p < s->nb_planes; p++) { \ 1022 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1023 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1024 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1026 dst[x] = smooth >= 0.5f ? xf0[x] : xf1[x]; \ 1035 #define PIXELIZE_TRANSITION(name, type, div) \ 1036 static void pixelize##name##_transition(AVFilterContext *ctx, \ 1037 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1039 int slice_start, int slice_end, int jobnr) \ 1041 XFadeContext *s = ctx->priv; \ 1042 const int w = out->width; \ 1043 const int h = out->height; \ 1044 const float d = fminf(progress, 1.f - progress); \ 1045 const float dist = ceilf(d * 50.f) / 50.f; \ 1046 const float sqx = 2.f * dist * FFMIN(w, h) / 20.f; \ 1047 const float sqy = 2.f * dist * FFMIN(w, h) / 20.f; \ 1049 for (int y = slice_start; y < slice_end; y++) { \ 1050 for (int x = 0; x < w; x++) { \ 1051 int sx = dist > 0.f ? FFMIN((floorf(x / sqx) + .5f) * sqx, w - 1) : x; \ 1052 int sy = dist > 0.f ? FFMIN((floorf(y / sqy) + .5f) * sqy, h - 1) : y; \ 1053 for (int p = 0; p < s->nb_planes; p++) { \ 1054 const type *xf0 = (const type *)(a->data[p] + sy * a->linesize[p]); \ 1055 const type *xf1 = (const type *)(b->data[p] + sy * b->linesize[p]); \ 1056 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1058 dst[x] = mix(xf0[sx], xf1[sx], progress); \ 1067 #define DIAGTL_TRANSITION(name, type, div) \ 1068 static void diagtl##name##_transition(AVFilterContext *ctx, \ 1069 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1071 int slice_start, int slice_end, int jobnr) \ 1073 XFadeContext *s = ctx->priv; \ 1074 const int width = out->width; \ 1075 const float w = width; \ 1076 const float h = out->height; \ 1078 for (int y = slice_start; y < slice_end; y++) { \ 1079 for (int x = 0; x < width; x++) { \ 1080 const float smooth = 1.f + x / w * y / h - progress * 2.f; \ 1082 for (int p = 0; p < s->nb_planes; p++) { \ 1083 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1084 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1085 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1087 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 1096 #define DIAGTR_TRANSITION(name, type, div) \ 1097 static void diagtr##name##_transition(AVFilterContext *ctx, \ 1098 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1100 int slice_start, int slice_end, int jobnr) \ 1102 XFadeContext *s = ctx->priv; \ 1103 const int width = out->width; \ 1104 const float w = width; \ 1105 const float h = out->height; \ 1107 for (int y = slice_start; y < slice_end; y++) { \ 1108 for (int x = 0; x < width; x++) { \ 1109 const float smooth = 1.f + (w - 1 - x) / w * y / h - progress * 2.f; \ 1111 for (int p = 0; p < s->nb_planes; p++) { \ 1112 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1113 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1114 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1116 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 1125 #define DIAGBL_TRANSITION(name, type, div) \ 1126 static void diagbl##name##_transition(AVFilterContext *ctx, \ 1127 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1129 int slice_start, int slice_end, int jobnr) \ 1131 XFadeContext *s = ctx->priv; \ 1132 const int width = out->width; \ 1133 const float w = width; \ 1134 const float h = out->height; \ 1136 for (int y = slice_start; y < slice_end; y++) { \ 1137 for (int x = 0; x < width; x++) { \ 1138 const float smooth = 1.f + x / w * (h - 1 - y) / h - progress * 2.f; \ 1140 for (int p = 0; p < s->nb_planes; p++) { \ 1141 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1142 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1143 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1145 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 1154 #define DIAGBR_TRANSITION(name, type, div) \ 1155 static void diagbr##name##_transition(AVFilterContext *ctx, \ 1156 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1158 int slice_start, int slice_end, int jobnr) \ 1160 XFadeContext *s = ctx->priv; \ 1161 const int width = out->width; \ 1162 const float w = width; \ 1163 const float h = out->height; \ 1165 for (int y = slice_start; y < slice_end; y++) { \ 1166 for (int x = 0; x < width; x++) { \ 1167 const float smooth = 1.f + (w - 1 - x) / w * (h - 1 - y) / h - \ 1170 for (int p = 0; p < s->nb_planes; p++) { \ 1171 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1172 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1173 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1175 dst[x] = mix(xf1[x], xf0[x], smoothstep(0.f, 1.f, smooth)); \ 1184 #define HLSLICE_TRANSITION(name, type, div) \ 1185 static void hlslice##name##_transition(AVFilterContext *ctx, \ 1186 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1188 int slice_start, int slice_end, int jobnr) \ 1190 XFadeContext *s = ctx->priv; \ 1191 const int width = out->width; \ 1192 const float w = width; \ 1194 for (int y = slice_start; y < slice_end; y++) { \ 1195 for (int x = 0; x < width; x++) { \ 1196 const float smooth = smoothstep(-0.5f, 0.f, x / w - progress * 1.5f); \ 1197 const float ss = smooth <= fract(10.f * x / w) ? 0.f : 1.f; \ 1199 for (int p = 0; p < s->nb_planes; p++) { \ 1200 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1201 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1202 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1204 dst[x] = mix(xf1[x], xf0[x], ss); \ 1213 #define HRSLICE_TRANSITION(name, type, div) \ 1214 static void hrslice##name##_transition(AVFilterContext *ctx, \ 1215 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1217 int slice_start, int slice_end, int jobnr) \ 1219 XFadeContext *s = ctx->priv; \ 1220 const int width = out->width; \ 1221 const float w = width; \ 1223 for (int y = slice_start; y < slice_end; y++) { \ 1224 for (int x = 0; x < width; x++) { \ 1225 const float xx = (w - 1 - x) / w; \ 1226 const float smooth = smoothstep(-0.5f, 0.f, xx - progress * 1.5f); \ 1227 const float ss = smooth <= fract(10.f * xx) ? 0.f : 1.f; \ 1229 for (int p = 0; p < s->nb_planes; p++) { \ 1230 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1231 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1232 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1234 dst[x] = mix(xf1[x], xf0[x], ss); \ 1243 #define VUSLICE_TRANSITION(name, type, div) \ 1244 static void vuslice##name##_transition(AVFilterContext *ctx, \ 1245 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1247 int slice_start, int slice_end, int jobnr) \ 1249 XFadeContext *s = ctx->priv; \ 1250 const int width = out->width; \ 1251 const float h = out->height; \ 1253 for (int y = slice_start; y < slice_end; y++) { \ 1254 const float smooth = smoothstep(-0.5f, 0.f, y / h - progress * 1.5f); \ 1255 const float ss = smooth <= fract(10.f * y / h) ? 0.f : 1.f; \ 1257 for (int x = 0; x < width; x++) { \ 1258 for (int p = 0; p < s->nb_planes; p++) { \ 1259 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1260 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1261 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1263 dst[x] = mix(xf1[x], xf0[x], ss); \ 1272 #define VDSLICE_TRANSITION(name, type, div) \ 1273 static void vdslice##name##_transition(AVFilterContext *ctx, \ 1274 const AVFrame *a, const AVFrame *b, AVFrame *out, \ 1276 int slice_start, int slice_end, int jobnr) \ 1278 XFadeContext *s = ctx->priv; \ 1279 const int width = out->width; \ 1280 const float h = out->height; \ 1282 for (int y = slice_start; y < slice_end; y++) { \ 1283 const float yy = (h - 1 - y) / h; \ 1284 const float smooth = smoothstep(-0.5f, 0.f, yy - progress * 1.5f); \ 1285 const float ss = smooth <= fract(10.f * yy) ? 0.f : 1.f; \ 1287 for (int x = 0; x < width; x++) { \ 1288 for (int p = 0; p < s->nb_planes; p++) { \ 1289 const type *xf0 = (const type *)(a->data[p] + y * a->linesize[p]); \ 1290 const type *xf1 = (const type *)(b->data[p] + y * b->linesize[p]); \ 1291 type *dst = (type *)(out->data[p] + y * out->linesize[p]); \ 1293 dst[x] = mix(xf1[x], xf0[x], ss); \ 1302 static inline
double getpix(
void *priv,
double x,
double y,
int plane,
int nb)
1313 xi = av_clipd(x, 0, w - 1);
1314 yi = av_clipd(y, 0, h - 1);
1317 const uint16_t *src16 = (
const uint16_t*)src;
1320 return src16[xi + yi * linesize];
1322 return src[xi + yi * linesize];
1326 static double a0(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 0, 0); }
1327 static double a1(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 1, 0); }
1328 static double a2(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 2, 0); }
1329 static double a3(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 3, 0); }
1331 static double b0(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 0, 1); }
1332 static double b1(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 1, 1); }
1333 static double b2(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 2, 1); }
1334 static double b3(
void *priv,
double x,
double y) {
return getpix(priv, x, y, 3, 1); }
1349 if (inlink0->
w != inlink1->
w || inlink0->
h != inlink1->
h) {
1351 "(size %dx%d) do not match the corresponding " 1352 "second input link %s parameters (size %dx%d)\n",
1361 "(%d/%d) do not match the corresponding " 1362 "second input link %s timebase (%d/%d)\n",
1368 outlink->
w = inlink0->
w;
1369 outlink->
h = inlink0->
h;
1432 "a0",
"a1",
"a2",
"a3",
1433 "b0",
"b1",
"b2",
"b3",
1436 double (*
func2[])(
void *, double, double) = {
1445 NULL, NULL, func2_names,
func2, 0, ctx);
1458 int slice_start = (outlink->
h * jobnr ) / nb_jobs;
1459 int slice_end = (outlink->
h * (jobnr+1)) / nb_jobs;
1491 int ret = 0, status;
1500 }
else if (ret > 0) {
1560 if (!s->
eof[0] && !s->
xf[0])
1564 if (s->
eof[0] && s->
eof[1] && (
1599 .priv_class = &xfade_class,
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
This structure describes decoded (raw) audio or video data.
#define AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_GBRAP10
#define DIAGBR_TRANSITION(name, type, div)
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
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.
Main libavfilter public API header.
#define PIXELIZE_TRANSITION(name, type, div)
int h
agreed upon image height
#define AV_PIX_FMT_GBRP10
static double a1(void *priv, double x, double y)
#define WIPELEFT_TRANSITION(name, type, div)
static int query_formats(AVFilterContext *ctx)
#define FFERROR_NOT_READY
Filters implementation helper functions.
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.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
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 int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
#define AV_PIX_FMT_GRAY10
const char * name
Pad name.
static int xfade_activate(AVFilterContext *ctx)
#define AV_PIX_FMT_GRAY12
AVFilterLink ** inputs
array of pointers to input links
#define HORZOPEN_TRANSITION(name, type, div)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
#define DIAGBL_TRANSITION(name, type, div)
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
#define WIPEDOWN_TRANSITION(name, type, div)
static double a2(void *priv, double x, double y)
#define SLIDEUP_TRANSITION(name, type, div)
AVFILTER_DEFINE_CLASS(xfade)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
static double a3(void *priv, double x, double y)
#define WIPEUP_TRANSITION(name, type, div)
#define FADE_TRANSITION(name, type, div)
#define AVERROR_EOF
End of file.
#define AV_PIX_FMT_YUV444P16
#define WIPERIGHT_TRANSITION(name, type, div)
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
A link between two filters.
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
static float mix(float a, float b, float mix)
AVFilterPad * input_pads
array of input pads
#define DIAGTL_TRANSITION(name, type, div)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void(* transitionf)(AVFilterContext *ctx, const AVFrame *a, const AVFrame *b, AVFrame *out, float progress, int slice_start, int slice_end, int jobnr)
#define HRSLICE_TRANSITION(name, type, div)
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0, will be automatically copied from the first input of the source filter if it exists.
static av_cold void uninit(AVFilterContext *ctx)
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define CUSTOM_TRANSITION(name, type, div)
void * priv
private data for use by the filter
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define HORZCLOSE_TRANSITION(name, type, div)
#define AV_PIX_FMT_YUVA444P16
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link...
#define AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_YUV444P10
static int xfade_frame(AVFilterContext *ctx, AVFrame *a, AVFrame *b)
#define VUSLICE_TRANSITION(name, type, div)
#define AV_PIX_FMT_GBRAP16
static double a0(void *priv, double x, double y)
int w
agreed upon image width
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
#define AV_PIX_FMT_GBRP16
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
#define AV_PIX_FMT_GRAY16
#define xi(width, name, var, range_min, range_max, subs,...)
#define AV_PIX_FMT_YUVA444P12
static double b0(void *priv, double x, double y)
static int activate(AVFilterContext *ctx)
#define SLIDELEFT_TRANSITION(name, type, div)
#define SMOOTHDOWN_TRANSITION(name, type, div)
static float fract(float a)
AVFilterContext * src
source filter
#define AV_PIX_FMT_YUVA444P10
static const char *const var_names[]
#define CIRCLECLOSE_TRANSITION(name, type, div)
static const AVFilterPad inputs[]
#define AV_PIX_FMT_GBRP14
AVFrame * ff_inlink_peek_frame(AVFilterLink *link, size_t idx)
Access a frame in the link fifo without consuming it.
static const AVFilterPad outputs[]
int format
agreed upon media format
#define FADEBLACK_TRANSITION(name, type, div)
static float frand(int x, int y)
static double b1(void *priv, double x, double y)
#define CIRCLEOPEN_TRANSITION(name, type, div)
typedef void(RENAME(mix_any_func_type))
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Used for passing data between threads.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
static int config_output(AVFilterLink *outlink)
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
#define SMOOTHUP_TRANSITION(name, type, div)
#define SLIDEDOWN_TRANSITION(name, type, div)
#define HLSLICE_TRANSITION(name, type, div)
double(* func2[])(void *, double, double)
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)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static const AVOption xfade_options[]
Describe the class of an AVClass context structure.
int ff_outlink_get_status(AVFilterLink *link)
Get the status on an output link.
static double b3(void *priv, double x, double y)
const char * name
Filter name.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
size_t ff_inlink_queued_frames(AVFilterLink *link)
Get the number of frames available on the link.
#define RECTCROP_TRANSITION(name, type, div)
AVFilterLink ** outputs
array of pointers to output links
static enum AVPixelFormat pix_fmts[]
#define AV_PIX_FMT_GBRP12
#define flags(name, subs,...)
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
#define AV_PIX_FMT_YUV444P12
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static float smoothstep(float edge0, float edge1, float x)
#define FADEWHITE_TRANSITION(name, type, div)
planar GBRA 4:4:4:4 32bpp
#define DISSOLVE_TRANSITION(name, type, div)
static int xfade_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
#define AV_PIX_FMT_YUVA444P9
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
avfilter_execute_func * execute
static const char *const func2_names[]
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
#define SMOOTHRIGHT_TRANSITION(name, type, div)
#define CIRCLECROP_TRANSITION(name, type, div)
#define VERTOPEN_TRANSITION(name, type, div)
#define SLIDERIGHT_TRANSITION(name, type, div)
static const AVFilterPad xfade_inputs[]
static const AVFilterPad xfade_outputs[]
#define VERTCLOSE_TRANSITION(name, type, div)
#define VDSLICE_TRANSITION(name, type, div)
#define DISTANCE_TRANSITION(name, type, div)
#define RADIAL_TRANSITION(name, type, div)
int depth
Number of bits in the component.
#define DIAGTR_TRANSITION(name, type, div)
static double getpix(void *priv, double x, double y, int plane, int nb)
AVPixelFormat
Pixel format.
#define SMOOTHLEFT_TRANSITION(name, type, div)
#define AV_NOPTS_VALUE
Undefined timestamp value.
simple arithmetic expression evaluator
static double b2(void *priv, double x, double y)