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.
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"
18 class ReceiverTimeOffsetEstimatorImplTest
: public ::testing::Test
{
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(),
28 cast_environment_
->Logging()->AddRawEventSubscriber(&estimator_
);
31 ~ReceiverTimeOffsetEstimatorImplTest() override
{
32 cast_environment_
->Logging()->RemoveRawEventSubscriber(&estimator_
);
35 void AdvanceClocks(base::TimeDelta time
) {
36 sender_clock_
->Advance(time
);
37 receiver_clock_
.Advance(time
);
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_
;
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].
52 TEST_F(ReceiverTimeOffsetEstimatorImplTest
, EstimateOffset
) {
53 int64 true_offset_ms
= 100;
54 receiver_clock_
.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms
));
56 base::TimeDelta lower_bound
;
57 base::TimeDelta upper_bound
;
59 EXPECT_FALSE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
61 RtpTimestamp rtp_timestamp
= 0;
64 AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
66 cast_environment_
->Logging()->InsertEncodedFrameEvent(
67 sender_clock_
->NowTicks(),
68 FRAME_ENCODED
, VIDEO_EVENT
,
77 cast_environment_
->Logging()->InsertPacketEvent(
78 sender_clock_
->NowTicks(),
79 PACKET_SENT_TO_NETWORK
, VIDEO_EVENT
,
84 EXPECT_FALSE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
86 AdvanceClocks(base::TimeDelta::FromMilliseconds(10));
87 cast_environment_
->Logging()->InsertFrameEvent(
88 receiver_clock_
.NowTicks(), FRAME_ACK_SENT
, VIDEO_EVENT
,
89 rtp_timestamp
, frame_id
);
91 cast_environment_
->Logging()->InsertPacketEvent(
92 receiver_clock_
.NowTicks(),
93 PACKET_RECEIVED
, VIDEO_EVENT
,
98 EXPECT_FALSE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
100 AdvanceClocks(base::TimeDelta::FromMilliseconds(30));
101 cast_environment_
->Logging()->InsertFrameEvent(
102 sender_clock_
->NowTicks(), FRAME_ACK_RECEIVED
, VIDEO_EVENT
,
103 rtp_timestamp
, frame_id
);
105 EXPECT_TRUE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
107 int64 lower_bound_ms
= lower_bound
.InMilliseconds();
108 int64 upper_bound_ms
= upper_bound
.InMilliseconds();
109 EXPECT_EQ(70, lower_bound_ms
);
110 EXPECT_EQ(110, upper_bound_ms
);
111 EXPECT_GE(true_offset_ms
, lower_bound_ms
);
112 EXPECT_LE(true_offset_ms
, upper_bound_ms
);
115 // Same scenario as above, but event C arrives before event B. It doens't mean
116 // event C occurred before event B.
117 TEST_F(ReceiverTimeOffsetEstimatorImplTest
, EventCArrivesBeforeEventB
) {
118 int64 true_offset_ms
= 100;
119 receiver_clock_
.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms
));
121 base::TimeDelta lower_bound
;
122 base::TimeDelta upper_bound
;
124 EXPECT_FALSE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
126 RtpTimestamp rtp_timestamp
= 0;
129 AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
131 cast_environment_
->Logging()->InsertEncodedFrameEvent(
132 sender_clock_
->NowTicks(),
133 FRAME_ENCODED
, VIDEO_EVENT
,
142 cast_environment_
->Logging()->InsertPacketEvent(
143 sender_clock_
->NowTicks(),
144 PACKET_SENT_TO_NETWORK
, VIDEO_EVENT
,
149 EXPECT_FALSE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
151 AdvanceClocks(base::TimeDelta::FromMilliseconds(10));
152 base::TimeTicks event_b_time
= receiver_clock_
.NowTicks();
153 AdvanceClocks(base::TimeDelta::FromMilliseconds(30));
154 base::TimeTicks event_c_time
= sender_clock_
->NowTicks();
156 cast_environment_
->Logging()->InsertFrameEvent(
157 event_c_time
, FRAME_ACK_RECEIVED
, VIDEO_EVENT
, rtp_timestamp
, frame_id
);
159 EXPECT_FALSE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
161 cast_environment_
->Logging()->InsertPacketEvent(
163 PACKET_RECEIVED
, VIDEO_EVENT
,
168 cast_environment_
->Logging()->InsertFrameEvent(
169 event_b_time
, FRAME_ACK_SENT
, VIDEO_EVENT
, rtp_timestamp
, frame_id
);
171 EXPECT_TRUE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
173 int64 lower_bound_ms
= lower_bound
.InMilliseconds();
174 int64 upper_bound_ms
= upper_bound
.InMilliseconds();
175 EXPECT_EQ(70, lower_bound_ms
);
176 EXPECT_EQ(110, upper_bound_ms
);
177 EXPECT_GE(true_offset_ms
, lower_bound_ms
);
178 EXPECT_LE(true_offset_ms
, upper_bound_ms
);
181 TEST_F(ReceiverTimeOffsetEstimatorImplTest
, MultipleIterations
) {
182 int64 true_offset_ms
= 100;
183 receiver_clock_
.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms
));
185 base::TimeDelta lower_bound
;
186 base::TimeDelta upper_bound
;
188 RtpTimestamp rtp_timestamp_a
= 0;
190 RtpTimestamp rtp_timestamp_b
= 90;
192 RtpTimestamp rtp_timestamp_c
= 180;
195 // Frame 1 times: [20, 30+100, 60]
196 // Frame 2 times: [30, 50+100, 55]
197 // Frame 3 times: [77, 80+100, 110]
198 // Bound should end up at [95, 103]
199 // Events times in chronological order: 20, 30 x2, 50, 55, 60, 77, 80, 110
200 AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
201 cast_environment_
->Logging()->InsertEncodedFrameEvent(
202 sender_clock_
->NowTicks(),
203 FRAME_ENCODED
, VIDEO_EVENT
,
212 cast_environment_
->Logging()->InsertPacketEvent(
213 sender_clock_
->NowTicks(),
214 PACKET_SENT_TO_NETWORK
, VIDEO_EVENT
,
219 AdvanceClocks(base::TimeDelta::FromMilliseconds(10));
220 cast_environment_
->Logging()->InsertEncodedFrameEvent(
221 sender_clock_
->NowTicks(),
222 FRAME_ENCODED
, VIDEO_EVENT
,
231 cast_environment_
->Logging()->InsertPacketEvent(
232 sender_clock_
->NowTicks(),
233 PACKET_SENT_TO_NETWORK
, VIDEO_EVENT
,
238 cast_environment_
->Logging()->InsertFrameEvent(
239 receiver_clock_
.NowTicks(), FRAME_ACK_SENT
, VIDEO_EVENT
,
240 rtp_timestamp_a
, frame_id_a
);
242 AdvanceClocks(base::TimeDelta::FromMilliseconds(20));
244 cast_environment_
->Logging()->InsertPacketEvent(
245 receiver_clock_
.NowTicks(),
246 PACKET_RECEIVED
, VIDEO_EVENT
,
251 cast_environment_
->Logging()->InsertFrameEvent(
252 receiver_clock_
.NowTicks(), FRAME_ACK_SENT
, VIDEO_EVENT
,
253 rtp_timestamp_b
, frame_id_b
);
255 AdvanceClocks(base::TimeDelta::FromMilliseconds(5));
256 cast_environment_
->Logging()->InsertFrameEvent(sender_clock_
->NowTicks(),
262 AdvanceClocks(base::TimeDelta::FromMilliseconds(5));
263 cast_environment_
->Logging()->InsertFrameEvent(sender_clock_
->NowTicks(),
269 AdvanceClocks(base::TimeDelta::FromMilliseconds(17));
270 cast_environment_
->Logging()->InsertEncodedFrameEvent(
271 sender_clock_
->NowTicks(),
272 FRAME_ENCODED
, VIDEO_EVENT
,
281 cast_environment_
->Logging()->InsertPacketEvent(
282 sender_clock_
->NowTicks(),
283 PACKET_SENT_TO_NETWORK
, VIDEO_EVENT
,
288 AdvanceClocks(base::TimeDelta::FromMilliseconds(3));
289 cast_environment_
->Logging()->InsertPacketEvent(
290 receiver_clock_
.NowTicks(),
291 PACKET_RECEIVED
, VIDEO_EVENT
,
296 cast_environment_
->Logging()->InsertFrameEvent(
297 receiver_clock_
.NowTicks(), FRAME_ACK_SENT
, VIDEO_EVENT
,
298 rtp_timestamp_c
, frame_id_c
);
300 AdvanceClocks(base::TimeDelta::FromMilliseconds(30));
301 cast_environment_
->Logging()->InsertFrameEvent(sender_clock_
->NowTicks(),
307 EXPECT_TRUE(estimator_
.GetReceiverOffsetBounds(&lower_bound
, &upper_bound
));
308 int64 lower_bound_ms
= lower_bound
.InMilliseconds();
309 int64 upper_bound_ms
= upper_bound
.InMilliseconds();
310 EXPECT_GT(lower_bound_ms
, 90);
311 EXPECT_LE(lower_bound_ms
, true_offset_ms
);
312 EXPECT_LT(upper_bound_ms
, 150);
313 EXPECT_GT(upper_bound_ms
, true_offset_ms
);