av_rescale_rnd进行单位换算,
av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)最基本的计算公式是:
a*b/c;
计算原理:
对一实物用单位b度量出来的值是a,那么用单位c来度量其值是多少?
设实物的真实值为x,用单位c度量的值为y,则有如下式满足:
x/a = b;
x/c = y;
所以有:a*b = c*y。进而得出:y = a*b/c
对换算后的数据有五种处理方法:
AV_ROUND_ZERO = 0, ///向下取整
AV_ROUND_INF = 1, ///向上取整
AV_ROUND_DOWN = 2, ///同AV_ROUND_ZERO,用于负数处理
AV_ROUND_UP = 3, ///同AV_ROUND_INF,用于负数处理
AV_ROUND_NEAR_INF = 5, ///四舍五入
如果rnd == AV_ROUND_NEAR_INF,那么 return a*b/c + r/c;r = c / 2,也即 return a*b/c + 0.5。
a*b/c | a*b/c + 0.5 | 浮点类型变为整数类型 |
0.4 | 0.9 | 0 |
0.6 | 1.1 | 1 |
如果rnd == AV_ROUND_INF,那么 return a*b/c + (c-1)/c。这种计算方法很常见,如内存对齐。还有诸如一个篮子能盛2个鸡蛋,问你3个鸡蛋需要几个篮子。a*b + (c-1)计算会把a*b产生不足c的小数据部分扩展到c的1倍多。这样小数据部分就会占用一个篮子。 (c-1)减号后面的1要求a*b计算出来的小1的部分会被丢弃。
a*b/3 | (a*b + (c-1))/3 | 浮点类型变为整数类型 |
1/3 | (1+2)/3 | 1 |
3/3 | (3+2)/3 | 1 |