FFmpeg
Loading...
Searching...
No Matches
mathematics.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (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 GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <inttypes.h>
20#include <stdint.h>
21#include <stdio.h>
22
23#include "libavutil/avutil.h"
24#include "libavutil/macros.h"
26#include "libavutil/rational.h"
27
28int main(void)
29{
30 int64_t last;
31
32 /* av_gcd */
33 printf("Testing av_gcd()\n");
34 static const struct { int64_t a, b, expected; } gcd_tests[] = {
35 { 0, 0, 0 },
36 { 1, 0, 1 },
37 { 0, 1, 1 },
38 { 6, 4, 2 },
39 { 12, 8, 4 },
40 { 17, 13, 1 },
41 { 100, 75, 25 },
42 { -6, 4, 2 },
43 { 6, -4, 2 },
44 };
45 for (int i = 0; i < FF_ARRAY_ELEMS(gcd_tests); i++)
46 printf("gcd(%"PRId64", %"PRId64") = %"PRId64" %s\n",
47 gcd_tests[i].a, gcd_tests[i].b,
48 av_gcd(gcd_tests[i].a, gcd_tests[i].b),
49 av_gcd(gcd_tests[i].a, gcd_tests[i].b) == gcd_tests[i].expected ? "OK" : "FAIL");
50
51 /* av_rescale */
52 printf("\nTesting av_rescale()\n");
53 printf("rescale(6, 3, 2) = %"PRId64"\n", av_rescale(6, 3, 2));
54 printf("rescale(0, 3, 2) = %"PRId64"\n", av_rescale(0, 3, 2));
55 printf("rescale(1, 1, 1) = %"PRId64"\n", av_rescale(1, 1, 1));
56 printf("rescale(-6, 3, 2) = %"PRId64"\n", av_rescale(-6, 3, 2));
57 printf("rescale(90000, 1, 90000) = %"PRId64"\n", av_rescale(90000, 1, 90000));
58
59 /* av_rescale_rnd with different rounding modes */
60 printf("\nTesting av_rescale_rnd()\n");
61 static const struct {
62 int64_t a, b, c;
63 enum AVRounding rnd;
64 int64_t expected;
65 } rnd_tests[] = {
66 { 7, 1, 2, AV_ROUND_ZERO, 3 },
67 { 7, 1, 2, AV_ROUND_INF, 4 },
68 { 7, 1, 2, AV_ROUND_DOWN, 3 },
69 { 7, 1, 2, AV_ROUND_UP, 4 },
70 { 7, 1, 2, AV_ROUND_NEAR_INF, 4 },
71 { -7, 1, 2, AV_ROUND_ZERO, -3 },
72 { -7, 1, 2, AV_ROUND_INF, -4 },
73 { -7, 1, 2, AV_ROUND_DOWN, -4 },
74 { -7, 1, 2, AV_ROUND_UP, -3 },
75 { 6, 1, 2, AV_ROUND_NEAR_INF, 3 },
76 };
77 for (int i = 0; i < FF_ARRAY_ELEMS(rnd_tests); i++) {
78 int64_t r = av_rescale_rnd(rnd_tests[i].a, rnd_tests[i].b,
79 rnd_tests[i].c, rnd_tests[i].rnd);
80 printf("rescale_rnd(%"PRId64", %"PRId64", %"PRId64", %d) = %"PRId64" %s\n",
81 rnd_tests[i].a, rnd_tests[i].b, rnd_tests[i].c,
82 rnd_tests[i].rnd, r,
83 r == rnd_tests[i].expected ? "OK" : "FAIL");
84 }
85
86 /* AV_ROUND_PASS_MINMAX */
87 printf("\nTesting AV_ROUND_PASS_MINMAX\n");
88 printf("INT64_MIN passthrough: %s\n",
89 av_rescale_rnd(INT64_MIN, 1, 2,
90 AV_ROUND_UP | AV_ROUND_PASS_MINMAX) == INT64_MIN ? "OK" : "FAIL");
91 printf("INT64_MAX passthrough: %s\n",
92 av_rescale_rnd(INT64_MAX, 1, 2,
93 AV_ROUND_UP | AV_ROUND_PASS_MINMAX) == INT64_MAX ? "OK" : "FAIL");
94 printf("normal with PASS_MINMAX: %"PRId64"\n",
96
97 /* large value rescale (exercises 128-bit multiply path) */
98 printf("\nTesting large value rescale\n");
99 printf("rescale(INT64_MAX/2, 2, 1) = %"PRId64"\n",
100 av_rescale_rnd(INT64_MAX / 2, 2, 1, AV_ROUND_ZERO));
101 printf("rescale(1000000007, 1000000009, 1000000007) = %"PRId64"\n",
102 av_rescale(1000000007LL, 1000000009LL, 1000000007LL));
103 /* b and c both > INT_MAX triggers 128-bit multiply */
104 printf("rescale_rnd(10, INT_MAX+1, INT_MAX+1, ZERO) = %"PRId64"\n",
105 av_rescale_rnd(10, (int64_t)INT32_MAX + 1, (int64_t)INT32_MAX + 1, AV_ROUND_ZERO));
106 printf("rescale_rnd(7, 3000000000, 2000000000, NEAR_INF) = %"PRId64"\n",
107 av_rescale_rnd(7, 3000000000LL, 2000000000LL, AV_ROUND_NEAR_INF));
108
109 /* av_rescale_q */
110 printf("\nTesting av_rescale_q()\n");
111 printf("rescale_q(90000, 1/90000, 1/1000) = %"PRId64"\n",
112 av_rescale_q(90000, (AVRational){1, 90000}, (AVRational){1, 1000}));
113 printf("rescale_q(48000, 1/48000, 1/44100) = %"PRId64"\n",
114 av_rescale_q(48000, (AVRational){1, 48000}, (AVRational){1, 44100}));
115
116 /* av_compare_ts */
117 printf("\nTesting av_compare_ts()\n");
118 printf("compare(1, 1/1, 1, 1/1) = %d\n",
119 av_compare_ts(1, (AVRational){1, 1}, 1, (AVRational){1, 1}));
120 printf("compare(1, 1/1, 2, 1/1) = %d\n",
121 av_compare_ts(1, (AVRational){1, 1}, 2, (AVRational){1, 1}));
122 printf("compare(2, 1/1, 1, 1/1) = %d\n",
123 av_compare_ts(2, (AVRational){1, 1}, 1, (AVRational){1, 1}));
124 printf("compare(1, 1/1000, 1, 1/90000) = %d\n",
125 av_compare_ts(1, (AVRational){1, 1000}, 1, (AVRational){1, 90000}));
126 /* large values trigger rescale-based comparison path */
127 printf("compare(INT64_MAX/2, 1/1, INT64_MAX/3, 1/1) = %d\n",
128 av_compare_ts(INT64_MAX / 2, (AVRational){1, 1},
129 INT64_MAX / 3, (AVRational){1, 1}));
130
131 /* av_compare_mod */
132 printf("\nTesting av_compare_mod()\n");
133 printf("compare_mod(3, 1, 16) = %"PRId64"\n", av_compare_mod(3, 1, 16));
134 printf("compare_mod(1, 3, 16) = %"PRId64"\n", av_compare_mod(1, 3, 16));
135 printf("compare_mod(5, 5, 16) = %"PRId64"\n", av_compare_mod(5, 5, 16));
136
137 /* av_rescale_delta */
138 printf("\nTesting av_rescale_delta()\n");
139 last = AV_NOPTS_VALUE;
140 for (int i = 0; i < 4; i++)
141 printf("delta step %d: %"PRId64"\n", i,
142 av_rescale_delta((AVRational){1, 48000}, i * 1024,
143 (AVRational){1, 48000}, 1024,
144 &last, (AVRational){1, 44100}));
145 /* trigger clip-based path: use different in_tb and fs_tb */
146 last = AV_NOPTS_VALUE;
147 for (int i = 0; i < 4; i++)
148 printf("delta clip %d: %"PRId64"\n", i,
149 av_rescale_delta((AVRational){1, 44100}, i * 940,
150 (AVRational){1, 48000}, 1024,
151 &last, (AVRational){1, 90000}));
152
153 /* av_add_stable */
154 printf("\nTesting av_add_stable()\n");
155 printf("add_stable(0, 1/1, 1/1000, 500) = %"PRId64"\n",
156 av_add_stable((AVRational){1, 1}, 0, (AVRational){1, 1000}, 500));
157 printf("add_stable(1000, 1/90000, 1/48000, 1024) = %"PRId64"\n",
158 av_add_stable((AVRational){1, 90000}, 1000, (AVRational){1, 48000}, 1024));
159 /* non-exact division path (m >= d, general case) */
160 printf("add_stable(0, 1/48000, 1/90000, 90000) = %"PRId64"\n",
161 av_add_stable((AVRational){1, 48000}, 0, (AVRational){1, 90000}, 90000));
162 printf("add_stable(100, 1/1000, 1/90000, 3000) = %"PRId64"\n",
163 av_add_stable((AVRational){1, 1000}, 100, (AVRational){1, 90000}, 3000));
164 /* repeated addition: verify no rounding error accumulation */
165 {
166 int64_t ts = 0;
167 for (int i = 0; i < 10000; i++)
168 ts = av_add_stable((AVRational){1, 48000}, ts, (AVRational){1, 48000}, 1024);
169 printf("add_stable 10000x1024 at 1/48000: %"PRId64" (expected %"PRId64") %s\n",
170 ts, (int64_t)10000 * 1024,
171 ts == (int64_t)10000 * 1024 ? "OK" : "FAIL");
172 }
173
174 return 0;
175}
Convenience header that includes libavutil's core.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define rnd
Definition checkasm.h:135
long long int64_t
Definition coverity.c:34
__device__ int printf(const char *,...)
int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc)
Add a value to a timestamp.
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb)
Rescale a timestamp while preserving known durations.
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition mathematics.c:58
AVRounding
Rounding methods.
int64_t av_gcd(int64_t a, int64_t b)
Compute the greatest common divisor of two integer operands.
Definition mathematics.c:37
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod)
Compare the remainders of two integer operands divided by a common divisor.
@ AV_ROUND_INF
Round away from zero.
@ AV_ROUND_ZERO
Round toward zero.
@ AV_ROUND_DOWN
Round toward -infinity.
@ AV_ROUND_PASS_MINMAX
Flag telling rescaling functions to pass INT64_MIN/MAX through unchanged, avoiding special cases for ...
@ AV_ROUND_UP
Round toward +infinity.
@ AV_ROUND_NEAR_INF
Round to nearest and halfway cases away from zero.
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
int a
#define r
Definition input.c:42
#define b
Definition input.c:43
Utility Preprocessor macros.
Utilities for rational number calculation.
#define FF_ARRAY_ELEMS(a)
Rational number (pair of numerator and denominator).
Definition rational.h:58
int main(void)
Definition mathematics.c:28
static double c[64]