1 /* 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 #include "webrtc/video/report_block_stats.h" 14 15 namespace webrtc { 16 17 class ReportBlockStatsTest : public ::testing::Test { 18 protected: 19 ReportBlockStatsTest() : kSsrc1(0x12345), kSsrc2(0x23456) {} 20 21 void SetUp() override { 22 // kSsrc1: block 1-3. 23 block1_1_.cumulativeLost = 10; 24 block1_1_.fractionLost = 123; 25 block1_1_.extendedHighSeqNum = 24000; 26 block1_1_.jitter = 777; 27 block1_1_.sourceSSRC = kSsrc1; 28 block1_2_.cumulativeLost = 15; 29 block1_2_.fractionLost = 0; 30 block1_2_.extendedHighSeqNum = 24100; 31 block1_2_.jitter = 222; 32 block1_2_.sourceSSRC = kSsrc1; 33 block1_3_.cumulativeLost = 50; 34 block1_3_.fractionLost = 0; 35 block1_3_.extendedHighSeqNum = 24200; 36 block1_3_.jitter = 333; 37 block1_3_.sourceSSRC = kSsrc1; 38 // kSsrc2: block 1,2. 39 block2_1_.cumulativeLost = 111; 40 block2_1_.fractionLost = 222; 41 block2_1_.extendedHighSeqNum = 8500; 42 block2_1_.jitter = 555; 43 block2_1_.sourceSSRC = kSsrc2; 44 block2_2_.cumulativeLost = 136; 45 block2_2_.fractionLost = 0; 46 block2_2_.extendedHighSeqNum = 8800; 47 block2_2_.jitter = 888; 48 block2_2_.sourceSSRC = kSsrc2; 49 50 ssrc1block1_.push_back(block1_1_); 51 ssrc1block2_.push_back(block1_2_); 52 ssrc12block1_.push_back(block1_1_); 53 ssrc12block1_.push_back(block2_1_); 54 ssrc12block2_.push_back(block1_2_); 55 ssrc12block2_.push_back(block2_2_); 56 } 57 58 RtcpStatistics RtcpReportBlockToRtcpStatistics( 59 const RTCPReportBlock& stats) { 60 RtcpStatistics block; 61 block.cumulative_lost = stats.cumulativeLost; 62 block.fraction_lost = stats.fractionLost; 63 block.extended_max_sequence_number = stats.extendedHighSeqNum; 64 block.jitter = stats.jitter; 65 return block; 66 } 67 68 const uint32_t kSsrc1; 69 const uint32_t kSsrc2; 70 RTCPReportBlock block1_1_; 71 RTCPReportBlock block1_2_; 72 RTCPReportBlock block1_3_; 73 RTCPReportBlock block2_1_; 74 RTCPReportBlock block2_2_; 75 std::vector<RTCPReportBlock> ssrc1block1_; 76 std::vector<RTCPReportBlock> ssrc1block2_; 77 std::vector<RTCPReportBlock> ssrc12block1_; 78 std::vector<RTCPReportBlock> ssrc12block2_; 79 }; 80 81 TEST_F(ReportBlockStatsTest, AggregateAndStore_NoSsrc) { 82 ReportBlockStats stats; 83 std::vector<RTCPReportBlock> empty; 84 RTCPReportBlock aggregated = stats.AggregateAndStore(empty); 85 EXPECT_EQ(0U, aggregated.fractionLost); 86 EXPECT_EQ(0U, aggregated.cumulativeLost); 87 EXPECT_EQ(0U, aggregated.jitter); 88 EXPECT_EQ(0U, aggregated.extendedHighSeqNum); 89 } 90 91 TEST_F(ReportBlockStatsTest, AggregateAndStore_OneSsrc) { 92 ReportBlockStats stats; 93 RTCPReportBlock aggregated = stats.AggregateAndStore(ssrc1block1_); 94 // One ssrc, no aggregation done. 95 EXPECT_EQ(123U, aggregated.fractionLost); 96 EXPECT_EQ(10U, aggregated.cumulativeLost); 97 EXPECT_EQ(777U, aggregated.jitter); 98 EXPECT_EQ(24000U, aggregated.extendedHighSeqNum); 99 100 aggregated = stats.AggregateAndStore(ssrc1block2_); 101 EXPECT_EQ(0U, aggregated.fractionLost); 102 EXPECT_EQ(15U, aggregated.cumulativeLost); 103 EXPECT_EQ(222U, aggregated.jitter); 104 EXPECT_EQ(24100U, aggregated.extendedHighSeqNum); 105 106 // fl: 100 * (15-10) / (24100-24000) = 5% 107 EXPECT_EQ(5, stats.FractionLostInPercent()); 108 } 109 110 TEST_F(ReportBlockStatsTest, AggregateAndStore_TwoSsrcs) { 111 ReportBlockStats stats; 112 RTCPReportBlock aggregated = stats.AggregateAndStore(ssrc12block1_); 113 EXPECT_EQ(0U, aggregated.fractionLost); 114 EXPECT_EQ(10U + 111U, aggregated.cumulativeLost); 115 EXPECT_EQ((777U + 555U) / 2, aggregated.jitter); 116 EXPECT_EQ(0U, aggregated.extendedHighSeqNum); 117 118 aggregated = stats.AggregateAndStore(ssrc12block2_); 119 // fl: 255 * ((15-10) + (136-111)) / ((24100-24000) + (8800-8500)) = 19 120 EXPECT_EQ(19U, aggregated.fractionLost); 121 EXPECT_EQ(15U + 136U, aggregated.cumulativeLost); 122 EXPECT_EQ((222U + 888U) / 2, aggregated.jitter); 123 EXPECT_EQ(0U, aggregated.extendedHighSeqNum); 124 125 // fl: 100 * ((15-10) + (136-111)) / ((24100-24000) + (8800-8500)) = 7% 126 EXPECT_EQ(7, stats.FractionLostInPercent()); 127 } 128 129 TEST_F(ReportBlockStatsTest, StoreAndGetFractionLost) { 130 const uint32_t kRemoteSsrc = 1; 131 ReportBlockStats stats; 132 EXPECT_EQ(-1, stats.FractionLostInPercent()); 133 134 // First block. 135 stats.Store(RtcpReportBlockToRtcpStatistics(block1_1_), kRemoteSsrc, kSsrc1); 136 EXPECT_EQ(-1, stats.FractionLostInPercent()); 137 // fl: 100 * (15-10) / (24100-24000) = 5% 138 stats.Store(RtcpReportBlockToRtcpStatistics(block1_2_), kRemoteSsrc, kSsrc1); 139 EXPECT_EQ(5, stats.FractionLostInPercent()); 140 // fl: 100 * (50-10) / (24200-24000) = 20% 141 stats.Store(RtcpReportBlockToRtcpStatistics(block1_3_), kRemoteSsrc, kSsrc1); 142 EXPECT_EQ(20, stats.FractionLostInPercent()); 143 } 144 145 } // namespace webrtc 146 147