| 441 | } |
| 442 | |
| 443 | av_cold int ff_set_cmp(const MECmpContext *c, me_cmp_func *cmp, int type, int mpvenc) |
| 444 | { |
| 445 | #define ENTRY(CMP_FLAG, ARRAY, MPVENC_ONLY) \ |
| 446 | [FF_CMP_ ## CMP_FLAG] = { \ |
| 447 | .offset = offsetof(MECmpContext, ARRAY), \ |
| 448 | .mpv_only = MPVENC_ONLY, \ |
| 449 | .available = 1, \ |
| 450 | } |
| 451 | static const struct { |
| 452 | char available; |
| 453 | char mpv_only; |
| 454 | uint16_t offset; |
| 455 | } cmp_func_list[] = { |
| 456 | ENTRY(SAD, sad, 0), |
| 457 | ENTRY(SSE, sse, 0), |
| 458 | ENTRY(SATD, hadamard8_diff, 0), |
| 459 | ENTRY(DCT, dct_sad, 1), |
| 460 | ENTRY(PSNR, quant_psnr, 1), |
| 461 | ENTRY(BIT, bit, 1), |
| 462 | ENTRY(RD, rd, 1), |
| 463 | ENTRY(VSAD, vsad, 0), |
| 464 | ENTRY(VSSE, vsse, 0), |
| 465 | ENTRY(NSSE, nsse, 0), |
| 466 | #if CONFIG_SNOW_DECODER || CONFIG_SNOW_ENCODER |
| 467 | ENTRY(W53, w53, 0), |
| 468 | ENTRY(W97, w97, 0), |
| 469 | #endif |
| 470 | ENTRY(DCTMAX, dct_max, 1), |
| 471 | #if CONFIG_GPL |
| 472 | ENTRY(DCT264, dct264_sad, 1), |
| 473 | #endif |
| 474 | ENTRY(MEDIAN_SAD, median_sad, 0), |
| 475 | }; |
| 476 | const me_cmp_func *me_cmp_func_array; |
| 477 | |
| 478 | type &= 0xFF; |
| 479 | |
| 480 | if (type == FF_CMP_ZERO) { |
| 481 | for (int i = 0; i < 6; i++) |
| 482 | cmp[i] = zero_cmp; |
| 483 | return 0; |
| 484 | } |
| 485 | if (type >= FF_ARRAY_ELEMS(cmp_func_list) || |
| 486 | !cmp_func_list[type].available || |
| 487 | !mpvenc && cmp_func_list[type].mpv_only) { |
| 488 | av_log(NULL, AV_LOG_ERROR, |
| 489 | "invalid cmp function selection\n"); |
| 490 | return AVERROR(EINVAL); |
| 491 | } |
| 492 | me_cmp_func_array = (const me_cmp_func*)(((const char*)c) + cmp_func_list[type].offset); |
| 493 | for (int i = 0; i < 6; i++) |
| 494 | cmp[i] = me_cmp_func_array[i]; |
| 495 | |
| 496 | return 0; |
| 497 | } |
| 498 | |
| 499 | #define BUTTERFLY2(o1, o2, i1, i2) \ |
| 500 | o1 = (i1) + (i2); \ |
no test coverage detected