Revert "Smoother frame dropping when screenshare_layers limits fps"
This reverts commit 28a06b16cc4daa9f380ad45af8acfd11b6057283.
Reason for revert: Causes some unexpected perf changes.
Original change's description:
> Smoother frame dropping when screenshare_layers limits fps
>
> Currently, when input fps is higher than the configured target fps in
> screenshare_layers, we drop frames with the help of a rate tracker using
> a one second sliding window. This is not optimal.
> For instance, given a 5fps limit and a 30fps capturer, the window will
> not be saturated until we have added the first 5 frames. Then we will
> drop all frames until the oldest one drops out, at which point we can
> immediately fill it's place. This results in quick 5 frame bursts every
> second.
>
> In addition to rate tracker, also set a limit on minimum interval
> required between input frames, based on target frame rate.
>
> Bug: webrtc:4172
> Change-Id: I49f0abf4d549673cc6b3fafe580b529ea3feaf57
> Reviewed-on: https://webrtc-review.googlesource.com/34380
> Commit-Queue: Erik Språng <sprang@webrtc.org>
> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#21325}
TBR=ilnik@webrtc.org,sprang@webrtc.org
Change-Id: I7ca5b0c847310dbb11dce28773082eac946c0ba4
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:4172
Reviewed-on: https://webrtc-review.googlesource.com/34780
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21354}
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers.cc b/modules/video_coding/codecs/vp8/screenshare_layers.cc
index e398687..782dc77 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers.cc
+++ b/modules/video_coding/codecs/vp8/screenshare_layers.cc
@@ -113,6 +113,14 @@
}
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 TemporalLayers::FrameConfig(kNone, kNone, kNone);
+ }
+
+ if (stats_.first_frame_time_ms_ == -1)
+ stats_.first_frame_time_ms_ = now_ms;
int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
int64_t ts_diff;
@@ -121,24 +129,6 @@
} else {
ts_diff = unwrapped_timestamp - last_timestamp_;
}
-
- // If input frame rate exceeds target frame rate, either over a one second
- // averaging window, or if frame interval is below 90% of desired value,
- // drop frame.
- if (target_framerate_) {
- bool exceeds_average_rate =
- encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_;
- bool exceeds_inter_frame_delay =
- ts_diff < (kOneSecond90Khz * 9) / (*target_framerate_ * 10);
- if (exceeds_average_rate || exceeds_inter_frame_delay) {
- // Max framerate exceeded, drop frame.
- return TemporalLayers::FrameConfig(kNone, kNone, kNone);
- }
- }
-
- if (stats_.first_frame_time_ms_ == -1)
- stats_.first_frame_time_ms_ = now_ms;
-
// Make sure both frame droppers leak out bits.
layers_[0].UpdateDebt(ts_diff / 90);
layers_[1].UpdateDebt(ts_diff / 90);
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
index f426b69..754235a 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
+++ b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
@@ -442,12 +442,7 @@
ASSERT_GT(kStartTimestamp + 90 * (kLargeFrameSizeBytes * 8) / kLowBitrateKbps,
kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90));
- // Expect drop one frame interval before the two second timeout. If we try
- // any later, the frame will be dropped anyway by the frame rate throttling
- // logic.
- EXPECT_TRUE(layers_->UpdateLayerConfig(kTwoSecondsLater - kTimestampDelta5Fps)
- .drop_frame);
-
+ EXPECT_TRUE(layers_->UpdateLayerConfig(kTwoSecondsLater).drop_frame);
// More than two seconds has passed since last frame, one should be emitted
// even if bitrate target is then exceeded.
EXPECT_EQ(kTl0Flags, VP8EncoderImpl::EncodeFlags(
@@ -477,6 +472,8 @@
// Simulate one overshoot.
layers_->FrameEncoded(0, 0);
overshoot = true;
+ flags =
+ VP8EncoderImpl::EncodeFlags(layers_->UpdateLayerConfig(timestamp));
}
if (flags == kTl0Flags) {
@@ -592,6 +589,13 @@
// Simulate overshoot of this frame.
layers_->FrameEncoded(0, -1);
+ // Reencode, frame config, flags and codec specific info should remain the
+ // same as for the dropped frame.
+ timestamp_ -= kTimestampDelta5Fps; // Undo last timestamp increment.
+ TemporalLayers::FrameConfig new_tl_config =
+ layers_->UpdateLayerConfig(timestamp_);
+ EXPECT_EQ(tl_config_, new_tl_config);
+
config_updated_ = layers_->UpdateConfiguration(&cfg_);
EXPECT_EQ(kTl1SyncFlags, VP8EncoderImpl::EncodeFlags(tl_config_));
@@ -600,24 +604,4 @@
EXPECT_TRUE(new_vp8_info.layerSync);
}
-TEST_F(ScreenshareLayerTest, DropOnTooShortFrameInterval) {
- // Run grace period so we have existing frames in both TL0 and Tl1.
- EXPECT_TRUE(RunGracePeriod());
-
- // Add a large gap, so there's plenty of room in the rate tracker.
- timestamp_ += kTimestampDelta5Fps * 3;
- EXPECT_FALSE(layers_->UpdateLayerConfig(timestamp_).drop_frame);
- layers_->FrameEncoded(frame_size_, kDefaultQp);
-
- // Frame interval below 90% if desired time is not allowed, try inserting
- // frame just before this limit.
- const int64_t kMinFrameInterval = (kTimestampDelta5Fps * 9) / 10;
- timestamp_ += kMinFrameInterval - 90;
- EXPECT_TRUE(layers_->UpdateLayerConfig(timestamp_).drop_frame);
-
- // Try again at the limit, now it should pass.
- timestamp_ += 90;
- EXPECT_FALSE(layers_->UpdateLayerConfig(timestamp_).drop_frame);
-}
-
} // namespace webrtc