Chromium Code Reviews| Index: webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc |
| diff --git a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc |
| index e81ab3df37f4445f01acc3917d140d59e7c8659b..5c670b6c635d791e33c71633db5fc60aa58fa77e 100644 |
| --- a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc |
| +++ b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc |
| @@ -76,7 +76,7 @@ ScreenshareLayers::ScreenshareLayers(int num_temporal_layers, |
| min_qp_(-1), |
| max_qp_(-1), |
| max_debt_bytes_(0), |
| - framerate_(-1), |
| + encode_framerate_(1000.0f, 1000.0f), // 1 second window, second scale. |
| bitrate_updated_(false) { |
| RTC_CHECK_GT(num_temporal_layers, 0); |
| RTC_CHECK_LE(num_temporal_layers, 2); |
| @@ -97,8 +97,15 @@ int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { |
| return 0; |
| } |
| + const int64_t now_ms = clock_->TimeInMilliseconds(); |
| + if (target_framerate_.value_or(0) > 0 && |
| + encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) { |
| + // Max framerate exceeded, drop frame. |
| + return -1; |
| + } |
| + |
| if (stats_.first_frame_time_ms_ == -1) |
| - stats_.first_frame_time_ms_ = clock_->TimeInMilliseconds(); |
| + stats_.first_frame_time_ms_ = now_ms; |
| int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); |
| int flags = 0; |
| @@ -148,7 +155,8 @@ int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { |
| int64_t ts_diff; |
| if (last_timestamp_ == -1) { |
| - ts_diff = kOneSecond90Khz / (framerate_ <= 0 ? 5 : framerate_); |
| + ts_diff = |
| + kOneSecond90Khz / incoming_framerate_.value_or(*target_framerate_); |
|
stefan-webrtc
2016/12/19 10:58:29
Looks like incoming_framerate_ can be zero. I'm pr
sprang_webrtc
2016/12/19 16:46:34
This "shouldn't happen" since we treat 0 fps as in
stefan-webrtc
2016/12/22 09:39:34
Yes, sounds like the check is pretty far away from
sprang_webrtc
2016/12/28 13:00:35
Sure, added dcheck to OnRatesUpdated.
|
| } else { |
| ts_diff = unwrapped_timestamp - last_timestamp_; |
| } |
| @@ -162,13 +170,27 @@ int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { |
| std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, |
| int max_bitrate_kbps, |
| int framerate) { |
| - bitrate_updated_ = |
| - bitrate_kbps != static_cast<int>(layers_[0].target_rate_kbps_) || |
| - max_bitrate_kbps != static_cast<int>(layers_[1].target_rate_kbps_) || |
| - framerate != framerate_; |
| + if (!target_framerate_) { |
| + // First OnRatesUpdated() is called during construction, with the configured |
| + // targets as parameters. |
| + target_framerate_.emplace(framerate); |
| + incoming_framerate_ = target_framerate_; |
| + bitrate_updated_ = true; |
| + } else { |
| + bitrate_updated_ = |
| + bitrate_kbps != static_cast<int>(layers_[0].target_rate_kbps_) || |
| + max_bitrate_kbps != static_cast<int>(layers_[1].target_rate_kbps_) || |
| + (incoming_framerate_ && |
| + framerate != static_cast<int>(*incoming_framerate_)); |
| + if (framerate < 0) { |
| + incoming_framerate_.reset(); |
| + } else { |
| + incoming_framerate_.emplace(framerate); |
| + } |
| + } |
| + |
| layers_[0].target_rate_kbps_ = bitrate_kbps; |
| layers_[1].target_rate_kbps_ = max_bitrate_kbps; |
| - framerate_ = framerate; |
| std::vector<uint32_t> allocation; |
| allocation.push_back(bitrate_kbps); |
| @@ -180,6 +202,9 @@ std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, |
| void ScreenshareLayers::FrameEncoded(unsigned int size, |
| uint32_t timestamp, |
| int qp) { |
| + if (size > 0) |
| + encode_framerate_.Update(1, clock_->TimeInMilliseconds()); |
| + |
| if (number_of_temporal_layers_ == 1) |
| return; |
| @@ -301,8 +326,9 @@ bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { |
| layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100); |
| } |
| - if (framerate_ > 0) { |
| - int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate_); |
| + if (incoming_framerate_) { |
| + int avg_frame_size = |
| + (target_bitrate_kbps * 1000) / (8 * *incoming_framerate_); |
| max_debt_bytes_ = 4 * avg_frame_size; |
| } |