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