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

Side by Side Diff: webrtc/video/overuse_frame_detector.cc

Issue 2764133002: Revert of Add framerate to VideoSinkWants and ability to signal on overuse (Closed)
Patch Set: Created 3 years, 9 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
« no previous file with comments | « webrtc/video/overuse_frame_detector.h ('k') | webrtc/video/send_statistics_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/video/overuse_frame_detector.h" 11 #include "webrtc/video/overuse_frame_detector.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <math.h> 14 #include <math.h>
15 15
16 #include <algorithm> 16 #include <algorithm>
17 #include <list> 17 #include <list>
18 #include <map> 18 #include <map>
19 #include <string>
20 #include <utility>
21 19
22 #include "webrtc/api/video/video_frame.h" 20 #include "webrtc/api/video/video_frame.h"
23 #include "webrtc/base/checks.h" 21 #include "webrtc/base/checks.h"
24 #include "webrtc/base/logging.h" 22 #include "webrtc/base/logging.h"
25 #include "webrtc/base/numerics/exp_filter.h" 23 #include "webrtc/base/numerics/exp_filter.h"
26 #include "webrtc/common_video/include/frame_callback.h" 24 #include "webrtc/common_video/include/frame_callback.h"
27 #include "webrtc/system_wrappers/include/field_trial.h"
28 25
29 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 26 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
30 #include <mach/mach.h> 27 #include <mach/mach.h>
31 #endif // defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 28 #endif // defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
32 29
33 namespace webrtc { 30 namespace webrtc {
34 31
35 namespace { 32 namespace {
36 const int64_t kCheckForOveruseIntervalMs = 5000; 33 const int64_t kCheckForOveruseIntervalMs = 5000;
37 const int64_t kTimeToFirstCheckForOveruseMs = 100; 34 const int64_t kTimeToFirstCheckForOveruseMs = 100;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 : kWeightFactorFrameDiff(0.998f), 109 : kWeightFactorFrameDiff(0.998f),
113 kWeightFactorProcessing(0.995f), 110 kWeightFactorProcessing(0.995f),
114 kInitialSampleDiffMs(40.0f), 111 kInitialSampleDiffMs(40.0f),
115 kMaxSampleDiffMs(45.0f), 112 kMaxSampleDiffMs(45.0f),
116 count_(0), 113 count_(0),
117 options_(options), 114 options_(options),
118 filtered_processing_ms_(new rtc::ExpFilter(kWeightFactorProcessing)), 115 filtered_processing_ms_(new rtc::ExpFilter(kWeightFactorProcessing)),
119 filtered_frame_diff_ms_(new rtc::ExpFilter(kWeightFactorFrameDiff)) { 116 filtered_frame_diff_ms_(new rtc::ExpFilter(kWeightFactorFrameDiff)) {
120 Reset(); 117 Reset();
121 } 118 }
122 virtual ~SendProcessingUsage() {} 119 ~SendProcessingUsage() {}
123 120
124 void Reset() { 121 void Reset() {
125 count_ = 0; 122 count_ = 0;
126 filtered_frame_diff_ms_->Reset(kWeightFactorFrameDiff); 123 filtered_frame_diff_ms_->Reset(kWeightFactorFrameDiff);
127 filtered_frame_diff_ms_->Apply(1.0f, kInitialSampleDiffMs); 124 filtered_frame_diff_ms_->Apply(1.0f, kInitialSampleDiffMs);
128 filtered_processing_ms_->Reset(kWeightFactorProcessing); 125 filtered_processing_ms_->Reset(kWeightFactorProcessing);
129 filtered_processing_ms_->Apply(1.0f, InitialProcessingMs()); 126 filtered_processing_ms_->Apply(1.0f, InitialProcessingMs());
130 } 127 }
131 128
132 void AddCaptureSample(float sample_ms) { 129 void AddCaptureSample(float sample_ms) {
133 float exp = sample_ms / kSampleDiffMs; 130 float exp = sample_ms / kSampleDiffMs;
134 exp = std::min(exp, kMaxExp); 131 exp = std::min(exp, kMaxExp);
135 filtered_frame_diff_ms_->Apply(exp, sample_ms); 132 filtered_frame_diff_ms_->Apply(exp, sample_ms);
136 } 133 }
137 134
138 void AddSample(float processing_ms, int64_t diff_last_sample_ms) { 135 void AddSample(float processing_ms, int64_t diff_last_sample_ms) {
139 ++count_; 136 ++count_;
140 float exp = diff_last_sample_ms / kSampleDiffMs; 137 float exp = diff_last_sample_ms / kSampleDiffMs;
141 exp = std::min(exp, kMaxExp); 138 exp = std::min(exp, kMaxExp);
142 filtered_processing_ms_->Apply(exp, processing_ms); 139 filtered_processing_ms_->Apply(exp, processing_ms);
143 } 140 }
144 141
145 virtual int Value() { 142 int Value() const {
146 if (count_ < static_cast<uint32_t>(options_.min_frame_samples)) { 143 if (count_ < static_cast<uint32_t>(options_.min_frame_samples)) {
147 return static_cast<int>(InitialUsageInPercent() + 0.5f); 144 return static_cast<int>(InitialUsageInPercent() + 0.5f);
148 } 145 }
149 float frame_diff_ms = std::max(filtered_frame_diff_ms_->filtered(), 1.0f); 146 float frame_diff_ms = std::max(filtered_frame_diff_ms_->filtered(), 1.0f);
150 frame_diff_ms = std::min(frame_diff_ms, kMaxSampleDiffMs); 147 frame_diff_ms = std::min(frame_diff_ms, kMaxSampleDiffMs);
151 float encode_usage_percent = 148 float encode_usage_percent =
152 100.0f * filtered_processing_ms_->filtered() / frame_diff_ms; 149 100.0f * filtered_processing_ms_->filtered() / frame_diff_ms;
153 return static_cast<int>(encode_usage_percent + 0.5); 150 return static_cast<int>(encode_usage_percent + 0.5);
154 } 151 }
155 152
(...skipping 11 matching lines...) Expand all
167 const float kWeightFactorFrameDiff; 164 const float kWeightFactorFrameDiff;
168 const float kWeightFactorProcessing; 165 const float kWeightFactorProcessing;
169 const float kInitialSampleDiffMs; 166 const float kInitialSampleDiffMs;
170 const float kMaxSampleDiffMs; 167 const float kMaxSampleDiffMs;
171 uint64_t count_; 168 uint64_t count_;
172 const CpuOveruseOptions options_; 169 const CpuOveruseOptions options_;
173 std::unique_ptr<rtc::ExpFilter> filtered_processing_ms_; 170 std::unique_ptr<rtc::ExpFilter> filtered_processing_ms_;
174 std::unique_ptr<rtc::ExpFilter> filtered_frame_diff_ms_; 171 std::unique_ptr<rtc::ExpFilter> filtered_frame_diff_ms_;
175 }; 172 };
176 173
177 // Class used for manual testing of overuse, enabled via field trial flag.
178 class OveruseFrameDetector::OverdoseInjector
179 : public OveruseFrameDetector::SendProcessingUsage {
180 public:
181 OverdoseInjector(const CpuOveruseOptions& options,
182 int64_t overuse_period_ms,
183 int64_t normal_period_ms)
184 : OveruseFrameDetector::SendProcessingUsage(options),
185 overuse_period_ms_(overuse_period_ms),
186 normal_period_ms_(normal_period_ms),
187 is_overusing_(false),
188 last_toggling_ms_(-1) {
189 RTC_DCHECK_GT(overuse_period_ms, 0);
190 RTC_DCHECK_GT(normal_period_ms, 0);
191 LOG(LS_INFO) << "Simulating overuse with intervals " << normal_period_ms
192 << "ms normal mode, " << overuse_period_ms
193 << "ms overuse mode.";
194 }
195
196 ~OverdoseInjector() override {}
197
198 int Value() override {
199 int64_t now_ms = rtc::TimeMillis();
200 if (last_toggling_ms_ == -1) {
201 last_toggling_ms_ = now_ms;
202 } else {
203 int64_t toggle_time_ms =
204 last_toggling_ms_ +
205 (is_overusing_ ? overuse_period_ms_ : normal_period_ms_);
206 if (now_ms > toggle_time_ms) {
207 is_overusing_ = !is_overusing_;
208 last_toggling_ms_ = now_ms;
209 if (is_overusing_) {
210 LOG(LS_INFO) << "Simulating CPU overuse.";
211 } else {
212 LOG(LS_INFO) << "Disabling CPU overuse simulation.";
213 }
214 }
215 }
216
217 if (is_overusing_)
218 return 250; // 250% should be enough for anyone.
219
220 return SendProcessingUsage::Value();
221 }
222
223 private:
224 const int64_t overuse_period_ms_;
225 const int64_t normal_period_ms_;
226 bool is_overusing_;
227 int64_t last_toggling_ms_;
228 };
229
230 std::unique_ptr<OveruseFrameDetector::SendProcessingUsage>
231 OveruseFrameDetector::CreateSendProcessingUsage(
232 const CpuOveruseOptions& options) {
233 std::unique_ptr<SendProcessingUsage> instance;
234 std::string toggling_interval =
235 field_trial::FindFullName("WebRTC-ForceSimulatedOveruseIntervalMs");
236 if (!toggling_interval.empty()) {
237 int overuse_period_ms = 0;
238 int normal_period_ms = 0;
239 if (sscanf(toggling_interval.c_str(), "%d-%d", &overuse_period_ms,
240 &normal_period_ms) == 2) {
241 if (overuse_period_ms > 0 && normal_period_ms > 0) {
242 instance.reset(
243 new OverdoseInjector(options, overuse_period_ms, normal_period_ms));
244 } else {
245 LOG(LS_WARNING) << "Invalid (non-positive) overuse / normal periods: "
246 << overuse_period_ms << " / " << normal_period_ms;
247 }
248 } else {
249 LOG(LS_WARNING) << "Malformed toggling interval: " << toggling_interval;
250 }
251 }
252
253 if (!instance) {
254 // No valid overuse simulation parameters set, use normal usage class.
255 instance.reset(new SendProcessingUsage(options));
256 }
257
258 return instance;
259 }
260
261 class OveruseFrameDetector::CheckOveruseTask : public rtc::QueuedTask { 174 class OveruseFrameDetector::CheckOveruseTask : public rtc::QueuedTask {
262 public: 175 public:
263 explicit CheckOveruseTask(OveruseFrameDetector* overuse_detector) 176 explicit CheckOveruseTask(OveruseFrameDetector* overuse_detector)
264 : overuse_detector_(overuse_detector) { 177 : overuse_detector_(overuse_detector) {
265 rtc::TaskQueue::Current()->PostDelayedTask( 178 rtc::TaskQueue::Current()->PostDelayedTask(
266 std::unique_ptr<rtc::QueuedTask>(this), kTimeToFirstCheckForOveruseMs); 179 std::unique_ptr<rtc::QueuedTask>(this), kTimeToFirstCheckForOveruseMs);
267 } 180 }
268 181
269 void Stop() { 182 void Stop() {
270 RTC_CHECK(task_checker_.CalledSequentially()); 183 RTC_CHECK(task_checker_.CalledSequentially());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 // TODO(nisse): Use rtc::Optional 215 // TODO(nisse): Use rtc::Optional
303 last_capture_time_us_(-1), 216 last_capture_time_us_(-1),
304 last_processed_capture_time_us_(-1), 217 last_processed_capture_time_us_(-1),
305 num_pixels_(0), 218 num_pixels_(0),
306 last_overuse_time_ms_(-1), 219 last_overuse_time_ms_(-1),
307 checks_above_threshold_(0), 220 checks_above_threshold_(0),
308 num_overuse_detections_(0), 221 num_overuse_detections_(0),
309 last_rampup_time_ms_(-1), 222 last_rampup_time_ms_(-1),
310 in_quick_rampup_(false), 223 in_quick_rampup_(false),
311 current_rampup_delay_ms_(kStandardRampUpDelayMs), 224 current_rampup_delay_ms_(kStandardRampUpDelayMs),
312 usage_(CreateSendProcessingUsage(options)) { 225 usage_(new SendProcessingUsage(options)) {
313 task_checker_.Detach(); 226 task_checker_.Detach();
314 } 227 }
315 228
316 OveruseFrameDetector::~OveruseFrameDetector() { 229 OveruseFrameDetector::~OveruseFrameDetector() {
317 RTC_DCHECK(!check_overuse_task_) << "StopCheckForOverUse must be called."; 230 RTC_DCHECK(!check_overuse_task_) << "StopCheckForOverUse must be called.";
318 } 231 }
319 232
320 void OveruseFrameDetector::StartCheckForOveruse() { 233 void OveruseFrameDetector::StartCheckForOveruse() {
321 RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_); 234 RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
322 RTC_DCHECK(!check_overuse_task_); 235 RTC_DCHECK(!check_overuse_task_);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 } 313 }
401 // TODO(pbos): Handle the case/log errors when not finding the corresponding 314 // TODO(pbos): Handle the case/log errors when not finding the corresponding
402 // frame (either very slow encoding or incorrect wrong timestamps returned 315 // frame (either very slow encoding or incorrect wrong timestamps returned
403 // from the encoder). 316 // from the encoder).
404 // This is currently the case for all frames on ChromeOS, so logging them 317 // This is currently the case for all frames on ChromeOS, so logging them
405 // would be spammy, and triggering overuse would be wrong. 318 // would be spammy, and triggering overuse would be wrong.
406 // https://crbug.com/350106 319 // https://crbug.com/350106
407 while (!frame_timing_.empty()) { 320 while (!frame_timing_.empty()) {
408 FrameTiming timing = frame_timing_.front(); 321 FrameTiming timing = frame_timing_.front();
409 if (time_sent_in_us - timing.capture_us < 322 if (time_sent_in_us - timing.capture_us <
410 kEncodingTimeMeasureWindowMs * rtc::kNumMicrosecsPerMillisec) { 323 kEncodingTimeMeasureWindowMs * rtc::kNumMicrosecsPerMillisec)
411 break; 324 break;
412 }
413 if (timing.last_send_us != -1) { 325 if (timing.last_send_us != -1) {
414 int encode_duration_us = 326 int encode_duration_us =
415 static_cast<int>(timing.last_send_us - timing.capture_us); 327 static_cast<int>(timing.last_send_us - timing.capture_us);
416 if (encoder_timing_) { 328 if (encoder_timing_) {
417 // TODO(nisse): Update encoder_timing_ to also use us units. 329 // TODO(nisse): Update encoder_timing_ to also use us units.
418 encoder_timing_->OnEncodeTiming(timing.capture_time_us / 330 encoder_timing_->OnEncodeTiming(timing.capture_time_us /
419 rtc::kNumMicrosecsPerMillisec, 331 rtc::kNumMicrosecsPerMillisec,
420 encode_duration_us / 332 encode_duration_us /
421 rtc::kNumMicrosecsPerMillisec); 333 rtc::kNumMicrosecsPerMillisec);
422 } 334 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_; 389 in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_;
478 390
479 LOG(LS_VERBOSE) << " Frame stats: " 391 LOG(LS_VERBOSE) << " Frame stats: "
480 << " encode usage " << metrics_->encode_usage_percent 392 << " encode usage " << metrics_->encode_usage_percent
481 << " overuse detections " << num_overuse_detections_ 393 << " overuse detections " << num_overuse_detections_
482 << " rampup delay " << rampup_delay; 394 << " rampup delay " << rampup_delay;
483 } 395 }
484 396
485 bool OveruseFrameDetector::IsOverusing(const CpuOveruseMetrics& metrics) { 397 bool OveruseFrameDetector::IsOverusing(const CpuOveruseMetrics& metrics) {
486 RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_); 398 RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
487
488 if (metrics.encode_usage_percent >= 399 if (metrics.encode_usage_percent >=
489 options_.high_encode_usage_threshold_percent) { 400 options_.high_encode_usage_threshold_percent) {
490 ++checks_above_threshold_; 401 ++checks_above_threshold_;
491 } else { 402 } else {
492 checks_above_threshold_ = 0; 403 checks_above_threshold_ = 0;
493 } 404 }
494 return checks_above_threshold_ >= options_.high_threshold_consecutive_count; 405 return checks_above_threshold_ >= options_.high_threshold_consecutive_count;
495 } 406 }
496 407
497 bool OveruseFrameDetector::IsUnderusing(const CpuOveruseMetrics& metrics, 408 bool OveruseFrameDetector::IsUnderusing(const CpuOveruseMetrics& metrics,
498 int64_t time_now) { 409 int64_t time_now) {
499 RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_); 410 RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
500 int delay = in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_; 411 int delay = in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_;
501 if (time_now < last_rampup_time_ms_ + delay) 412 if (time_now < last_rampup_time_ms_ + delay)
502 return false; 413 return false;
503 414
504 return metrics.encode_usage_percent < 415 return metrics.encode_usage_percent <
505 options_.low_encode_usage_threshold_percent; 416 options_.low_encode_usage_threshold_percent;
506 } 417 }
507 } // namespace webrtc 418 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/overuse_frame_detector.h ('k') | webrtc/video/send_statistics_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698