| 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 |