TCC丢包率计算

一、FeedbackRtpTransportPacket

/* RTP Extensions for Transport-wide Congestion Control
 * draft-holmer-rmcat-transport-wide-cc-extensions-01
​
   0               1               2               3
   0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |V=2|P|  FMT=15 |    PT=205     |           length              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                     SSRC of packet sender                     |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                      SSRC of media source                     |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |      base sequence number     |      packet status count      |  // packet status count: 发送包总数
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                 reference time                | fb pkt. count |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |          packet chunk         |         packet chunk          |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  .                                                               .
  .                                                               .
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |         packet chunk          |  recv delta   |  recv delta   |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  .                                                               .
  .                                                               .
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           recv delta          |  recv delta   | zero padding  |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */

1)、base sequence number:参考seq, 初始统计序号

2)、packet status count:反馈状态包数

3)、reference time:参考时间戳

4)、fb pkt. count:反馈的总包数,累计值(计算丢包率丢包率)

5)、packet chunk:包状态记录块,记录每个包到达的状态,分为

enum Status : uint8_t
{
    NotReceived = 0,    // 没有收到
    SmallDelta,         // 正常到达
    LargeDelta,         // 到达缓慢
    Reserved,           
    None  
};

packet chunk的两种压缩模式(通过首bit标识chunk类型、可以理解为字符串压缩算法):

——Run length chunk(行程长度编码数据块)

// 对于包



有一串字符串 aaabbbcddeeeeee,我们怎么尽量简单地去表示它让它长度变短呢?
// 其实可以写为:3a3bc2d6e —— 也就是按数字表示每个字母的数量,不带数字的就为一个。
​
// 对应到packet chunk里 结构就是:
0                   1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T| S |       Run Length        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// T 就为第一个 bit —— 编码类型
// S 两个bit 表示状态 (00未到达、01正常到达、10来慢了)
// Run Length 就是具体的数据
​
// 例如下面:
0                   1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0 0|0 0 0 0 0 1 1 0 1 1 1 0 1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
// 第一个bit是0,表示run length编码
// 后面两个bit是00, 表示未到达包状态
// 后面的数据 0 0 0 0 0 1 1 0 1 1 1 0 1 -> 11011101 换算成十进制就是221个包,存在221个包连续未到达

——Status vector chunk(状态矢量编码数据块)

// 有一串字符串 aaabbbcddeeeeee,我们怎么尽量简单地去表示它让它长度变短呢?
// 其实可以写为:3a3bc2d6e —— 也就是按数字表示每个字母的数量,不带数字的就为一个。
​
// 对应到packet chunk里 结构就是:
0                   1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|S|        symbol list        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// T 就为第一个 bit —— 编码类型
// S 一个bit 表示状态  (注意:只有一位): 0表示后面的数据都按一位来(简单表示到达的状态,所以一般表示0未到达、1已到达)这样后面14个bit可以表示14个包。
//                                    1表示后面使用两位来表示(例如:00、01、10完全表示接到的状态,00未到达、01正常到达、10慢了)这样后面只能表示7个包。
// Run Length 就是具体的数据
​
// 例如下面:
0                   1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1|0|0 1 1 1 1 1 0 0 0 1 1 1 0 0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
// 第一个bit是1,表示symbol list编码
// 后面一个bit是0, 表示使用一位表示法
// 后面的数据 01111100011100 ——>表示:第一个包未到达、接着5个包都到达了、随后3个包未到达、三个包到达了、最后两个包未到达 —— 一共14个包可表示。
​
0                   1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1|1|0 0 1 1 0 1 0 1 0 1 0 0 0 0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
// 第一个bit是1,表示symbol list编码
// 后面一个bit是1, 表示使用两位表示法
// 后面的数据 0 0 1 1 0 1 0 1 0 1 0 0 0 0 ——>表示:第一个包未到达、第二个包 11 到慢了、01连续三个 正常达到、最后两个未到达 —— 一共7个包可表示。

6)、recv delta:到达时间间隔, 以0.25ms为间隔,表示RTP包到达时间与前面一个RTP包到达时间的间隔,对于记录的第一个RTP包,该包的时间间隔是相对reference time的。

如果在packet chunk记录了一个"Packet received, small delta"状态的包,那么就会在receive delta列表中添加一个无符号1字节长度receive delta,无符号1字节取值范围[0,255],由于Receive Delta以0.25ms为单位,故此时Receive Delta取值范围[0, 63.75]ms

如果在packet chunk记录了一个"Packet received, large or negative delta"状态的包,那么就会在receive delta列表中添加一个有符号2字节长度的receive delta,范围[-8192.0, 8191.75] ms

  如果时间间隔超过了最大限制,那么就会构建一个新的TransportFeedback RTCP包,由于reference time长度为3字节,所以目前的包中3字节长度能够覆盖很大范围了

