OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/ref_counted.h" | 5 #include "base/memory/ref_counted.h" |
6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
7 #include "base/rand_util.h" | |
7 #include "base/test/simple_test_tick_clock.h" | 8 #include "base/test/simple_test_tick_clock.h" |
8 #include "base/time/tick_clock.h" | 9 #include "base/time/tick_clock.h" |
9 #include "media/cast/cast_environment.h" | 10 #include "media/cast/cast_environment.h" |
10 #include "media/cast/logging/logging_defines.h" | 11 #include "media/cast/logging/logging_defines.h" |
11 #include "media/cast/logging/stats_event_subscriber.h" | 12 #include "media/cast/logging/stats_event_subscriber.h" |
13 #include "media/cast/test/fake_receiver_time_offset_estimator.h" | |
12 #include "media/cast/test/fake_single_thread_task_runner.h" | 14 #include "media/cast/test/fake_single_thread_task_runner.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
14 | 16 |
17 namespace { | |
18 const int kReceiverOffsetSecs = 100; | |
19 } | |
20 | |
15 namespace media { | 21 namespace media { |
16 namespace cast { | 22 namespace cast { |
17 | 23 |
18 class StatsEventSubscriberTest : public ::testing::Test { | 24 class StatsEventSubscriberTest : public ::testing::Test { |
19 protected: | 25 protected: |
20 StatsEventSubscriberTest() | 26 StatsEventSubscriberTest() |
21 : testing_clock_(new base::SimpleTestTickClock()), | 27 : sender_clock_(new base::SimpleTestTickClock()), |
22 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), | 28 task_runner_(new test::FakeSingleThreadTaskRunner(sender_clock_)), |
23 cast_environment_(new CastEnvironment( | 29 cast_environment_(new CastEnvironment( |
24 scoped_ptr<base::TickClock>(testing_clock_).Pass(), | 30 scoped_ptr<base::TickClock>(sender_clock_).Pass(), |
25 task_runner_, | 31 task_runner_, |
26 task_runner_, | 32 task_runner_, |
27 task_runner_)) {} | 33 task_runner_)), |
34 fake_offset_estimator_( | |
35 base::TimeDelta::FromSeconds(kReceiverOffsetSecs)) { | |
36 receiver_clock_.Advance(base::TimeDelta::FromSeconds(kReceiverOffsetSecs)); | |
37 cast_environment_->Logging()->AddRawEventSubscriber( | |
38 &fake_offset_estimator_); | |
39 } | |
28 | 40 |
29 virtual ~StatsEventSubscriberTest() { | 41 virtual ~StatsEventSubscriberTest() { |
30 if (subscriber_.get()) | 42 if (subscriber_.get()) |
31 cast_environment_->Logging()->RemoveRawEventSubscriber(subscriber_.get()); | 43 cast_environment_->Logging()->RemoveRawEventSubscriber(subscriber_.get()); |
44 cast_environment_->Logging()->RemoveRawEventSubscriber( | |
45 &fake_offset_estimator_); | |
46 } | |
47 | |
48 void AdvanceClocks(base::TimeDelta delta) { | |
49 sender_clock_->Advance(delta); | |
50 receiver_clock_.Advance(delta); | |
32 } | 51 } |
33 | 52 |
34 void Init(EventMediaType event_media_type) { | 53 void Init(EventMediaType event_media_type) { |
35 DCHECK(!subscriber_.get()); | 54 DCHECK(!subscriber_.get()); |
36 subscriber_.reset(new StatsEventSubscriber(event_media_type)); | 55 subscriber_.reset(new StatsEventSubscriber( |
56 event_media_type, cast_environment_->Clock(), &fake_offset_estimator_)); | |
37 cast_environment_->Logging()->AddRawEventSubscriber(subscriber_.get()); | 57 cast_environment_->Logging()->AddRawEventSubscriber(subscriber_.get()); |
38 } | 58 } |
39 | 59 |
40 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. | 60 base::SimpleTestTickClock* sender_clock_; // Owned by CastEnvironment. |
61 base::SimpleTestTickClock receiver_clock_; | |
41 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 62 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
42 scoped_refptr<CastEnvironment> cast_environment_; | 63 scoped_refptr<CastEnvironment> cast_environment_; |
64 test::FakeReceiverTimeOffsetEstimator fake_offset_estimator_; | |
43 scoped_ptr<StatsEventSubscriber> subscriber_; | 65 scoped_ptr<StatsEventSubscriber> subscriber_; |
44 }; | 66 }; |
45 | 67 |
46 TEST_F(StatsEventSubscriberTest, FrameStats) { | 68 TEST_F(StatsEventSubscriberTest, EmptyStats) { |
47 Init(VIDEO_EVENT); | 69 Init(VIDEO_EVENT); |
70 | |
71 StatsEventSubscriber::StatsMap stats_map; | |
72 subscriber_->GetStatsInternal(&stats_map); | |
73 | |
74 EXPECT_TRUE(stats_map.empty()); | |
75 } | |
76 | |
77 TEST_F(StatsEventSubscriberTest, Capture) { | |
78 Init(VIDEO_EVENT); | |
79 | |
48 uint32 rtp_timestamp = 0; | 80 uint32 rtp_timestamp = 0; |
49 uint32 frame_id = 0; | 81 uint32 frame_id = 0; |
50 int num_frames = 10; | 82 int num_frames = 10; |
51 int frame_size = 123; | 83 base::TimeTicks start_time = sender_clock_->NowTicks(); |
52 int delay_base_ms = 10; | |
53 base::TimeTicks now; | |
54 for (int i = 0; i < num_frames; i++) { | 84 for (int i = 0; i < num_frames; i++) { |
55 now = testing_clock_->NowTicks(); | 85 cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(), |
56 cast_environment_->Logging()->InsertFrameEvent( | 86 kVideoFrameCaptured, |
57 now, kVideoFrameReceived, rtp_timestamp, frame_id); | 87 rtp_timestamp, |
58 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(30)); | 88 frame_id); |
59 | 89 |
60 cast_environment_->Logging()->InsertEncodedFrameEvent( | 90 AdvanceClocks(base::TimeDelta::FromMilliseconds(30)); |
61 now, kVideoFrameEncoded, rtp_timestamp, i, frame_size, true); | 91 rtp_timestamp += 90; |
62 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(30)); | 92 frame_id++; |
63 | 93 } |
94 | |
95 base::TimeTicks end_time = sender_clock_->NowTicks(); | |
96 | |
97 StatsEventSubscriber::StatsMap stats_map; | |
98 subscriber_->GetStatsInternal(&stats_map); | |
99 | |
100 StatsEventSubscriber::StatsMap::iterator it = | |
101 stats_map.find(StatsEventSubscriber::CAPTURE_FPS); | |
102 ASSERT_NE(it, stats_map.end()); | |
103 | |
104 base::TimeDelta duration = end_time - start_time; | |
105 EXPECT_NEAR( | |
106 it->second, | |
107 static_cast<double>(num_frames) / duration.InMilliseconds() * 1000, | |
miu
2014/04/18 00:02:03
Use InMillisecondsF(), not InMilliseconds() throug
imcheng
2014/04/18 18:20:27
Done.
| |
108 0.05); | |
109 } | |
110 | |
111 TEST_F(StatsEventSubscriberTest, Encode) { | |
112 Init(VIDEO_EVENT); | |
113 | |
114 uint32 rtp_timestamp = 0; | |
115 uint32 frame_id = 0; | |
116 int num_frames = 10; | |
117 base::TimeTicks start_time = sender_clock_->NowTicks(); | |
118 int total_size = 0; | |
119 for (int i = 0; i < num_frames; i++) { | |
120 int size = 1000 + base::RandInt(-100, 100); | |
121 total_size += size; | |
122 cast_environment_->Logging()->InsertFrameEventWithSize( | |
123 sender_clock_->NowTicks(), | |
124 kVideoFrameEncoded, | |
125 rtp_timestamp, | |
126 frame_id, | |
127 size); | |
128 | |
129 AdvanceClocks(base::TimeDelta::FromMilliseconds(30)); | |
130 rtp_timestamp += 90; | |
131 frame_id++; | |
132 } | |
133 | |
134 base::TimeTicks end_time = sender_clock_->NowTicks(); | |
135 | |
136 StatsEventSubscriber::StatsMap stats_map; | |
137 subscriber_->GetStatsInternal(&stats_map); | |
138 | |
139 StatsEventSubscriber::StatsMap::iterator it = | |
140 stats_map.find(StatsEventSubscriber::ENCODE_FPS); | |
141 ASSERT_NE(it, stats_map.end()); | |
142 | |
143 base::TimeDelta duration = end_time - start_time; | |
144 EXPECT_NEAR( | |
145 it->second, | |
146 static_cast<double>(num_frames) / duration.InMilliseconds() * 1000, | |
147 0.05); | |
148 | |
149 it = stats_map.find(StatsEventSubscriber::ENCODE_KBPS); | |
150 ASSERT_NE(it, stats_map.end()); | |
151 | |
152 EXPECT_NEAR(it->second, | |
153 static_cast<double>(total_size) / duration.InMilliseconds() * 8, | |
154 0.05); | |
155 } | |
156 | |
157 TEST_F(StatsEventSubscriberTest, Decode) { | |
158 Init(VIDEO_EVENT); | |
159 | |
160 uint32 rtp_timestamp = 0; | |
161 uint32 frame_id = 0; | |
162 int num_frames = 10; | |
163 base::TimeTicks start_time = sender_clock_->NowTicks(); | |
164 for (int i = 0; i < num_frames; i++) { | |
165 cast_environment_->Logging()->InsertFrameEvent(receiver_clock_.NowTicks(), | |
166 kVideoFrameDecoded, | |
167 rtp_timestamp, | |
168 frame_id); | |
169 | |
170 AdvanceClocks(base::TimeDelta::FromMilliseconds(30)); | |
171 rtp_timestamp += 90; | |
172 frame_id++; | |
173 } | |
174 | |
175 base::TimeTicks end_time = sender_clock_->NowTicks(); | |
176 | |
177 StatsEventSubscriber::StatsMap stats_map; | |
178 subscriber_->GetStatsInternal(&stats_map); | |
179 | |
180 StatsEventSubscriber::StatsMap::iterator it = | |
181 stats_map.find(StatsEventSubscriber::DECODE_FPS); | |
182 ASSERT_NE(it, stats_map.end()); | |
183 | |
184 base::TimeDelta duration = end_time - start_time; | |
185 EXPECT_NEAR( | |
186 it->second, | |
187 static_cast<double>(num_frames) / duration.InMilliseconds() * 1000, | |
188 0.05); | |
189 } | |
190 | |
191 TEST_F(StatsEventSubscriberTest, PlayoutDelay) { | |
192 Init(VIDEO_EVENT); | |
193 | |
194 uint32 rtp_timestamp = 0; | |
195 uint32 frame_id = 0; | |
196 int num_frames = 10; | |
197 int total_delay_ms = 0; | |
198 for (int i = 0; i < num_frames; i++) { | |
199 int delay_ms = base::RandInt(-50, 50); | |
200 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(delay_ms); | |
201 total_delay_ms += delay_ms; | |
64 cast_environment_->Logging()->InsertFrameEventWithDelay( | 202 cast_environment_->Logging()->InsertFrameEventWithDelay( |
65 now, | 203 receiver_clock_.NowTicks(), |
66 kVideoRenderDelay, | 204 kVideoRenderDelay, |
67 rtp_timestamp, | 205 rtp_timestamp, |
68 i, | 206 frame_id, |
69 base::TimeDelta::FromMilliseconds(i * delay_base_ms)); | 207 delay); |
70 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(30)); | 208 |
71 | 209 AdvanceClocks(base::TimeDelta::FromMilliseconds(30)); |
72 rtp_timestamp += 90; | 210 rtp_timestamp += 90; |
73 } | 211 frame_id++; |
74 | 212 } |
75 // Verify stats. | 213 |
76 FrameStatsMap frame_stats; | 214 StatsEventSubscriber::StatsMap stats_map; |
77 subscriber_->GetFrameStats(&frame_stats); | 215 subscriber_->GetStatsInternal(&stats_map); |
78 | 216 |
79 // Size of stats equals the number of events. | 217 StatsEventSubscriber::StatsMap::iterator it = |
80 EXPECT_EQ(3u, frame_stats.size()); | 218 stats_map.find(StatsEventSubscriber::AVG_PLAYOUT_DELAY_MS); |
81 FrameStatsMap::const_iterator it = frame_stats.find(kVideoFrameReceived); | 219 ASSERT_NE(it, stats_map.end()); |
82 ASSERT_TRUE(it != frame_stats.end()); | 220 |
83 EXPECT_EQ(num_frames, it->second.event_counter); | 221 EXPECT_NEAR( |
84 | 222 it->second, static_cast<double>(total_delay_ms) / num_frames, 0.05); |
85 it = frame_stats.find(kVideoFrameEncoded); | 223 } |
86 ASSERT_TRUE(it != frame_stats.end()); | 224 |
87 | 225 TEST_F(StatsEventSubscriberTest, E2ELatency) { |
88 EXPECT_EQ(num_frames * frame_size, static_cast<int>(it->second.sum_size)); | 226 Init(VIDEO_EVENT); |
89 | 227 |
90 it = frame_stats.find(kVideoRenderDelay); | |
91 ASSERT_TRUE(it != frame_stats.end()); | |
92 | |
93 EXPECT_EQ(0, it->second.min_delay.InMilliseconds()); | |
94 EXPECT_EQ((num_frames - 1) * delay_base_ms, | |
95 it->second.max_delay.InMilliseconds()); | |
96 EXPECT_EQ((num_frames - 1) * num_frames / 2 * delay_base_ms, | |
97 it->second.sum_delay.InMilliseconds()); | |
98 } | |
99 | |
100 TEST_F(StatsEventSubscriberTest, PacketStats) { | |
101 Init(AUDIO_EVENT); | |
102 uint32 rtp_timestamp = 0; | 228 uint32 rtp_timestamp = 0; |
103 uint32 frame_id = 0; | 229 uint32 frame_id = 0; |
230 int num_frames = 10; | |
231 int total_latency_ms = 0; | |
232 for (int i = 0; i < num_frames; i++) { | |
233 cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(), | |
234 kVideoFrameCaptured, | |
235 rtp_timestamp, | |
236 frame_id); | |
237 | |
238 int latency_ms = 100 + base::RandInt(-50, 50); | |
239 AdvanceClocks(base::TimeDelta::FromMilliseconds(latency_ms)); | |
240 | |
241 int delay_ms = base::RandInt(-50, 50); | |
242 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(delay_ms); | |
243 total_latency_ms += latency_ms + delay_ms; | |
244 | |
245 cast_environment_->Logging()->InsertFrameEventWithDelay( | |
246 receiver_clock_.NowTicks(), | |
247 kVideoRenderDelay, | |
248 rtp_timestamp, | |
249 frame_id, | |
250 delay); | |
251 | |
252 rtp_timestamp += 90; | |
253 frame_id++; | |
254 } | |
255 | |
256 StatsEventSubscriber::StatsMap stats_map; | |
257 subscriber_->GetStatsInternal(&stats_map); | |
258 | |
259 StatsEventSubscriber::StatsMap::iterator it = | |
260 stats_map.find(StatsEventSubscriber::AVG_E2E_LATENCY_MS); | |
261 ASSERT_NE(it, stats_map.end()); | |
262 | |
263 EXPECT_NEAR( | |
264 it->second, static_cast<double>(total_latency_ms) / num_frames, 0.05); | |
265 } | |
266 | |
267 TEST_F(StatsEventSubscriberTest, Packets) { | |
268 Init(VIDEO_EVENT); | |
269 | |
270 uint32 rtp_timestamp = 0; | |
104 int num_packets = 10; | 271 int num_packets = 10; |
105 int packet_size = 123; | 272 int num_latency_recorded_packets = 0; |
106 base::TimeTicks first_event_time = testing_clock_->NowTicks(); | 273 base::TimeTicks start_time = sender_clock_->NowTicks(); |
107 base::TimeTicks now; | 274 int total_size = 0; |
275 int retransmit_total_size = 0; | |
276 int total_latency_ms = 0; | |
277 int num_packets_sent = 0; | |
278 int num_packets_retransmitted = 0; | |
279 // Every 2nd packet will be retransmitted once. | |
280 // Every 4th packet will be retransmitted twice. | |
281 // Every 8th packet will be retransmitted 3 times. | |
108 for (int i = 0; i < num_packets; i++) { | 282 for (int i = 0; i < num_packets; i++) { |
109 now = testing_clock_->NowTicks(); | 283 int size = 1000 + base::RandInt(-100, 100); |
110 cast_environment_->Logging()->InsertPacketEvent(now, | 284 total_size += size; |
111 kAudioPacketSentToPacer, | 285 |
286 cast_environment_->Logging()->InsertPacketEvent(sender_clock_->NowTicks(), | |
287 kVideoPacketSentToNetwork, | |
112 rtp_timestamp, | 288 rtp_timestamp, |
113 frame_id, | |
114 0, | 289 0, |
115 10, | 290 i, |
116 packet_size); | 291 num_packets - 1, |
117 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(30)); | 292 size); |
118 } | 293 num_packets_sent++; |
119 | 294 |
120 PacketStatsMap stats_map; | 295 int latency_ms = 20 + base::RandInt(-10, 10); |
121 subscriber_->GetPacketStats(&stats_map); | 296 // Latency is only recorded for packets that aren't retransmitted. |
122 | 297 if (i % 2 != 0) { |
123 // Size of stats equals the number of event types. | 298 total_latency_ms += latency_ms; |
124 EXPECT_EQ(1u, stats_map.size()); | 299 num_latency_recorded_packets++; |
125 PacketStatsMap::const_iterator it = stats_map.find(kAudioPacketSentToPacer); | 300 } |
126 ASSERT_NE(stats_map.end(), it); | 301 |
127 | 302 AdvanceClocks(base::TimeDelta::FromMilliseconds(latency_ms)); |
128 EXPECT_EQ(first_event_time, it->second.first_event_time); | 303 |
129 EXPECT_EQ(now, it->second.last_event_time); | 304 base::TimeTicks received_time = receiver_clock_.NowTicks(); |
130 EXPECT_EQ(num_packets, it->second.event_counter); | 305 |
131 EXPECT_EQ(num_packets * packet_size, static_cast<int>(it->second.sum_size)); | 306 // Retransmission 1. |
132 } | 307 AdvanceClocks(base::TimeDelta::FromMilliseconds(10)); |
133 | 308 if (i % 2 == 0) { |
134 TEST_F(StatsEventSubscriberTest, GenericStats) { | 309 cast_environment_->Logging()->InsertPacketEvent( |
135 Init(OTHER_EVENT); | 310 receiver_clock_.NowTicks(), |
136 int num_generic_events = 10; | 311 kVideoPacketRetransmitted, |
137 int value = 123; | 312 rtp_timestamp, |
138 for (int i = 0; i < num_generic_events; i++) { | 313 0, |
139 cast_environment_->Logging()->InsertGenericEvent( | 314 i, |
140 testing_clock_->NowTicks(), kRttMs, value); | 315 num_packets - 1, |
141 } | 316 size); |
142 | 317 retransmit_total_size += size; |
143 GenericStatsMap stats_map; | 318 num_packets_sent++; |
144 subscriber_->GetGenericStats(&stats_map); | 319 num_packets_retransmitted++; |
145 | 320 } |
146 EXPECT_EQ(1u, stats_map.size()); | 321 |
147 GenericStatsMap::const_iterator it = stats_map.find(kRttMs); | 322 // Retransmission 2. |
148 ASSERT_NE(stats_map.end(), it); | 323 AdvanceClocks(base::TimeDelta::FromMilliseconds(10)); |
149 | 324 if (i % 4 == 0) { |
150 EXPECT_EQ(num_generic_events, it->second.event_counter); | 325 cast_environment_->Logging()->InsertPacketEvent( |
151 EXPECT_EQ(num_generic_events * value, it->second.sum); | 326 receiver_clock_.NowTicks(), |
152 EXPECT_EQ(static_cast<uint64>(num_generic_events * value * value), | 327 kVideoPacketRetransmitted, |
153 it->second.sum_squared); | 328 rtp_timestamp, |
154 EXPECT_LE(value, it->second.min); | 329 0, |
155 EXPECT_GE(value, it->second.max); | 330 i, |
156 } | 331 num_packets - 1, |
157 | 332 size); |
158 TEST_F(StatsEventSubscriberTest, Reset) { | 333 retransmit_total_size += size; |
159 Init(VIDEO_EVENT); | 334 num_packets_sent++; |
160 cast_environment_->Logging()->InsertFrameEvent( | 335 num_packets_retransmitted++; |
161 testing_clock_->NowTicks(), kVideoFrameReceived, 0, 0); | 336 } |
162 | 337 |
163 FrameStatsMap frame_stats; | 338 // Retransmission 3. |
164 subscriber_->GetFrameStats(&frame_stats); | 339 AdvanceClocks(base::TimeDelta::FromMilliseconds(10)); |
165 EXPECT_EQ(1u, frame_stats.size()); | 340 if (i % 8 == 0) { |
166 | 341 cast_environment_->Logging()->InsertPacketEvent( |
167 subscriber_->Reset(); | 342 receiver_clock_.NowTicks(), |
168 subscriber_->GetFrameStats(&frame_stats); | 343 kVideoPacketRetransmitted, |
169 EXPECT_TRUE(frame_stats.empty()); | 344 rtp_timestamp, |
345 0, | |
346 i, | |
347 num_packets - 1, | |
348 size); | |
349 retransmit_total_size += size; | |
350 num_packets_sent++; | |
351 num_packets_retransmitted++; | |
352 } | |
353 | |
354 cast_environment_->Logging()->InsertPacketEvent(received_time, | |
355 kVideoPacketReceived, | |
356 rtp_timestamp, | |
357 0, | |
358 i, | |
359 num_packets - 1, | |
360 size); | |
361 } | |
362 | |
363 base::TimeTicks end_time = sender_clock_->NowTicks(); | |
364 base::TimeDelta duration = end_time - start_time; | |
365 | |
366 StatsEventSubscriber::StatsMap stats_map; | |
367 subscriber_->GetStatsInternal(&stats_map); | |
368 | |
369 // Measure AVG_NETWORK_LATENCY_MS, TRANSMISSION_KBPS, RETRANSMISSION_KBPS, | |
370 // and PACKET_LOSS_PERCENTAGE. | |
371 StatsEventSubscriber::StatsMap::iterator it = | |
372 stats_map.find(StatsEventSubscriber::AVG_NETWORK_LATENCY_MS); | |
373 ASSERT_NE(it, stats_map.end()); | |
374 | |
375 EXPECT_NEAR( | |
376 it->second, | |
377 static_cast<double>(total_latency_ms) / num_latency_recorded_packets, | |
378 0.05); | |
379 | |
380 it = stats_map.find(StatsEventSubscriber::TRANSMISSION_KBPS); | |
381 ASSERT_NE(it, stats_map.end()); | |
382 | |
383 EXPECT_NEAR(it->second, | |
384 static_cast<double>(total_size) / duration.InMilliseconds() * 8, | |
385 0.05); | |
386 | |
387 it = stats_map.find(StatsEventSubscriber::RETRANSMISSION_KBPS); | |
388 ASSERT_NE(it, stats_map.end()); | |
389 | |
390 EXPECT_NEAR(it->second, | |
391 static_cast<double>(retransmit_total_size) / | |
392 duration.InMilliseconds() * 8, | |
393 0.05); | |
394 | |
395 it = stats_map.find(StatsEventSubscriber::PACKET_LOSS_PERCENTAGE); | |
396 ASSERT_NE(it, stats_map.end()); | |
397 | |
398 EXPECT_NEAR( | |
399 it->second, | |
400 static_cast<double>(num_packets_retransmitted) / num_packets_sent * 100, | |
401 0.05); | |
170 } | 402 } |
171 | 403 |
miu
2014/04/18 00:02:03
Given the issues of precision found in the .cc fil
imcheng
2014/04/18 18:20:27
I have converted all AdvanceClock args to have sub
| |
172 } // namespace cast | 404 } // namespace cast |
173 } // namespace media | 405 } // namespace media |
OLD | NEW |