receiver_time_offset_estimator_impl_unittest.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
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 "base/memory/ref_counted.h"
6#include "base/memory/scoped_ptr.h"
7#include "base/test/simple_test_tick_clock.h"
8#include "base/time/tick_clock.h"
9#include "media/cast/cast_environment.h"
10#include "media/cast/logging/logging_defines.h"
11#include "media/cast/logging/receiver_time_offset_estimator_impl.h"
12#include "media/cast/test/fake_single_thread_task_runner.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace media {
16namespace cast {
17
18class ReceiverTimeOffsetEstimatorImplTest : public ::testing::Test {
19 protected:
20  ReceiverTimeOffsetEstimatorImplTest()
21      : sender_clock_(new base::SimpleTestTickClock()),
22        task_runner_(new test::FakeSingleThreadTaskRunner(sender_clock_)),
23        cast_environment_(new CastEnvironment(
24            scoped_ptr<base::TickClock>(sender_clock_).Pass(),
25            task_runner_,
26            task_runner_,
27            task_runner_)) {
28    cast_environment_->Logging()->AddRawEventSubscriber(&estimator_);
29  }
30
31  virtual ~ReceiverTimeOffsetEstimatorImplTest() {
32    cast_environment_->Logging()->RemoveRawEventSubscriber(&estimator_);
33  }
34
35  void AdvanceClocks(base::TimeDelta time) {
36    sender_clock_->Advance(time);
37    receiver_clock_.Advance(time);
38  }
39
40  base::SimpleTestTickClock* sender_clock_;  // Owned by CastEnvironment.
41  scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
42  scoped_refptr<CastEnvironment> cast_environment_;
43  base::SimpleTestTickClock receiver_clock_;
44  ReceiverTimeOffsetEstimatorImpl estimator_;
45};
46
47// Suppose the true offset is 100ms.
48// Event A occurred at sender time 20ms.
49// Event B occurred at receiver time 130ms. (sender time 30ms)
50// Event C occurred at sender time 60ms.
51// Then the bound after all 3 events have arrived is [130-60=70, 130-20=110].
52TEST_F(ReceiverTimeOffsetEstimatorImplTest, EstimateOffset) {
53  int64 true_offset_ms = 100;
54  receiver_clock_.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms));
55
56  base::TimeDelta lower_bound;
57  base::TimeDelta upper_bound;
58
59  EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
60
61  RtpTimestamp rtp_timestamp = 0;
62  uint32 frame_id = 0;
63
64  AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
65
66  cast_environment_->Logging()->InsertEncodedFrameEvent(
67      sender_clock_->NowTicks(),
68      kVideoFrameEncoded,
69      rtp_timestamp,
70      frame_id,
71      1234,
72      true,
73      5678);
74
75  EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
76
77  AdvanceClocks(base::TimeDelta::FromMilliseconds(10));
78  cast_environment_->Logging()->InsertFrameEvent(
79      receiver_clock_.NowTicks(), kVideoAckSent, rtp_timestamp, frame_id);
80
81  EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
82
83  AdvanceClocks(base::TimeDelta::FromMilliseconds(30));
84  cast_environment_->Logging()->InsertFrameEvent(
85      sender_clock_->NowTicks(), kVideoAckReceived, rtp_timestamp, frame_id);
86
87  EXPECT_TRUE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
88
89  int64 lower_bound_ms = lower_bound.InMilliseconds();
90  int64 upper_bound_ms = upper_bound.InMilliseconds();
91  EXPECT_EQ(70, lower_bound_ms);
92  EXPECT_EQ(110, upper_bound_ms);
93  EXPECT_GE(true_offset_ms, lower_bound_ms);
94  EXPECT_LE(true_offset_ms, upper_bound_ms);
95}
96
97// Same scenario as above, but event C arrives before event B. It doens't mean
98// event C occurred before event B.
99TEST_F(ReceiverTimeOffsetEstimatorImplTest, EventCArrivesBeforeEventB) {
100  int64 true_offset_ms = 100;
101  receiver_clock_.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms));
102
103  base::TimeDelta lower_bound;
104  base::TimeDelta upper_bound;
105
106  EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
107
108  RtpTimestamp rtp_timestamp = 0;
109  uint32 frame_id = 0;
110
111  AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
112
113  cast_environment_->Logging()->InsertEncodedFrameEvent(
114      sender_clock_->NowTicks(),
115      kVideoFrameEncoded,
116      rtp_timestamp,
117      frame_id,
118      1234,
119      true,
120      5678);
121
122  EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
123
124  AdvanceClocks(base::TimeDelta::FromMilliseconds(10));
125  base::TimeTicks event_b_time = receiver_clock_.NowTicks();
126  AdvanceClocks(base::TimeDelta::FromMilliseconds(30));
127  base::TimeTicks event_c_time = sender_clock_->NowTicks();
128
129  cast_environment_->Logging()->InsertFrameEvent(
130      event_c_time, kVideoAckReceived, rtp_timestamp, frame_id);
131
132  EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
133
134  cast_environment_->Logging()->InsertFrameEvent(
135      event_b_time, kVideoAckSent, rtp_timestamp, frame_id);
136
137  EXPECT_TRUE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
138
139  int64 lower_bound_ms = lower_bound.InMilliseconds();
140  int64 upper_bound_ms = upper_bound.InMilliseconds();
141  EXPECT_EQ(70, lower_bound_ms);
142  EXPECT_EQ(110, upper_bound_ms);
143  EXPECT_GE(true_offset_ms, lower_bound_ms);
144  EXPECT_LE(true_offset_ms, upper_bound_ms);
145}
146
147TEST_F(ReceiverTimeOffsetEstimatorImplTest, MultipleIterations) {
148  int64 true_offset_ms = 100;
149  receiver_clock_.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms));
150
151  base::TimeDelta lower_bound;
152  base::TimeDelta upper_bound;
153
154  RtpTimestamp rtp_timestamp_a = 0;
155  int frame_id_a = 0;
156  RtpTimestamp rtp_timestamp_b = 90;
157  int frame_id_b = 1;
158  RtpTimestamp rtp_timestamp_c = 180;
159  int frame_id_c = 2;
160
161  // Frame 1 times: [20, 30+100, 60]
162  // Frame 2 times: [30, 50+100, 55]
163  // Frame 3 times: [77, 80+100, 110]
164  // Bound should end up at [95, 103]
165  // Events times in chronological order: 20, 30 x2, 50, 55, 60, 77, 80, 110
166  AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
167  cast_environment_->Logging()->InsertEncodedFrameEvent(
168      sender_clock_->NowTicks(),
169      kVideoFrameEncoded,
170      rtp_timestamp_a,
171      frame_id_a,
172      1234,
173      true,
174      5678);
175
176  AdvanceClocks(base::TimeDelta::FromMilliseconds(10));
177  cast_environment_->Logging()->InsertEncodedFrameEvent(
178      sender_clock_->NowTicks(),
179      kVideoFrameEncoded,
180      rtp_timestamp_b,
181      frame_id_b,
182      1234,
183      true,
184      5678);
185  cast_environment_->Logging()->InsertFrameEvent(
186      receiver_clock_.NowTicks(), kVideoAckSent, rtp_timestamp_a, frame_id_a);
187
188  AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
189  cast_environment_->Logging()->InsertFrameEvent(
190      receiver_clock_.NowTicks(), kVideoAckSent, rtp_timestamp_b, frame_id_b);
191
192  AdvanceClocks(base::TimeDelta::FromMilliseconds(5));
193  cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(),
194                                                 kVideoAckReceived,
195                                                 rtp_timestamp_b,
196                                                 frame_id_b);
197
198  AdvanceClocks(base::TimeDelta::FromMilliseconds(5));
199  cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(),
200                                                 kVideoAckReceived,
201                                                 rtp_timestamp_a,
202                                                 frame_id_a);
203
204  AdvanceClocks(base::TimeDelta::FromMilliseconds(17));
205  cast_environment_->Logging()->InsertEncodedFrameEvent(
206      sender_clock_->NowTicks(),
207      kVideoFrameEncoded,
208      rtp_timestamp_c,
209      frame_id_c,
210      1234,
211      true,
212      5678);
213
214  AdvanceClocks(base::TimeDelta::FromMilliseconds(3));
215  cast_environment_->Logging()->InsertFrameEvent(
216      receiver_clock_.NowTicks(), kVideoAckSent, rtp_timestamp_c, frame_id_c);
217
218  AdvanceClocks(base::TimeDelta::FromMilliseconds(30));
219  cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(),
220                                                 kVideoAckReceived,
221                                                 rtp_timestamp_c,
222                                                 frame_id_c);
223
224  EXPECT_TRUE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound));
225  int64 lower_bound_ms = lower_bound.InMilliseconds();
226  int64 upper_bound_ms = upper_bound.InMilliseconds();
227  EXPECT_EQ(95, lower_bound_ms);
228  EXPECT_EQ(103, upper_bound_ms);
229  EXPECT_GE(true_offset_ms, lower_bound_ms);
230  EXPECT_LE(true_offset_ms, upper_bound_ms);
231}
232
233}  // namespace cast
234}  // namespace media
235