• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdint.h>
8 
9 #include "base/test/simple_test_tick_clock.h"
10 #include "base/time/time.h"
11 #include "media/cast/rtp_receiver/receiver_stats.h"
12 #include "media/cast/rtp_receiver/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:
ReceiverStatsTest()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   }
~ReceiverStatsTest()33   virtual ~ReceiverStatsTest() {}
34 
ExpectedJitter(uint32 const_interval,int num_packets)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 
TEST_F(ReceiverStatsTest,ResetState)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 
TEST_F(ReceiverStatsTest,LossCount)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 
TEST_F(ReceiverStatsTest,NoLossWrap)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 
TEST_F(ReceiverStatsTest,LossCountWrap)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 
TEST_F(ReceiverStatsTest,BasicJitter)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 
TEST_F(ReceiverStatsTest,NonTrivialJitter)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