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 15 namespace media { 16 namespace cast { 17 18 class 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]. 52 TEST_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 FRAME_ENCODED, VIDEO_EVENT, 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(), FRAME_ACK_SENT, VIDEO_EVENT, 80 rtp_timestamp, frame_id); 81 82 EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound)); 83 84 AdvanceClocks(base::TimeDelta::FromMilliseconds(30)); 85 cast_environment_->Logging()->InsertFrameEvent( 86 sender_clock_->NowTicks(), FRAME_ACK_RECEIVED, VIDEO_EVENT, 87 rtp_timestamp, frame_id); 88 89 EXPECT_TRUE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound)); 90 91 int64 lower_bound_ms = lower_bound.InMilliseconds(); 92 int64 upper_bound_ms = upper_bound.InMilliseconds(); 93 EXPECT_EQ(70, lower_bound_ms); 94 EXPECT_EQ(110, upper_bound_ms); 95 EXPECT_GE(true_offset_ms, lower_bound_ms); 96 EXPECT_LE(true_offset_ms, upper_bound_ms); 97 } 98 99 // Same scenario as above, but event C arrives before event B. It doens't mean 100 // event C occurred before event B. 101 TEST_F(ReceiverTimeOffsetEstimatorImplTest, EventCArrivesBeforeEventB) { 102 int64 true_offset_ms = 100; 103 receiver_clock_.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms)); 104 105 base::TimeDelta lower_bound; 106 base::TimeDelta upper_bound; 107 108 EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound)); 109 110 RtpTimestamp rtp_timestamp = 0; 111 uint32 frame_id = 0; 112 113 AdvanceClocks(base::TimeDelta::FromMilliseconds(20)); 114 115 cast_environment_->Logging()->InsertEncodedFrameEvent( 116 sender_clock_->NowTicks(), 117 FRAME_ENCODED, VIDEO_EVENT, 118 rtp_timestamp, 119 frame_id, 120 1234, 121 true, 122 5678); 123 124 EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound)); 125 126 AdvanceClocks(base::TimeDelta::FromMilliseconds(10)); 127 base::TimeTicks event_b_time = receiver_clock_.NowTicks(); 128 AdvanceClocks(base::TimeDelta::FromMilliseconds(30)); 129 base::TimeTicks event_c_time = sender_clock_->NowTicks(); 130 131 cast_environment_->Logging()->InsertFrameEvent( 132 event_c_time, FRAME_ACK_RECEIVED, VIDEO_EVENT, rtp_timestamp, frame_id); 133 134 EXPECT_FALSE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound)); 135 136 cast_environment_->Logging()->InsertFrameEvent( 137 event_b_time, FRAME_ACK_SENT, VIDEO_EVENT, rtp_timestamp, frame_id); 138 139 EXPECT_TRUE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound)); 140 141 int64 lower_bound_ms = lower_bound.InMilliseconds(); 142 int64 upper_bound_ms = upper_bound.InMilliseconds(); 143 EXPECT_EQ(70, lower_bound_ms); 144 EXPECT_EQ(110, upper_bound_ms); 145 EXPECT_GE(true_offset_ms, lower_bound_ms); 146 EXPECT_LE(true_offset_ms, upper_bound_ms); 147 } 148 149 TEST_F(ReceiverTimeOffsetEstimatorImplTest, MultipleIterations) { 150 int64 true_offset_ms = 100; 151 receiver_clock_.Advance(base::TimeDelta::FromMilliseconds(true_offset_ms)); 152 153 base::TimeDelta lower_bound; 154 base::TimeDelta upper_bound; 155 156 RtpTimestamp rtp_timestamp_a = 0; 157 int frame_id_a = 0; 158 RtpTimestamp rtp_timestamp_b = 90; 159 int frame_id_b = 1; 160 RtpTimestamp rtp_timestamp_c = 180; 161 int frame_id_c = 2; 162 163 // Frame 1 times: [20, 30+100, 60] 164 // Frame 2 times: [30, 50+100, 55] 165 // Frame 3 times: [77, 80+100, 110] 166 // Bound should end up at [95, 103] 167 // Events times in chronological order: 20, 30 x2, 50, 55, 60, 77, 80, 110 168 AdvanceClocks(base::TimeDelta::FromMilliseconds(20)); 169 cast_environment_->Logging()->InsertEncodedFrameEvent( 170 sender_clock_->NowTicks(), 171 FRAME_ENCODED, VIDEO_EVENT, 172 rtp_timestamp_a, 173 frame_id_a, 174 1234, 175 true, 176 5678); 177 178 AdvanceClocks(base::TimeDelta::FromMilliseconds(10)); 179 cast_environment_->Logging()->InsertEncodedFrameEvent( 180 sender_clock_->NowTicks(), 181 FRAME_ENCODED, VIDEO_EVENT, 182 rtp_timestamp_b, 183 frame_id_b, 184 1234, 185 true, 186 5678); 187 cast_environment_->Logging()->InsertFrameEvent( 188 receiver_clock_.NowTicks(), FRAME_ACK_SENT, VIDEO_EVENT, 189 rtp_timestamp_a, frame_id_a); 190 191 AdvanceClocks(base::TimeDelta::FromMilliseconds(20)); 192 cast_environment_->Logging()->InsertFrameEvent( 193 receiver_clock_.NowTicks(), FRAME_ACK_SENT, VIDEO_EVENT, 194 rtp_timestamp_b, frame_id_b); 195 196 AdvanceClocks(base::TimeDelta::FromMilliseconds(5)); 197 cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(), 198 FRAME_ACK_RECEIVED, 199 VIDEO_EVENT, 200 rtp_timestamp_b, 201 frame_id_b); 202 203 AdvanceClocks(base::TimeDelta::FromMilliseconds(5)); 204 cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(), 205 FRAME_ACK_RECEIVED, 206 VIDEO_EVENT, 207 rtp_timestamp_a, 208 frame_id_a); 209 210 AdvanceClocks(base::TimeDelta::FromMilliseconds(17)); 211 cast_environment_->Logging()->InsertEncodedFrameEvent( 212 sender_clock_->NowTicks(), 213 FRAME_ENCODED, VIDEO_EVENT, 214 rtp_timestamp_c, 215 frame_id_c, 216 1234, 217 true, 218 5678); 219 220 AdvanceClocks(base::TimeDelta::FromMilliseconds(3)); 221 cast_environment_->Logging()->InsertFrameEvent( 222 receiver_clock_.NowTicks(), FRAME_ACK_SENT, VIDEO_EVENT, 223 rtp_timestamp_c, frame_id_c); 224 225 AdvanceClocks(base::TimeDelta::FromMilliseconds(30)); 226 cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(), 227 FRAME_ACK_RECEIVED, 228 VIDEO_EVENT, 229 rtp_timestamp_c, 230 frame_id_c); 231 232 EXPECT_TRUE(estimator_.GetReceiverOffsetBounds(&lower_bound, &upper_bound)); 233 int64 lower_bound_ms = lower_bound.InMilliseconds(); 234 int64 upper_bound_ms = upper_bound.InMilliseconds(); 235 EXPECT_EQ(95, lower_bound_ms); 236 EXPECT_EQ(103, upper_bound_ms); 237 EXPECT_GE(true_offset_ms, lower_bound_ms); 238 EXPECT_LE(true_offset_ms, upper_bound_ms); 239 } 240 241 } // namespace cast 242 } // namespace media 243