FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/tests/checkasm/snowdsp.c
Date: 2026-05-02 21:46:34
Exec Total Coverage
Lines: 58 59 98.3%
Functions: 2 2 100.0%
Branches: 36 46 78.3%

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 <assert.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <string.h>
23
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/macros.h"
26 #include "libavutil/mem_internal.h"
27
28 #include "libavcodec/snow.h"
29 #include "libavcodec/snow_dwt.h"
30
31 #include "checkasm.h"
32
33 #define randomize_buffer(buf) \
34 do { \
35 for (size_t k = 0; k < (sizeof(buf) & ~3); k += 4) \
36 AV_WN32A((char*)buf + k, rnd()); \
37 for (size_t k = sizeof(buf) & ~3; k < sizeof(buf); ++k) \
38 ((char*)buf)[k] = rnd(); \
39 } while (0)
40
41 14 static void checkasm_check_inner_add_yblock(const SnowDWTContext *const snowdsp)
42 {
43 enum {
44 LOG2_MAX_BLOCKSIZE = 4,
45 MAX_BLOCKSIZE = 1 << LOG2_MAX_BLOCKSIZE,
46 LOG2_MIN_BLOCKSIZE = 1,
47 MAX_STRIDE = 256,
48 };
49 14 declare_func(void, const uint8_t *obmc, const int obmc_stride,
50 uint8_t **block, int b_w, int b_h, int src_x,
51 int src_stride, IDWTELEM * const *lines,
52 int add, uint8_t *dst8);
53 DECLARE_ALIGNED(16, uint8_t, dst8_ref)[MAX_STRIDE * MAX_BLOCKSIZE];
54 DECLARE_ALIGNED(16, uint8_t, dst8_new)[MAX_STRIDE * MAX_BLOCKSIZE];
55 DECLARE_ALIGNED(16, uint8_t, block)[4][MAX_STRIDE * (MAX_BLOCKSIZE - 1) + MAX_BLOCKSIZE];
56 DECLARE_ALIGNED(16, IDWTELEM, linebuf)[MAX_BLOCKSIZE][MAX_STRIDE];
57 14 int inited = 0;
58
59
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
42 for (int i = 0; i < 2; ++i) {
60
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 28 times.
140 for (int j = LOG2_MIN_BLOCKSIZE; j <= LOG2_MAX_BLOCKSIZE; ++j) {
61 112 int b_w = 1 << j;
62
63
4/4
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 5 taken 96 times.
✓ Branch 6 taken 16 times.
112 if (!check_func(snowdsp->inner_add_yblock, "inner_add_yblock_%d%s", b_w, i ? "_border" : ""))
64 96 continue;
65
66 16 const uint8_t *obmc = ff_obmc_tab[LOG2_MAX_BLOCKSIZE - j];
67 16 int obmc_stride = 2 << j;
68 16 int b_h = b_w, mb_x;
69 16 int width = 1 + rnd() % MAX_STRIDE;
70
71
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (!i) {
72 // Test the ordinary case of a complete block.
73 8 width = FFMAX(width, 2 * b_w);
74 8 int nb_complete_blocks = (width - b_w / 2) / b_w;
75 8 mb_x = 1 + rnd() % nb_complete_blocks;
76 } else {
77 // Test a boundary block. If width == b_w/2 mod b_w,
78 // there is no right boundary block, so use the left one.
79
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 3 times.
8 mb_x = (width + b_w/2) % b_w && rnd() & 1 ? (width + b_w/2) / b_w : 0;
80 }
81 16 ptrdiff_t src_stride = FFALIGN(width + rnd() % (MAX_STRIDE - width + 1), 16);
82 16 int src_x = b_w*mb_x - b_w/2;
83
84
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 if (src_x < 0) {
85 6 obmc -= src_x;
86 6 b_w += src_x;
87 6 src_x = 0;
88 }
89
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
16 if (src_x + b_w > width) {
90 2 b_w = width - src_x;
91 }
92
93 16 uint8_t *dst8p_ref = dst8_ref + src_x;
94 16 uint8_t *dst8p_new = dst8_new + src_x;
95 16 unsigned rand = rnd();
96 16 uint8_t *blocks[4] = { block[rand % 4], block[rand / 4 % 4],
97 16 block[rand / 16 % 4], block[rand / 64 % 4] };
98
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 6 times.
16 if (rnd() & 1) { // negate stride
99 10 dst8p_ref += (b_h - 1) * src_stride;
100 10 dst8p_new += (b_h - 1) * src_stride;
101 10 blocks[0] += (b_h - 1) * src_stride;
102 10 blocks[1] += (b_h - 1) * src_stride;
103 10 blocks[2] += (b_h - 1) * src_stride;
104 10 blocks[3] += (b_h - 1) * src_stride;
105 10 src_stride = -src_stride;
106 }
107 IDWTELEM *lines[MAX_BLOCKSIZE];
108
109
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 16 times.
136 for (int k = 0; k < b_h; ++k)
110 120 lines[k] = linebuf[rnd() % MAX_BLOCKSIZE];
111
112
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
16 if (!inited) {
113 2 inited = 1;
114
3/4
✓ Branch 1 taken 7712 times.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7714 randomize_buffer(block);
115
3/4
✓ Branch 1 taken 2048 times.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2050 randomize_buffer(dst8_ref);
116
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
34 for (size_t k = 0; k < FF_ARRAY_ELEMS(linebuf); ++k) {
117
2/2
✓ Branch 0 taken 8192 times.
✓ Branch 1 taken 32 times.
8224 for (size_t l = 0; l < FF_ARRAY_ELEMS(linebuf[0]); ++l)
118 8192 linebuf[k][l] = sign_extend(rnd(), 15);
119 }
120 }
121
122 16 memcpy(dst8_new, dst8_ref, sizeof(dst8_new));
123
124 16 call_ref(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, lines, 1, dst8p_ref);
125 16 call_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, lines, 1, dst8p_new);
126
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (memcmp(dst8_ref, dst8_new, sizeof(dst8_new)))
128 fail();
129
130
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 16 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.
16 bench_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, lines, 1, dst8p_new);
131 }
132 }
133 14 report("inner_add_yblock");
134 14 }
135
136 14 void checkasm_check_snowdsp(void)
137 {
138 SnowDWTContext snowdsp;
139
140 14 ff_dwt_init(&snowdsp);
141
142 14 checkasm_check_inner_add_yblock(&snowdsp);
143 14 }
144