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.
5 #include <gtest/gtest.h>
7 #include "base/test/simple_test_tick_clock.h"
8 #include "base/time/time.h"
9 #include "media/cast/rtp_common/rtp_defines.h"
10 #include "media/cast/rtp_receiver/receiver_stats.h"
15 static const int64 kStartMillisecond = GG_INT64_C(12345678900000);
16 static const uint32 kStdTimeIncrementMs = 33;
18 class ReceiverStatsTest : public ::testing::Test {
21 : stats_(&testing_clock_),
25 extended_high_sequence_number_(0),
27 testing_clock_.Advance(
28 base::TimeDelta::FromMilliseconds(kStartMillisecond));
29 start_time_ = testing_clock_.NowTicks();
30 delta_increments_ = base::TimeDelta::FromMilliseconds(kStdTimeIncrementMs);
32 virtual ~ReceiverStatsTest() {}
34 virtual void SetUp() {
35 rtp_header_.webrtc.header.sequenceNumber = 0;
36 rtp_header_.webrtc.header.timestamp = 0;
39 uint32 ExpectedJitter(uint32 const_interval, int num_packets) {
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;
47 return static_cast<uint32>(jitter + 0.5f);
51 RtpCastHeader rtp_header_;
53 uint32 cumulative_lost_;
54 uint32 extended_high_sequence_number_;
56 base::SimpleTestTickClock testing_clock_;
57 base::TimeTicks start_time_;
58 base::TimeDelta delta_increments_;
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_);
70 TEST_F(ReceiverStatsTest, LossCount) {
71 for (int i = 0; i < 300; ++i) {
73 stats_.UpdateStatistics(rtp_header_);
75 rtp_header_.webrtc.header.timestamp += 33 * 90;
77 ++rtp_header_.webrtc.header.sequenceNumber;
78 testing_clock_.Advance(delta_increments_);
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_);
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_);
94 rtp_header_.webrtc.header.timestamp += 33 * 90;
96 ++rtp_header_.webrtc.header.sequenceNumber;
97 testing_clock_.Advance(delta_increments_);
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_);
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) {
114 stats_.UpdateStatistics(rtp_header_);
117 ++rtp_header_.webrtc.header.timestamp;
118 ++rtp_header_.webrtc.header.sequenceNumber;
119 testing_clock_.Advance(delta_increments_);
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_);
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_);
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_);
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);
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_);
166 ExpectedJitter(kStdTimeIncrementMs + kAdditionalIncrement, 300), jitter_);