二、计算丢包率

1)、通过Transport统计出来当前的丢包率

// 预计发送包数
size_t expected_packets = feedback->GetPacketStatusCount();
// 统计丢包总数
size_t lost_packets     = 0;
for (const auto& result : feedback->GetPacketResults())
{
    if (!result.received)
        lost_packets += 1;
}
this->UpdatePacketLoss(static_cast<double>(lost_packets) / expected_packets);

2)、通过丢包直方图算法计算丢包率(加权平均)

void TransportCongestionControlClient::UpdatePacketLoss(double packetLoss)
{
    // 把当前的丢包率统计进丢包直方图中
    if (this->packetLossHistory.size() == PacketLossHistogramLength)
        this->packetLossHistory.pop_front();
​
    this->packetLossHistory.push_back(packetLoss);
​
    /*
     * 计算加权平均值
     *
     * 丢包率越靠近权重越大,最初的丢包率权重为1,后续的权重一次+1
     *
     */
    size_t weight{ 0 };
    size_t samples{ 0 };
    double totalPacketLoss{ 0 };
​
    // 丢包率遍历
    for (auto packetLossEntry : this->packetLossHistory)
    {
        // 权重累加
        weight++;
        // 总计权重累加
        samples += weight;
        // 总计丢包率
        totalPacketLoss += weight * packetLossEntry;
    }
​
    // 加权平均丢包率
    this->packetLoss = totalPacketLoss / samples;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于MATLAB的时间轮转算法的简单实现。本实现假设存在一个名为`processes`的向量,其中包含每个进程需要执行的时间。另外,我们还需要指定一个时间片大小,即量子大小。 ``` function [turnaround, waiting, dropped] = roundRobin(processes, quantum, bufferSize, bufferThreshold, lossRate) n = length(processes); remaining = processes; waiting = zeros(1, n); turnaround = zeros(1, n); dropped = 0; buffer = zeros(1, bufferSize); head = 1; tail = 1; t = 0; while any(remaining) for i = 1:n if remaining(i) > 0 if remaining(i) > quantum t = t + quantum; remaining(i) = remaining(i) - quantum; buffer(tail) = i; tail = mod(tail, bufferSize) + 1; else t = t + remaining(i); waiting(i) = t - processes(i); remaining(i) = 0; turnaround(i) = waiting(i) + processes(i); end end end if head ~= tail && (tail > head || tail == 1) p = buffer(head); head = mod(head, bufferSize) + 1; if rand() > lossRate if sum(buffer == p) < bufferThreshold remaining(p) = remaining(p) - 1; else dropped = dropped + 1; end end end end end ``` 该函数接受五个参数:一个包含进程执行时间的向量,一个时间片大小(即量子大小),一个缓冲区大小,一个缓冲区阈值和一个丢包。函数返回三个向量,一个是每个进程的周转时间,一个是每个进程的等待时间,另一个是丢失的数据包数量。 为了测试该函数,我们可以生成一个随机的进程执行时间向量,并使用以下代码调用该函数: ``` processes = randi([1 10], 1, 10); quantum = 2; bufferSize = 10; bufferThreshold = 3; lossRate = 0.1; [turnaround, waiting, dropped] = roundRobin(processes, quantum, bufferSize, bufferThreshold, lossRate); avgTurnaround = mean(turnaround); avgWaiting = mean(waiting); packetLossRate = dropped / sum(processes); ``` 该代码将计算平均周转时间、平均等待时间和丢包,并将其存储在`avgTurnaround`、`avgWaiting`和`packetLossRate`变量中。 为了显示结果,我们可以使用MATLAB的绘图功能。以下是一个简单的示例,演示如何绘制平均延迟、丢包和缓存占比图像: ``` figure subplot(2, 2, 1) bar(processes) title('Process execution time') xlabel('Process ID') ylabel('Execution time') subplot(2, 2, 2) bar(turnaround) title('Turnaround time') xlabel('Process ID') ylabel('Time') subplot(2, 2, 3) bar(waiting) title('Waiting time') xlabel('Process ID') ylabel('Time') subplot(2, 2, 4) pie([dropped length(processes) - dropped]) title('Packet loss rate') legend({'Dropped', 'Sent'}) ``` 该代码将生成一个4个图像的图表,其中第一个图像显示每个进程的执行时间,第二个图像显示每个进程的周转时间,第三个图像显示每个进程的等待时间,第四个图像显示丢包和剩余包的比例。 希望这可以帮助您了解如何使用MATLAB实现时间轮转算法并显示结果。请注意,本实现是一个简单的示例,实际的时间轮转算法可能会更加复杂和高级。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值