• TCC丢包率计算


    一、FeedbackRtpTransportPacket

    1. /* RTP Extensions for Transport-wide Congestion Control
    2. * draft-holmer-rmcat-transport-wide-cc-extensions-01
    3.   0               1               2               3
    4.   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
    5.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    6.  |V=2|P| FMT=15 |   PT=205     |           length             |
    7.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    8.  |                     SSRC of packet sender                     |
    9.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    10.  |                     SSRC of media source                     |
    11.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    12.  |     base sequence number     |     packet status count     | // packet status count: 发送包总数
    13.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    14.  |                 reference time               | fb pkt. count |
    15.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    16.  |         packet chunk         |         packet chunk         |
    17.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    18.  .                                                               .
    19.  .                                                               .
    20.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    21.  |         packet chunk         | recv delta   | recv delta   |
    22.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    23.  .                                                               .
    24.  .                                                               .
    25.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    26.  |           recv delta         | recv delta   | zero padding |
    27.  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    28. */

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

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

    3)、reference time:参考时间戳

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

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

    1. enum Status : uint8_t
    2. {
    3. NotReceived = 0,    // 没有收到
    4. SmallDelta,         // 正常到达
    5. LargeDelta,         // 到达缓慢
    6. Reserved,          
    7. None  
    8. };

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

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

    1. // 对于包
    2. 有一串字符串 aaabbbcddeeeeee,我们怎么尽量简单地去表示它让它长度变短呢?
    3. // 其实可以写为:3a3bc2d6e —— 也就是按数字表示每个字母的数量,不带数字的就为一个。
    4. // 对应到packet chunk里 结构就是:
    5. 0                   1
    6. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
    7. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    8. |T| S |       Run Length        |
    9. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    10. // T 就为第一个 bit —— 编码类型
    11. // S 两个bit 表示状态 (00未到达、01正常到达、10来慢了)
    12. // Run Length 就是具体的数据
    13. // 例如下面:
    14. 0                   1
    15. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
    16. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    17. |0|0 0|0 0 0 0 0 1 1 0 1 1 1 0 1|
    18. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    19. // 第一个bit是0,表示run length编码
    20. // 后面两个bit是00, 表示未到达包状态
    21. // 后面的数据 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(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;
    }
  • 相关阅读:
    窄带物联网,开启万物互联新篇章
    土壤养分检测:缺少氮磷钾元素时,作物表现的症状各不相同
    筛斗数据提取技术对企业决策过程的影响
    IO流(复习)
    Android组件化实现,理解吸收
    R语言和医学统计学系列(1):t检验
    ol(openlayers)使用记录
    观点|周鸿祎:大模型真正的竞争在于使其与用户场景相结合
    《Python - 文本文件的读写》
    leetcode-简单
  • 原文地址:https://blog.csdn.net/qq_15821883/article/details/126162540