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
14namespace media {
15namespace cast {
16
17static const int64 kStartMillisecond = INT64_C(12345678900000);
18static const uint32 kStdTimeIncrementMs = 33;
19
20class 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
59TEST_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
70TEST_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
91TEST_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
112TEST_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
135TEST_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
154TEST_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