FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/tests/rational64.c
Date: 2026-09-30 10:56:58
Exec Total Coverage
Lines: 44 72 61.1%
Functions: 1 1 100.0%
Branches: 45 58 77.6%

Line Branch Exec Source
1 /*
2 * rational numbers
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "libswscale/rational64.c"
22 #include "libavutil/integer.h"
23 #include "libavutil/intfloat.h"
24 #include "libavutil/log.h"
25 #include "libavutil/macros.h"
26
27 1 int main(void)
28 {
29 AVRational64 a64,b64,r64;
30 int i;
31 1 int ret = 0;
32
33
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (a64.num = -2; a64.num <= 2; a64.num++) {
34
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 5 times.
30 for (a64.den = -2; a64.den <= 2; a64.den++) {
35
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 25 times.
150 for (b64.num = -2; b64.num <= 2; b64.num++) {
36
2/2
✓ Branch 0 taken 625 times.
✓ Branch 1 taken 125 times.
750 for (b64.den = -2; b64.den <= 2; b64.den++) {
37 625 const double adbl = ff_q2d_64(a64);
38 625 const double bdbl = ff_q2d_64(b64);
39 625 const int c = ff_cmp_q64(a64,b64);
40
2/2
✓ Branch 0 taken 553 times.
✓ Branch 1 taken 72 times.
1178 const int d = adbl == bdbl ? 0 :
41
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 301 times.
854 adbl > bdbl ? 1 :
42
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 49 times.
301 adbl < bdbl ? -1 : INT_MIN;
43
44
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 625 times.
625 if (c != d) {
45 ✗ av_log(NULL, AV_LOG_ERROR, "%lld/%lld %lld/%lld, %d != %d\n",
46 ✗ (long long) a64.num, (long long) a64.den,
47 ✗ (long long) b64.num, (long long) b64.den, c,d);
48 ✗ ret = 1;
49 }
50
51 // Check arithmetic result
52
4/4
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 125 times.
✓ Branch 2 taken 400 times.
✓ Branch 3 taken 100 times.
625 if (a64.den && b64.den) {
53 double rdbl;
54
55 400 r64 = ff_add_q64(a64, b64);
56 400 rdbl = ff_q2d_64(r64);
57
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
400 if (rdbl != adbl + bdbl) {
58 ✗ av_log(NULL, AV_LOG_ERROR, "%f + %f = %f != %f\n",
59 adbl, bdbl, rdbl, adbl + bdbl);
60 ✗ ret = 1;
61 }
62
63 400 r64 = ff_mul_q64(a64, b64);
64 400 rdbl = ff_q2d_64(r64);
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
400 if (rdbl != adbl * bdbl) {
66 ✗ av_log(NULL, AV_LOG_ERROR, "%f * %f = %f != %f\n",
67 adbl, bdbl, rdbl, adbl * bdbl);
68 ✗ ret = 1;
69 }
70 }
71
72 // Check addition round-trip
73 625 r64 = ff_sub_q64(ff_add_q64(a64, b64), b64);
74
3/4
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 125 times.
✓ Branch 2 taken 500 times.
✗ Branch 3 not taken.
625 if (b64.den && (r64.num*a64.den != a64.num*r64.den ||
75
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 !r64.num != !a64.num ||
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 500 times.
500 !r64.den != !a64.den))
77 {
78 ✗ av_log(NULL, AV_LOG_ERROR, "%lld/%lld != %lld/%lld\n",
79 ✗ (long long) a64.num, (long long) a64.den,
80 ✗ (long long) r64.num, (long long) r64.den);
81 ✗ ret = 1;
82 }
83
84
2/2
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 125 times.
625 if (b64.num) {
85 // Check multiplication round-trip
86 500 r64 = ff_div_q64(ff_mul_q64(a64, b64), b64);
87
3/4
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
500 if (b64.den && (r64.num*a64.den != a64.num*r64.den ||
88
1/2
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
400 !r64.num != !a64.num ||
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
400 !r64.den != !a64.den))
90 {
91 ✗ av_log(NULL, AV_LOG_ERROR, "%lld/%lld != %lld/%lld\n",
92 ✗ (long long) a64.num, (long long) a64.den,
93 ✗ (long long) r64.num, (long long) r64.den);
94 ✗ ret = 1;
95 }
96 }
97 }
98 }
99 }
100 }
101
102 /* Check overflow behavior and edge cases */
103 static const AVRational64 unit_mul_q64[][3] = {
104 {{INT64_MAX, 2}, { 2, 1}, { INT64_MAX, 1}},
105 {{INT64_MAX, 2}, {-2, 1}, {-INT64_MAX, 1}},
106 {{INT64_MAX, 2}, { 0, 1}, {0, 1}},
107 {{INT64_MIN, 2}, { 2, 1}, {-INT64_MAX, 1}}, /* not INT64_MIN */
108 {{INT64_MIN, 2}, {-2, 1}, { INT64_MAX, 1}},
109 {{INT64_MIN, 2}, { 0, 1}, {0, 1}},
110 {{INT64_MAX >> 8, 1}, {INT64_MAX >> 8, 1}, {INT64_MAX, 1}},
111 {{1, INT64_MAX >> 8}, {1, INT64_MAX >> 8}, {0, 1}},
112 {{1, 1}, {0, 0}, {0, 0}},
113 {{0, 1}, {0, 0}, {0, 0}},
114 };
115
116
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 for (i = 0; i < FF_ARRAY_ELEMS(unit_mul_q64); i++) {
117
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int c = 0; c < 2; c++) { /* test commutativity */
118 20 AVRational64 a = unit_mul_q64[i][c ? 1 : 0];
119 20 AVRational64 b = unit_mul_q64[i][c ? 0 : 1];
120 20 AVRational64 c = unit_mul_q64[i][2];
121 20 AVRational64 r = ff_mul_q64(a, b);
122
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
20 if (r.num != c.num || r.den != c.den) {
123 ✗ av_log(NULL, AV_LOG_ERROR, "%lld/%lld * %lld/%lld = %lld/%lld, expected %lld/%lld\n",
124 ✗ (long long) a.num, (long long) a.den,
125 ✗ (long long) b.num, (long long) b.den,
126 ✗ (long long) r.num, (long long) r.den,
127 ✗ (long long) c.num, (long long) c.den);
128 ✗ ret = 1;
129 }
130 }
131 }
132
133 static const AVRational64 unit_add_q64[][3] = {
134 {{INT64_MAX, 1}, { 2, 2}, { INT64_MAX, 1}},
135 {{INT64_MAX, 1}, {-2, 2}, { INT64_MAX - 1, 1}},
136 {{INT64_MAX, 1}, { 0, 2}, { INT64_MAX, 1}},
137 {{INT64_MIN, 1}, { 2, 2}, {-INT64_MAX, 1}},
138 {{INT64_MIN, 1}, {-2, 2}, {-INT64_MAX, 1}},
139 {{INT64_MIN, 1}, { 0, 2}, {-INT64_MAX, 1}},
140 {{INT64_MAX - 10, 1}, {20, 1}, { INT64_MAX, 1}},
141 {{2, INT64_MAX}, {2, INT64_MAX}, {4, INT64_MAX}},
142 {{1, 1}, {0, 0}, {0, 0}},
143 {{0, 1}, {0, 0}, {0, 0}},
144 };
145
146
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 for (i = 0; i < FF_ARRAY_ELEMS(unit_add_q64); i++) {
147
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int c = 0; c < 2; c++) { /* test commutativity */
148 20 AVRational64 a = unit_add_q64[i][c ? 1 : 0];
149 20 AVRational64 b = unit_add_q64[i][c ? 0 : 1];
150 20 AVRational64 c = unit_add_q64[i][2];
151 20 AVRational64 r = ff_add_q64(a, b);
152
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
20 if (r.num != c.num || r.den != c.den) {
153 ✗ av_log(NULL, AV_LOG_ERROR, "%lld/%lld + %lld/%lld = %lld/%lld, expected %lld/%lld\n",
154 ✗ (long long) a.num, (long long) a.den,
155 ✗ (long long) b.num, (long long) b.den,
156 ✗ (long long) r.num, (long long) r.den,
157 ✗ (long long) c.num, (long long) c.den);
158 ✗ ret = 1;
159 }
160 }
161 }
162
163 1 return ret;
164 }
165