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

Side by Side Diff: media/capture/content/smooth_event_sampler_unittest.cc

Issue 1865283003: Revert of Tab/Desktop Capture: Use requests instead of timer-based refreshing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@video_refresh_from_sinks
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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 "media/capture/content/smooth_event_sampler.h" 5 #include "media/capture/content/smooth_event_sampler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 10 matching lines...) Expand all
21 return sampler->ShouldSample(); 21 return sampler->ShouldSample();
22 } 22 }
23 23
24 void SteadyStateSampleAndAdvance(base::TimeDelta vsync, 24 void SteadyStateSampleAndAdvance(base::TimeDelta vsync,
25 SmoothEventSampler* sampler, 25 SmoothEventSampler* sampler,
26 base::TimeTicks* t) { 26 base::TimeTicks* t) {
27 ASSERT_TRUE(AddEventAndConsiderSampling(sampler, *t)); 27 ASSERT_TRUE(AddEventAndConsiderSampling(sampler, *t));
28 ASSERT_TRUE(sampler->HasUnrecordedEvent()); 28 ASSERT_TRUE(sampler->HasUnrecordedEvent());
29 sampler->RecordSample(); 29 sampler->RecordSample();
30 ASSERT_FALSE(sampler->HasUnrecordedEvent()); 30 ASSERT_FALSE(sampler->HasUnrecordedEvent());
31 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
31 *t += vsync; 32 *t += vsync;
33 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
32 } 34 }
33 35
34 void SteadyStateNoSampleAndAdvance(base::TimeDelta vsync, 36 void SteadyStateNoSampleAndAdvance(base::TimeDelta vsync,
35 SmoothEventSampler* sampler, 37 SmoothEventSampler* sampler,
36 base::TimeTicks* t) { 38 base::TimeTicks* t) {
37 ASSERT_FALSE(AddEventAndConsiderSampling(sampler, *t)); 39 ASSERT_FALSE(AddEventAndConsiderSampling(sampler, *t));
38 ASSERT_TRUE(sampler->HasUnrecordedEvent()); 40 ASSERT_TRUE(sampler->HasUnrecordedEvent());
41 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
39 *t += vsync; 42 *t += vsync;
43 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
40 } 44 }
41 45
42 base::TimeTicks InitialTestTimeTicks() { 46 base::TimeTicks InitialTestTimeTicks() {
43 return base::TimeTicks() + base::TimeDelta::FromSeconds(1); 47 return base::TimeTicks() + base::TimeDelta::FromSeconds(1);
44 } 48 }
45 49
50 void TestRedundantCaptureStrategy(base::TimeDelta capture_period,
51 int redundant_capture_goal,
52 SmoothEventSampler* sampler,
53 base::TimeTicks* t) {
54 // Before any events have been considered, we're overdue for sampling.
55 ASSERT_TRUE(sampler->IsOverdueForSamplingAt(*t));
56
57 // Consider the first event. We want to sample that.
58 ASSERT_FALSE(sampler->HasUnrecordedEvent());
59 ASSERT_TRUE(AddEventAndConsiderSampling(sampler, *t));
60 ASSERT_TRUE(sampler->HasUnrecordedEvent());
61 sampler->RecordSample();
62 ASSERT_FALSE(sampler->HasUnrecordedEvent());
63
64 // After more than 250 ms has passed without considering an event, we should
65 // repeatedly be overdue for sampling. However, once the redundant capture
66 // goal is achieved, we should no longer be overdue for sampling.
67 *t += base::TimeDelta::FromMilliseconds(250);
68 for (int i = 0; i < redundant_capture_goal; i++) {
69 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
70 ASSERT_FALSE(sampler->HasUnrecordedEvent());
71 ASSERT_TRUE(sampler->IsOverdueForSamplingAt(*t))
72 << "Should sample until redundant capture goal is hit";
73 sampler->RecordSample();
74 *t += capture_period; // Timer fires once every capture period.
75 }
76 ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t))
77 << "Should not be overdue once redundant capture goal achieved.";
78 }
46 79
47 } // namespace 80 } // namespace
48 81
49 // 60Hz sampled at 30Hz should produce 30Hz. In addition, this test contains 82 // 60Hz sampled at 30Hz should produce 30Hz. In addition, this test contains
50 // much more comprehensive before/after/edge-case scenarios than the others. 83 // much more comprehensive before/after/edge-case scenarios than the others.
51 TEST(SmoothEventSamplerTest, Sample60HertzAt30Hertz) { 84 TEST(SmoothEventSamplerTest, Sample60HertzAt30Hertz) {
52 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 85 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
86 const int redundant_capture_goal = 200;
53 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60; 87 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60;
54 88
55 SmoothEventSampler sampler(capture_period); 89 SmoothEventSampler sampler(capture_period, redundant_capture_goal);
56 base::TimeTicks t = InitialTestTimeTicks(); 90 base::TimeTicks t = InitialTestTimeTicks();
57 91
92 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, &sampler,
93 &t);
94
58 // Steady state, we should capture every other vsync, indefinitely. 95 // Steady state, we should capture every other vsync, indefinitely.
59 for (int i = 0; i < 100; i++) { 96 for (int i = 0; i < 100; i++) {
60 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 97 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
61 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 98 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
62 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 99 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
63 } 100 }
64 101
65 // Now pretend we're limited by backpressure in the pipeline. In this scenario 102 // Now pretend we're limited by backpressure in the pipeline. In this scenario
66 // case we are adding events but not sampling them. 103 // case we are adding events but not sampling them.
67 for (int i = 0; i < 20; i++) { 104 for (int i = 0; i < 20; i++) {
68 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 105 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
106 ASSERT_EQ(i >= 14, sampler.IsOverdueForSamplingAt(t));
69 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); 107 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t));
70 ASSERT_TRUE(sampler.HasUnrecordedEvent()); 108 ASSERT_TRUE(sampler.HasUnrecordedEvent());
71 t += vsync; 109 t += vsync;
72 } 110 }
73 111
74 // Now suppose we can sample again. We should be back in the steady state, 112 // Now suppose we can sample again. We should be back in the steady state,
75 // but at a different phase. 113 // but at a different phase.
114 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
76 for (int i = 0; i < 100; i++) { 115 for (int i = 0; i < 100; i++) {
77 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 116 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
78 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 117 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
79 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 118 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
80 } 119 }
81 } 120 }
82 121
83 // 50Hz sampled at 30Hz should produce a sequence where some frames are skipped. 122 // 50Hz sampled at 30Hz should produce a sequence where some frames are skipped.
84 TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) { 123 TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) {
85 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 124 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
125 const int redundant_capture_goal = 2;
86 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50; 126 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50;
87 127
88 SmoothEventSampler sampler(capture_period); 128 SmoothEventSampler sampler(capture_period, redundant_capture_goal);
89 base::TimeTicks t = InitialTestTimeTicks(); 129 base::TimeTicks t = InitialTestTimeTicks();
90 130
131 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, &sampler,
132 &t);
133
91 // Steady state, we should capture 1st, 2nd and 4th frames out of every five 134 // Steady state, we should capture 1st, 2nd and 4th frames out of every five
92 // frames, indefinitely. 135 // frames, indefinitely.
93 for (int i = 0; i < 100; i++) { 136 for (int i = 0; i < 100; i++) {
94 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 137 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
95 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 138 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
96 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 139 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
97 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 140 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
98 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 141 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
99 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 142 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
100 } 143 }
101 144
102 // Now pretend we're limited by backpressure in the pipeline. In this scenario 145 // Now pretend we're limited by backpressure in the pipeline. In this scenario
103 // case we are adding events but not sampling them. 146 // case we are adding events but not sampling them.
104 for (int i = 0; i < 20; i++) { 147 for (int i = 0; i < 20; i++) {
105 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 148 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
149 ASSERT_EQ(i >= 11, sampler.IsOverdueForSamplingAt(t));
106 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); 150 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t));
107 t += vsync; 151 t += vsync;
108 } 152 }
109 153
110 // Now suppose we can sample again. We should be back in the steady state 154 // Now suppose we can sample again. We should be back in the steady state
111 // again. 155 // again.
156 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
112 for (int i = 0; i < 100; i++) { 157 for (int i = 0; i < 100; i++) {
113 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 158 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
114 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 159 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
115 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 160 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
116 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 161 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
117 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 162 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
118 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 163 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
119 } 164 }
120 } 165 }
121 166
122 // 75Hz sampled at 30Hz should produce a sequence where some frames are skipped. 167 // 75Hz sampled at 30Hz should produce a sequence where some frames are skipped.
123 TEST(SmoothEventSamplerTest, Sample75HertzAt30Hertz) { 168 TEST(SmoothEventSamplerTest, Sample75HertzAt30Hertz) {
124 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 169 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
170 const int redundant_capture_goal = 32;
125 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 75; 171 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 75;
126 172
127 SmoothEventSampler sampler(capture_period); 173 SmoothEventSampler sampler(capture_period, redundant_capture_goal);
128 base::TimeTicks t = InitialTestTimeTicks(); 174 base::TimeTicks t = InitialTestTimeTicks();
129 175
176 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, &sampler,
177 &t);
178
130 // Steady state, we should capture 1st and 3rd frames out of every five 179 // Steady state, we should capture 1st and 3rd frames out of every five
131 // frames, indefinitely. 180 // frames, indefinitely.
132 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 181 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
133 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 182 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
134 for (int i = 0; i < 100; i++) { 183 for (int i = 0; i < 100; i++) {
135 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 184 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
136 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 185 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
137 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 186 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
138 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 187 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
139 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 188 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
140 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 189 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
141 } 190 }
142 191
143 // Now pretend we're limited by backpressure in the pipeline. In this scenario 192 // Now pretend we're limited by backpressure in the pipeline. In this scenario
144 // case we are adding events but not sampling them. 193 // case we are adding events but not sampling them.
145 for (int i = 0; i < 20; i++) { 194 for (int i = 0; i < 20; i++) {
146 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 195 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
196 ASSERT_EQ(i >= 16, sampler.IsOverdueForSamplingAt(t));
147 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); 197 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t));
148 t += vsync; 198 t += vsync;
149 } 199 }
150 200
151 // Now suppose we can sample again. We capture the next frame, and not the one 201 // Now suppose we can sample again. We capture the next frame, and not the one
152 // after that, and then we're back in the steady state again. 202 // after that, and then we're back in the steady state again.
203 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
153 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 204 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
154 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 205 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
155 for (int i = 0; i < 100; i++) { 206 for (int i = 0; i < 100; i++) {
156 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 207 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
157 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 208 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
158 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 209 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
159 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 210 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
160 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 211 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
161 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 212 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
162 } 213 }
163 } 214 }
164 215
165 // 30Hz sampled at 30Hz should produce 30Hz. 216 // 30Hz sampled at 30Hz should produce 30Hz.
166 TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) { 217 TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) {
167 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 218 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
219 const int redundant_capture_goal = 1;
168 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30; 220 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30;
169 221
170 SmoothEventSampler sampler(capture_period); 222 SmoothEventSampler sampler(capture_period, redundant_capture_goal);
171 base::TimeTicks t = InitialTestTimeTicks(); 223 base::TimeTicks t = InitialTestTimeTicks();
172 224
225 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, &sampler,
226 &t);
227
173 // Steady state, we should capture every vsync, indefinitely. 228 // Steady state, we should capture every vsync, indefinitely.
174 for (int i = 0; i < 200; i++) { 229 for (int i = 0; i < 200; i++) {
175 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 230 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
176 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 231 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
177 } 232 }
178 233
179 // Now pretend we're limited by backpressure in the pipeline. In this scenario 234 // Now pretend we're limited by backpressure in the pipeline. In this scenario
180 // case we are adding events but not sampling them. 235 // case we are adding events but not sampling them.
181 for (int i = 0; i < 10; i++) { 236 for (int i = 0; i < 10; i++) {
182 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 237 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
238 ASSERT_EQ(i >= 7, sampler.IsOverdueForSamplingAt(t));
183 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); 239 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t));
184 t += vsync; 240 t += vsync;
185 } 241 }
186 242
187 // Now suppose we can sample again. We should be back in the steady state. 243 // Now suppose we can sample again. We should be back in the steady state.
244 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
188 for (int i = 0; i < 100; i++) { 245 for (int i = 0; i < 100; i++) {
189 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 246 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
190 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 247 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
191 } 248 }
192 } 249 }
193 250
194 // 24Hz sampled at 30Hz should produce 24Hz. 251 // 24Hz sampled at 30Hz should produce 24Hz.
195 TEST(SmoothEventSamplerTest, Sample24HertzAt30Hertz) { 252 TEST(SmoothEventSamplerTest, Sample24HertzAt30Hertz) {
196 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30; 253 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
254 const int redundant_capture_goal = 333;
197 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 24; 255 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 24;
198 256
199 SmoothEventSampler sampler(capture_period); 257 SmoothEventSampler sampler(capture_period, redundant_capture_goal);
200 base::TimeTicks t = InitialTestTimeTicks(); 258 base::TimeTicks t = InitialTestTimeTicks();
201 259
260 TestRedundantCaptureStrategy(capture_period, redundant_capture_goal, &sampler,
261 &t);
262
202 // Steady state, we should capture every vsync, indefinitely. 263 // Steady state, we should capture every vsync, indefinitely.
203 for (int i = 0; i < 200; i++) { 264 for (int i = 0; i < 200; i++) {
204 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 265 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
205 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 266 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
206 } 267 }
207 268
208 // Now pretend we're limited by backpressure in the pipeline. In this scenario 269 // Now pretend we're limited by backpressure in the pipeline. In this scenario
209 // case we are adding events but not sampling them. 270 // case we are adding events but not sampling them.
210 for (int i = 0; i < 10; i++) { 271 for (int i = 0; i < 10; i++) {
211 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 272 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
273 ASSERT_EQ(i >= 6, sampler.IsOverdueForSamplingAt(t));
212 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t)); 274 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t));
213 t += vsync; 275 t += vsync;
214 } 276 }
215 277
216 // Now suppose we can sample again. We should be back in the steady state. 278 // Now suppose we can sample again. We should be back in the steady state.
279 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
217 for (int i = 0; i < 100; i++) { 280 for (int i = 0; i < 100; i++) {
218 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 281 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
219 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 282 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
220 } 283 }
221 } 284 }
222 285
223 // Tests that changing the minimum capture period during usage results in the 286 // Tests that changing the minimum capture period during usage results in the
224 // desired behavior. 287 // desired behavior.
225 TEST(SmoothEventSamplerTest, Sample60HertzWithVariedCapturePeriods) { 288 TEST(SmoothEventSamplerTest, Sample60HertzWithVariedCapturePeriods) {
226 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60; 289 const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60;
227 const base::TimeDelta one_to_one_period = vsync; 290 const base::TimeDelta one_to_one_period = vsync;
228 const base::TimeDelta two_to_one_period = vsync * 2; 291 const base::TimeDelta two_to_one_period = vsync * 2;
229 const base::TimeDelta two_and_three_to_one_period = 292 const base::TimeDelta two_and_three_to_one_period =
230 base::TimeDelta::FromSeconds(1) / 24; 293 base::TimeDelta::FromSeconds(1) / 24;
294 const int redundant_capture_goal = 1;
231 295
232 SmoothEventSampler sampler(one_to_one_period); 296 SmoothEventSampler sampler(one_to_one_period, redundant_capture_goal);
233 base::TimeTicks t = InitialTestTimeTicks(); 297 base::TimeTicks t = InitialTestTimeTicks();
234 298
299 TestRedundantCaptureStrategy(one_to_one_period, redundant_capture_goal,
300 &sampler, &t);
301
235 // With the capture rate at 60 Hz, we should capture every vsync. 302 // With the capture rate at 60 Hz, we should capture every vsync.
236 for (int i = 0; i < 100; i++) { 303 for (int i = 0; i < 100; i++) {
237 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 304 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
238 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 305 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
239 } 306 }
240 307
241 // Now change to the capture rate to 30 Hz, and we should capture every other 308 // Now change to the capture rate to 30 Hz, and we should capture every other
242 // vsync. 309 // vsync.
243 sampler.SetMinCapturePeriod(two_to_one_period); 310 sampler.SetMinCapturePeriod(two_to_one_period);
244 for (int i = 0; i < 100; i++) { 311 for (int i = 0; i < 100; i++) {
(...skipping 16 matching lines...) Expand all
261 for (int i = 0; i < 100; i++) { 328 for (int i = 0; i < 100; i++) {
262 SCOPED_TRACE(base::StringPrintf("Iteration %d", i)); 329 SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
263 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 330 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
264 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 331 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
265 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 332 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
266 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t); 333 SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
267 SteadyStateSampleAndAdvance(vsync, &sampler, &t); 334 SteadyStateSampleAndAdvance(vsync, &sampler, &t);
268 } 335 }
269 } 336 }
270 337
338 TEST(SmoothEventSamplerTest, DoubleDrawAtOneTimeStillDirties) {
339 const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
340 const base::TimeDelta overdue_period = base::TimeDelta::FromSeconds(1);
341
342 SmoothEventSampler sampler(capture_period, 1);
343 base::TimeTicks t = InitialTestTimeTicks();
344
345 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t));
346 sampler.RecordSample();
347 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t))
348 << "Sampled last event; should not be dirty.";
349 t += overdue_period;
350
351 // Now simulate 2 events with the same clock value.
352 ASSERT_TRUE(AddEventAndConsiderSampling(&sampler, t));
353 sampler.RecordSample();
354 ASSERT_FALSE(AddEventAndConsiderSampling(&sampler, t))
355 << "Two events at same time -- expected second not to be sampled.";
356 ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t + overdue_period))
357 << "Second event should dirty the capture state.";
358 sampler.RecordSample();
359 ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t + overdue_period));
360 }
361
271 namespace { 362 namespace {
272 363
273 struct DataPoint { 364 struct DataPoint {
274 bool should_capture; 365 bool should_capture;
275 double increment_ms; 366 double increment_ms;
276 }; 367 };
277 368
278 void ReplayCheckingSamplerDecisions(const DataPoint* data_points, 369 void ReplayCheckingSamplerDecisions(const DataPoint* data_points,
279 size_t num_data_points, 370 size_t num_data_points,
280 SmoothEventSampler* sampler) { 371 SmoothEventSampler* sampler) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 {true, 33.44}, 452 {true, 33.44},
362 {true, 50.161}, 453 {true, 50.161},
363 {true, 33.44}, 454 {true, 33.44},
364 {true, 50.161}, 455 {true, 50.161},
365 {true, 33.44}, 456 {true, 33.44},
366 {true, 83.601}, 457 {true, 83.601},
367 {true, 16.72}, 458 {true, 16.72},
368 {true, 33.44}, 459 {true, 33.44},
369 {false, 0}}; 460 {false, 0}};
370 461
371 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30); 462 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, 3);
372 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); 463 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler);
373 } 464 }
374 465
375 TEST(SmoothEventSamplerTest, DrawingAt30FpsWith60HzVsyncSampledAt30Hertz) { 466 TEST(SmoothEventSamplerTest, DrawingAt30FpsWith60HzVsyncSampledAt30Hertz) {
376 // Actual capturing of timing data: Initial instability as a 30 FPS video was 467 // Actual capturing of timing data: Initial instability as a 30 FPS video was
377 // started from a still screen, then followed by steady-state. Drawing 468 // started from a still screen, then followed by steady-state. Drawing
378 // framerate from the video rendering was a bit volatile, but averaged 30 FPS. 469 // framerate from the video rendering was a bit volatile, but averaged 30 FPS.
379 static const DataPoint data_points[] = {{true, 2407.69}, 470 static const DataPoint data_points[] = {{true, 2407.69},
380 {true, 16.733}, 471 {true, 16.733},
381 {true, 217.362}, 472 {true, 217.362},
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 {false, 16.72}, 561 {false, 16.72},
471 {true, 66.88}, 562 {true, 66.88},
472 {true, 16.721}, 563 {true, 16.721},
473 {true, 50.16}, 564 {true, 50.16},
474 {true, 33.44}, 565 {true, 33.44},
475 {true, 16.72}, 566 {true, 16.72},
476 {true, 33.441}, 567 {true, 33.441},
477 {true, 33.44}, 568 {true, 33.44},
478 {true, 33.44}}; 569 {true, 33.44}};
479 570
480 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30); 571 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, 3);
481 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); 572 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler);
482 } 573 }
483 574
484 TEST(SmoothEventSamplerTest, DrawingAt60FpsWith60HzVsyncSampledAt30Hertz) { 575 TEST(SmoothEventSamplerTest, DrawingAt60FpsWith60HzVsyncSampledAt30Hertz) {
485 // Actual capturing of timing data: WebGL Acquarium demo 576 // Actual capturing of timing data: WebGL Acquarium demo
486 // (http://webglsamples.googlecode.com/hg/aquarium/aquarium.html) which ran 577 // (http://webglsamples.googlecode.com/hg/aquarium/aquarium.html) which ran
487 // between 55-60 FPS in the steady-state. 578 // between 55-60 FPS in the steady-state.
488 static const DataPoint data_points[] = {{true, 16.72}, 579 static const DataPoint data_points[] = {{true, 16.72},
489 {true, 16.72}, 580 {true, 16.72},
490 {true, 4163.29}, 581 {true, 4163.29},
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 {true, 50.161}, 694 {true, 50.161},
604 {false, 0}, 695 {false, 0},
605 {true, 16.72}, 696 {true, 16.72},
606 {true, 33.44}, 697 {true, 33.44},
607 {false, 0}, 698 {false, 0},
608 {true, 33.441}, 699 {true, 33.441},
609 {false, 16.72}, 700 {false, 16.72},
610 {true, 16.72}, 701 {true, 16.72},
611 {true, 50.16}}; 702 {true, 50.16}};
612 703
613 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30); 704 SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, 3);
614 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler); 705 ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler);
615 } 706 }
616 707
617 } // namespace media 708 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/content/smooth_event_sampler.cc ('k') | media/capture/content/thread_safe_capture_oracle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698