之前有个网友问基于时延的带宽预测代码中如下时间转换什么含义:
1 2 3 4 5 6 7 8 9 |
uint32_t send_time_24bits = static_cast<uint32_t>( ((static_cast<uint64_t>(packet_feedback.sent_packet.send_time.ms()) << kAbsSendTimeFraction) + 500) / 1000) & 0x00FFFFFF; uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; |
那时因为工作比较忙,没去细看,没回答上。最近重新看了下这个问题,我想现在应该能回答上了(现在看起来其实很简单)。所以本文分析下如上时间转换代码为什么这么写。
绝对发送时间
在WebRTC使用绝对发送时间(Absolute Send Time)记录RTP包发送出去的时间。在GCC拥塞控制中的带宽预测,通过这个发送时间,以及包接收时间,计算带宽增长趋势。在基于接收端的带宽预测中,会在RTP包报头扩展中记录这个发送时间,从而在接收端进行带宽预测计算。在基于发送端的带宽预测中,这个发送时间由发送端另外记录。
WebRTC中使用3字节标识这个绝对发送时间,单位为秒。其中使用6bit标识整数部分,18bit标识小数部分。
保留N位小数
这里我们讲下如何进行N位小数的保留,知道后前面的代码就非常easy了。
假设我们有一个十进制数256.2562要处理,但是程序中某函数小数点取值范围只有0~100,也就是0~10^2,所以我们要对256.256进行保留小数点后两位的处理。一般这么处理:(256.2562x10^2+0.5)/10^2=256.26,+0.5操作是为了对保留的最后一位小数进行四舍五入。
代码导读
看完前面我想代码就很好理解了,只不过现在换成处理二进制数了,这里再贴下代码:
1 2 3 4 5 6 7 8 9 10 11 |
void DelayBasedBwe::IncomingPacketFeedback() { uint32_t send_time_24bits = static_cast<uint32_t>( ((static_cast<uint64_t>(packet_feedback.sent_packet.send_time.ms()) << kAbsSendTimeFraction) + 500) / 1000) & 0x00FFFFFF; uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; } |
- 首先获取以ms为单位的发送时间
send_time.ms
,大小为64bit - 左移
kAbsSendTimeFraction
(18)bit,也就是乘以2^18,因为绝对发送时间使用18bit标识小数部分,所以需要进行小数点后有效数字的保留 - 除以1000将时间单位转换为s,加500是为了四舍五入操作
- 接着&0x00FFFFFF得到后24bit时间值
send_time_24bits
左移kAbsSendTimeInterArrivalUpshift
(8bit),得到32bit大小的发送时间timestamp
是不是很简单,其实就是个简单的数学处理。所以为了学好WebRTC很多基本的数学处理还是不能忘的。
本文已收录到大话WebRTC专栏,更多精彩请访问《大话WebRTC》。
文章评论
先评论再看