FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/tests/checkasm/sw_range_convert.c
Date: 2025-01-20 09:27:23
Exec Total Coverage
Lines: 125 133 94.0%
Functions: 4 4 100.0%
Branches: 77 104 74.0%

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 <string.h>
20
21 #include "libavutil/common.h"
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/mem.h"
24 #include "libavutil/mem_internal.h"
25
26 #include "libswscale/swscale.h"
27 #include "libswscale/swscale_internal.h"
28
29 #include "checkasm.h"
30
31 static const enum AVPixelFormat pixel_formats[] = {
32 AV_PIX_FMT_YUV444P,
33 AV_PIX_FMT_YUV444P9,
34 AV_PIX_FMT_YUV444P10,
35 AV_PIX_FMT_YUV444P12,
36 AV_PIX_FMT_YUV444P14,
37 AV_PIX_FMT_YUV444P16,
38 };
39
40 216 static void randomize_buffers(int16_t *buf0, int16_t *buf1, int bit_depth, int width)
41 {
42 216 int32_t *buf0_32 = (int32_t *) buf0;
43 216 int32_t *buf1_32 = (int32_t *) buf1;
44 216 int mask = (1 << bit_depth) - 1;
45
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 36 times.
216 int src_shift = bit_depth <= 14 ? 15 - bit_depth : 19 - bit_depth;
46
2/2
✓ Branch 0 taken 208224 times.
✓ Branch 1 taken 216 times.
208440 for (int i = 0; i < width; i++) {
47 208224 int32_t r = rnd() & mask;
48
2/2
✓ Branch 0 taken 34704 times.
✓ Branch 1 taken 173520 times.
208224 if (bit_depth == 16) {
49 34704 buf0_32[i] = r << src_shift;
50 34704 buf1_32[i] = r << src_shift;
51 } else {
52 173520 buf0[i] = r << src_shift;
53 173520 buf1[i] = r << src_shift;
54 }
55 }
56 216 }
57
58 26 static void check_lumConvertRange(int from)
59 {
60
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 const char *func_str = from ? "lumRangeFromJpeg" : "lumRangeToJpeg";
61 #define LARGEST_INPUT_SIZE 1920
62 static const int input_sizes[] = {8, LARGEST_INPUT_SIZE};
63 SwsContext *sws;
64 SwsInternal *c;
65
66 26 LOCAL_ALIGNED_32(int16_t, dst0, [LARGEST_INPUT_SIZE * 2]);
67 26 LOCAL_ALIGNED_32(int16_t, dst1, [LARGEST_INPUT_SIZE * 2]);
68 26 int32_t *dst0_32 = (int32_t *) dst0;
69 26 int32_t *dst1_32 = (int32_t *) dst1;
70
71 26 declare_func(void, int16_t *dst, int width,
72 uint32_t coeff, int64_t offset);
73
74 26 sws = sws_alloc_context();
75
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (sws_init_context(sws, NULL, NULL) < 0)
76 fail();
77
78 26 c = sws_internal(sws);
79 26 sws->src_range = from;
80 26 sws->dst_range = !from;
81
82
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 26 times.
182 for (int pfi = 0; pfi < FF_ARRAY_ELEMS(pixel_formats); pfi++) {
83 156 enum AVPixelFormat pix_fmt = pixel_formats[pfi];
84 156 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
85 156 int bit_depth = desc->comp[0].depth;
86
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 130 times.
156 int sample_size = bit_depth == 16 ? sizeof(int32_t) : sizeof(int16_t);
87
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 26 times.
156 int src_shift = bit_depth <= 14 ? 15 - bit_depth : 19 - bit_depth;
88 156 int mpeg_min = 16 << (bit_depth - 8);
89 156 int mpeg_max = 235 << (bit_depth - 8);
90 156 int jpeg_max = (1 << bit_depth) - 1;
91 156 sws->src_format = pix_fmt;
92 156 sws->dst_format = pix_fmt;
93 156 c->dstBpc = bit_depth;
94 156 ff_sws_init_scale(c);
95
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 156 times.
468 for (int dstWi = 0; dstWi < FF_ARRAY_ELEMS(input_sizes); dstWi++) {
96 312 int width = input_sizes[dstWi];
97
2/2
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 240 times.
312 if (check_func(c->lumConvertRange, "%s%d_%d", func_str, bit_depth, width)) {
98 72 randomize_buffers(dst0, dst1, bit_depth, width);
99
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 60 times.
72 if (bit_depth == 16) {
100
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (!from) {
101 6 dst1_32[0] = dst0_32[0] = mpeg_min << src_shift;
102 6 dst1_32[1] = dst0_32[1] = mpeg_max << src_shift;
103 }
104 12 dst1_32[2] = dst0_32[2] = -1;
105 } else {
106
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
60 if (!from) {
107 30 dst1[0] = dst0[0] = mpeg_min << src_shift;
108 30 dst1[1] = dst0[1] = mpeg_max << src_shift;
109 }
110 60 dst1[2] = dst0[2] = -1;
111 }
112 72 call_ref(dst0, width,
113 c->lumConvertRange_coeff, c->lumConvertRange_offset);
114 72 call_new(dst1, width,
115 c->lumConvertRange_coeff, c->lumConvertRange_offset);
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (memcmp(dst0, dst1, width * sample_size))
117 fail();
118
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
72 if (!from) {
119 /* check that the mpeg range is respected */
120
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
36 if (bit_depth == 16) {
121
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if ((dst1_32[0] >> src_shift) > 0 || (dst1_32[1] >> src_shift) != jpeg_max)
122 fail();
123 } else {
124
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 if ((dst1[0] >> src_shift) > 0 || (dst1[1] >> src_shift) != jpeg_max)
125 fail();
126 }
127 }
128
6/6
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 24 times.
72 if (width == LARGEST_INPUT_SIZE && (bit_depth == 8 || bit_depth == 16))
129
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
12 bench_new(dst1, width,
130 c->lumConvertRange_coeff, c->lumConvertRange_offset);
131 }
132 }
133 }
134
135 26 sws_freeContext(sws);
136 26 }
137 #undef LARGEST_INPUT_SIZE
138
139 26 static void check_chrConvertRange(int from)
140 {
141
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 const char *func_str = from ? "chrRangeFromJpeg" : "chrRangeToJpeg";
142 #define LARGEST_INPUT_SIZE 1920
143 static const int input_sizes[] = {8, LARGEST_INPUT_SIZE};
144 SwsContext *sws;
145 SwsInternal *c;
146
147 26 LOCAL_ALIGNED_32(int16_t, dstU0, [LARGEST_INPUT_SIZE * 2]);
148 26 LOCAL_ALIGNED_32(int16_t, dstV0, [LARGEST_INPUT_SIZE * 2]);
149 26 LOCAL_ALIGNED_32(int16_t, dstU1, [LARGEST_INPUT_SIZE * 2]);
150 26 LOCAL_ALIGNED_32(int16_t, dstV1, [LARGEST_INPUT_SIZE * 2]);
151 26 int32_t *dstU0_32 = (int32_t *) dstU0;
152 26 int32_t *dstU1_32 = (int32_t *) dstU1;
153
154 26 declare_func(void, int16_t *dstU, int16_t *dstV, int width,
155 uint32_t coeff, int64_t offset);
156
157 26 sws = sws_alloc_context();
158
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (sws_init_context(sws, NULL, NULL) < 0)
159 fail();
160
161 26 c = sws_internal(sws);
162 26 sws->src_range = from;
163 26 sws->dst_range = !from;
164
165
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 26 times.
182 for (int pfi = 0; pfi < FF_ARRAY_ELEMS(pixel_formats); pfi++) {
166 156 enum AVPixelFormat pix_fmt = pixel_formats[pfi];
167 156 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
168 156 int bit_depth = desc->comp[0].depth;
169
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 130 times.
156 int sample_size = bit_depth == 16 ? sizeof(int32_t) : sizeof(int16_t);
170
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 26 times.
156 int src_shift = bit_depth <= 14 ? 15 - bit_depth : 19 - bit_depth;
171 156 int mpeg_min = 16 << (bit_depth - 8);
172 156 int mpeg_max = 240 << (bit_depth - 8);
173 156 int jpeg_max = (1 << bit_depth) - 1;
174 156 sws->src_format = pix_fmt;
175 156 sws->dst_format = pix_fmt;
176 156 c->dstBpc = bit_depth;
177 156 ff_sws_init_scale(c);
178
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 156 times.
468 for (int dstWi = 0; dstWi < FF_ARRAY_ELEMS(input_sizes); dstWi++) {
179 312 int width = input_sizes[dstWi];
180
2/2
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 240 times.
312 if (check_func(c->chrConvertRange, "%s%d_%d", func_str, bit_depth, width)) {
181 72 randomize_buffers(dstU0, dstU1, bit_depth, width);
182 72 randomize_buffers(dstV0, dstV1, bit_depth, width);
183
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 60 times.
72 if (bit_depth == 16) {
184
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (!from) {
185 6 dstU1_32[0] = dstU0_32[0] = mpeg_min << src_shift;
186 6 dstU1_32[1] = dstU0_32[1] = mpeg_max << src_shift;
187 }
188 12 dstU1_32[2] = dstU0_32[2] = -1;
189 } else {
190
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
60 if (!from) {
191 30 dstU1[0] = dstU0[0] = mpeg_min << src_shift;
192 30 dstU1[1] = dstU0[1] = mpeg_max << src_shift;
193 }
194 60 dstU1[2] = dstU0[2] = -1;
195 }
196 72 call_ref(dstU0, dstV0, width,
197 c->chrConvertRange_coeff, c->chrConvertRange_offset);
198 72 call_new(dstU1, dstV1, width,
199 c->chrConvertRange_coeff, c->chrConvertRange_offset);
200
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if (memcmp(dstU0, dstU1, width * sample_size) ||
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 memcmp(dstV0, dstV1, width * sample_size))
202 fail();
203
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
72 if (!from) {
204 /* check that the mpeg range is respected */
205
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
36 if (bit_depth == 16) {
206
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if ((dstU1_32[0] >> src_shift) > 0 || (dstU1_32[1] >> src_shift) != jpeg_max)
207 fail();
208 } else {
209
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 if ((dstU1[0] >> src_shift) > 0 || (dstU1[1] >> src_shift) != jpeg_max)
210 fail();
211 }
212 }
213
6/6
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 24 times.
72 if (width == LARGEST_INPUT_SIZE && (bit_depth == 8 || bit_depth == 16))
214
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
12 bench_new(dstU1, dstV1, width,
215 c->chrConvertRange_coeff, c->chrConvertRange_offset);
216 }
217 }
218 }
219
220 26 sws_freeContext(sws);
221 26 }
222 #undef LARGEST_INPUT_SIZE
223
224 13 void checkasm_check_sw_range_convert(void)
225 {
226 13 check_lumConvertRange(1);
227 13 report("lumRangeFromJpeg");
228 13 check_chrConvertRange(1);
229 13 report("chrRangeFromJpeg");
230 13 check_lumConvertRange(0);
231 13 report("lumRangeToJpeg");
232 13 check_chrConvertRange(0);
233 13 report("chrRangeToJpeg");
234 13 }
235