Add target bitrate headroom signal to VideoStreamEncoder.
This CL plumbs an additional signal from VideoSendStream down to
VideoStreamEncoder, namely the amount of headroom that's left between
the encoder max bitrate and the current bitrate allocation for the
media track.
This will be used in follow-up CLs to tune encoder rate adjustment
and some codec specific paramaters a bit differently, based on the
knowledge if we are network constrained or not.
Bug: webrtc:10155
Change-Id: Ic6ccc79be5c6845468bab65b4ca9918b56923fa4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/125981
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27008}
diff --git a/api/video/BUILD.gn b/api/video/BUILD.gn
index b20b3a8..ed8a030 100644
--- a/api/video/BUILD.gn
+++ b/api/video/BUILD.gn
@@ -189,6 +189,7 @@
":video_bitrate_allocator",
":video_bitrate_allocator_factory",
":video_frame",
+ "../units:data_rate",
# For rtpparameters.h
"..:libjingle_peerconnection_api",
diff --git a/api/video/video_stream_encoder_interface.h b/api/video/video_stream_encoder_interface.h
index 7181143..b6fed6b 100644
--- a/api/video/video_stream_encoder_interface.h
+++ b/api/video/video_stream_encoder_interface.h
@@ -14,6 +14,7 @@
#include <vector>
#include "api/rtp_parameters.h" // For DegradationPreference.
+#include "api/units/data_rate.h"
#include "api/video/video_bitrate_allocator.h"
#include "api/video/video_sink_interface.h"
#include "api/video/video_source_interface.h"
@@ -79,7 +80,8 @@
// Set the currently estimated network properties. A |bitrate_bps|
// of zero pauses the encoder.
- virtual void OnBitrateUpdated(uint32_t bitrate_bps,
+ virtual void OnBitrateUpdated(DataRate target_bitrate,
+ DataRate target_headroom,
uint8_t fraction_lost,
int64_t round_trip_time_ms) = 0;
diff --git a/video/test/mock_video_stream_encoder.h b/video/test/mock_video_stream_encoder.h
index 8ce6f41..cdfb4e6 100644
--- a/video/test/mock_video_stream_encoder.h
+++ b/video/test/mock_video_stream_encoder.h
@@ -23,7 +23,7 @@
MOCK_METHOD2(SetSink, void(EncoderSink*, bool));
MOCK_METHOD1(SetStartBitrate, void(int));
MOCK_METHOD0(SendKeyFrame, void());
- MOCK_METHOD3(OnBitrateUpdated, void(uint32_t, uint8_t, int64_t));
+ MOCK_METHOD4(OnBitrateUpdated, void(DataRate, DataRate, uint8_t, int64_t));
MOCK_METHOD1(OnFrame, void(const VideoFrame&));
MOCK_METHOD1(SetBitrateAllocationObserver,
void(VideoBitrateAllocationObserver*));
diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc
index 507cc72..b0e1f0d 100644
--- a/video/video_send_stream_impl.cc
+++ b/video/video_send_stream_impl.cc
@@ -423,7 +423,8 @@
void VideoSendStreamImpl::StopVideoSendStream() {
bitrate_allocator_->RemoveObserver(this);
check_encoder_activity_task_.Stop();
- video_stream_encoder_->OnBitrateUpdated(0, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), 0,
+ 0);
stats_proxy_->OnSetEncoderTargetRate(0);
}
@@ -649,10 +650,15 @@
rtc::dchecked_cast<uint8_t>(update.packet_loss_ratio * 256),
update.round_trip_time.ms(), stats_proxy_->GetSendFrameRate());
encoder_target_rate_bps_ = rtp_video_sender_->GetPayloadBitrateBps();
+ DataRate headroom = DataRate::Zero();
+ if (encoder_target_rate_bps_ > encoder_max_bitrate_bps_) {
+ headroom =
+ DataRate::bps(encoder_target_rate_bps_ - encoder_max_bitrate_bps_);
+ }
encoder_target_rate_bps_ =
std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
video_stream_encoder_->OnBitrateUpdated(
- encoder_target_rate_bps_,
+ DataRate::bps(encoder_target_rate_bps_), headroom,
rtc::dchecked_cast<uint8_t>(update.packet_loss_ratio * 256),
update.round_trip_time.ms());
stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc
index ea70408..53846bf 100644
--- a/video/video_send_stream_impl_unittest.cc
+++ b/video/video_send_stream_impl_unittest.cc
@@ -616,5 +616,77 @@
});
}
+TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
+ test_queue_.SendTask([this] {
+ config_.track_id = "test";
+ const bool kSuspend = false;
+ config_.suspend_below_min_bitrate = kSuspend;
+ config_.rtp.extensions.emplace_back(
+ RtpExtension::kTransportSequenceNumberUri, 1);
+ auto vss_impl = CreateVideoSendStreamImpl(
+ kDefaultInitialBitrateBps, kDefaultBitratePriority,
+ VideoEncoderConfig::ContentType::kRealtimeVideo);
+ vss_impl->Start();
+
+ VideoStream qvga_stream;
+ qvga_stream.width = 320;
+ qvga_stream.height = 180;
+ qvga_stream.max_framerate = 30;
+ qvga_stream.min_bitrate_bps = 30000;
+ qvga_stream.target_bitrate_bps = 150000;
+ qvga_stream.max_bitrate_bps = 200000;
+ qvga_stream.max_qp = 56;
+ qvga_stream.bitrate_priority = 1;
+
+ int min_transmit_bitrate_bps = 30000;
+
+ config_.rtp.ssrcs.emplace_back(1);
+
+ static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
+ ->OnEncoderConfigurationChanged(
+ std::vector<VideoStream>{qvga_stream},
+ VideoEncoderConfig::ContentType::kRealtimeVideo,
+ min_transmit_bitrate_bps);
+
+ const DataRate network_constrained_rate =
+ DataRate::bps(qvga_stream.target_bitrate_bps);
+ BitrateAllocationUpdate update;
+ update.target_bitrate = network_constrained_rate;
+ update.link_capacity = network_constrained_rate;
+ update.round_trip_time = TimeDelta::ms(1);
+ EXPECT_CALL(rtp_video_sender_,
+ OnBitrateUpdated(network_constrained_rate.bps(), _,
+ update.round_trip_time.ms(), _));
+ EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
+ .WillOnce(Return(network_constrained_rate.bps()));
+ EXPECT_CALL(
+ video_stream_encoder_,
+ OnBitrateUpdated(network_constrained_rate, DataRate::Zero(), 0, _));
+ static_cast<BitrateAllocatorObserver*>(vss_impl.get())
+ ->OnBitrateUpdated(update);
+
+ const DataRate qvga_max_bitrate =
+ DataRate::bps(qvga_stream.max_bitrate_bps);
+ const DataRate headroom = DataRate::bps(50000);
+ const DataRate rate_with_headroom = qvga_max_bitrate + headroom;
+ EXPECT_CALL(rtp_video_sender_,
+ OnBitrateUpdated(rate_with_headroom.bps(), _,
+ update.round_trip_time.ms(), _));
+ EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
+ .WillOnce(Return(rate_with_headroom.bps()));
+ EXPECT_CALL(video_stream_encoder_,
+ OnBitrateUpdated(qvga_max_bitrate, headroom, 0, _));
+ update.target_bitrate = rate_with_headroom;
+ update.link_capacity = rate_with_headroom;
+ static_cast<BitrateAllocatorObserver*>(vss_impl.get())
+ ->OnBitrateUpdated(update);
+
+ // Set rates to zero on stop.
+ EXPECT_CALL(video_stream_encoder_,
+ OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), 0, 0));
+ vss_impl->Stop();
+ });
+}
+
} // namespace internal
} // namespace webrtc
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 4b75c62..75f8b9b 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -1409,20 +1409,23 @@
}
}
-void VideoStreamEncoder::OnBitrateUpdated(uint32_t bitrate_bps,
+void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
+ DataRate target_headroom,
uint8_t fraction_lost,
int64_t round_trip_time_ms) {
if (!encoder_queue_.IsCurrent()) {
- encoder_queue_.PostTask(
- [this, bitrate_bps, fraction_lost, round_trip_time_ms] {
- OnBitrateUpdated(bitrate_bps, fraction_lost, round_trip_time_ms);
- });
+ encoder_queue_.PostTask([this, target_bitrate, target_headroom,
+ fraction_lost, round_trip_time_ms] {
+ OnBitrateUpdated(target_bitrate, target_headroom, fraction_lost,
+ round_trip_time_ms);
+ });
return;
}
RTC_DCHECK_RUN_ON(&encoder_queue_);
RTC_DCHECK(sink_) << "sink_ must be set before the encoder is active.";
- RTC_LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate " << bitrate_bps
+ RTC_LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate " << target_bitrate.bps()
+ << " headroom = " << target_headroom.bps()
<< " packet loss " << static_cast<int>(fraction_lost)
<< " rtt " << round_trip_time_ms;
// On significant changes to BWE at the start of the call,
@@ -1430,7 +1433,7 @@
if (encoder_start_bitrate_bps_ != 0 &&
!has_seen_first_significant_bwe_change_ && quality_scaler_ &&
initial_framedrop_on_bwe_enabled_ &&
- abs_diff(bitrate_bps, encoder_start_bitrate_bps_) >=
+ abs_diff(target_bitrate.bps(), encoder_start_bitrate_bps_) >=
kFramedropThreshold * encoder_start_bitrate_bps_) {
// Reset initial framedrop feature when first real BW estimate arrives.
// TODO(kthelgason): Update BitrateAllocator to not call OnBitrateUpdated
@@ -1440,16 +1443,17 @@
}
uint32_t framerate_fps = GetInputFramerateFps();
- frame_dropper_.SetRates((bitrate_bps + 500) / 1000, framerate_fps);
- SetEncoderRates(
- GetBitrateAllocationAndNotifyObserver(bitrate_bps, framerate_fps),
- framerate_fps);
+ frame_dropper_.SetRates((target_bitrate.bps() + 500) / 1000, framerate_fps);
+ SetEncoderRates(GetBitrateAllocationAndNotifyObserver(target_bitrate.bps(),
+ framerate_fps),
+ framerate_fps);
- encoder_start_bitrate_bps_ =
- bitrate_bps != 0 ? bitrate_bps : encoder_start_bitrate_bps_;
- bool video_is_suspended = bitrate_bps == 0;
+ encoder_start_bitrate_bps_ = target_bitrate.bps() != 0
+ ? target_bitrate.bps()
+ : encoder_start_bitrate_bps_;
+ bool video_is_suspended = target_bitrate == DataRate::Zero();
bool video_suspension_changed = video_is_suspended != EncoderPaused();
- last_observed_bitrate_bps_ = bitrate_bps;
+ last_observed_bitrate_bps_ = target_bitrate.bps();
if (video_suspension_changed) {
RTC_LOG(LS_INFO) << "Video suspend state changed to: "
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 70e2c89..fd0835191 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -81,7 +81,8 @@
void SendKeyFrame() override;
- void OnBitrateUpdated(uint32_t bitrate_bps,
+ void OnBitrateUpdated(DataRate target_bitrate,
+ DataRate target_headroom,
uint8_t fraction_lost,
int64_t round_trip_time_ms) override;
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 23984e9..ad4200b 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -888,7 +888,8 @@
};
TEST_F(VideoStreamEncoderTest, EncodeOneFrame) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
rtc::Event frame_destroyed_event;
video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
WaitForEncodedFrame(1);
@@ -906,7 +907,8 @@
video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// The pending frame should be received.
WaitForEncodedFrame(2);
@@ -917,18 +919,21 @@
}
TEST_F(VideoStreamEncoderTest, DropsFramesWhenRateSetToZero) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
WaitForEncodedFrame(1);
- video_stream_encoder_->OnBitrateUpdated(0, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(0), DataRate::Zero(), 0,
+ 0);
// The encoder will cache up to one frame for a short duration. Adding two
// frames means that the first frame will be dropped and the second frame will
// be sent when the encoder is resumed.
video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
WaitForEncodedFrame(3);
video_source_.IncomingCapturedFrame(CreateFrame(4, nullptr));
WaitForEncodedFrame(4);
@@ -936,7 +941,8 @@
}
TEST_F(VideoStreamEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
WaitForEncodedFrame(1);
@@ -949,7 +955,8 @@
}
TEST_F(VideoStreamEncoderTest, DropsFrameAfterStop) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
WaitForEncodedFrame(1);
@@ -962,7 +969,8 @@
}
TEST_F(VideoStreamEncoderTest, DropsPendingFramesOnSlowEncode) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
fake_encoder_.BlockNextEncode();
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
@@ -979,7 +987,8 @@
TEST_F(VideoStreamEncoderTest,
ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
EXPECT_EQ(0, sink_.number_of_reconfigurations());
// Capture a frame and wait for it to synchronize with the encoder thread.
@@ -1005,7 +1014,8 @@
}
TEST_F(VideoStreamEncoderTest, FrameResolutionChangeReconfigureEncoder) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Capture a frame and wait for it to synchronize with the encoder thread.
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
@@ -1056,7 +1066,8 @@
video_source_.set_adaptation_enabled(true);
// Enable BALANCED preference, no initial limitation.
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_stream_encoder_->SetSource(&video_source_,
webrtc::DegradationPreference::BALANCED);
VerifyNoLimitation(video_source_.sink_wants());
@@ -1138,7 +1149,8 @@
video_stream_encoder_->Stop();
}
TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
VerifyNoLimitation(video_source_.sink_wants());
const int kFrameWidth = 1280;
@@ -1226,7 +1238,8 @@
}
TEST_F(VideoStreamEncoderTest, StatsTracksQualityAdaptationStats) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kWidth = 1280;
const int kHeight = 720;
@@ -1259,7 +1272,8 @@
}
TEST_F(VideoStreamEncoderTest, StatsTracksCpuAdaptationStats) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kWidth = 1280;
const int kHeight = 720;
@@ -1292,7 +1306,8 @@
}
TEST_F(VideoStreamEncoderTest, SwitchingSourceKeepsCpuAdaptation) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kWidth = 1280;
const int kHeight = 720;
@@ -1360,7 +1375,8 @@
}
TEST_F(VideoStreamEncoderTest, SwitchingSourceKeepsQualityAdaptation) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kWidth = 1280;
const int kHeight = 720;
@@ -1420,7 +1436,8 @@
TEST_F(VideoStreamEncoderTest,
QualityAdaptationStatsAreResetWhenScalerIsDisabled) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kWidth = 1280;
const int kHeight = 720;
@@ -1475,7 +1492,8 @@
TEST_F(VideoStreamEncoderTest,
StatsTracksCpuAdaptationStatsWhenSwitchingSource) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kWidth = 1280;
const int kHeight = 720;
@@ -1611,7 +1629,8 @@
ScalingUpAndDownDoesNothingWithMaintainResolution) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Expect no scaling to begin with.
VerifyNoLimitation(video_source_.sink_wants());
@@ -1659,7 +1678,8 @@
SkipsSameAdaptDownRequest_MaintainFramerateMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable MAINTAIN_FRAMERATE preference, no initial limitation.
test::FrameForwarder source;
@@ -1691,7 +1711,8 @@
TEST_F(VideoStreamEncoderTest, SkipsSameOrLargerAdaptDownRequest_BalancedMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable BALANCED preference, no initial limitation.
test::FrameForwarder source;
@@ -1731,7 +1752,8 @@
NoChangeForInitialNormalUsage_MaintainFramerateMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable MAINTAIN_FRAMERATE preference, no initial limitation.
test::FrameForwarder source;
@@ -1757,7 +1779,8 @@
NoChangeForInitialNormalUsage_MaintainResolutionMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable MAINTAIN_RESOLUTION preference, no initial limitation.
test::FrameForwarder source;
@@ -1782,7 +1805,8 @@
TEST_F(VideoStreamEncoderTest, NoChangeForInitialNormalUsage_BalancedMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable BALANCED preference, no initial limitation.
test::FrameForwarder source;
@@ -1809,7 +1833,8 @@
TEST_F(VideoStreamEncoderTest, NoChangeForInitialNormalUsage_DisabledMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable DISABLED preference, no initial limitation.
test::FrameForwarder source;
@@ -1837,7 +1862,8 @@
AdaptsResolutionForLowQuality_MaintainFramerateMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable MAINTAIN_FRAMERATE preference, no initial limitation.
AdaptingFrameForwarder source;
@@ -1874,7 +1900,8 @@
const int kWidth = 1280;
const int kHeight = 720;
const int kInputFps = 30;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
VideoSendStream::Stats stats = stats_proxy_->GetStats();
stats.input_frame_rate = kInputFps;
@@ -1915,7 +1942,8 @@
const int kHeight = 720;
const size_t kNumFrames = 10;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable adapter, expected input resolutions when downscaling:
// 1280x720 -> 960x540 -> 640x360 -> 480x270 -> 320x180 (kMinPixelsPerFrame)
@@ -1950,7 +1978,8 @@
AdaptsResolutionUpAndDownTwiceOnOveruse_MaintainFramerateMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable MAINTAIN_FRAMERATE preference, no initial limitation.
AdaptingFrameForwarder source;
@@ -2008,7 +2037,8 @@
AdaptsResolutionUpAndDownTwiceForLowQuality_BalancedMode_NoFpsLimit) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable BALANCED preference, no initial limitation.
AdaptingFrameForwarder source;
@@ -2066,7 +2096,8 @@
AdaptsResolutionOnOveruseAndLowQuality_MaintainFramerateMode) {
const int kWidth = 1280;
const int kHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable MAINTAIN_FRAMERATE preference, no initial limitation.
AdaptingFrameForwarder source;
@@ -2203,7 +2234,8 @@
const int kWidth = 640;
const int kHeight = 360;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
video_source_.IncomingCapturedFrame(CreateFrame(i, kWidth, kHeight));
@@ -2229,7 +2261,8 @@
TEST_F(VideoStreamEncoderTest,
CpuLimitedHistogramIsNotReportedForDisabledDegradation) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kWidth = 640;
const int kHeight = 360;
@@ -2260,7 +2293,8 @@
EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
.Times(1);
- video_stream_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kLowTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(
CreateFrame(rtc::TimeMillis(), codec_width_, codec_height_));
@@ -2303,7 +2337,8 @@
const int kFrameHeight = 720;
const int kFramerate = 24;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
test::FrameForwarder source;
video_stream_encoder_->SetSource(
&source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
@@ -2363,7 +2398,8 @@
const int kLowFramerate = 15;
const int kHighFramerate = 25;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
test::FrameForwarder source;
video_stream_encoder_->SetSource(
&source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
@@ -2426,7 +2462,8 @@
const int kFrameHeight = 720;
const int kFramerate = 24;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
test::FrameForwarder source;
video_stream_encoder_->SetSource(
&source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
@@ -2471,7 +2508,8 @@
TEST_F(VideoStreamEncoderTest, DropsFramesAndScalesWhenBitrateIsTooLow) {
const int kTooLowBitrateForFrameSizeBps = 10000;
- video_stream_encoder_->OnBitrateUpdated(kTooLowBitrateForFrameSizeBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kTooLowBitrateForFrameSizeBps), DataRate::Zero(), 0, 0);
const int kWidth = 640;
const int kHeight = 360;
@@ -2500,7 +2538,8 @@
TEST_F(VideoStreamEncoderTest,
NumberOfDroppedFramesLimitedWhenBitrateIsTooLow) {
const int kTooLowBitrateForFrameSizeBps = 10000;
- video_stream_encoder_->OnBitrateUpdated(kTooLowBitrateForFrameSizeBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kTooLowBitrateForFrameSizeBps), DataRate::Zero(), 0, 0);
const int kWidth = 640;
const int kHeight = 360;
@@ -2524,7 +2563,8 @@
InitialFrameDropOffWithMaintainResolutionPreference) {
const int kWidth = 640;
const int kHeight = 360;
- video_stream_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kLowTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Set degradation preference.
video_stream_encoder_->SetSource(
@@ -2548,7 +2588,8 @@
video_encoder_config.video_format.parameters["foo"] = "foo";
video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
kMaxPayloadLength);
- video_stream_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kLowTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Force quality scaler reconfiguration by resetting the source.
video_stream_encoder_->SetSource(&video_source_,
@@ -2571,12 +2612,14 @@
const int kWidth = 640;
const int kHeight = 360;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
// Frame should not be dropped.
WaitForEncodedFrame(1);
- video_stream_encoder_->OnBitrateUpdated(kTooLowBitrateForFrameSizeBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kTooLowBitrateForFrameSizeBps), DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
// Expect to drop this frame, the wait should time out.
ExpectDroppedFrame();
@@ -2590,7 +2633,8 @@
ResolutionNotAdaptedForTooSmallFrame_MaintainFramerateMode) {
const int kTooSmallWidth = 10;
const int kTooSmallHeight = 10;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable MAINTAIN_FRAMERATE preference, no initial limitation.
test::FrameForwarder source;
@@ -2615,7 +2659,8 @@
const int kTooSmallWidth = 10;
const int kTooSmallHeight = 10;
const int kFpsLimit = 7;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable BALANCED preference, no initial limitation.
test::FrameForwarder source;
@@ -2648,7 +2693,8 @@
TEST_F(VideoStreamEncoderTest, FailingInitEncodeDoesntCauseCrash) {
fake_encoder_.ForceInitEncodeFailure(true);
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
ResetEncoder("VP8", 2, 1, 1, false);
const int kFrameWidth = 1280;
const int kFrameHeight = 720;
@@ -2661,7 +2707,8 @@
// TODO(sprang): Extend this with fps throttling and any "balanced" extensions.
TEST_F(VideoStreamEncoderTest,
AdaptsResolutionOnOveruse_MaintainFramerateMode) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
const int kFrameWidth = 1280;
const int kFrameHeight = 720;
@@ -2694,7 +2741,8 @@
const int kFrameWidth = 1280;
const int kFrameHeight = 720;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_stream_encoder_->SetSource(
&video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
video_source_.set_adaptation_enabled(true);
@@ -2795,7 +2843,8 @@
// disable frame dropping and make testing easier.
ResetEncoder("VP8", 1, 2, 1, true);
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_stream_encoder_->SetSource(
&video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
video_source_.set_adaptation_enabled(true);
@@ -2834,7 +2883,8 @@
const int kHeight = 720;
const int64_t kFrameIntervalMs = 150;
int64_t timestamp_ms = kFrameIntervalMs;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable BALANCED preference, no initial limitation.
AdaptingFrameForwarder source;
@@ -3014,7 +3064,8 @@
const int kHeight = 720;
const int64_t kFrameIntervalMs = 150;
int64_t timestamp_ms = kFrameIntervalMs;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable BALANCED preference, no initial limitation.
AdaptingFrameForwarder source;
@@ -3127,7 +3178,8 @@
const int kFpsLimit = 15;
const int64_t kFrameIntervalMs = 150;
int64_t timestamp_ms = kFrameIntervalMs;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Enable BALANCED preference, no initial limitation.
AdaptingFrameForwarder source;
@@ -3245,7 +3297,8 @@
const int kAdaptedFrameHeight = 808;
const int kFramerate = 24;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Trigger reconfigure encoder (without resetting the entire instance).
VideoEncoderConfig video_encoder_config;
video_encoder_config.codec_type = kVideoCodecVP8;
@@ -3278,7 +3331,8 @@
const int kLowFps = 2;
const int kHighFps = 30;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
max_framerate_ = kLowFps;
@@ -3292,7 +3346,8 @@
}
// Make sure encoder is updated with new target.
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(
CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
WaitForEncodedFrame(timestamp_ms);
@@ -3330,7 +3385,8 @@
MockBitrateObserver bitrate_observer;
video_stream_encoder_->SetBitrateAllocationObserver(&bitrate_observer);
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
// Insert a first video frame, causes another bitrate update.
@@ -3341,7 +3397,8 @@
WaitForEncodedFrame(timestamp_ms);
// Next, simulate video suspension due to pacer queue overrun.
- video_stream_encoder_->OnBitrateUpdated(0, 0, 1);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(0), DataRate::Zero(), 0,
+ 1);
// Skip ahead until a new periodic parameter update should have occured.
timestamp_ms += vcm::VCMProcessTimer::kDefaultProcessIntervalMs;
@@ -3363,7 +3420,8 @@
const int kFrameWidth = 1280;
const int kFrameHeight = 720;
const CpuOveruseOptions default_options;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(
CreateFrame(1, kFrameWidth, kFrameHeight));
WaitForEncodedFrame(1);
@@ -3385,7 +3443,8 @@
hardware_options.high_encode_usage_threshold_percent = 200;
fake_encoder_.SetIsHardwareAccelerated(true);
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
video_source_.IncomingCapturedFrame(
CreateFrame(1, kFrameWidth, kFrameHeight));
WaitForEncodedFrame(1);
@@ -3405,7 +3464,8 @@
const int kTargetBitrateBps = 120000;
const int kNumFramesInRun = kFps * 5; // Runs of five seconds.
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
max_framerate_ = kFps;
@@ -3439,7 +3499,8 @@
overshoot_factor *= 2;
}
fake_encoder_.SimulateOvershoot(overshoot_factor);
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps + 1000, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kTargetBitrateBps + 1000), DataRate::Zero(), 0, 0);
num_dropped = 0;
for (int i = 0; i < kNumFramesInRun; ++i) {
video_source_.IncomingCapturedFrame(
@@ -3451,7 +3512,8 @@
timestamp_ms += 1000 / kFps;
}
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Target framerate should be still be near the expected target, despite
// the frame drops.
@@ -3473,7 +3535,8 @@
int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
max_framerate_ = kActualInputFps;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Insert 3 seconds of video, with an input fps lower than configured max.
for (int i = 0; i < kActualInputFps * 3; ++i) {
@@ -3491,7 +3554,8 @@
TEST_F(VideoStreamEncoderTest, AccumulatesUpdateRectOnDroppedFrames) {
VideoFrame::UpdateRect rect;
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
fake_encoder_.BlockNextEncode();
video_source_.IncomingCapturedFrame(
@@ -3534,7 +3598,8 @@
}
TEST_F(VideoStreamEncoderTest, SetsFrameTypes) {
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// First frame is always keyframe.
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
@@ -3561,7 +3626,8 @@
TEST_F(VideoStreamEncoderTest, SetsFrameTypesSimulcast) {
// Setup simulcast with three streams.
ResetEncoder("VP8", 3, 1, 1, false);
- video_stream_encoder_->OnBitrateUpdated(kSimulcastTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(
+ DataRate::bps(kSimulcastTargetBitrateBps), DataRate::Zero(), 0, 0);
// Wait for all three layers before triggering event.
sink_.SetNumExpectedLayers(3);
@@ -3595,7 +3661,8 @@
// Configure internal source factory and setup test again.
encoder_factory_.SetHasInternalSource(true);
ResetEncoder("VP8", 1, 1, 1, false);
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
// Call encoder directly, simulating internal source where encoded frame
// callback in VideoStreamEncoder is called despite no OnFrame().
@@ -3627,7 +3694,8 @@
// Configure internal source factory and setup test again.
encoder_factory_.SetHasInternalSource(true);
ResetEncoder("VP8", 1, 1, 1, false);
- video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+ video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kTargetBitrateBps),
+ DataRate::Zero(), 0, 0);
int64_t timestamp = 1;
EncodedImage image;