| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with FFmpeg; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <stddef.h> | ||
| 20 | #include <stdint.h> | ||
| 21 | |||
| 22 | #include "checkasm.h" | ||
| 23 | #include "libavfilter/vf_fsppdsp.h" | ||
| 24 | #include "libavcodec/mathops.h" | ||
| 25 | #include "libavutil/mem_internal.h" | ||
| 26 | |||
| 27 | #define randomize_buffers(buf) \ | ||
| 28 | do { \ | ||
| 29 | for (size_t j = 0; j < FF_ARRAY_ELEMS(buf); ++j) \ | ||
| 30 | buf[j] = rnd(); \ | ||
| 31 | } while (0) | ||
| 32 | |||
| 33 | #define randomize_mask_buffers(buf, buf2, nb_elems, nb_bits)\ | ||
| 34 | do { \ | ||
| 35 | for (size_t j = 0; j < nb_elems; ++j) \ | ||
| 36 | buf[j] = buf2[j] = sign_extend(rnd(), nb_bits); \ | ||
| 37 | } while (0) | ||
| 38 | |||
| 39 | #define randomize_buffer_range(buf, min, max) \ | ||
| 40 | do { \ | ||
| 41 | for (size_t j = 0; j < FF_ARRAY_ELEMS(buf); ++j) \ | ||
| 42 | buf[j] = min + rnd() % (max - min + 1); \ | ||
| 43 | } while (0) | ||
| 44 | |||
| 45 | 14 | static void check_store_slice(void) | |
| 46 | { | ||
| 47 | enum { | ||
| 48 | MAX_WIDTH = 256, | ||
| 49 | /// in elements, not in bytes; 32 is arbitrary | ||
| 50 | MAX_STRIDE = MAX_WIDTH + 32, | ||
| 51 | MAX_HEIGHT = 8, | ||
| 52 | }; | ||
| 53 | FSPPDSPContext fspp; | ||
| 54 | 14 | ff_fsppdsp_init(&fspp); | |
| 55 | 14 | declare_func(void, uint8_t *dst, int16_t *src, | |
| 56 | ptrdiff_t dst_stride, ptrdiff_t src_stride, | ||
| 57 | ptrdiff_t width, ptrdiff_t height, ptrdiff_t log2_scale); | ||
| 58 | |||
| 59 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
|
42 | for (int i = 0; i < 2; ++i) { |
| 60 |
6/6✓ Branch 2 taken 14 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 14 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 24 times.
|
28 | if (check_func(i ? fspp.store_slice2 : fspp.store_slice, "store_slice%s", i ? "2" : "")) { |
| 61 | // store slice resets the row eight lines above the current one | ||
| 62 | DECLARE_ALIGNED(16, int16_t, src_ref1)[MAX_STRIDE * ( 8 + MAX_HEIGHT - 1) + MAX_WIDTH]; | ||
| 63 | DECLARE_ALIGNED(16, int16_t, src_new1)[MAX_STRIDE * ( 8 + MAX_HEIGHT - 1) + MAX_WIDTH]; | ||
| 64 | // store_slice2 resets the row 16 lines below the current one | ||
| 65 | DECLARE_ALIGNED(16, int16_t, src_ref2)[MAX_STRIDE * (16 + MAX_HEIGHT - 1) + MAX_WIDTH]; | ||
| 66 | DECLARE_ALIGNED(16, int16_t, src_new2)[MAX_STRIDE * (16 + MAX_HEIGHT - 1) + MAX_WIDTH]; | ||
| 67 | uint8_t dstbuf_new[MAX_STRIDE * (MAX_HEIGHT - 1) + MAX_WIDTH], dstbuf_ref[MAX_STRIDE * (MAX_HEIGHT - 1) + MAX_WIDTH]; | ||
| 68 | 4 | uint8_t *dst_new = dstbuf_new, *dst_ref = dstbuf_ref; | |
| 69 | int16_t *src_ref, *src_new, *or_src_ref, *or_src_new; | ||
| 70 | 4 | ptrdiff_t width = 1 + rnd() % MAX_WIDTH; | |
| 71 | 4 | ptrdiff_t src_stride = FFALIGN(width + 1 + rnd() % (MAX_STRIDE - MAX_WIDTH), 8); | |
| 72 | 4 | ptrdiff_t dst_stride = FFALIGN(width + 1 + rnd() % (MAX_STRIDE - MAX_WIDTH), 8); | |
| 73 | 4 | ptrdiff_t height = 1 + rnd() % 8; | |
| 74 | size_t nb_elems; | ||
| 75 | |||
| 76 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (i) { |
| 77 | 2 | src_ref = src_ref2; | |
| 78 | 2 | src_new = src_new2; | |
| 79 | 2 | or_src_ref = src_ref2; | |
| 80 | 2 | or_src_new = src_new2; | |
| 81 | 2 | nb_elems = FF_ARRAY_ELEMS(src_ref2); | |
| 82 | } else { | ||
| 83 | 2 | src_ref = src_ref1 + 8 * src_stride; | |
| 84 | 2 | src_new = src_new1 + 8 * src_stride; | |
| 85 | 2 | or_src_ref = src_ref1; | |
| 86 | 2 | or_src_new = src_new1; | |
| 87 | 2 | nb_elems = FF_ARRAY_ELEMS(src_ref1); | |
| 88 | } | ||
| 89 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 | if (rnd() & 1) { |
| 90 | 2 | dst_ref += dst_stride * (height - 1); | |
| 91 | 2 | dst_new += dst_stride * (height - 1); | |
| 92 | 2 | dst_stride *= -1; | |
| 93 | } | ||
| 94 |
2/2✓ Branch 1 taken 9088 times.
✓ Branch 2 taken 4 times.
|
9092 | randomize_buffers(dstbuf_new); |
| 95 | 4 | memcpy(dstbuf_ref, dstbuf_new, sizeof(dstbuf_ref)); | |
| 96 |
2/2✓ Branch 1 taken 22912 times.
✓ Branch 2 taken 4 times.
|
22916 | randomize_mask_buffers(or_src_ref, or_src_new, nb_elems, 14); |
| 97 | |||
| 98 | 4 | ptrdiff_t log2_scale = rnd() & 1; | |
| 99 | 4 | call_ref(dst_ref, src_ref, dst_stride, src_stride, width, height, log2_scale); | |
| 100 | 4 | call_new(dst_new, src_new, dst_stride, src_stride, width, height, log2_scale); | |
| 101 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (memcmp(dstbuf_new, dstbuf_ref, sizeof(dstbuf_ref)) || |
| 102 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | memcmp(or_src_ref, or_src_new, sizeof(*or_src_new) * nb_elems)) |
| 103 | ✗ | fail(); | |
| 104 | // don't use random parameters for benchmarks | ||
| 105 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | src_ref = or_src_ref + !i * 8 * MAX_STRIDE; |
| 106 |
1/8✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
|
4 | bench_new(dstbuf_new, src_ref, |
| 107 | MAX_STRIDE, MAX_STRIDE, MAX_WIDTH, 8, 1); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | 14 | } | |
| 111 | |||
| 112 | 14 | static void check_mul_thrmat(void) | |
| 113 | { | ||
| 114 | FSPPDSPContext fspp; | ||
| 115 | DECLARE_ALIGNED(16, int16_t, src)[64]; | ||
| 116 | DECLARE_ALIGNED(16, int16_t, dst_ref)[64]; | ||
| 117 | DECLARE_ALIGNED(16, int16_t, dst_new)[64]; | ||
| 118 | 14 | const int q = (uint8_t)rnd(); | |
| 119 | 14 | declare_func(void, const int16_t *thr_adr_noq, int16_t *thr_adr, int q); | |
| 120 | |||
| 121 | 14 | ff_fsppdsp_init(&fspp); | |
| 122 | |||
| 123 |
2/2✓ Branch 3 taken 2 times.
✓ Branch 4 taken 12 times.
|
14 | if (check_func(fspp.mul_thrmat, "mul_thrmat")) { |
| 124 |
2/2✓ Branch 1 taken 128 times.
✓ Branch 2 taken 2 times.
|
130 | randomize_buffers(src); |
| 125 | 2 | call_ref(src, dst_ref, q); | |
| 126 | 2 | call_new(src, dst_new, q); | |
| 127 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (memcmp(dst_ref, dst_new, sizeof(dst_ref))) |
| 128 | ✗ | fail(); | |
| 129 |
1/8✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
|
2 | bench_new(src, dst_new, q); |
| 130 | } | ||
| 131 | 14 | } | |
| 132 | |||
| 133 | 14 | static void check_column_fidct(void) | |
| 134 | { | ||
| 135 | enum { | ||
| 136 | NB_BLOCKS = 8, ///< arbitrary | ||
| 137 | }; | ||
| 138 | FSPPDSPContext fspp; | ||
| 139 | 14 | declare_func(void, const int16_t *thr_adr, const int16_t *data, | |
| 140 | int16_t *output, int cnt); | ||
| 141 | |||
| 142 | 14 | ff_fsppdsp_init(&fspp); | |
| 143 | |||
| 144 |
2/2✓ Branch 3 taken 2 times.
✓ Branch 4 taken 12 times.
|
14 | if (check_func(fspp.column_fidct, "column_fidct")) { |
| 145 | DECLARE_ALIGNED(16, int16_t, threshold)[64]; | ||
| 146 | DECLARE_ALIGNED(16, int16_t, src)[8*(8*NB_BLOCKS + 6)]; | ||
| 147 | DECLARE_ALIGNED(16, int16_t, dst_new)[8*(8*NB_BLOCKS + 6)]; | ||
| 148 | DECLARE_ALIGNED(16, int16_t, dst_ref)[8*(8*NB_BLOCKS + 6)]; | ||
| 149 | |||
| 150 |
2/2✓ Branch 1 taken 128 times.
✓ Branch 2 taken 2 times.
|
130 | randomize_buffer_range(threshold, 0, INT16_MAX); |
| 151 |
2/2✓ Branch 1 taken 1120 times.
✓ Branch 2 taken 2 times.
|
1122 | randomize_buffer_range(src, -1284, 1284); |
| 152 |
2/2✓ Branch 1 taken 1120 times.
✓ Branch 2 taken 2 times.
|
1122 | randomize_buffers(dst_new); |
| 153 | 2 | memcpy(dst_ref, dst_new, sizeof(dst_ref)); | |
| 154 | |||
| 155 | 2 | call_ref(threshold, src, dst_ref, NB_BLOCKS * 8); | |
| 156 | 2 | call_new(threshold, src, dst_new, NB_BLOCKS * 8); | |
| 157 | |||
| 158 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (memcmp(dst_new, dst_ref, sizeof(dst_new))) |
| 159 | ✗ | fail(); | |
| 160 | |||
| 161 |
1/8✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
|
2 | bench_new(threshold, src, dst_new, NB_BLOCKS * 8); |
| 162 | } | ||
| 163 | 14 | } | |
| 164 | |||
| 165 | 14 | void checkasm_check_vf_fspp(void) | |
| 166 | { | ||
| 167 | 14 | check_store_slice(); | |
| 168 | 14 | report("store_slice"); | |
| 169 | 14 | check_mul_thrmat(); | |
| 170 | 14 | report("mul_thrmat"); | |
| 171 | 14 | check_column_fidct(); | |
| 172 | 14 | report("column_fidct"); | |
| 173 | 14 | } | |
| 174 |