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

Side by Side Diff: media/capture/content/video_capture_oracle.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/video_capture_oracle.h" 5 #include "media/capture/content/video_capture_oracle.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/numerics/safe_conversions.h" 10 #include "base/numerics/safe_conversions.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 12
13 namespace media { 13 namespace media {
14 14
15 namespace { 15 namespace {
16 16
17 // When a non-compositor event arrives after animation has halted, this 17 // This value controls how many redundant, timer-base captures occur when the
18 // controls how much time must elapse before deciding to allow a capture. 18 // content is static. Redundantly capturing the same frame allows iterative
19 const int kAnimationHaltPeriodBeforeOtherSamplingMicros = 250000; 19 // quality enhancement, and also allows the buffer to fill in "buffered mode".
20 20 //
21 // When estimating frame durations, this is the hard upper-bound on the 21 // TODO(nick): Controlling this here is a hack and a layering violation, since
22 // estimate. 22 // it's a strategy specific to the WebRTC consumer, and probably just papers
23 const int kUpperBoundDurationEstimateMicros = 1000000; // 1 second 23 // over some frame dropping and quality bugs. It should either be controlled at
24 // a higher level, or else redundant frame generation should be pushed down
25 // further into the WebRTC encoding stack.
26 const int kNumRedundantCapturesOfStaticContent = 200;
24 27
25 // The half-life of data points provided to the accumulator used when evaluating 28 // The half-life of data points provided to the accumulator used when evaluating
26 // the recent utilization of the buffer pool. This value is based on a 29 // the recent utilization of the buffer pool. This value is based on a
27 // simulation, and reacts quickly to change to avoid depleting the buffer pool 30 // simulation, and reacts quickly to change to avoid depleting the buffer pool
28 // (which would cause hard frame drops). 31 // (which would cause hard frame drops).
29 const int kBufferUtilizationEvaluationMicros = 200000; // 0.2 seconds 32 const int kBufferUtilizationEvaluationMicros = 200000; // 0.2 seconds
30 33
31 // The half-life of data points provided to the accumulator used when evaluating 34 // The half-life of data points provided to the accumulator used when evaluating
32 // the recent resource utilization of the consumer. The trade-off made here is 35 // the recent resource utilization of the consumer. The trade-off made here is
33 // reaction time versus over-reacting to outlier data points. 36 // reaction time versus over-reacting to outlier data points.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 99
97 VideoCaptureOracle::VideoCaptureOracle( 100 VideoCaptureOracle::VideoCaptureOracle(
98 base::TimeDelta min_capture_period, 101 base::TimeDelta min_capture_period,
99 const gfx::Size& max_frame_size, 102 const gfx::Size& max_frame_size,
100 media::ResolutionChangePolicy resolution_change_policy, 103 media::ResolutionChangePolicy resolution_change_policy,
101 bool enable_auto_throttling) 104 bool enable_auto_throttling)
102 : auto_throttling_enabled_(enable_auto_throttling), 105 : auto_throttling_enabled_(enable_auto_throttling),
103 next_frame_number_(0), 106 next_frame_number_(0),
104 last_successfully_delivered_frame_number_(-1), 107 last_successfully_delivered_frame_number_(-1),
105 num_frames_pending_(0), 108 num_frames_pending_(0),
106 smoothing_sampler_(min_capture_period), 109 smoothing_sampler_(min_capture_period,
110 kNumRedundantCapturesOfStaticContent),
107 content_sampler_(min_capture_period), 111 content_sampler_(min_capture_period),
108 resolution_chooser_(max_frame_size, resolution_change_policy), 112 resolution_chooser_(max_frame_size, resolution_change_policy),
109 buffer_pool_utilization_(base::TimeDelta::FromMicroseconds( 113 buffer_pool_utilization_(base::TimeDelta::FromMicroseconds(
110 kBufferUtilizationEvaluationMicros)), 114 kBufferUtilizationEvaluationMicros)),
111 estimated_capable_area_(base::TimeDelta::FromMicroseconds( 115 estimated_capable_area_(base::TimeDelta::FromMicroseconds(
112 kConsumerCapabilityEvaluationMicros)) { 116 kConsumerCapabilityEvaluationMicros)) {
113 VLOG(1) << "Auto-throttling is " 117 VLOG(1) << "Auto-throttling is "
114 << (auto_throttling_enabled_ ? "enabled." : "disabled."); 118 << (auto_throttling_enabled_ ? "enabled." : "disabled.");
115 } 119 }
116 120
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 duration_of_next_frame_ = content_sampler_.sampling_period(); 157 duration_of_next_frame_ = content_sampler_.sampling_period();
154 } 158 }
155 last_time_animation_was_detected_ = event_time; 159 last_time_animation_was_detected_ = event_time;
156 } else { 160 } else {
157 VLOG_IF(1, had_proposal) << "Content sampler detects animation ended."; 161 VLOG_IF(1, had_proposal) << "Content sampler detects animation ended.";
158 should_sample = smoothing_sampler_.ShouldSample(); 162 should_sample = smoothing_sampler_.ShouldSample();
159 } 163 }
160 break; 164 break;
161 } 165 }
162 166
163 case kActiveRefreshRequest: 167 case kTimerPoll:
164 case kPassiveRefreshRequest: 168 // While the timer is firing, only allow a sampling if there are none
169 // currently in-progress.
170 if (num_frames_pending_ == 0)
171 should_sample = smoothing_sampler_.IsOverdueForSamplingAt(event_time);
172 break;
173
165 case kMouseCursorUpdate: 174 case kMouseCursorUpdate:
166 // Only allow non-compositor samplings when content has not recently been 175 // Only allow a sampling if there are none currently in-progress.
167 // animating, and only if there are no samplings currently in progress.
168 if (num_frames_pending_ == 0) { 176 if (num_frames_pending_ == 0) {
169 if (!content_sampler_.HasProposal() || 177 smoothing_sampler_.ConsiderPresentationEvent(event_time);
170 ((event_time - last_time_animation_was_detected_).InMicroseconds() > 178 should_sample = smoothing_sampler_.ShouldSample();
171 kAnimationHaltPeriodBeforeOtherSamplingMicros)) {
172 smoothing_sampler_.ConsiderPresentationEvent(event_time);
173 should_sample = smoothing_sampler_.ShouldSample();
174 }
175 } 179 }
176 break; 180 break;
177
178 case kNumEvents: 181 case kNumEvents:
179 NOTREACHED(); 182 NOTREACHED();
180 break; 183 break;
181 } 184 }
182 185
183 if (!should_sample) 186 if (!should_sample)
184 return false; 187 return false;
185 188
186 // If the exact duration of the next frame has not been determined, estimate 189 // If the exact duration of the next frame has not been determined, estimate
187 // it using the difference between the current and last frame. 190 // it using the difference between the current and last frame.
188 if (duration_of_next_frame_.is_zero()) { 191 if (duration_of_next_frame_.is_zero()) {
189 if (next_frame_number_ > 0) { 192 if (next_frame_number_ > 0) {
190 duration_of_next_frame_ = 193 duration_of_next_frame_ =
191 event_time - GetFrameTimestamp(next_frame_number_ - 1); 194 event_time - GetFrameTimestamp(next_frame_number_ - 1);
192 } 195 }
193 const base::TimeDelta upper_bound = 196 const base::TimeDelta upper_bound = base::TimeDelta::FromMilliseconds(
194 base::TimeDelta::FromMilliseconds(kUpperBoundDurationEstimateMicros); 197 SmoothEventSampler::OVERDUE_DIRTY_THRESHOLD_MILLIS);
195 duration_of_next_frame_ = 198 duration_of_next_frame_ =
196 std::max(std::min(duration_of_next_frame_, upper_bound), 199 std::max(std::min(duration_of_next_frame_, upper_bound),
197 smoothing_sampler_.min_capture_period()); 200 smoothing_sampler_.min_capture_period());
198 } 201 }
199 202
200 // Update |capture_size_| and reset all feedback signal accumulators if 203 // Update |capture_size_| and reset all feedback signal accumulators if
201 // either: 1) this is the first frame; or 2) |resolution_chooser_| has an 204 // either: 1) this is the first frame; or 2) |resolution_chooser_| has an
202 // updated capture size and sufficient time has passed since the last size 205 // updated capture size and sufficient time has passed since the last size
203 // change. 206 // change.
204 if (next_frame_number_ == 0) { 207 if (next_frame_number_ == 0) {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 // Translate the utilization metric to be in terms of the capable frame area 333 // Translate the utilization metric to be in terms of the capable frame area
331 // and update the feedback accumulators. Research suggests utilization is at 334 // and update the feedback accumulators. Research suggests utilization is at
332 // most linearly proportional to area, and typically is sublinear. Either 335 // most linearly proportional to area, and typically is sublinear. Either
333 // way, the end-to-end system should converge to the right place using the 336 // way, the end-to-end system should converge to the right place using the
334 // more-conservative assumption (linear). 337 // more-conservative assumption (linear).
335 const int area_at_full_utilization = 338 const int area_at_full_utilization =
336 base::saturated_cast<int>(capture_size_.GetArea() / resource_utilization); 339 base::saturated_cast<int>(capture_size_.GetArea() / resource_utilization);
337 estimated_capable_area_.Update(area_at_full_utilization, timestamp); 340 estimated_capable_area_.Update(area_at_full_utilization, timestamp);
338 } 341 }
339 342
340 // static
341 const char* VideoCaptureOracle::EventAsString(Event event) {
342 switch (event) {
343 case kCompositorUpdate:
344 return "compositor";
345 case kActiveRefreshRequest:
346 return "active_refresh";
347 case kPassiveRefreshRequest:
348 return "passive_refresh";
349 case kMouseCursorUpdate:
350 return "mouse";
351 case kNumEvents:
352 break;
353 }
354 NOTREACHED();
355 return "unknown";
356 }
357
358 base::TimeTicks VideoCaptureOracle::GetFrameTimestamp(int frame_number) const { 343 base::TimeTicks VideoCaptureOracle::GetFrameTimestamp(int frame_number) const {
359 DCHECK(IsFrameInRecentHistory(frame_number)); 344 DCHECK(IsFrameInRecentHistory(frame_number));
360 return frame_timestamps_[frame_number % kMaxFrameTimestamps]; 345 return frame_timestamps_[frame_number % kMaxFrameTimestamps];
361 } 346 }
362 347
363 void VideoCaptureOracle::SetFrameTimestamp(int frame_number, 348 void VideoCaptureOracle::SetFrameTimestamp(int frame_number,
364 base::TimeTicks timestamp) { 349 base::TimeTicks timestamp) {
365 DCHECK(IsFrameInRecentHistory(frame_number)); 350 DCHECK(IsFrameInRecentHistory(frame_number));
366 frame_timestamps_[frame_number % kMaxFrameTimestamps] = timestamp; 351 frame_timestamps_[frame_number % kMaxFrameTimestamps] = timestamp;
367 } 352 }
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 // Content is not animating, so permit an immediate increase in the capture 533 // Content is not animating, so permit an immediate increase in the capture
549 // area. This allows the system to quickly improve the quality of 534 // area. This allows the system to quickly improve the quality of
550 // non-animating content (frame drops are not much of a concern). 535 // non-animating content (frame drops are not much of a concern).
551 VLOG(2) << "Proposing a " 536 VLOG(2) << "Proposing a "
552 << (100.0 * (increased_area - current_area) / current_area) 537 << (100.0 * (increased_area - current_area) / current_area)
553 << "% increase in capture area for non-animating content. :-)"; 538 << "% increase in capture area for non-animating content. :-)";
554 return increased_area; 539 return increased_area;
555 } 540 }
556 541
557 } // namespace media 542 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/content/video_capture_oracle.h ('k') | media/capture/content/video_capture_oracle_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698