1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <gtest/gtest.h> 6 7 #include <stdint.h> 8 9 #include "base/test/simple_test_tick_clock.h" 10 #include "base/time/time.h" 11 #include "media/cast/net/rtp/receiver_stats.h" 12 #include "media/cast/net/rtp/rtp_receiver_defines.h" 13 14 namespace media { 15 namespace cast { 16 17 static const int64 kStartMillisecond = INT64_C(12345678900000); 18 static const uint32 kStdTimeIncrementMs = 33; 19 20 class ReceiverStatsTest : public ::testing::Test { 21 protected: 22 ReceiverStatsTest() 23 : stats_(&testing_clock_), 24 fraction_lost_(0), 25 cumulative_lost_(0), 26 extended_high_sequence_number_(0), 27 jitter_(0) { 28 testing_clock_.Advance( 29 base::TimeDelta::FromMilliseconds(kStartMillisecond)); 30 start_time_ = testing_clock_.NowTicks(); 31 delta_increments_ = base::TimeDelta::FromMilliseconds(kStdTimeIncrementMs); 32 } 33 virtual ~ReceiverStatsTest() {} 34 35 uint32 ExpectedJitter(uint32 const_interval, int num_packets) { 36 float jitter = 0; 37 // Assume timestamps have a constant kStdTimeIncrementMs interval. 38 float float_interval = 39 static_cast<float>(const_interval - kStdTimeIncrementMs); 40 for (int i = 0; i < num_packets; ++i) { 41 jitter += (float_interval - jitter) / 16; 42 } 43 return static_cast<uint32>(jitter + 0.5f); 44 } 45 46 ReceiverStats stats_; 47 RtpCastHeader rtp_header_; 48 uint8 fraction_lost_; 49 uint32 cumulative_lost_; 50 uint32 extended_high_sequence_number_; 51 uint32 jitter_; 52 base::SimpleTestTickClock testing_clock_; 53 base::TimeTicks start_time_; 54 base::TimeDelta delta_increments_; 55 56 DISALLOW_COPY_AND_ASSIGN(ReceiverStatsTest); 57 }; 58 59 TEST_F(ReceiverStatsTest, ResetState) { 60 stats_.GetStatistics(&fraction_lost_, 61 &cumulative_lost_, 62 &extended_high_sequence_number_, 63 &jitter_); 64 EXPECT_EQ(0u, fraction_lost_); 65 EXPECT_EQ(0u, cumulative_lost_); 66 EXPECT_EQ(0u, extended_high_sequence_number_); 67 EXPECT_EQ(0u, jitter_); 68 } 69 70 TEST_F(ReceiverStatsTest, LossCount) { 71 for (int i = 0; i < 300; ++i) { 72 if (i % 4) 73 stats_.UpdateStatistics(rtp_header_); 74 if (i % 3) { 75 rtp_header_.rtp_timestamp += 33 * 90; 76 } 77 ++rtp_header_.sequence_number; 78 testing_clock_.Advance(delta_increments_); 79 } 80 stats_.GetStatistics(&fraction_lost_, 81 &cumulative_lost_, 82 &extended_high_sequence_number_, 83 &jitter_); 84 EXPECT_EQ(63u, fraction_lost_); 85 EXPECT_EQ(74u, cumulative_lost_); 86 // Build extended sequence number. 87 const uint32 extended_seq_num = rtp_header_.sequence_number - 1; 88 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 89 } 90 91 TEST_F(ReceiverStatsTest, NoLossWrap) { 92 rtp_header_.sequence_number = 65500; 93 for (int i = 0; i < 300; ++i) { 94 stats_.UpdateStatistics(rtp_header_); 95 if (i % 3) { 96 rtp_header_.rtp_timestamp += 33 * 90; 97 } 98 ++rtp_header_.sequence_number; 99 testing_clock_.Advance(delta_increments_); 100 } 101 stats_.GetStatistics(&fraction_lost_, 102 &cumulative_lost_, 103 &extended_high_sequence_number_, 104 &jitter_); 105 EXPECT_EQ(0u, fraction_lost_); 106 EXPECT_EQ(0u, cumulative_lost_); 107 // Build extended sequence number (one wrap cycle). 108 const uint32 extended_seq_num = (1 << 16) + rtp_header_.sequence_number - 1; 109 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 110 } 111 112 TEST_F(ReceiverStatsTest, LossCountWrap) { 113 const uint32 kStartSequenceNumber = 65500; 114 rtp_header_.sequence_number = kStartSequenceNumber; 115 for (int i = 0; i < 300; ++i) { 116 if (i % 4) 117 stats_.UpdateStatistics(rtp_header_); 118 if (i % 3) 119 // Update timestamp. 120 ++rtp_header_.rtp_timestamp; 121 ++rtp_header_.sequence_number; 122 testing_clock_.Advance(delta_increments_); 123 } 124 stats_.GetStatistics(&fraction_lost_, 125 &cumulative_lost_, 126 &extended_high_sequence_number_, 127 &jitter_); 128 EXPECT_EQ(63u, fraction_lost_); 129 EXPECT_EQ(74u, cumulative_lost_); 130 // Build extended sequence number (one wrap cycle). 131 const uint32 extended_seq_num = (1 << 16) + rtp_header_.sequence_number - 1; 132 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 133 } 134 135 TEST_F(ReceiverStatsTest, BasicJitter) { 136 for (int i = 0; i < 300; ++i) { 137 stats_.UpdateStatistics(rtp_header_); 138 ++rtp_header_.sequence_number; 139 rtp_header_.rtp_timestamp += 33 * 90; 140 testing_clock_.Advance(delta_increments_); 141 } 142 stats_.GetStatistics(&fraction_lost_, 143 &cumulative_lost_, 144 &extended_high_sequence_number_, 145 &jitter_); 146 EXPECT_FALSE(fraction_lost_); 147 EXPECT_FALSE(cumulative_lost_); 148 // Build extended sequence number (one wrap cycle). 149 const uint32 extended_seq_num = rtp_header_.sequence_number - 1; 150 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 151 EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs, 300), jitter_); 152 } 153 154 TEST_F(ReceiverStatsTest, NonTrivialJitter) { 155 const int kAdditionalIncrement = 5; 156 for (int i = 0; i < 300; ++i) { 157 stats_.UpdateStatistics(rtp_header_); 158 ++rtp_header_.sequence_number; 159 rtp_header_.rtp_timestamp += 33 * 90; 160 base::TimeDelta additional_delta = 161 base::TimeDelta::FromMilliseconds(kAdditionalIncrement); 162 testing_clock_.Advance(delta_increments_ + additional_delta); 163 } 164 stats_.GetStatistics(&fraction_lost_, 165 &cumulative_lost_, 166 &extended_high_sequence_number_, 167 &jitter_); 168 EXPECT_FALSE(fraction_lost_); 169 EXPECT_FALSE(cumulative_lost_); 170 // Build extended sequence number (one wrap cycle). 171 const uint32 extended_seq_num = rtp_header_.sequence_number - 1; 172 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 173 EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs + kAdditionalIncrement, 300), 174 jitter_); 175 } 176 177 } // namespace cast 178 } // namespace media 179