av_reduce

22 篇文章 1 订阅
int av_reduce(int *dst_num, int *dst_den,

              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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值