1 // Copyright 2013 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 "base/test/simple_test_tick_clock.h" 8 #include "base/time/time.h" 9 #include "media/cast/rtp_receiver/receiver_stats.h" 10 #include "media/cast/rtp_receiver/rtp_receiver_defines.h" 11 12 namespace media { 13 namespace cast { 14 15 static const int64 kStartMillisecond = GG_INT64_C(12345678900000); 16 static const uint32 kStdTimeIncrementMs = 33; 17 18 class ReceiverStatsTest : public ::testing::Test { 19 protected: 20 ReceiverStatsTest() 21 : stats_(&testing_clock_), 22 rtp_header_(), 23 fraction_lost_(0), 24 cumulative_lost_(0), 25 extended_high_sequence_number_(0), 26 jitter_(0) { 27 testing_clock_.Advance( 28 base::TimeDelta::FromMilliseconds(kStartMillisecond)); 29 start_time_ = testing_clock_.NowTicks(); 30 delta_increments_ = base::TimeDelta::FromMilliseconds(kStdTimeIncrementMs); 31 } 32 virtual ~ReceiverStatsTest() {} 33 34 virtual void SetUp() { 35 rtp_header_.webrtc.header.sequenceNumber = 0; 36 rtp_header_.webrtc.header.timestamp = 0; 37 } 38 39 uint32 ExpectedJitter(uint32 const_interval, int num_packets) { 40 float jitter = 0; 41 // Assume timestamps have a constant kStdTimeIncrementMs interval. 42 float float_interval = 43 static_cast<float>(const_interval - kStdTimeIncrementMs); 44 for (int i = 0; i < num_packets; ++i) { 45 jitter += (float_interval - jitter) / 16; 46 } 47 return static_cast<uint32>(jitter + 0.5f); 48 } 49 50 ReceiverStats stats_; 51 RtpCastHeader rtp_header_; 52 uint8 fraction_lost_; 53 uint32 cumulative_lost_; 54 uint32 extended_high_sequence_number_; 55 uint32 jitter_; 56 base::SimpleTestTickClock testing_clock_; 57 base::TimeTicks start_time_; 58 base::TimeDelta delta_increments_; 59 }; 60 61 TEST_F(ReceiverStatsTest, ResetState) { 62 stats_.GetStatistics(&fraction_lost_, &cumulative_lost_, 63 &extended_high_sequence_number_, &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_.webrtc.header.timestamp += 33 * 90; 76 } 77 ++rtp_header_.webrtc.header.sequenceNumber; 78 testing_clock_.Advance(delta_increments_); 79 } 80 stats_.GetStatistics(&fraction_lost_, &cumulative_lost_, 81 &extended_high_sequence_number_, &jitter_); 82 EXPECT_EQ(63u, fraction_lost_); 83 EXPECT_EQ(74u, cumulative_lost_); 84 // Build extended sequence number. 85 uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1; 86 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 87 } 88 89 TEST_F(ReceiverStatsTest, NoLossWrap) { 90 rtp_header_.webrtc.header.sequenceNumber = 65500; 91 for (int i = 0; i < 300; ++i) { 92 stats_.UpdateStatistics(rtp_header_); 93 if (i % 3) { 94 rtp_header_.webrtc.header.timestamp += 33 * 90; 95 } 96 ++rtp_header_.webrtc.header.sequenceNumber; 97 testing_clock_.Advance(delta_increments_); 98 } 99 stats_.GetStatistics(&fraction_lost_, &cumulative_lost_, 100 &extended_high_sequence_number_, &jitter_); 101 EXPECT_EQ(0u, fraction_lost_); 102 EXPECT_EQ(0u, cumulative_lost_); 103 // Build extended sequence number (one wrap cycle). 104 uint32 extended_seq_num = (1 << 16) + 105 rtp_header_.webrtc.header.sequenceNumber - 1; 106 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 107 } 108 109 TEST_F(ReceiverStatsTest, LossCountWrap) { 110 const uint32 start_sequence_number = 65500; 111 rtp_header_.webrtc.header.sequenceNumber = start_sequence_number; 112 for (int i = 0; i < 300; ++i) { 113 if (i % 4) 114 stats_.UpdateStatistics(rtp_header_); 115 if (i % 3) 116 // Update timestamp. 117 ++rtp_header_.webrtc.header.timestamp; 118 ++rtp_header_.webrtc.header.sequenceNumber; 119 testing_clock_.Advance(delta_increments_); 120 } 121 stats_.GetStatistics(&fraction_lost_, &cumulative_lost_, 122 &extended_high_sequence_number_, &jitter_); 123 EXPECT_EQ(63u, fraction_lost_); 124 EXPECT_EQ(74u, cumulative_lost_); 125 // Build extended sequence number (one wrap cycle). 126 uint32 extended_seq_num = (1 << 16) + 127 rtp_header_.webrtc.header.sequenceNumber - 1; 128 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 129 } 130 131 TEST_F(ReceiverStatsTest, BasicJitter) { 132 for (int i = 0; i < 300; ++i) { 133 stats_.UpdateStatistics(rtp_header_); 134 ++rtp_header_.webrtc.header.sequenceNumber; 135 rtp_header_.webrtc.header.timestamp += 33 * 90; 136 testing_clock_.Advance(delta_increments_); 137 } 138 stats_.GetStatistics(&fraction_lost_, &cumulative_lost_, 139 &extended_high_sequence_number_, &jitter_); 140 EXPECT_FALSE(fraction_lost_); 141 EXPECT_FALSE(cumulative_lost_); 142 // Build extended sequence number (one wrap cycle). 143 uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1; 144 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 145 EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs, 300), jitter_); 146 } 147 148 TEST_F(ReceiverStatsTest, NonTrivialJitter) { 149 const int kAdditionalIncrement = 5; 150 for (int i = 0; i < 300; ++i) { 151 stats_.UpdateStatistics(rtp_header_); 152 ++rtp_header_.webrtc.header.sequenceNumber; 153 rtp_header_.webrtc.header.timestamp += 33 * 90; 154 base::TimeDelta additional_delta = 155 base::TimeDelta::FromMilliseconds(kAdditionalIncrement); 156 testing_clock_.Advance(delta_increments_ + additional_delta); 157 } 158 stats_.GetStatistics(&fraction_lost_, &cumulative_lost_, 159 &extended_high_sequence_number_, &jitter_); 160 EXPECT_FALSE(fraction_lost_); 161 EXPECT_FALSE(cumulative_lost_); 162 // Build extended sequence number (one wrap cycle). 163 uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1; 164 EXPECT_EQ(extended_seq_num, extended_high_sequence_number_); 165 EXPECT_EQ( 166 ExpectedJitter(kStdTimeIncrementMs + kAdditionalIncrement, 300), jitter_); 167 } 168 169 } // namespace cast 170 } // namespace media 171