Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: content/browser/renderer_host/media/video_capture_oracle_unittest.cc

Issue 101843005: Convert video capture pipline to base::TimeTicks (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 9890509b Rebase, Windows compile fixes Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "content/browser/renderer_host/media/video_capture_oracle.h" 5 #include "content/browser/renderer_host/media/video_capture_oracle.h"
6 6
7 #include "base/strings/stringprintf.h" 7 #include "base/strings/stringprintf.h"
8 #include "base/time/time.h" 8 #include "base/time/time.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 10
11 namespace content { 11 namespace content {
12 namespace { 12 namespace {
13 13
14 void SteadyStateSampleAndAdvance(base::TimeDelta vsync, 14 void SteadyStateSampleAndAdvance(base::TimeDelta vsync,
15 SmoothEventSampler* sampler, base::Time* t) { 15 SmoothEventSampler* sampler,
16 base::TimeTicks* t) {
16 ASSERT_TRUE(sampler->AddEventAndConsiderSampling(*t)); 17 ASSERT_TRUE(sampler->AddEventAndConsiderSampling(*t));
17 ASSERT_TRUE(sampler->HasUnrecordedEvent()); 18 ASSERT_TRUE(sampler->HasUnrecordedEvent());
18 sampler->RecordSample(); 19 sampler->RecordSample();
19 ASSERT_FALSE(sampler->HasUnrecordedEvent()); 20 ASSERT_FALSE(sampler->HasUnrecordedEvent());
20 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t)); 21 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
21 *t += vsync; 22 *t += vsync;
22 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t)); 23 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
23 } 24 }
24 25
25 void SteadyStateNoSampleAndAdvance(base::TimeDelta vsync, 26 void SteadyStateNoSampleAndAdvance(base::TimeDelta vsync,
26 SmoothEventSampler* sampler, base::Time* t) { 27 SmoothEventSampler* sampler,
28 base::TimeTicks* t) {
27 ASSERT_FALSE(sampler->AddEventAndConsiderSampling(*t)); 29 ASSERT_FALSE(sampler->AddEventAndConsiderSampling(*t));
28 ASSERT_TRUE(sampler->HasUnrecordedEvent()); 30 ASSERT_TRUE(sampler->HasUnrecordedEvent());
29 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t)); 31 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
30 *t += vsync; 32 *t += vsync;
31 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t)); 33 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
32 } 34 }
33 35
36 void TimeTicksFromString(const char* string, base::TimeTicks* t) {
37 base::Time time;
38 ASSERT_TRUE(base::Time::FromString(string, &time));
39 *t = base::TimeTicks::UnixEpoch() + (time - base::Time::UnixEpoch());
40 }
41
34 void TestRedundantCaptureStrategy(base::TimeDelta capture_period, 42 void TestRedundantCaptureStrategy(base::TimeDelta capture_period,
35 int redundant_capture_goal, 43 int redundant_capture_goal,
36 SmoothEventSampler* sampler, base::Time* t) { 44 SmoothEventSampler* sampler,
45 base::TimeTicks* t) {
37 // Before any events have been considered, we're overdue for sampling. 46 // Before any events have been considered, we're overdue for sampling.
38 ASSERT_TRUE(sampler->IsOverdueForSamplingAt(*t)); 47 ASSERT_TRUE(sampler->IsOverdueForSamplingAt(*t));
39 48
40 // Consider the first event. We want to sample that. 49 // Consider the first event. We want to sample that.
41 ASSERT_FALSE(sampler->HasUnrecordedEvent()); 50 ASSERT_FALSE(sampler->HasUnrecordedEvent());
42 ASSERT_TRUE(sampler->AddEventAndConsiderSampling(*t)); 51 ASSERT_TRUE(sampler->AddEventAndConsiderSampling(*t));
43 ASSERT_TRUE(sampler->HasUnrecordedEvent()); 52 ASSERT_TRUE(sampler->HasUnrecordedEvent());
44 sampler->RecordSample(); 53 sampler->RecordSample();
45 ASSERT_FALSE(sampler->HasUnrecordedEvent()); 54 ASSERT_FALSE(sampler->HasUnrecordedEvent());
46 55
(...skipping 14 matching lines...) Expand all
61 } 70 }
62 71
63 // 60Hz sampled at 30Hz should produce 30Hz. In addition, this test contains 72 // 60Hz sampled at 30Hz should produce 30Hz. In addition, this test contains
64 // much more comprehensive before/after/edge-case scenarios than the others. 73 // much more comprehensive before/after/edge-case scenarios than the others.
65 TEST(SmoothEventSamplerTest, Sample60HertzAt30Hertz) { 74 TEST(SmoothEventSamplerTest, Sample60HertzAt30Hertz) {
66 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 75 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
67 const int redundant_capture_goal = 200; 76 const int redundant_capture_goal = 200;
68 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60; 77 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60;
69 78
70 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); 79 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
71 base::Time t; 80 base::TimeTicks t;
72 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 81 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
73 82
74 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, 83 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
75 &sampler, &t); 84 &sampler, &t);
76 85
77 // Steady state, we should capture every other vsync, indefinitely. 86 // Steady state, we should capture every other vsync, indefinitely.
78 for (int i = 0; i < 100; i++) { 87 for (int i = 0; i < 100; i++) {
79 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 88 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
80 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 89 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
81 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 90 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
82 } 91 }
(...skipping 18 matching lines...) Expand all
101 } 110 }
102 } 111 }
103 112
104 // 50Hz sampled at 30Hz should produce a sequence where some frames are skipped. 113 // 50Hz sampled at 30Hz should produce a sequence where some frames are skipped.
105 TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) { 114 TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) {
106 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 115 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
107 const int redundant_capture_goal = 2; 116 const int redundant_capture_goal = 2;
108 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50; 117 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50;
109 118
110 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); 119 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
111 base::Time t; 120 base::TimeTicks t;
112 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 121 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
113 122
114 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, 123 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
115 &sampler, &t); 124 &sampler, &t);
116 125
117 // Steady state, we should capture 1st, 2nd and 4th frames out of every five 126 // Steady state, we should capture 1st, 2nd and 4th frames out of every five
118 // frames, indefinitely. 127 // frames, indefinitely.
119 for (int i = 0; i < 100; i++) { 128 for (int i = 0; i < 100; i++) {
120 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 129 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
121 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 130 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
122 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 131 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
(...skipping 24 matching lines...) Expand all
147 } 156 }
148 } 157 }
149 158
150 // 75Hz sampled at 30Hz should produce a sequence where some frames are skipped. 159 // 75Hz sampled at 30Hz should produce a sequence where some frames are skipped.
151 TEST(SmoothEventSamplerTest, Sample75HertzAt30Hertz) { 160 TEST(SmoothEventSamplerTest, Sample75HertzAt30Hertz) {
152 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 161 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
153 const int redundant_capture_goal = 32; 162 const int redundant_capture_goal = 32;
154 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 75; 163 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 75;
155 164
156 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); 165 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
157 base::Time t; 166 base::TimeTicks t;
158 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 167 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
159 168
160 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, 169 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
161 &sampler, &t); 170 &sampler, &t);
162 171
163 // Steady state, we should capture 1st and 3rd frames out of every five 172 // Steady state, we should capture 1st and 3rd frames out of every five
164 // frames, indefinitely. 173 // frames, indefinitely.
165 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 174 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
166 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 175 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
167 for (int i = 0; i < 100; i++) { 176 for (int i = 0; i < 100; i++) {
168 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 177 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
(...skipping 28 matching lines...) Expand all
197 } 206 }
198 } 207 }
199 208
200 // 30Hz sampled at 30Hz should produce 30Hz. 209 // 30Hz sampled at 30Hz should produce 30Hz.
201 TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) { 210 TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) {
202 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 211 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
203 const int redundant_capture_goal = 1; 212 const int redundant_capture_goal = 1;
204 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30; 213 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30;
205 214
206 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); 215 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
207 base::Time t; 216 base::TimeTicks t;
208 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 217 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
209 218
210 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, 219 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
211 &sampler, &t); 220 &sampler, &t);
212 221
213 // Steady state, we should capture every vsync, indefinitely. 222 // Steady state, we should capture every vsync, indefinitely.
214 for (int i = 0; i < 200; i++) { 223 for (int i = 0; i < 200; i++) {
215 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 224 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
216 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 225 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
217 } 226 }
218 227
(...skipping 14 matching lines...) Expand all
233 } 242 }
234 } 243 }
235 244
236 // 24Hz sampled at 30Hz should produce 24Hz. 245 // 24Hz sampled at 30Hz should produce 24Hz.
237 TEST(SmoothEventSamplerTest, Sample24HertzAt30Hertz) { 246 TEST(SmoothEventSamplerTest, Sample24HertzAt30Hertz) {
238 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 247 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
239 const int redundant_capture_goal = 333; 248 const int redundant_capture_goal = 333;
240 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 24; 249 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 24;
241 250
242 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); 251 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
243 base::Time t; 252 base::TimeTicks t;
244 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 253 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
245 254
246 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, 255 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
247 &sampler, &t); 256 &sampler, &t);
248 257
249 // Steady state, we should capture every vsync, indefinitely. 258 // Steady state, we should capture every vsync, indefinitely.
250 for (int i = 0; i < 200; i++) { 259 for (int i = 0; i < 200; i++) {
251 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 260 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
252 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 261 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
253 } 262 }
254 263
(...skipping 12 matching lines...) Expand all
267 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 276 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
268 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 277 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
269 } 278 }
270 } 279 }
271 280
272 TEST(SmoothEventSamplerTest, DoubleDrawAtOneTimeStillDirties) { 281 TEST(SmoothEventSamplerTest, DoubleDrawAtOneTimeStillDirties) {
273 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 282 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
274 const base::TimeDelta overdue_period = base::TimeDelta::FromSeconds(1); 283 const base::TimeDelta overdue_period = base::TimeDelta::FromSeconds(1);
275 284
276 SmoothEventSampler sampler(capture_period, true, 1); 285 SmoothEventSampler sampler(capture_period, true, 1);
277 base::Time t; 286 base::TimeTicks t;
278 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 287 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
279 288
280 ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t)); 289 ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
281 sampler.RecordSample(); 290 sampler.RecordSample();
282 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t)) 291 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t))
283 << "Sampled last event; should not be dirty."; 292 << "Sampled last event; should not be dirty.";
284 t += overdue_period; 293 t += overdue_period;
285 294
286 // Now simulate 2 events with the same clock value. 295 // Now simulate 2 events with the same clock value.
287 ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t)); 296 ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
288 sampler.RecordSample(); 297 sampler.RecordSample();
289 ASSERT_FALSE(sampler.AddEventAndConsiderSampling(t)) 298 ASSERT_FALSE(sampler.AddEventAndConsiderSampling(t))
290 << "Two events at same time -- expected second not to be sampled."; 299 << "Two events at same time -- expected second not to be sampled.";
291 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t + overdue_period)) 300 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t + overdue_period))
292 << "Second event should dirty the capture state."; 301 << "Second event should dirty the capture state.";
293 sampler.RecordSample(); 302 sampler.RecordSample();
294 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t + overdue_period)); 303 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t + overdue_period));
295 } 304 }
296 305
297 TEST(SmoothEventSamplerTest, FallbackToPollingIfUpdatesUnreliable) { 306 TEST(SmoothEventSamplerTest, FallbackToPollingIfUpdatesUnreliable) {
298 const base::TimeDelta timer_interval = base::TimeDelta::FromSeconds(1) / 30; 307 const base::TimeDelta timer_interval = base::TimeDelta::FromSeconds(1) / 30;
299 308
300 SmoothEventSampler should_not_poll(timer_interval, true, 1); 309 SmoothEventSampler should_not_poll(timer_interval, true, 1);
301 SmoothEventSampler should_poll(timer_interval, false, 1); 310 SmoothEventSampler should_poll(timer_interval, false, 1);
302 base::Time t; 311 base::TimeTicks t;
303 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 312 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
304 313
305 // Do one round of the "happy case" where an event was received and 314 // Do one round of the "happy case" where an event was received and
306 // RecordSample() was called by the client. 315 // RecordSample() was called by the client.
307 ASSERT_TRUE(should_not_poll.AddEventAndConsiderSampling(t)); 316 ASSERT_TRUE(should_not_poll.AddEventAndConsiderSampling(t));
308 ASSERT_TRUE(should_poll.AddEventAndConsiderSampling(t)); 317 ASSERT_TRUE(should_poll.AddEventAndConsiderSampling(t));
309 should_not_poll.RecordSample(); 318 should_not_poll.RecordSample();
310 should_poll.RecordSample(); 319 should_poll.RecordSample();
311 320
312 // One time period ahead, neither sampler says we're overdue. 321 // One time period ahead, neither sampler says we're overdue.
313 for (int i = 0; i < 3; i++) { 322 for (int i = 0; i < 3; i++) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 357 }
349 358
350 struct DataPoint { 359 struct DataPoint {
351 bool should_capture; 360 bool should_capture;
352 double increment_ms; 361 double increment_ms;
353 }; 362 };
354 363
355 void ReplayCheckingSamplerDecisions(const DataPoint* data_points, 364 void ReplayCheckingSamplerDecisions(const DataPoint* data_points,
356 size_t num_data_points, 365 size_t num_data_points,
357 SmoothEventSampler* sampler) { 366 SmoothEventSampler* sampler) {
358 base::Time t; 367 base::TimeTicks t;
359 ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t)); 368 TimeTicksFromString("Sat, 23 Mar 2013 1:21:08 GMT", &t);
360 for (size_t i = 0; i < num_data_points; ++i) { 369 for (size_t i = 0; i < num_data_points; ++i) {
361 t += base::TimeDelta::FromMicroseconds( 370 t += base::TimeDelta::FromMicroseconds(
362 static_cast<int64>(data_points[i].increment_ms * 1000)); 371 static_cast<int64>(data_points[i].increment_ms * 1000));
363 ASSERT_EQ(data_points[i].should_capture, 372 ASSERT_EQ(data_points[i].should_capture,
364 sampler->AddEventAndConsiderSampling(t)) 373 sampler->AddEventAndConsiderSampling(t))
365 << "at data_points[" << i << ']'; 374 << "at data_points[" << i << ']';
366 if (data_points[i].should_capture) 375 if (data_points[i].should_capture)
367 sampler->RecordSample(); 376 sampler->RecordSample();
368 } 377 }
369 } 378 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 { false, 0 }, { true, 16.72 }, { true, 33.44 }, { false, 0 }, 478 { false, 0 }, { true, 16.72 }, { true, 33.44 }, { false, 0 },
470 { true, 33.441 }, { false, 16.72 }, { true, 16.72 }, { true, 50.16 } 479 { true, 33.441 }, { false, 16.72 }, { true, 16.72 }, { true, 50.16 }
471 }; 480 };
472 481
473 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3); 482 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3);
474 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); 483 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler);
475 } 484 }
476 485
477 } // namespace 486 } // namespace
478 } // namespace content 487 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698