Chromium Code Reviews| Index: webrtc/video/vie_encoder.cc |
| diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc |
| index eaf693af169392883496a2f7fff370029248b433..9e2ef05853e03b1f5fe18c20c9a134dbba1aca08 100644 |
| --- a/webrtc/video/vie_encoder.cc |
| +++ b/webrtc/video/vie_encoder.cc |
| @@ -42,6 +42,10 @@ const int kMinPixelsPerFrame = 320 * 180; |
| const int kMinPixelsPerFrame = 120 * 90; |
| #endif |
| +// The maximum number of frames to drop at beginning of stream |
| +// to try and achieve desired bitrate. |
| +const int kMaxInitialFramedrop = 4; |
| + |
| // TODO(pbos): Lower these thresholds (to closer to 100%) when we handle |
| // pipelining encoders better (multiple input frames before something comes |
| // out). This should effectively turn off CPU adaptations for systems that |
| @@ -55,6 +59,17 @@ CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) { |
| return options; |
| } |
| +uint32_t MaximumFrameSizeForBitrate(uint32_t kbps) { |
| + if (kbps > 0) { |
| + if (kbps < 300 /* qvga */) { |
| + return 320 * 240; |
| + } else if (kbps < 500 /* vga */) { |
| + return 640 * 480; |
| + } |
| + } |
| + return std::numeric_limits<uint32_t>::max(); |
| +} |
| + |
| } // namespace |
| class ViEEncoder::ConfigureEncoderTask : public rtc::QueuedTask { |
| @@ -244,6 +259,7 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
| EncodedFrameObserver* encoder_timing) |
| : shutdown_event_(true /* manual_reset */, false), |
| number_of_cores_(number_of_cores), |
| + initial_rampup_(0), |
| source_proxy_(new VideoSourceProxy(this)), |
| sink_(nullptr), |
| settings_(settings), |
| @@ -439,6 +455,7 @@ void ViEEncoder::ReconfigureEncoder() { |
| const auto scaling_settings = settings_.encoder->GetScalingSettings(); |
| if (scaling_enabled_ && scaling_settings.enabled) { |
| + // Drop frames and scale down until desired quality is achieved. |
| if (scaling_settings.thresholds) { |
| quality_scaler_.reset( |
|
perkj_webrtc
2017/01/24 12:58:22
quality scaler is only created when the codec is r
kthelgason
2017/01/25 10:01:58
Acknowledged.
|
| new QualityScaler(this, *(scaling_settings.thresholds))); |
| @@ -446,6 +463,7 @@ void ViEEncoder::ReconfigureEncoder() { |
| quality_scaler_.reset(new QualityScaler(this, codec_type_)); |
| } |
| } else { |
| + initial_rampup_ = kMaxInitialFramedrop; |
|
perkj_webrtc
2017/01/24 12:58:23
This will not necessarily be called when scaling_e
kthelgason
2017/01/25 10:01:58
Acknowledged.
|
| quality_scaler_.reset(nullptr); |
| stats_proxy_->SetResolutionRestrictionStats( |
| false, scale_counter_[kCpu] > 0, scale_counter_[kQuality]); |
| @@ -545,6 +563,18 @@ void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame, |
| << ", texture=" << last_frame_info_->is_texture; |
| } |
| + uint32_t max_pixel_count = |
| + MaximumFrameSizeForBitrate(encoder_start_bitrate_bps_ / 1000); |
| + if (initial_rampup_ < kMaxInitialFramedrop && |
|
perkj_webrtc
2017/01/24 12:58:22
I guess you will also need to check if (scaling_en
kthelgason
2017/01/25 10:01:58
Yes, this sucks.
|
| + video_frame.size() > max_pixel_count) { |
|
perkj_webrtc
2017/01/24 12:58:23
nit: prefer video_frame_size() > MaximumFrameSizeF
kthelgason
2017/01/25 10:01:58
Done.
|
| + LOG(LS_INFO) << "Dropping frame. Too large for target bitrate."; |
| + ScaleDown(kQuality); |
| + ++initial_rampup_; |
| + return; |
| + } |
| + initial_rampup_ = kMaxInitialFramedrop; |
| + |
| + |
|
perkj_webrtc
2017/01/24 12:58:23
nit: remove extra empty line.
kthelgason
2017/01/25 10:01:58
Done.
|
| int64_t now_ms = clock_->TimeInMilliseconds(); |
| if (pending_encoder_reconfiguration_) { |
| ReconfigureEncoder(); |