Use bitrate limits provided by encoder.
- Use minimum start bitrate to drop frame and adapt resolution in the
beginning of call.
- Use minimum bitrate to decide whether or not resolution should be
increased based on quality in MAINTAIN_FRAMERATE and BALANCED modes.
In BALANCED mode bitrate limits provided by the corresponding field
trial are prioritized over the limits provided by encoder.
Bug: webrtc:10853
Change-Id: I8257eb64565bcafa6ae9887a1af18e90f8400cac
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156302
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29461}
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 31d3aa1..2cea126 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -67,6 +67,10 @@
const int kDefaultFramerate = 30;
const int64_t kFrameIntervalMs = rtc::kNumMillisecsPerSec / kDefaultFramerate;
const int64_t kProcessIntervalMs = 1000;
+const VideoEncoder::ResolutionBitrateLimits
+ kEncoderBitrateLimits540p(960 * 540, 100 * 1000, 100 * 1000, 2000 * 1000);
+const VideoEncoder::ResolutionBitrateLimits
+ kEncoderBitrateLimits720p(1280 * 720, 200 * 1000, 200 * 1000, 4000 * 1000);
uint8_t optimal_sps[] = {0, 0, 0, 1, H264::NaluType::kSps,
0x00, 0x00, 0x03, 0x03, 0xF4,
@@ -2668,6 +2672,87 @@
video_stream_encoder_->Stop();
}
+TEST_F(VideoStreamEncoderTest, AdaptUpIfBwEstimateIsHigherThanMinBitrate) {
+ fake_encoder_.SetResolutionBitrateLimits(
+ {kEncoderBitrateLimits540p, kEncoderBitrateLimits720p});
+
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0, 0);
+
+ // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
+ AdaptingFrameForwarder source;
+ source.set_adaptation_enabled(true);
+ video_stream_encoder_->SetSource(
+ &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
+
+ // Insert 720p frame.
+ int64_t timestamp_ms = kFrameIntervalMs;
+ source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
+ WaitForEncodedFrame(1280, 720);
+
+ // Reduce bitrate and trigger adapt down.
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0, 0);
+ video_stream_encoder_->TriggerQualityLow();
+
+ // Insert 720p frame. It should be downscaled and encoded.
+ timestamp_ms += kFrameIntervalMs;
+ source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
+ WaitForEncodedFrame(960, 540);
+
+ // Trigger adapt up. Higher resolution should not be requested duo to lack
+ // of bitrate.
+ video_stream_encoder_->TriggerQualityHigh();
+ VerifyFpsMaxResolutionLt(source.sink_wants(), 1280 * 720);
+
+ // Increase bitrate.
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0, 0);
+
+ // Trigger adapt up. Higher resolution should be requested.
+ video_stream_encoder_->TriggerQualityHigh();
+ VerifyFpsMaxResolutionMax(source.sink_wants());
+
+ video_stream_encoder_->Stop();
+}
+
+TEST_F(VideoStreamEncoderTest, DropFirstFramesIfBwEstimateIsTooLow) {
+ fake_encoder_.SetResolutionBitrateLimits(
+ {kEncoderBitrateLimits540p, kEncoderBitrateLimits720p});
+
+ // Set bitrate equal to min bitrate of 540p.
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps),
+ DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0, 0);
+
+ // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
+ AdaptingFrameForwarder source;
+ source.set_adaptation_enabled(true);
+ video_stream_encoder_->SetSource(
+ &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
+
+ // Insert 720p frame. It should be dropped and lower resolution should be
+ // requested.
+ int64_t timestamp_ms = kFrameIntervalMs;
+ source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
+ ExpectDroppedFrame();
+ VerifyFpsMaxResolutionLt(source.sink_wants(), 1280 * 720);
+
+ // Insert 720p frame. It should be downscaled and encoded.
+ timestamp_ms += kFrameIntervalMs;
+ source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
+ WaitForEncodedFrame(960, 540);
+
+ video_stream_encoder_->Stop();
+}
+
class BalancedDegradationTest : public VideoStreamEncoderTest {
protected:
void SetupTest() {