转自:http://blog.csdn.net/fireroll/article/details/8485482
一、函数声明:
-
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd);
直接看代码, 它的作用是计算 "a * b / c" 的值并分五种方式来取整.
用在FFmpeg中,
则是将以 "时钟基c" 表示的 数值a 转换成以 "时钟基b" 来表示。
一共有5种方式:
-
AV_ROUND_ZERO = 0,
-
AV_ROUND_INF = 1,
-
AV_ROUND_DOWN = 2,
-
AV_ROUND_UP = 3,
-
AV_ROUND_NEAR_INF = 5,
-
二、函数定义(见于libavutil/mathematics.c):
-
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
-
{
-
int64_t r=0;
-
assert(c > 0);
-
assert(b >=0);
-
assert((unsigned)rnd<=5 && rnd!=4);
-
-
-
"color:#009900;">
-
if (a<0 && a != INT64_MIN)
-
return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1));
-
-
-
if (rnd==AV_ROUND_NEAR_INF)
-
r= c / 2;
-
else if (rnd&1)
-
r= c - 1;
-
-
-
if (b<=INT_MAX && c<=INT_MAX)
-
{
-
"color:#33cc00;">
-
if (a<=INT_MAX)
-
return (a * b + r)/c;
-
else
-
return a/c*b + (a%c*b + r)/c;
-
}
-
else
-
{
-
"color:#009900;">
-
uint64_t a0= a&0xFFFFFFFF;
-
uint64_t a1= a>>32;
-
uint64_t b0= b&0xFFFFFFFF;
-
uint64_t b1= b>>32;
-
uint64_t t1= a0*b1 + a1*b0;
-
uint64_t t1a= t1<<32;
-
int i;
-
-
-
a0 = a0*b0 + t1a;
-
a1 = a1*b1 + (t1>>32) + (a0
-
a0 += r;
-
a1 += a0
-
-
-
for (i=63; i>=0; i--)
-
{
-
a1+= a1 + ((a0>>i)&1);
-
t1+=t1;
-
if (c <= a1)
-
{
-
a1 -= c;
-
t1++;
-
}
-
}
-
}
-
return t1;
-
}
三、实例分析
将以"1MHz时钟基" 表示的 "PTS/DTS值a" 转换成以 "90kHz时钟基" 表示。
-
av_rescale_q(a=-10949117256,
-
bq={num=1, den=1000000},
-
cq={num=1, den=90000))
-
{
-
int64_t b= bq.num * (int64_t)cq.den;
-
int64_t c= cq.num * (int64_t)bq.den;
-
return av_rescale_rnd(a, b, c, 5);
-
}
-
-
-
av_rescale_rnd(a=10949117256, b=90000, c=1000000, rnd=5)
-
{
-
if (rnd==5)
-
r = c / 2;
-
-
if (b<=INT_MAX && c<=INT_MAX)
-
{
-
if (a<=INT_MAX)
-
return (a * b + r)/c;
-
else
-
return a/c*b + (a%c*b + r)/c;
-
-
-
}
-
else
-
{
-
...
-
}
-
}
阅读(10962) | 评论(0) | 转发(0) |