Webrtc delay-base-bwe代码分析(2): InterArrival模块
来源:互联网 发布:ipad换壁纸软件 编辑:程序博客网 时间:2024/06/02 03:54
@(webrtc)[webrtc, congestion control]
Webrtc delay-base-bwe代码分析(2): InterArrival模块
0. 参考文档
[1] google congestion control
[2] Rtp payload format for h264
1. 功能
该模块主要对到达的时间进行小范围内的统计、采样,并根据一定的时间间隔计算出对应的延迟、传输大小变化。
The arrival-time filter. The goal of this block is to produce an estimate m(ti) of the one way delay gradient. For this purpose, we employ a Kalman filter that estimatesm(ti) based on the measured one way delay gradient dm(ti) which is computed as follows: dm(t(i) = (t(i) - t(i-1))-(Ti - T(i-1))where Ti is the time at which the first packet of the i-th video frame has been sent and ti is the time at which the last packet that forms the video frame has been received.
2. 流程
注:RTP的timestamp默认频率为90kHz。
以发送的时间戳为准,每5ms内发送的包划为一个时间戳范围内,组成一个TimestampGroup,同一个TimestampGroup内的包,后来的时间覆盖先到的。当某个包到来时,根据时间戳判断是一个新的TimestampGroup,此时才会执行延迟差值的计算,计算使用上一个group和当前group的时间值。
注2:这里代码不涉及使用绝对的时间,涉及sdp中的abs_time。
注3:这里默认的一个group时间为5ms,对于rtp的timestamp默认频率,450个rtp timestamp为一个group的tick。
3. 代码
流程比较简单,主要就是new group的判断,以及group时间的更新和差值计算。
bool InterArrival::ComputeDeltas(uint32_t timestamp, int64_t arrival_time_ms, int64_t system_time_ms, size_t packet_size, uint32_t* timestamp_delta, int64_t* arrival_time_delta_ms, int* packet_size_delta) { assert(timestamp_delta != NULL); assert(arrival_time_delta_ms != NULL); assert(packet_size_delta != NULL); bool calculated_deltas = false; if (current_timestamp_group_.IsFirstPacket()) { // We don't have enough data to update the filter, so we store it until we // have two frames of data to process. // 尚未完全初始化 current_timestamp_group_.timestamp = timestamp; current_timestamp_group_.first_timestamp = timestamp; } else if (!PacketInOrder(timestamp)) { return false; } else if (NewTimestampGroup(arrival_time_ms, timestamp)) { // First packet of a later frame, the previous frame sample is ready. // 需要新开一个group,此时计算prev_group和current_group的差值。 if (prev_timestamp_group_.complete_time_ms >= 0) { // 发送时间的差值,即公式中的T(i) - T(i - 1) *timestamp_delta = current_timestamp_group_.timestamp - prev_timestamp_group_.timestamp; // 接收时间的差值,即公式中的t(i) - t(i - 1) *arrival_time_delta_ms = current_timestamp_group_.complete_time_ms - prev_timestamp_group_.complete_time_ms; // Check system time differences to see if we have an unproportional jump // in arrival time. In that case reset the inter-arrival computations. // 防止一些时间戳异常处理。 int64_t system_time_delta_ms = current_timestamp_group_.last_system_time_ms - prev_timestamp_group_.last_system_time_ms; if (*arrival_time_delta_ms - system_time_delta_ms >= kArrivalTimeOffsetThresholdMs) { LOG(LS_WARNING) << "The arrival time clock offset has changed (diff = " << *arrival_time_delta_ms - system_time_delta_ms << " ms), resetting."; Reset(); return false; } // 乱序包的异常处理 if (*arrival_time_delta_ms < 0) { // The group of packets has been reordered since receiving its local // arrival timestamp. ++num_consecutive_reordered_packets_; // 连续乱序包的异常处理 if (num_consecutive_reordered_packets_ >= kReorderedResetThreshold) { LOG(LS_WARNING) << "Packets are being reordered on the path from the " "socket to the bandwidth estimator. Ignoring this " "packet for bandwidth estimation, resetting."; Reset(); } return false; } else { num_consecutive_reordered_packets_ = 0; } assert(*arrival_time_delta_ms >= 0); *packet_size_delta = static_cast<int>(current_timestamp_group_.size) - static_cast<int>(prev_timestamp_group_.size); calculated_deltas = true; } // 更新整组group prev_timestamp_group_ = current_timestamp_group_; // The new timestamp is now the current frame. current_timestamp_group_.first_timestamp = timestamp; current_timestamp_group_.timestamp = timestamp; current_timestamp_group_.size = 0; } else { // 还在之前的时间范围内,此时将rtp timestanp更新,更新为一个新值。 current_timestamp_group_.timestamp = LatestTimestamp( current_timestamp_group_.timestamp, timestamp); } // Accumulate the frame size. // 更新group中的数据。 current_timestamp_group_.size += packet_size; current_timestamp_group_.complete_time_ms = arrival_time_ms; current_timestamp_group_.last_system_time_ms = system_time_ms; return calculated_deltas;}// Assumes that |timestamp| is not reordered compared to// |current_timestamp_group_|.bool InterArrival::NewTimestampGroup(int64_t arrival_time_ms, uint32_t timestamp) const { if (current_timestamp_group_.IsFirstPacket()) { return false; } else if (BelongsToBurst(arrival_time_ms, timestamp)) { return false; } else { uint32_t timestamp_diff = timestamp - current_timestamp_group_.first_timestamp; // rtp时间差大于一个Tick,即 90 * 5 个rtp时间采样点。 return timestamp_diff > kTimestampGroupLengthTicks; }}// 允许group超出定死的group时间范围。// 当这个函数返回false,会认为不是一个新的group。bool InterArrival::BelongsToBurst(int64_t arrival_time_ms, uint32_t timestamp) const { if (!burst_grouping_) { return false; } assert(current_timestamp_group_.complete_time_ms >= 0); int64_t arrival_time_delta_ms = arrival_time_ms - current_timestamp_group_.complete_time_ms; uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp; // 将rtp的时间差值转换为ms,乘上采样频率 1 / 90. int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5; if (ts_delta_ms == 0) return true; int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms; // 传播时间差,即当前包的RTT小于上一个包的RTT,且到达时间差小于爆发的阈值 return propagation_delta_ms < 0 && arrival_time_delta_ms <= kBurstDeltaThresholdMs;}
阅读全文
0 0
- Webrtc delay-base-bwe代码分析(2): InterArrival模块
- Webrtc delay-base-bwe代码分析(1): RateStatistics模块
- Webrtc delay-base-bwe代码分析(3): OveruseEstimator模块
- Webrtc delay-base-bwe代码分析(4): OveruseDetector模块
- Webrtc delay-base-bwe代码分析(5): AimdRateControl模块
- Webrtc delay-base-bwe代码分析(6): 整体分析
- webRTC base模块Event事件的实现
- webRTC base模块SharedExclusiveLock读写锁实现
- WebRTC代码走读(十):rtp_rtcp模块分析
- WebRTC代码走读(十一):video_coding模块分析
- webRTC base模块CritScope临界锁的实现
- webRTC base模块MessageQueue消息队列的实现
- webRTC base模块SigSlot信号与槽实现
- WebRTC源码分析:音频模块结构分析
- WebRTC源码分析:音频模块结构分析
- Bandwidth Estimation in WebRTC (and the new Sender Side BWE)
- WebRTC源码分析二:音频模块结构
- WebRTC源码分析四:视频模块结构
- 开启cdn后无法显示字体图标——CDN服务器跨域问题
- 逻辑结构定义及其分类
- 文章标题
- 【C语言 数据结构】汉诺塔(hanoi)的原理
- nodejs npm 安装 设置国内镜像
- Webrtc delay-base-bwe代码分析(2): InterArrival模块
- java基础代码练习
- 最长回文子串——Manacher 算法
- 怎么修改列的定义
- 如何解决SpringBoot与ODataJClient版本冲突的问题?
- 英雄联盟开发例子生动形象地为你讲解StrategyPattern------策略模式
- BZOJ1602: [Usaco2008 Oct]牧场行走
- 实训的第七天 加油
- HDU Text Reverse/1.2