OLD | NEW |
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/media/capture/video_capture_oracle.h" | 5 #include "content/browser/media/capture/video_capture_oracle.h" |
6 | 6 |
7 #include <cstdlib> | 7 #include <cstdlib> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 | 81 |
82 } // namespace | 82 } // namespace |
83 | 83 |
84 // 60Hz sampled at 30Hz should produce 30Hz. In addition, this test contains | 84 // 60Hz sampled at 30Hz should produce 30Hz. In addition, this test contains |
85 // much more comprehensive before/after/edge-case scenarios than the others. | 85 // much more comprehensive before/after/edge-case scenarios than the others. |
86 TEST(SmoothEventSamplerTest, Sample60HertzAt30Hertz) { | 86 TEST(SmoothEventSamplerTest, Sample60HertzAt30Hertz) { |
87 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; | 87 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; |
88 const int redundant_capture_goal = 200; | 88 const int redundant_capture_goal = 200; |
89 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60; | 89 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60; |
90 | 90 |
91 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); | 91 SmoothEventSampler sampler(capture_period, redundant_capture_goal); |
92 base::TimeTicks t = InitialTestTimeTicks(); | 92 base::TimeTicks t = InitialTestTimeTicks(); |
93 | 93 |
94 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, | 94 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, |
95 &sampler, &t); | 95 &sampler, &t); |
96 | 96 |
97 // Steady state, we should capture every other vsync, indefinitely. | 97 // Steady state, we should capture every other vsync, indefinitely. |
98 for (int i = 0; i < 100; i++) { | 98 for (int i = 0; i < 100; i++) { |
99 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); | 99 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); |
100 SteadyStateSampleAndAdvance(vsync, &sampler, &t); | 100 SteadyStateSampleAndAdvance(vsync, &sampler, &t); |
101 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); | 101 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); |
(...skipping 18 matching lines...) Expand all Loading... |
120 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); | 120 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
124 // 50Hz sampled at 30Hz should produce a sequence where some frames are skipped. | 124 // 50Hz sampled at 30Hz should produce a sequence where some frames are skipped. |
125 TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) { | 125 TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) { |
126 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; | 126 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; |
127 const int redundant_capture_goal = 2; | 127 const int redundant_capture_goal = 2; |
128 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50; | 128 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50; |
129 | 129 |
130 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); | 130 SmoothEventSampler sampler(capture_period, redundant_capture_goal); |
131 base::TimeTicks t = InitialTestTimeTicks(); | 131 base::TimeTicks t = InitialTestTimeTicks(); |
132 | 132 |
133 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, | 133 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, |
134 &sampler, &t); | 134 &sampler, &t); |
135 | 135 |
136 // Steady state, we should capture 1st, 2nd and 4th frames out of every five | 136 // Steady state, we should capture 1st, 2nd and 4th frames out of every five |
137 // frames, indefinitely. | 137 // frames, indefinitely. |
138 for (int i = 0; i < 100; i++) { | 138 for (int i = 0; i < 100; i++) { |
139 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); | 139 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); |
140 SteadyStateSampleAndAdvance(vsync, &sampler, &t); | 140 SteadyStateSampleAndAdvance(vsync, &sampler, &t); |
(...skipping 24 matching lines...) Expand all Loading... |
165 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); | 165 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); |
166 } | 166 } |
167 } | 167 } |
168 | 168 |
169 // 75Hz sampled at 30Hz should produce a sequence where some frames are skipped. | 169 // 75Hz sampled at 30Hz should produce a sequence where some frames are skipped. |
170 TEST(SmoothEventSamplerTest, Sample75HertzAt30Hertz) { | 170 TEST(SmoothEventSamplerTest, Sample75HertzAt30Hertz) { |
171 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; | 171 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; |
172 const int redundant_capture_goal = 32; | 172 const int redundant_capture_goal = 32; |
173 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 75; | 173 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 75; |
174 | 174 |
175 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); | 175 SmoothEventSampler sampler(capture_period, redundant_capture_goal); |
176 base::TimeTicks t = InitialTestTimeTicks(); | 176 base::TimeTicks t = InitialTestTimeTicks(); |
177 | 177 |
178 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, | 178 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, |
179 &sampler, &t); | 179 &sampler, &t); |
180 | 180 |
181 // Steady state, we should capture 1st and 3rd frames out of every five | 181 // Steady state, we should capture 1st and 3rd frames out of every five |
182 // frames, indefinitely. | 182 // frames, indefinitely. |
183 SteadyStateSampleAndAdvance(vsync, &sampler, &t); | 183 SteadyStateSampleAndAdvance(vsync, &sampler, &t); |
184 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); | 184 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); |
185 for (int i = 0; i < 100; i++) { | 185 for (int i = 0; i < 100; i++) { |
(...skipping 28 matching lines...) Expand all Loading... |
214 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); | 214 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); |
215 } | 215 } |
216 } | 216 } |
217 | 217 |
218 // 30Hz sampled at 30Hz should produce 30Hz. | 218 // 30Hz sampled at 30Hz should produce 30Hz. |
219 TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) { | 219 TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) { |
220 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; | 220 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; |
221 const int redundant_capture_goal = 1; | 221 const int redundant_capture_goal = 1; |
222 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30; | 222 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30; |
223 | 223 |
224 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); | 224 SmoothEventSampler sampler(capture_period, redundant_capture_goal); |
225 base::TimeTicks t = InitialTestTimeTicks(); | 225 base::TimeTicks t = InitialTestTimeTicks(); |
226 | 226 |
227 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, | 227 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, |
228 &sampler, &t); | 228 &sampler, &t); |
229 | 229 |
230 // Steady state, we should capture every vsync, indefinitely. | 230 // Steady state, we should capture every vsync, indefinitely. |
231 for (int i = 0; i < 200; i++) { | 231 for (int i = 0; i < 200; i++) { |
232 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); | 232 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); |
233 SteadyStateSampleAndAdvance(vsync, &sampler, &t); | 233 SteadyStateSampleAndAdvance(vsync, &sampler, &t); |
234 } | 234 } |
(...skipping 14 matching lines...) Expand all Loading... |
249 SteadyStateSampleAndAdvance(vsync, &sampler, &t); | 249 SteadyStateSampleAndAdvance(vsync, &sampler, &t); |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 // 24Hz sampled at 30Hz should produce 24Hz. | 253 // 24Hz sampled at 30Hz should produce 24Hz. |
254 TEST(SmoothEventSamplerTest, Sample24HertzAt30Hertz) { | 254 TEST(SmoothEventSamplerTest, Sample24HertzAt30Hertz) { |
255 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; | 255 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; |
256 const int redundant_capture_goal = 333; | 256 const int redundant_capture_goal = 333; |
257 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 24; | 257 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 24; |
258 | 258 |
259 SmoothEventSampler sampler(capture_period, true, redundant_capture_goal); | 259 SmoothEventSampler sampler(capture_period, redundant_capture_goal); |
260 base::TimeTicks t = InitialTestTimeTicks(); | 260 base::TimeTicks t = InitialTestTimeTicks(); |
261 | 261 |
262 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, | 262 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, |
263 &sampler, &t); | 263 &sampler, &t); |
264 | 264 |
265 // Steady state, we should capture every vsync, indefinitely. | 265 // Steady state, we should capture every vsync, indefinitely. |
266 for (int i = 0; i < 200; i++) { | 266 for (int i = 0; i < 200; i++) { |
267 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); | 267 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); |
268 SteadyStateSampleAndAdvance(vsync, &sampler, &t); | 268 SteadyStateSampleAndAdvance(vsync, &sampler, &t); |
269 } | 269 } |
(...skipping 12 matching lines...) Expand all Loading... |
282 for (int i = 0; i < 100; i++) { | 282 for (int i = 0; i < 100; i++) { |
283 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); | 283 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); |
284 SteadyStateSampleAndAdvance(vsync, &sampler, &t); | 284 SteadyStateSampleAndAdvance(vsync, &sampler, &t); |
285 } | 285 } |
286 } | 286 } |
287 | 287 |
288 TEST(SmoothEventSamplerTest, DoubleDrawAtOneTimeStillDirties) { | 288 TEST(SmoothEventSamplerTest, DoubleDrawAtOneTimeStillDirties) { |
289 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; | 289 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; |
290 const base::TimeDelta overdue_period = base::TimeDelta::FromSeconds(1); | 290 const base::TimeDelta overdue_period = base::TimeDelta::FromSeconds(1); |
291 | 291 |
292 SmoothEventSampler sampler(capture_period, true, 1); | 292 SmoothEventSampler sampler(capture_period, 1); |
293 base::TimeTicks t = InitialTestTimeTicks(); | 293 base::TimeTicks t = InitialTestTimeTicks(); |
294 | 294 |
295 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); | 295 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); |
296 sampler.RecordSample(); | 296 sampler.RecordSample(); |
297 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t)) | 297 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t)) |
298 << "Sampled last event; should not be dirty."; | 298 << "Sampled last event; should not be dirty."; |
299 t += overdue_period; | 299 t += overdue_period; |
300 | 300 |
301 // Now simulate 2 events with the same clock value. | 301 // Now simulate 2 events with the same clock value. |
302 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); | 302 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); |
303 sampler.RecordSample(); | 303 sampler.RecordSample(); |
304 ASSERT_FALSE(AddEventAndConsiderSampling(&sampler, t)) | 304 ASSERT_FALSE(AddEventAndConsiderSampling(&sampler, t)) |
305 << "Two events at same time -- expected second not to be sampled."; | 305 << "Two events at same time -- expected second not to be sampled."; |
306 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t + overdue_period)) | 306 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t + overdue_period)) |
307 << "Second event should dirty the capture state."; | 307 << "Second event should dirty the capture state."; |
308 sampler.RecordSample(); | 308 sampler.RecordSample(); |
309 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t + overdue_period)); | 309 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t + overdue_period)); |
310 } | 310 } |
311 | 311 |
312 TEST(SmoothEventSamplerTest, FallbackToPollingIfUpdatesUnreliable) { | |
313 const base::TimeDelta timer_interval = base::TimeDelta::FromSeconds(1) / 30; | |
314 | |
315 SmoothEventSampler should_not_poll(timer_interval, true, 1); | |
316 SmoothEventSampler should_poll(timer_interval, false, 1); | |
317 base::TimeTicks t = InitialTestTimeTicks(); | |
318 | |
319 // Do one round of the "happy case" where an event was received and | |
320 // RecordSample() was called by the client. | |
321 ASSERT_TRUE(AddEventAndConsiderSampling(&should_not_poll, t)); | |
322 ASSERT_TRUE(AddEventAndConsiderSampling(&should_poll, t)); | |
323 should_not_poll.RecordSample(); | |
324 should_poll.RecordSample(); | |
325 | |
326 // For the following time period, before 250 ms has elapsed, neither sampler | |
327 // says we're overdue. | |
328 const int non_overdue_intervals = static_cast<int>( | |
329 base::TimeDelta::FromMilliseconds(250) / timer_interval); | |
330 for (int i = 0; i < non_overdue_intervals; i++) { | |
331 t += timer_interval; | |
332 ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t)) | |
333 << "Sampled last event; should not be dirty."; | |
334 ASSERT_FALSE(should_poll.IsOverdueForSamplingAt(t)) | |
335 << "Dirty interval has not elapsed yet."; | |
336 } | |
337 | |
338 // Next time period ahead, both samplers say we're overdue. The non-polling | |
339 // sampler is returning true here because it has been configured to allow one | |
340 // redundant capture. | |
341 t += timer_interval; // Step past the 250 ms threshold. | |
342 ASSERT_TRUE(should_not_poll.IsOverdueForSamplingAt(t)) | |
343 << "Sampled last event; is dirty one time only to meet redundancy goal."; | |
344 ASSERT_TRUE(should_poll.IsOverdueForSamplingAt(t)) | |
345 << "If updates are unreliable, must fall back to polling when idle."; | |
346 should_not_poll.RecordSample(); | |
347 should_poll.RecordSample(); | |
348 | |
349 // Forever more, the non-polling sampler returns false while the polling one | |
350 // returns true. | |
351 for (int i = 0; i < 100; ++i) { | |
352 t += timer_interval; | |
353 ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t)) | |
354 << "Sampled last event; should not be dirty."; | |
355 ASSERT_TRUE(should_poll.IsOverdueForSamplingAt(t)) | |
356 << "If updates are unreliable, must fall back to polling when idle."; | |
357 should_poll.RecordSample(); | |
358 } | |
359 t += timer_interval / 3; | |
360 ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t)) | |
361 << "Sampled last event; should not be dirty."; | |
362 ASSERT_TRUE(should_poll.IsOverdueForSamplingAt(t)) | |
363 << "If updates are unreliable, must fall back to polling when idle."; | |
364 should_poll.RecordSample(); | |
365 } | |
366 | |
367 namespace { | 312 namespace { |
368 | 313 |
369 struct DataPoint { | 314 struct DataPoint { |
370 bool should_capture; | 315 bool should_capture; |
371 double increment_ms; | 316 double increment_ms; |
372 }; | 317 }; |
373 | 318 |
374 void ReplayCheckingSamplerDecisions(const DataPoint* data_points, | 319 void ReplayCheckingSamplerDecisions(const DataPoint* data_points, |
375 size_t num_data_points, | 320 size_t num_data_points, |
376 SmoothEventSampler* sampler) { | 321 SmoothEventSampler* sampler) { |
(...skipping 28 matching lines...) Expand all Loading... |
405 { true, 33.441 }, { true, 50.337 }, { true, 50.183 }, { true, 16.722 }, | 350 { true, 33.441 }, { true, 50.337 }, { true, 50.183 }, { true, 16.722 }, |
406 { true, 50.161 }, { true, 33.441 }, { true, 50.16 }, { true, 33.441 }, | 351 { true, 50.161 }, { true, 33.441 }, { true, 50.16 }, { true, 33.441 }, |
407 { true, 50.16 }, { true, 33.441 }, { true, 50.16 }, { true, 33.44 }, | 352 { true, 50.16 }, { true, 33.441 }, { true, 50.16 }, { true, 33.44 }, |
408 { true, 50.161 }, { true, 50.16 }, { true, 33.44 }, { true, 33.441 }, | 353 { true, 50.161 }, { true, 50.16 }, { true, 33.44 }, { true, 33.441 }, |
409 { true, 50.16 }, { true, 50.161 }, { true, 33.44 }, { true, 33.441 }, | 354 { true, 50.16 }, { true, 50.161 }, { true, 33.44 }, { true, 33.441 }, |
410 { true, 50.16 }, { true, 33.44 }, { true, 50.161 }, { true, 33.44 }, | 355 { true, 50.16 }, { true, 33.44 }, { true, 50.161 }, { true, 33.44 }, |
411 { true, 50.161 }, { true, 33.44 }, { true, 50.161 }, { true, 33.44 }, | 356 { true, 50.161 }, { true, 33.44 }, { true, 50.161 }, { true, 33.44 }, |
412 { true, 83.601 }, { true, 16.72 }, { true, 33.44 }, { false, 0 } | 357 { true, 83.601 }, { true, 16.72 }, { true, 33.44 }, { false, 0 } |
413 }; | 358 }; |
414 | 359 |
415 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3); | 360 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, 3); |
416 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); | 361 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); |
417 } | 362 } |
418 | 363 |
419 TEST(SmoothEventSamplerTest, DrawingAt30FpsWith60HzVsyncSampledAt30Hertz) { | 364 TEST(SmoothEventSamplerTest, DrawingAt30FpsWith60HzVsyncSampledAt30Hertz) { |
420 // Actual capturing of timing data: Initial instability as a 30 FPS video was | 365 // Actual capturing of timing data: Initial instability as a 30 FPS video was |
421 // started from a still screen, then followed by steady-state. Drawing | 366 // started from a still screen, then followed by steady-state. Drawing |
422 // framerate from the video rendering was a bit volatile, but averaged 30 FPS. | 367 // framerate from the video rendering was a bit volatile, but averaged 30 FPS. |
423 static const DataPoint data_points[] = { | 368 static const DataPoint data_points[] = { |
424 { true, 2407.69 }, { true, 16.733 }, { true, 217.362 }, { true, 33.441 }, | 369 { true, 2407.69 }, { true, 16.733 }, { true, 217.362 }, { true, 33.441 }, |
425 { true, 33.44 }, { true, 33.44 }, { true, 33.441 }, { true, 33.44 }, | 370 { true, 33.44 }, { true, 33.44 }, { true, 33.441 }, { true, 33.44 }, |
(...skipping 15 matching lines...) Expand all Loading... |
441 { true, 33.441 }, { true, 33.44 }, { true, 33.44 }, { false, 0 }, | 386 { true, 33.441 }, { true, 33.44 }, { true, 33.44 }, { false, 0 }, |
442 { true, 16.72 }, { true, 50.161 }, { false, 0 }, { true, 50.16 }, | 387 { true, 16.72 }, { true, 50.161 }, { false, 0 }, { true, 50.16 }, |
443 { false, 0.001 }, { true, 16.721 }, { true, 66.88 }, { true, 33.44 }, | 388 { false, 0.001 }, { true, 16.721 }, { true, 66.88 }, { true, 33.44 }, |
444 { true, 33.441 }, { true, 33.44 }, { true, 50.161 }, { true, 16.72 }, | 389 { true, 33.441 }, { true, 33.44 }, { true, 50.161 }, { true, 16.72 }, |
445 { false, 0 }, { true, 33.44 }, { false, 16.72 }, { true, 66.881 }, | 390 { false, 0 }, { true, 33.44 }, { false, 16.72 }, { true, 66.881 }, |
446 { true, 33.44 }, { true, 16.72 }, { true, 33.441 }, { false, 16.72 }, | 391 { true, 33.44 }, { true, 16.72 }, { true, 33.441 }, { false, 16.72 }, |
447 { true, 66.88 }, { true, 16.721 }, { true, 50.16 }, { true, 33.44 }, | 392 { true, 66.88 }, { true, 16.721 }, { true, 50.16 }, { true, 33.44 }, |
448 { true, 16.72 }, { true, 33.441 }, { true, 33.44 }, { true, 33.44 } | 393 { true, 16.72 }, { true, 33.441 }, { true, 33.44 }, { true, 33.44 } |
449 }; | 394 }; |
450 | 395 |
451 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3); | 396 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, 3); |
452 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); | 397 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); |
453 } | 398 } |
454 | 399 |
455 TEST(SmoothEventSamplerTest, DrawingAt60FpsWith60HzVsyncSampledAt30Hertz) { | 400 TEST(SmoothEventSamplerTest, DrawingAt60FpsWith60HzVsyncSampledAt30Hertz) { |
456 // Actual capturing of timing data: WebGL Acquarium demo | 401 // Actual capturing of timing data: WebGL Acquarium demo |
457 // (http://webglsamples.googlecode.com/hg/aquarium/aquarium.html) which ran | 402 // (http://webglsamples.googlecode.com/hg/aquarium/aquarium.html) which ran |
458 // between 55-60 FPS in the steady-state. | 403 // between 55-60 FPS in the steady-state. |
459 static const DataPoint data_points[] = { | 404 static const DataPoint data_points[] = { |
460 { true, 16.72 }, { true, 16.72 }, { true, 4163.29 }, { true, 50.193 }, | 405 { true, 16.72 }, { true, 16.72 }, { true, 4163.29 }, { true, 50.193 }, |
461 { true, 117.041 }, { true, 50.161 }, { true, 50.16 }, { true, 33.441 }, | 406 { true, 117.041 }, { true, 50.161 }, { true, 50.16 }, { true, 33.441 }, |
(...skipping 21 matching lines...) Expand all Loading... |
483 { true, 16.721 }, { true, 50.161 }, { false, 0 }, { true, 16.72 }, | 428 { true, 16.721 }, { true, 50.161 }, { false, 0 }, { true, 16.72 }, |
484 { true, 33.44 }, { true, 33.441 }, { false, 0 }, { true, 33.44 }, | 429 { true, 33.44 }, { true, 33.441 }, { false, 0 }, { true, 33.44 }, |
485 { true, 33.44 }, { false, 0 }, { true, 33.441 }, { false, 16.72 }, | 430 { true, 33.44 }, { false, 0 }, { true, 33.441 }, { false, 16.72 }, |
486 { true, 16.72 }, { true, 50.16 }, { false, 0 }, { true, 16.72 }, | 431 { true, 16.72 }, { true, 50.16 }, { false, 0 }, { true, 16.72 }, |
487 { true, 33.441 }, { false, 0 }, { true, 33.44 }, { false, 16.72 }, | 432 { true, 33.441 }, { false, 0 }, { true, 33.44 }, { false, 16.72 }, |
488 { true, 33.44 }, { false, 0 }, { true, 16.721 }, { true, 50.161 }, | 433 { true, 33.44 }, { false, 0 }, { true, 16.721 }, { true, 50.161 }, |
489 { false, 0 }, { true, 16.72 }, { true, 33.44 }, { false, 0 }, | 434 { false, 0 }, { true, 16.72 }, { true, 33.44 }, { false, 0 }, |
490 { true, 33.441 }, { false, 16.72 }, { true, 16.72 }, { true, 50.16 } | 435 { true, 33.441 }, { false, 16.72 }, { true, 16.72 }, { true, 50.16 } |
491 }; | 436 }; |
492 | 437 |
493 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3); | 438 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, 3); |
494 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); | 439 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); |
495 } | 440 } |
496 | 441 |
497 class AnimatedContentSamplerTest : public ::testing::Test { | 442 class AnimatedContentSamplerTest : public ::testing::Test { |
498 public: | 443 public: |
499 AnimatedContentSamplerTest() {} | 444 AnimatedContentSamplerTest() {} |
500 ~AnimatedContentSamplerTest() override {} | 445 ~AnimatedContentSamplerTest() override {} |
501 | 446 |
502 void SetUp() override { | 447 void SetUp() override { |
503 const base::TimeDelta since_epoch = | 448 const base::TimeDelta since_epoch = |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 Scenario(FpsAsPeriod(60), FpsAsPeriod(30), FpsAsPeriod(33)))); | 1054 Scenario(FpsAsPeriod(60), FpsAsPeriod(30), FpsAsPeriod(33)))); |
1110 | 1055 |
1111 // Tests that VideoCaptureOracle filters out events whose timestamps are | 1056 // Tests that VideoCaptureOracle filters out events whose timestamps are |
1112 // decreasing. | 1057 // decreasing. |
1113 TEST(VideoCaptureOracleTest, EnforcesEventTimeMonotonicity) { | 1058 TEST(VideoCaptureOracleTest, EnforcesEventTimeMonotonicity) { |
1114 const base::TimeDelta min_capture_period = | 1059 const base::TimeDelta min_capture_period = |
1115 base::TimeDelta::FromSeconds(1) / 30; | 1060 base::TimeDelta::FromSeconds(1) / 30; |
1116 const gfx::Rect damage_rect(0, 0, 1280, 720); | 1061 const gfx::Rect damage_rect(0, 0, 1280, 720); |
1117 const base::TimeDelta event_increment = min_capture_period * 2; | 1062 const base::TimeDelta event_increment = min_capture_period * 2; |
1118 | 1063 |
1119 VideoCaptureOracle oracle(min_capture_period, true); | 1064 VideoCaptureOracle oracle(min_capture_period); |
1120 | 1065 |
1121 base::TimeTicks t = InitialTestTimeTicks(); | 1066 base::TimeTicks t = InitialTestTimeTicks(); |
1122 for (int i = 0; i < 10; ++i) { | 1067 for (int i = 0; i < 10; ++i) { |
1123 t += event_increment; | 1068 t += event_increment; |
1124 ASSERT_TRUE(oracle.ObserveEventAndDecideCapture( | 1069 ASSERT_TRUE(oracle.ObserveEventAndDecideCapture( |
1125 VideoCaptureOracle::kCompositorUpdate, | 1070 VideoCaptureOracle::kCompositorUpdate, |
1126 damage_rect, t)); | 1071 damage_rect, t)); |
1127 } | 1072 } |
1128 | 1073 |
1129 base::TimeTicks furthest_event_time = t; | 1074 base::TimeTicks furthest_event_time = t; |
(...skipping 15 matching lines...) Expand all Loading... |
1145 | 1090 |
1146 // Tests that VideoCaptureOracle is enforcing the requirement that captured | 1091 // Tests that VideoCaptureOracle is enforcing the requirement that captured |
1147 // frames are delivered in order. Otherwise, downstream consumers could be | 1092 // frames are delivered in order. Otherwise, downstream consumers could be |
1148 // tripped-up by out-of-order frames or frame timestamps. | 1093 // tripped-up by out-of-order frames or frame timestamps. |
1149 TEST(VideoCaptureOracleTest, EnforcesFramesDeliveredInOrder) { | 1094 TEST(VideoCaptureOracleTest, EnforcesFramesDeliveredInOrder) { |
1150 const base::TimeDelta min_capture_period = | 1095 const base::TimeDelta min_capture_period = |
1151 base::TimeDelta::FromSeconds(1) / 30; | 1096 base::TimeDelta::FromSeconds(1) / 30; |
1152 const gfx::Rect damage_rect(0, 0, 1280, 720); | 1097 const gfx::Rect damage_rect(0, 0, 1280, 720); |
1153 const base::TimeDelta event_increment = min_capture_period * 2; | 1098 const base::TimeDelta event_increment = min_capture_period * 2; |
1154 | 1099 |
1155 VideoCaptureOracle oracle(min_capture_period, true); | 1100 VideoCaptureOracle oracle(min_capture_period); |
1156 | 1101 |
1157 // Most basic scenario: Frames delivered one at a time, with no additional | 1102 // Most basic scenario: Frames delivered one at a time, with no additional |
1158 // captures in-between deliveries. | 1103 // captures in-between deliveries. |
1159 base::TimeTicks t = InitialTestTimeTicks(); | 1104 base::TimeTicks t = InitialTestTimeTicks(); |
1160 int last_frame_number; | 1105 int last_frame_number; |
1161 base::TimeTicks ignored; | 1106 base::TimeTicks ignored; |
1162 for (int i = 0; i < 10; ++i) { | 1107 for (int i = 0; i < 10; ++i) { |
1163 t += event_increment; | 1108 t += event_increment; |
1164 ASSERT_TRUE(oracle.ObserveEventAndDecideCapture( | 1109 ASSERT_TRUE(oracle.ObserveEventAndDecideCapture( |
1165 VideoCaptureOracle::kCompositorUpdate, | 1110 VideoCaptureOracle::kCompositorUpdate, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 } | 1146 } |
1202 | 1147 |
1203 // Tests that VideoCaptureOracle transitions between using its two samplers in a | 1148 // Tests that VideoCaptureOracle transitions between using its two samplers in a |
1204 // way that does not introduce severe jank, pauses, etc. | 1149 // way that does not introduce severe jank, pauses, etc. |
1205 TEST(VideoCaptureOracleTest, TransitionsSmoothlyBetweenSamplers) { | 1150 TEST(VideoCaptureOracleTest, TransitionsSmoothlyBetweenSamplers) { |
1206 const base::TimeDelta min_capture_period = | 1151 const base::TimeDelta min_capture_period = |
1207 base::TimeDelta::FromSeconds(1) / 30; | 1152 base::TimeDelta::FromSeconds(1) / 30; |
1208 const gfx::Rect animation_damage_rect(0, 0, 1280, 720); | 1153 const gfx::Rect animation_damage_rect(0, 0, 1280, 720); |
1209 const base::TimeDelta event_increment = min_capture_period * 2; | 1154 const base::TimeDelta event_increment = min_capture_period * 2; |
1210 | 1155 |
1211 VideoCaptureOracle oracle(min_capture_period, true); | 1156 VideoCaptureOracle oracle(min_capture_period); |
1212 | 1157 |
1213 // Run sequences of animation events and non-animation events through the | 1158 // Run sequences of animation events and non-animation events through the |
1214 // oracle. As the oracle transitions between each sampler, make sure the | 1159 // oracle. As the oracle transitions between each sampler, make sure the |
1215 // frame timestamps won't trip-up downstream consumers. | 1160 // frame timestamps won't trip-up downstream consumers. |
1216 base::TimeTicks t = InitialTestTimeTicks(); | 1161 base::TimeTicks t = InitialTestTimeTicks(); |
1217 base::TimeTicks last_frame_timestamp; | 1162 base::TimeTicks last_frame_timestamp; |
1218 for (int i = 0; i < 1000; ++i) { | 1163 for (int i = 0; i < 1000; ++i) { |
1219 t += event_increment; | 1164 t += event_increment; |
1220 | 1165 |
1221 // For every 100 events, provide 50 that will cause the | 1166 // For every 100 events, provide 50 that will cause the |
(...skipping 30 matching lines...) Expand all Loading... |
1252 // |event_increment|. | 1197 // |event_increment|. |
1253 const base::TimeDelta max_acceptable_delta = (i % 100) == 78 ? | 1198 const base::TimeDelta max_acceptable_delta = (i % 100) == 78 ? |
1254 event_increment * 5 : event_increment * 2; | 1199 event_increment * 5 : event_increment * 2; |
1255 EXPECT_GE(max_acceptable_delta.InMicroseconds(), delta.InMicroseconds()); | 1200 EXPECT_GE(max_acceptable_delta.InMicroseconds(), delta.InMicroseconds()); |
1256 } | 1201 } |
1257 last_frame_timestamp = frame_timestamp; | 1202 last_frame_timestamp = frame_timestamp; |
1258 } | 1203 } |
1259 } | 1204 } |
1260 | 1205 |
1261 } // namespace content | 1206 } // namespace content |
OLD | NEW |