av_reduce
来源:互联网 发布:可以做生意的软件 编辑:程序博客网 时间:2024/04/30 09:09
int64_t num, int64_t den, int64_t max)
根据num 和den 计算两个数字的比例值,保存到dst_num和dst_den里面。
int av_reduce(int *dst_num, int *dst_den,
int64_t num, int64_t den, int64_t max)
{
AVRational a0 = { 0, 1 }, a1 = { 1, 0 };
int sign = (num < 0) ^ (den < 0);
//计算num和den的最大公约数
int64_t gcd = av_gcd(FFABS(num), FFABS(den));
//如果最大公约数不为零,则将num和den同时除以 最大公约数
if (gcd) {
num = FFABS(num) / gcd;
den = FFABS(den) / gcd;
}
//判断刚才计算的两个值是否大约max
if (num <= max && den <= max) {
a1 = (AVRational) { num, den };
den = 0;
}
while (den) {
uint64_t x = num / den;
int64_t next_den = num - den * x;
int64_t a2n = x * a1.num + a0.num;
int64_t a2d = x * a1.den + a0.den;
if (a2n > max || a2d > max) {
if (a1.num) x = (max - a0.num) / a1.num;
if (a1.den) x = FFMIN(x, (max - a0.den) / a1.den);
if (den * (2 * x * a1.den + a0.den) > num * a1.den)
a1 = (AVRational) { x * a1.num + a0.num, x * a1.den + a0.den };
break;
}
a0 = a1;
a1 = (AVRational) { a2n, a2d };
num = den;
den = next_den;
}
av_assert2(av_gcd(a1.num, a1.den) <= 1U);
av_assert2(a1.num <= max && a1.den <= max);
//将获取的值返回
*dst_num = sign ? -a1.num : a1.num;
*dst_den = a1.den;
return den == 0;
}