Replace usage of old SetRates/SetRateAllocation methods
This rather large CL replaces all relevant usage of the old
VideoEncoder::SetRates()/SetRateAllocation() methods in WebRTC.
API is unchanged to allow downstream projects to update without
breakage.
Bug: webrtc:10481
Change-Id: Iab8f292ce6be6c3f5056a239d26361962b14bb38
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131949
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27554}
diff --git a/api/test/mock_video_encoder.h b/api/test/mock_video_encoder.h
index d4f7baf..f99f7e3 100644
--- a/api/test/mock_video_encoder.h
+++ b/api/test/mock_video_encoder.h
@@ -48,6 +48,7 @@
MOCK_METHOD2(SetRateAllocation,
int32_t(const VideoBitrateAllocation& newBitRate,
uint32_t frameRate));
+ MOCK_METHOD1(SetRates, void(const RateControlParameters& parameters));
MOCK_CONST_METHOD0(GetEncoderInfo, EncoderInfo(void));
};
diff --git a/api/test/peerconnection_quality_test_fixture.h b/api/test/peerconnection_quality_test_fixture.h
index b22b392..289f850 100644
--- a/api/test/peerconnection_quality_test_fixture.h
+++ b/api/test/peerconnection_quality_test_fixture.h
@@ -186,7 +186,7 @@
// used to emulate overshooting of video encoders. This multiplier will
// be applied for all video encoder on both sides for all layers. Bitrate
// estimated by WebRTC stack will be multiplied on this multiplier and then
- // provided into VideoEncoder::SetRateAllocation(...).
+ // provided into VideoEncoder::SetRates(...).
double video_encoder_bitrate_multiplier = 1.0;
};
diff --git a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
index 8ccafcc..2a382ef 100644
--- a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
+++ b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
@@ -114,10 +114,8 @@
return WEBRTC_VIDEO_CODEC_OK;
}
- int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
- uint32_t framerate) override {
+ void SetRates(const RateControlParameters& parameters) override {
++set_rates_count_;
- return WEBRTC_VIDEO_CODEC_OK;
}
EncoderInfo GetEncoderInfo() const override {
@@ -205,10 +203,8 @@
fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize));
- EXPECT_EQ(
- WEBRTC_VIDEO_CODEC_OK,
- fallback_wrapper_->SetRateAllocation(
- rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
+ fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
int callback_count = callback_.callback_count_;
int encode_count = fake_encoder_->encode_count_;
@@ -226,10 +222,8 @@
codec_.VP8()->numberOfTemporalLayers = 1;
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
fallback_wrapper_->InitEncode(&codec_, 2, kMaxPayloadSize);
- EXPECT_EQ(
- WEBRTC_VIDEO_CODEC_OK,
- fallback_wrapper_->SetRateAllocation(
- rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
+ fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
EXPECT_EQ(1, fake_encoder_->init_encode_count_);
// Have the non-fallback encoder request a software fallback.
@@ -302,7 +296,8 @@
SetRatesForwardedDuringFallback) {
UtilizeFallbackEncoder();
EXPECT_EQ(1, fake_encoder_->set_rates_count_);
- fallback_wrapper_->SetRateAllocation(VideoBitrateAllocation(), 1);
+ fallback_wrapper_->SetRates(
+ VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 1));
EXPECT_EQ(2, fake_encoder_->set_rates_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
}
@@ -386,10 +381,9 @@
}
void SetRateAllocation(uint32_t bitrate_kbps) {
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->SetRateAllocation(
- rate_allocator_->GetAllocation(
- bitrate_kbps * 1000, kFramerate),
- kFramerate));
+ fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(bitrate_kbps * 1000, kFramerate),
+ kFramerate));
}
void EncodeFrameAndVerifyLastName(const char* expected_name) {
diff --git a/api/video_codecs/video_encoder.cc b/api/video_codecs/video_encoder.cc
index 66ba9e4..d91bb4e 100644
--- a/api/video_codecs/video_encoder.cc
+++ b/api/video_codecs/video_encoder.cc
@@ -108,6 +108,13 @@
VideoEncoder::RateControlParameters::RateControlParameters(
const VideoBitrateAllocation& bitrate,
+ double framerate_fps)
+ : bitrate(bitrate),
+ framerate_fps(framerate_fps),
+ bandwidth_allocation(DataRate::bps(bitrate.get_sum_bps())) {}
+
+VideoEncoder::RateControlParameters::RateControlParameters(
+ const VideoBitrateAllocation& bitrate,
double framerate_fps,
DataRate bandwidth_allocation)
: bitrate(bitrate),
diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h
index 1c8dfd5..3af7dfd 100644
--- a/api/video_codecs/video_encoder.h
+++ b/api/video_codecs/video_encoder.h
@@ -196,6 +196,8 @@
struct RateControlParameters {
RateControlParameters();
RateControlParameters(const VideoBitrateAllocation& bitrate,
+ double framerate_fps);
+ RateControlParameters(const VideoBitrateAllocation& bitrate,
double framerate_fps,
DataRate bandwidth_allocation);
virtual ~RateControlParameters();
diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc
index 46659a4..a687b84 100644
--- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc
+++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc
@@ -88,8 +88,7 @@
int32_t Release() override;
int32_t Encode(const VideoFrame& frame,
const std::vector<VideoFrameType>* frame_types) override;
- int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
- uint32_t framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
EncoderInfo GetEncoderInfo() const override;
private:
@@ -122,10 +121,8 @@
int32_t number_of_cores_;
size_t max_payload_size_;
- // The last bitrate/framerate set, and a flag for noting they are set.
- bool rates_set_;
- VideoBitrateAllocation bitrate_allocation_;
- uint32_t framerate_;
+ // The last rate control settings, if set.
+ absl::optional<RateControlParameters> rate_control_parameters_;
// The last channel parameters set, and a flag for noting they are set.
bool channel_parameters_set_;
@@ -147,8 +144,6 @@
std::unique_ptr<webrtc::VideoEncoder> hw_encoder)
: number_of_cores_(0),
max_payload_size_(0),
- rates_set_(false),
- framerate_(0),
channel_parameters_set_(false),
packet_loss_(0),
rtt_(0),
@@ -181,8 +176,8 @@
// Replay callback, rates, and channel parameters.
if (callback_)
fallback_encoder_->RegisterEncodeCompleteCallback(callback_);
- if (rates_set_)
- fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate_);
+ if (rate_control_parameters_)
+ fallback_encoder_->SetRates(*rate_control_parameters_);
// Since we're switching to the fallback encoder, Release the real encoder. It
// may be re-initialized via InitEncode later, and it will continue to get
@@ -201,7 +196,7 @@
number_of_cores_ = number_of_cores;
max_payload_size_ = max_payload_size;
// Clear stored rate/channel parameters.
- rates_set_ = false;
+ rate_control_parameters_ = absl::nullopt;
ValidateSettingsForForcedFallback();
// Try to reinit forced software codec if it is in use.
@@ -264,16 +259,12 @@
return ret;
}
-int32_t VideoEncoderSoftwareFallbackWrapper::SetRateAllocation(
- const VideoBitrateAllocation& bitrate_allocation,
- uint32_t framerate) {
- rates_set_ = true;
- bitrate_allocation_ = bitrate_allocation;
- framerate_ = framerate;
- int32_t ret = encoder_->SetRateAllocation(bitrate_allocation_, framerate);
+void VideoEncoderSoftwareFallbackWrapper::SetRates(
+ const RateControlParameters& parameters) {
+ rate_control_parameters_ = parameters;
+ encoder_->SetRates(parameters);
if (use_fallback_encoder_)
- return fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate);
- return ret;
+ fallback_encoder_->SetRates(parameters);
}
VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo()
diff --git a/call/call_perf_tests.cc b/call/call_perf_tests.cc
index f3955c9..4a686ed 100644
--- a/call/call_perf_tests.cc
+++ b/call/call_perf_tests.cc
@@ -774,14 +774,13 @@
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
- int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
- uint32_t framerate) override {
- last_set_bitrate_kbps_ = rate_allocation.get_sum_kbps();
+ void SetRates(const RateControlParameters& parameters) override {
+ last_set_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
if (encoder_inits_ == 1 &&
- rate_allocation.get_sum_kbps() > kReconfigureThresholdKbps) {
+ parameters.bitrate.get_sum_kbps() > kReconfigureThresholdKbps) {
time_to_reconfigure_.Set();
}
- return FakeEncoder::SetRateAllocation(rate_allocation, framerate);
+ FakeEncoder::SetRates(parameters);
}
void ModifySenderBitrateConfig(
diff --git a/media/engine/encoder_simulcast_proxy.cc b/media/engine/encoder_simulcast_proxy.cc
index 8c2f825..f2c87ff 100644
--- a/media/engine/encoder_simulcast_proxy.cc
+++ b/media/engine/encoder_simulcast_proxy.cc
@@ -55,10 +55,8 @@
return encoder_->RegisterEncodeCompleteCallback(callback);
}
-int EncoderSimulcastProxy::SetRateAllocation(
- const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) {
- return encoder_->SetRateAllocation(bitrate, new_framerate);
+void EncoderSimulcastProxy::SetRates(const RateControlParameters& parameters) {
+ return encoder_->SetRates(parameters);
}
void EncoderSimulcastProxy::OnPacketLossRateUpdate(float packet_loss_rate) {
diff --git a/media/engine/encoder_simulcast_proxy.h b/media/engine/encoder_simulcast_proxy.h
index 1251e58..41ffcba 100644
--- a/media/engine/encoder_simulcast_proxy.h
+++ b/media/engine/encoder_simulcast_proxy.h
@@ -48,8 +48,7 @@
int Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override;
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
- int SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
void OnPacketLossRateUpdate(float packet_loss_rate) override;
void OnRttUpdate(int64_t rtt_ms) override;
void OnLossNotification(const LossNotification& loss_notification) override;
diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc
index d4de300..5d657fe 100644
--- a/media/engine/fake_webrtc_video_engine.cc
+++ b/media/engine/fake_webrtc_video_engine.cc
@@ -166,10 +166,7 @@
return WEBRTC_VIDEO_CODEC_OK;
}
-int32_t FakeWebRtcVideoEncoder::SetRateAllocation(
- const webrtc::VideoBitrateAllocation& allocation,
- uint32_t framerate) {
- return WEBRTC_VIDEO_CODEC_OK;
+void FakeWebRtcVideoEncoder::SetRates(const RateControlParameters& parameters) {
}
webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo()
diff --git a/media/engine/fake_webrtc_video_engine.h b/media/engine/fake_webrtc_video_engine.h
index 3265274..662caf1 100644
--- a/media/engine/fake_webrtc_video_engine.h
+++ b/media/engine/fake_webrtc_video_engine.h
@@ -93,8 +93,7 @@
int32_t RegisterEncodeCompleteCallback(
webrtc::EncodedImageCallback* callback) override;
int32_t Release() override;
- int32_t SetRateAllocation(const webrtc::VideoBitrateAllocation& allocation,
- uint32_t framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override;
bool WaitForInitEncode();
diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc
index 09b0545..1147d45 100644
--- a/media/engine/simulcast_encoder_adapter.cc
+++ b/media/engine/simulcast_encoder_adapter.cc
@@ -28,6 +28,7 @@
#include "rtc_base/atomic_ops.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/rate_control_settings.h"
+#include "rtc_base/logging.h"
#include "system_wrappers/include/field_trial.h"
#include "third_party/libyuv/include/libyuv/scale.h"
@@ -443,41 +444,54 @@
return WEBRTC_VIDEO_CODEC_OK;
}
-int SimulcastEncoderAdapter::SetRateAllocation(
- const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) {
+void SimulcastEncoderAdapter::SetRates(
+ const RateControlParameters& parameters) {
RTC_DCHECK_RUN_ON(&encoder_queue_);
if (!Initialized()) {
- return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ RTC_LOG(LS_WARNING) << "SetRates while not initialized";
+ return;
}
- if (new_framerate < 1) {
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ if (parameters.framerate_fps < 1.0) {
+ RTC_LOG(LS_WARNING) << "Invalid framerate: " << parameters.framerate_fps;
+ return;
}
- if (codec_.maxBitrate > 0 && bitrate.get_sum_kbps() > codec_.maxBitrate) {
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ if (codec_.maxBitrate > 0 &&
+ parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) {
+ RTC_LOG(LS_WARNING) << "Total bitrate " << parameters.bitrate.get_sum_kbps()
+ << " exceeds max bitrate: " << codec_.maxBitrate;
+ return;
}
- if (bitrate.get_sum_bps() > 0) {
+ if (parameters.bitrate.get_sum_bps() > 0) {
// Make sure the bitrate fits the configured min bitrates. 0 is a special
// value that means paused, though, so leave it alone.
- if (bitrate.get_sum_kbps() < codec_.minBitrate) {
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ if (parameters.bitrate.get_sum_kbps() < codec_.minBitrate) {
+ RTC_LOG(LS_WARNING) << "Total bitrate "
+ << parameters.bitrate.get_sum_kbps()
+ << " is lower than minimum bitrate: "
+ << codec_.minBitrate;
+ return;
}
if (codec_.numberOfSimulcastStreams > 0 &&
- bitrate.get_sum_kbps() < codec_.simulcastStream[0].minBitrate) {
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ parameters.bitrate.get_sum_kbps() <
+ codec_.simulcastStream[0].minBitrate) {
+ RTC_LOG(LS_WARNING) << "Total bitrate "
+ << parameters.bitrate.get_sum_kbps()
+ << " is lower than minimum bitrate of base layer: "
+ << codec_.simulcastStream[0].minBitrate;
+ return;
}
}
- codec_.maxFramerate = new_framerate;
+ codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) {
uint32_t stream_bitrate_kbps =
- bitrate.GetSpatialLayerSum(stream_idx) / 1000;
+ parameters.bitrate.GetSpatialLayerSum(stream_idx) / 1000;
// Need a key frame if we have not sent this stream before.
if (stream_bitrate_kbps > 0 && !streaminfos_[stream_idx].send_stream) {
@@ -487,17 +501,31 @@
// Slice the temporal layers out of the full allocation and pass it on to
// the encoder handling the current simulcast stream.
- VideoBitrateAllocation stream_allocation;
+ RateControlParameters stream_parameters = parameters;
+ stream_parameters.bitrate = VideoBitrateAllocation();
for (int i = 0; i < kMaxTemporalStreams; ++i) {
- if (bitrate.HasBitrate(stream_idx, i)) {
- stream_allocation.SetBitrate(0, i, bitrate.GetBitrate(stream_idx, i));
+ if (parameters.bitrate.HasBitrate(stream_idx, i)) {
+ stream_parameters.bitrate.SetBitrate(
+ 0, i, parameters.bitrate.GetBitrate(stream_idx, i));
}
}
- streaminfos_[stream_idx].encoder->SetRateAllocation(stream_allocation,
- new_framerate);
- }
- return WEBRTC_VIDEO_CODEC_OK;
+ // Assign link allocation proportionally to spatial layer allocation.
+ if (parameters.bandwidth_allocation != DataRate::Zero()) {
+ stream_parameters.bandwidth_allocation =
+ DataRate::bps((parameters.bandwidth_allocation.bps() *
+ stream_parameters.bitrate.get_sum_bps()) /
+ parameters.bitrate.get_sum_bps());
+ // Make sure we don't allocate bandwidth lower than target bitrate.
+ if (stream_parameters.bandwidth_allocation.bps() <
+ stream_parameters.bitrate.get_sum_bps()) {
+ stream_parameters.bandwidth_allocation =
+ DataRate::bps(stream_parameters.bitrate.get_sum_bps());
+ }
+ }
+
+ streaminfos_[stream_idx].encoder->SetRates(stream_parameters);
+ }
}
// TODO(brandtr): Add task checker to this member function, when all encoder
diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h
index a7b0361..5bc0bec 100644
--- a/media/engine/simulcast_encoder_adapter.h
+++ b/media/engine/simulcast_encoder_adapter.h
@@ -48,8 +48,7 @@
int Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override;
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
- int SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
// Eventual handler for the contained encoders' EncodedImageCallbacks, but
// called from an internal helper that also knows the correct stream
diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc
index 8d68fa1..1bab49a 100644
--- a/media/engine/simulcast_encoder_adapter_unittest.cc
+++ b/media/engine/simulcast_encoder_adapter_unittest.cc
@@ -207,10 +207,8 @@
MOCK_METHOD0(Release, int32_t());
- int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
- uint32_t framerate) {
- last_set_bitrate_ = bitrate_allocation;
- return 0;
+ void SetRates(const RateControlParameters& parameters) {
+ last_set_rates_ = parameters;
}
EncoderInfo GetEncoderInfo() const override {
@@ -271,7 +269,7 @@
fps_allocation_ = fps_allocation;
}
- VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
+ RateControlParameters last_set_rates() const { return last_set_rates_; }
private:
MockVideoEncoderFactory* const factory_;
@@ -282,7 +280,7 @@
bool is_hardware_accelerated_ = false;
bool has_internal_source_ = false;
int32_t init_encode_return_value_ = 0;
- VideoBitrateAllocation last_set_bitrate_;
+ VideoEncoder::RateControlParameters last_set_rates_;
FramerateFractions fps_allocation_;
VideoCodec codec_;
@@ -500,7 +498,8 @@
SetupCodec();
// Set bitrates so that we send all layers.
- adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(1200, 30), 30.0));
// At this point, the simulcast encoder adapter should have 3 streams: HD,
// quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
@@ -560,8 +559,8 @@
// Encode with three streams.
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
VerifyCodecSettings();
- adapter_->SetRateAllocation(
- rate_allocator_->GetAllocation(target_bitrate, 30), 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
std::vector<MockVideoEncoder*> original_encoders =
helper_->factory()->encoders();
@@ -587,8 +586,8 @@
codec_.height /= 2;
codec_.numberOfSimulcastStreams = 2;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
- adapter_->SetRateAllocation(
- rate_allocator_->GetAllocation(target_bitrate, 30), 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
ASSERT_EQ(2u, new_encoders.size());
ASSERT_EQ(original_encoders[0], new_encoders[0]);
@@ -610,8 +609,8 @@
codec_.height /= 2;
codec_.numberOfSimulcastStreams = 1;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
- adapter_->SetRateAllocation(
- rate_allocator_->GetAllocation(target_bitrate, 30), 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
new_encoders = helper_->factory()->encoders();
ASSERT_EQ(1u, new_encoders.size());
ASSERT_EQ(original_encoders[0], new_encoders[0]);
@@ -628,8 +627,8 @@
codec_.height *= 4;
codec_.numberOfSimulcastStreams = 3;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
- adapter_->SetRateAllocation(
- rate_allocator_->GetAllocation(target_bitrate, 30), 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
new_encoders = helper_->factory()->encoders();
ASSERT_EQ(3u, new_encoders.size());
// The first encoder is reused.
@@ -712,7 +711,8 @@
// discontinuities.
TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
SetupCodec();
- adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(1200, 30), 30.0));
VerifyCodecSettings();
// Send frames on all streams.
@@ -736,7 +736,8 @@
// Reinitialize.
EXPECT_EQ(0, adapter_->Release());
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
- adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(1200, 30), 30.0));
// Verify that the same encoder sends out frames on the same simulcast index.
encoders[0]->SendEncodedImage(1152, 704);
@@ -780,21 +781,23 @@
// Above min should be respected.
VideoBitrateAllocation target_bitrate =
rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
- adapter_->SetRateAllocation(target_bitrate, 30);
+ adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
EXPECT_EQ(target_bitrate,
- helper_->factory()->encoders()[0]->last_set_bitrate());
+ helper_->factory()->encoders()[0]->last_set_rates().bitrate);
// Below min but non-zero should be replaced with the min bitrate.
VideoBitrateAllocation too_low_bitrate =
rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
- adapter_->SetRateAllocation(too_low_bitrate, 30);
+ adapter_->SetRates(
+ VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
EXPECT_EQ(target_bitrate,
- helper_->factory()->encoders()[0]->last_set_bitrate());
+ helper_->factory()->encoders()[0]->last_set_rates().bitrate);
// Zero should be passed on as is, since it means "pause".
- adapter_->SetRateAllocation(VideoBitrateAllocation(), 30);
+ adapter_->SetRates(
+ VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
EXPECT_EQ(VideoBitrateAllocation(),
- helper_->factory()->encoders()[0]->last_set_bitrate());
+ helper_->factory()->encoders()[0]->last_set_rates().bitrate);
}
TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
@@ -1157,5 +1160,45 @@
::testing::ElementsAreArray(expected_fps_allocation));
}
+TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
+ SimulcastTestFixtureImpl::DefaultSettings(
+ &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
+ kVideoCodecVP8);
+ codec_.numberOfSimulcastStreams = 3;
+ const DataRate target_bitrate =
+ DataRate::kbps(codec_.simulcastStream[0].targetBitrate +
+ codec_.simulcastStream[1].targetBitrate +
+ codec_.simulcastStream[2].minBitrate);
+ const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
+
+ rate_allocator_.reset(new SimulcastRateAllocator(codec_));
+ EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
+ adapter_->RegisterEncodeCompleteCallback(this);
+
+ // Set bitrates so that we send all layers.
+ adapter_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(target_bitrate.bps(), 30), 30.0,
+ bandwidth_allocation));
+
+ std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
+
+ ASSERT_EQ(3u, encoders.size());
+
+ for (size_t i = 0; i < 3; ++i) {
+ const uint32_t layer_bitrate_bps =
+ (i < static_cast<size_t>(codec_.numberOfSimulcastStreams) - 1
+ ? codec_.simulcastStream[i].targetBitrate
+ : codec_.simulcastStream[i].minBitrate) *
+ 1000;
+ EXPECT_EQ(layer_bitrate_bps,
+ encoders[i]->last_set_rates().bitrate.get_sum_bps())
+ << i;
+ EXPECT_EQ(
+ (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(),
+ encoders[i]->last_set_rates().bandwidth_allocation.bps())
+ << i;
+ }
+}
+
} // namespace test
} // namespace webrtc
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
index 9d96100..495c11a 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
@@ -306,7 +306,8 @@
SimulcastRateAllocator init_allocator(codec_);
VideoBitrateAllocation allocation = init_allocator.GetAllocation(
codec_.startBitrate * 1000, codec_.maxFramerate);
- return SetRateAllocation(allocation, codec_.maxFramerate);
+ SetRates(RateControlParameters(allocation, codec_.maxFramerate));
+ return WEBRTC_VIDEO_CODEC_OK;
}
int32_t H264EncoderImpl::Release() {
@@ -331,36 +332,40 @@
return WEBRTC_VIDEO_CODEC_OK;
}
-int32_t H264EncoderImpl::SetRateAllocation(
- const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) {
- if (encoders_.empty())
- return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+void H264EncoderImpl::SetRates(const RateControlParameters& parameters) {
+ if (encoders_.empty()) {
+ RTC_LOG(LS_WARNING) << "SetRates() while uninitialized.";
+ return;
+ }
- if (new_framerate < 1)
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ if (parameters.framerate_fps < 1.0) {
+ RTC_LOG(LS_WARNING) << "Invalid frame rate: " << parameters.framerate_fps;
+ return;
+ }
- if (bitrate.get_sum_bps() == 0) {
+ if (parameters.bitrate.get_sum_bps() == 0) {
// Encoder paused, turn off all encoding.
for (size_t i = 0; i < configurations_.size(); ++i)
configurations_[i].SetStreamState(false);
- return WEBRTC_VIDEO_CODEC_OK;
+ return;
}
// At this point, bitrate allocation should already match codec settings.
if (codec_.maxBitrate > 0)
- RTC_DCHECK_LE(bitrate.get_sum_kbps(), codec_.maxBitrate);
- RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate);
+ RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate);
+ RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate);
if (codec_.numberOfSimulcastStreams > 0)
- RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate);
+ RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(),
+ codec_.simulcastStream[0].minBitrate);
- codec_.maxFramerate = new_framerate;
+ codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps);
size_t stream_idx = encoders_.size() - 1;
for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
// Update layer config.
- configurations_[i].target_bps = bitrate.GetSpatialLayerSum(stream_idx);
- configurations_[i].max_frame_rate = static_cast<float>(new_framerate);
+ configurations_[i].target_bps =
+ parameters.bitrate.GetSpatialLayerSum(stream_idx);
+ configurations_[i].max_frame_rate = parameters.framerate_fps;
if (configurations_[i].target_bps) {
configurations_[i].SetStreamState(true);
@@ -377,8 +382,6 @@
configurations_[i].SetStreamState(false);
}
}
-
- return WEBRTC_VIDEO_CODEC_OK;
}
int32_t H264EncoderImpl::Encode(
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.h b/modules/video_coding/codecs/h264/h264_encoder_impl.h
index d0cde34..74592ef 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl.h
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl.h
@@ -61,8 +61,7 @@
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override;
- int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
- uint32_t framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
// The result of encoding - an EncodedImage and RTPFragmentationHeader - are
// passed to the encode complete callback.
diff --git a/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h b/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h
index de010c9..bb00b54 100644
--- a/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h
+++ b/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h
@@ -45,8 +45,7 @@
int Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override;
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
- int SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
int Release() override;
EncoderInfo GetEncoderInfo() const override;
diff --git a/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc b/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc
index 16bcd51..8c86699 100644
--- a/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc
+++ b/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc
@@ -216,23 +216,21 @@
return WEBRTC_VIDEO_CODEC_OK;
}
-int MultiplexEncoderAdapter::SetRateAllocation(
- const VideoBitrateAllocation& bitrate,
- uint32_t framerate) {
- VideoBitrateAllocation bitrate_allocation(bitrate);
+void MultiplexEncoderAdapter::SetRates(
+ const RateControlParameters& parameters) {
+ VideoBitrateAllocation bitrate_allocation(parameters.bitrate);
bitrate_allocation.SetBitrate(
- 0, 0, bitrate.GetBitrate(0, 0) - augmenting_data_size_);
+ 0, 0, parameters.bitrate.GetBitrate(0, 0) - augmenting_data_size_);
for (auto& encoder : encoders_) {
// TODO(emircan): |framerate| is used to calculate duration in encoder
// instances. We report the total frame rate to keep real time for now.
// Remove this after refactoring duration logic.
- const int rv = encoder->SetRateAllocation(
+ encoder->SetRates(RateControlParameters(
bitrate_allocation,
- static_cast<uint32_t>(encoders_.size()) * framerate);
- if (rv)
- return rv;
+ static_cast<uint32_t>(encoders_.size() * parameters.framerate_fps),
+ parameters.bandwidth_allocation -
+ DataRate::bps(augmenting_data_size_)));
}
- return WEBRTC_VIDEO_CODEC_OK;
}
int MultiplexEncoderAdapter::Release() {
diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc
index 708f6fe..8d6d3ad 100644
--- a/modules/video_coding/codecs/test/videoprocessor.cc
+++ b/modules/video_coding/codecs/test/videoprocessor.cc
@@ -300,10 +300,8 @@
framerate_fps_ = static_cast<uint32_t>(framerate_fps);
bitrate_allocation_ = bitrate_allocator_->GetAllocation(
static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_);
- const int set_rates_result =
- encoder_->SetRateAllocation(bitrate_allocation_, framerate_fps_);
- RTC_DCHECK_GE(set_rates_result, 0)
- << "Failed to update encoder with new rate " << bitrate_kbps << ".";
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation_, static_cast<double>(framerate_fps_)));
}
int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded(
diff --git a/modules/video_coding/codecs/test/videoprocessor_unittest.cc b/modules/video_coding/codecs/test/videoprocessor_unittest.cc
index 842ad7e..de1d798 100644
--- a/modules/video_coding/codecs/test/videoprocessor_unittest.cc
+++ b/modules/video_coding/codecs/test/videoprocessor_unittest.cc
@@ -25,7 +25,10 @@
#include "test/testsupport/mock/mock_frame_reader.h"
using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Field;
using ::testing::Property;
+using ::testing::ResultOf;
using ::testing::Return;
namespace webrtc {
@@ -96,9 +99,11 @@
TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
const int kBitrateKbps = 456;
const int kFramerateFps = 31;
- EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kFramerateFps))
- .Times(1)
- .WillOnce(Return(0));
+ EXPECT_CALL(
+ encoder_mock_,
+ SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
+ static_cast<double>(kFramerateFps))))
+ .Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
EXPECT_CALL(frame_reader_mock_, ReadFrame())
@@ -122,9 +127,11 @@
const int kBitrateKbps = 456;
const int kStartFramerateFps = 27;
const int kStartTimestamp = 90000 / kStartFramerateFps;
- EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kStartFramerateFps))
- .Times(1)
- .WillOnce(Return(0));
+ EXPECT_CALL(
+ encoder_mock_,
+ SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
+ static_cast<double>(kStartFramerateFps))))
+ .Times(1);
q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); });
@@ -136,9 +143,11 @@
q_.SendTask([this] { video_processor_->ProcessFrame(); });
const int kNewFramerateFps = 13;
- EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kNewFramerateFps))
- .Times(1)
- .WillOnce(Return(0));
+ EXPECT_CALL(
+ encoder_mock_,
+ SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
+ static_cast<double>(kNewFramerateFps))))
+ .Times(1);
q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); });
@@ -153,21 +162,32 @@
}
TEST_F(VideoProcessorTest, SetRates) {
- const int kBitrateKbps = 123;
+ const uint32_t kBitrateKbps = 123;
const int kFramerateFps = 17;
- EXPECT_CALL(encoder_mock_,
- SetRateAllocation(
- Property(&VideoBitrateAllocation::get_sum_kbps, kBitrateKbps),
- kFramerateFps))
+
+ EXPECT_CALL(
+ encoder_mock_,
+ SetRates(AllOf(ResultOf(
+ [](const VideoEncoder::RateControlParameters& params) {
+ return params.bitrate.get_sum_kbps();
+ },
+ kBitrateKbps),
+ Field(&VideoEncoder::RateControlParameters::framerate_fps,
+ static_cast<double>(kFramerateFps)))))
.Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
- const int kNewBitrateKbps = 456;
+ const uint32_t kNewBitrateKbps = 456;
const int kNewFramerateFps = 34;
- EXPECT_CALL(encoder_mock_,
- SetRateAllocation(Property(&VideoBitrateAllocation::get_sum_kbps,
- kNewBitrateKbps),
- kNewFramerateFps))
+ EXPECT_CALL(
+ encoder_mock_,
+ SetRates(AllOf(ResultOf(
+ [](const VideoEncoder::RateControlParameters& params) {
+ return params.bitrate.get_sum_kbps();
+ },
+ kNewBitrateKbps),
+ Field(&VideoEncoder::RateControlParameters::framerate_fps,
+ static_cast<double>(kNewFramerateFps)))))
.Times(1);
q_.SendTask(
[=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); });
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
index e2d4089..9329f22 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
@@ -36,6 +36,7 @@
#include "rtc_base/checks.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/experiments/field_trial_units.h"
+#include "rtc_base/logging.h"
#include "rtc_base/trace_event.h"
#include "system_wrappers/include/field_trial.h"
#include "third_party/libyuv/include/libyuv/scale.h"
@@ -247,33 +248,40 @@
return ret_val;
}
-int LibvpxVp8Encoder::SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) {
- if (!inited_)
- return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) {
+ if (!inited_) {
+ RTC_LOG(LS_WARNING) << "SetRates() while not initialize";
+ return;
+ }
- if (encoders_[0].err)
- return WEBRTC_VIDEO_CODEC_ERROR;
+ if (encoders_[0].err) {
+ RTC_LOG(LS_WARNING) << "Encoder in error state.";
+ return;
+ }
- if (new_framerate < 1)
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ if (parameters.framerate_fps < 1.0) {
+ RTC_LOG(LS_WARNING) << "Unsupported framerate (must be >= 1.0): "
+ << parameters.framerate_fps;
+ return;
+ }
- if (bitrate.get_sum_bps() == 0) {
+ if (parameters.bitrate.get_sum_bps() == 0) {
// Encoder paused, turn off all encoding.
const int num_streams = static_cast<size_t>(encoders_.size());
for (int i = 0; i < num_streams; ++i)
SetStreamState(false, i);
- return WEBRTC_VIDEO_CODEC_OK;
+ return;
}
// At this point, bitrate allocation should already match codec settings.
if (codec_.maxBitrate > 0)
- RTC_DCHECK_LE(bitrate.get_sum_kbps(), codec_.maxBitrate);
- RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate);
+ RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate);
+ RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate);
if (codec_.numberOfSimulcastStreams > 0)
- RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate);
+ RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(),
+ codec_.simulcastStream[0].minBitrate);
- codec_.maxFramerate = new_framerate;
+ codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
if (encoders_.size() > 1) {
// If we have more than 1 stream, reduce the qp_max for the low resolution
@@ -282,7 +290,7 @@
// above some threshold (base temporal layer is down to 1/4 for 3 layers).
// We may want to condition this on bitrate later.
if (rate_control_settings_.Vp8BoostBaseLayerQuality() &&
- new_framerate > 20) {
+ parameters.framerate_fps > 20.0) {
configurations_[encoders_.size() - 1].rc_max_quantizer = 45;
} else {
// Go back to default value set in InitEncode.
@@ -293,7 +301,7 @@
size_t stream_idx = encoders_.size() - 1;
for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
unsigned int target_bitrate_kbps =
- bitrate.GetSpatialLayerSum(stream_idx) / 1000;
+ parameters.bitrate.GetSpatialLayerSum(stream_idx) / 1000;
bool send_stream = target_bitrate_kbps > 0;
if (send_stream || encoders_.size() > 1)
@@ -302,18 +310,19 @@
configurations_[i].rc_target_bitrate = target_bitrate_kbps;
if (send_stream) {
frame_buffer_controller_->OnRatesUpdated(
- stream_idx, bitrate.GetTemporalLayerAllocation(stream_idx),
- new_framerate);
+ stream_idx, parameters.bitrate.GetTemporalLayerAllocation(stream_idx),
+ static_cast<int>(parameters.framerate_fps + 0.5));
}
UpdateVpxConfiguration(stream_idx, frame_buffer_controller_.get(),
&configurations_[i]);
- if (libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i])) {
- return WEBRTC_VIDEO_CODEC_ERROR;
+ vpx_codec_err_t err =
+ libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i]);
+ if (err != VPX_CODEC_OK) {
+ RTC_LOG(LS_WARNING) << "Error configuring codec, error code: " << err;
}
}
- return WEBRTC_VIDEO_CODEC_OK;
}
void LibvpxVp8Encoder::OnPacketLossRateUpdate(float packet_loss_rate) {
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
index 535f032..0913f5b 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
@@ -54,8 +54,7 @@
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
- int SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t new_framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
void OnPacketLossRateUpdate(float packet_loss_rate) override;
diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
index a9248bd..a5381c3 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -110,20 +110,23 @@
}
};
-TEST_F(TestVp8Impl, SetRateAllocation) {
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
+TEST_F(TestVp8Impl, SetRates) {
+ auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
+ LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder.InitEncode(&codec_settings_, 1, 1000));
- const int kBitrateBps = 300000;
+ const uint32_t kBitrateBps = 300000;
VideoBitrateAllocation bitrate_allocation;
bitrate_allocation.SetBitrate(0, 0, kBitrateBps);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ EXPECT_CALL(*vpx, codec_enc_config_set(_, _))
+ .WillOnce(
+ Invoke([&](vpx_codec_ctx_t* ctx, const vpx_codec_enc_cfg_t* cfg) {
+ EXPECT_EQ(cfg->rc_target_bitrate, kBitrateBps / 1000);
+ return VPX_CODEC_OK;
+ }));
+ encoder.SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, static_cast<double>(codec_settings_.maxFramerate)));
}
TEST_F(TestVp8Impl, EncodeFrameAndRelease) {
@@ -441,7 +444,8 @@
VideoBitrateAllocation bitrate_allocation;
// Bitrate only enough for TL0.
bitrate_allocation.SetBitrate(0, 0, 200000);
- encoder_->SetRateAllocation(bitrate_allocation, 5);
+ encoder_->SetRates(
+ VideoEncoder::RateControlParameters(bitrate_allocation, 5.0));
EncodedImage encoded_frame;
CodecSpecificInfo codec_specific_info;
diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index 87f991d..3db7c93 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -375,9 +375,8 @@
bitrate_allocation.SetBitrate(
sl_idx, 0,
codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000 * 2);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
SetWaitForEncodedFramesThreshold(sl_idx + 1);
@@ -394,9 +393,8 @@
for (size_t i = 0; i < num_spatial_layers - 1; ++i) {
const size_t sl_idx = num_spatial_layers - i - 1;
bitrate_allocation.SetBitrate(sl_idx, 0, 0);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
SetWaitForEncodedFramesThreshold(sl_idx);
@@ -426,9 +424,8 @@
0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000);
bitrate_allocation.SetBitrate(
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr));
@@ -442,9 +439,8 @@
// Encode only base layer. Check that end-of-superframe flag is
// set on base layer frame.
bitrate_allocation.SetBitrate(1, 0, 0);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
@@ -479,9 +475,8 @@
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
@@ -550,9 +545,8 @@
bitrate_allocation.SetBitrate(
sl_idx, 0,
codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode;
++frame_num) {
@@ -610,9 +604,8 @@
bitrate_allocation.SetBitrate(
sl_idx, 0,
codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode;
++frame_num) {
@@ -668,9 +661,8 @@
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frame;
std::vector<CodecSpecificInfo> codec_specific_info;
@@ -687,9 +679,8 @@
// Disable SL1 layer.
bitrate_allocation.SetBitrate(1, 0, 0);
bitrate_allocation.SetBitrate(1, 1, 0);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Encode 1 frame.
SetWaitForEncodedFramesThreshold(1);
@@ -706,9 +697,8 @@
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Encode 1 frame.
SetWaitForEncodedFramesThreshold(2);
@@ -746,9 +736,8 @@
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frame;
std::vector<CodecSpecificInfo> codec_specific_info;
@@ -765,9 +754,8 @@
// Disable SL1 layer.
bitrate_allocation.SetBitrate(1, 0, 0);
bitrate_allocation.SetBitrate(1, 1, 0);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Encode 11 frames. More than Gof length 2, and odd to end at TL1 frame.
for (int i = 0; i < 11; ++i) {
@@ -787,9 +775,8 @@
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Encode 1 frame.
SetWaitForEncodedFramesThreshold(2);
@@ -835,9 +822,8 @@
bitrate_allocation.SetBitrate(
sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
}
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Encode enough frames to force drop due to framerate capping.
for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop;
@@ -855,9 +841,8 @@
num_spatial_layers - 1, 0,
codec_settings_.spatialLayers[num_spatial_layers - 1].targetBitrate *
1000);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_dropped_frames; ++frame_num) {
SetWaitForEncodedFramesThreshold(1);
@@ -913,9 +898,8 @@
bitrate_allocation.SetBitrate(
sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
}
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Encode enough frames to force drop due to framerate capping.
for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop;
@@ -944,9 +928,8 @@
// Disable the last layer.
bitrate_allocation.SetBitrate(num_spatial_layers - 1, 0, 0);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Still expected to drop first layer. Last layer has to be disable also.
for (size_t frame_num = num_dropped_frames - 2;
@@ -1002,9 +985,8 @@
num_temporal_layers);
}
}
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frames;
std::vector<CodecSpecificInfo> codec_specific_info;
@@ -1020,9 +1002,8 @@
for (size_t tl_idx = 0; tl_idx < num_temporal_layers; ++tl_idx) {
bitrate_allocation.SetBitrate(num_spatial_layers - 1, tl_idx, 0);
}
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
// Next is TL1 frame. The last layer is disabled immediately, but SS structure
// is not provided here.
@@ -1059,9 +1040,8 @@
VideoBitrateAllocation bitrate_allocation;
bitrate_allocation.SetBitrate(
0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000);
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr));
EncodedImage encoded_frame;
@@ -1329,9 +1309,8 @@
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation,
- codec_settings_.maxFramerate));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
VideoFrame* input_frame = NextInputFrame();
for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
@@ -1384,9 +1363,8 @@
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */));
- EXPECT_EQ(
- WEBRTC_VIDEO_CODEC_OK,
- encoder_->SetRateAllocation(bitrate_allocation, codec_max_framerate_fps));
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_max_framerate_fps));
VideoFrame* input_frame = NextInputFrame();
for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc
index a6c7643..b012d6b 100644
--- a/modules/video_coding/codecs/vp9/vp9_impl.cc
+++ b/modules/video_coding/codecs/vp9/vp9_impl.cc
@@ -309,29 +309,33 @@
return true;
}
-int VP9EncoderImpl::SetRateAllocation(
- const VideoBitrateAllocation& bitrate_allocation,
- uint32_t frame_rate) {
+void VP9EncoderImpl::SetRates(const RateControlParameters& parameters) {
if (!inited_) {
- return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ RTC_LOG(LS_WARNING) << "SetRates() calll while uninitialzied.";
+ return;
}
if (encoder_->err) {
- return WEBRTC_VIDEO_CODEC_ERROR;
+ RTC_LOG(LS_WARNING) << "Encoder in error state: " << encoder_->err;
+ return;
}
- if (frame_rate < 1) {
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ if (parameters.framerate_fps < 1.0) {
+ RTC_LOG(LS_WARNING) << "Unsupported framerate: "
+ << parameters.framerate_fps;
+ return;
}
// Update bit rate
if (codec_.maxBitrate > 0 &&
- bitrate_allocation.get_sum_kbps() > codec_.maxBitrate) {
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) {
+ RTC_LOG(LS_WARNING) << "Target bitrate exceeds maximum: "
+ << parameters.bitrate.get_sum_kbps() << " vs "
+ << codec_.maxBitrate;
+ return;
}
- codec_.maxFramerate = frame_rate;
+ codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
+ requested_bitrate_allocation_ = parameters.bitrate;
- requested_bitrate_allocation_ = bitrate_allocation;
-
- return WEBRTC_VIDEO_CODEC_OK;
+ return;
}
int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h
index 3fc5398..9fa4750 100644
--- a/modules/video_coding/codecs/vp9/vp9_impl.h
+++ b/modules/video_coding/codecs/vp9/vp9_impl.h
@@ -48,8 +48,7 @@
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
- int SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
- uint32_t frame_rate) override;
+ void SetRates(const RateControlParameters& parameters) override;
EncoderInfo GetEncoderInfo() const override;
diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
index b745fae..0646270 100644
--- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc
+++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
@@ -288,8 +288,9 @@
}
void SimulcastTestFixtureImpl::SetRates(uint32_t bitrate_kbps, uint32_t fps) {
- encoder_->SetRateAllocation(
- rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), fps);
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps),
+ static_cast<double>(fps)));
}
void SimulcastTestFixtureImpl::RunActiveStreamsTest(
diff --git a/sdk/android/src/jni/android_media_encoder.cc b/sdk/android/src/jni/android_media_encoder.cc
index dbf2b31..863b4b2 100644
--- a/sdk/android/src/jni/android_media_encoder.cc
+++ b/sdk/android/src/jni/android_media_encoder.cc
@@ -104,8 +104,7 @@
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override;
int32_t Release() override;
- int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
- uint32_t frame_rate) override;
+ void SetRates(const RateControlParameters& parameters) override;
EncoderInfo GetEncoderInfo() const override;
// Fills the input buffer with data from the buffers passed as parameters.
@@ -900,17 +899,16 @@
return WEBRTC_VIDEO_CODEC_OK;
}
-int32_t MediaCodecVideoEncoder::SetRateAllocation(
- const VideoBitrateAllocation& rate_allocation,
- uint32_t frame_rate) {
+void MediaCodecVideoEncoder::SetRates(const RateControlParameters& parameters) {
RTC_DCHECK_RUN_ON(&encoder_queue_checker_);
- const uint32_t new_bit_rate = rate_allocation.get_sum_kbps();
+ const uint32_t new_bit_rate = parameters.bitrate.get_sum_kbps();
if (sw_fallback_required_)
- return WEBRTC_VIDEO_CODEC_OK;
+ return;
+ uint32_t frame_rate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
frame_rate =
(frame_rate < MAX_ALLOWED_VIDEO_FPS) ? frame_rate : MAX_ALLOWED_VIDEO_FPS;
if (last_set_bitrate_kbps_ == new_bit_rate && last_set_fps_ == frame_rate) {
- return WEBRTC_VIDEO_CODEC_OK;
+ return;
}
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni);
@@ -926,10 +924,7 @@
rtc::dchecked_cast<int>(last_set_fps_));
if (CheckException(jni) || !ret) {
ProcessHWError(true /* reset_if_fallback_unavailable */);
- return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_OK
- : WEBRTC_VIDEO_CODEC_ERROR;
}
- return WEBRTC_VIDEO_CODEC_OK;
}
VideoEncoder::EncoderInfo MediaCodecVideoEncoder::GetEncoderInfo() const {
diff --git a/sdk/android/src/jni/video_encoder_wrapper.cc b/sdk/android/src/jni/video_encoder_wrapper.cc
index 960847f..6238e94 100644
--- a/sdk/android/src/jni/video_encoder_wrapper.cc
+++ b/sdk/android/src/jni/video_encoder_wrapper.cc
@@ -146,16 +146,15 @@
return HandleReturnCode(jni, ret, "encode");
}
-int32_t VideoEncoderWrapper::SetRateAllocation(
- const VideoBitrateAllocation& allocation,
- uint32_t framerate) {
+void VideoEncoderWrapper::SetRates(const RateControlParameters& parameters) {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedJavaLocalRef<jobject> j_bitrate_allocation =
- ToJavaBitrateAllocation(jni, allocation);
+ ToJavaBitrateAllocation(jni, parameters.bitrate);
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_setRateAllocation(
- jni, encoder_, j_bitrate_allocation, (jint)framerate);
- return HandleReturnCode(jni, ret, "setRateAllocation");
+ jni, encoder_, j_bitrate_allocation,
+ (jint)(parameters.framerate_fps + 0.5));
+ HandleReturnCode(jni, ret, "setRateAllocation");
}
VideoEncoder::EncoderInfo VideoEncoderWrapper::GetEncoderInfo() const {
diff --git a/sdk/android/src/jni/video_encoder_wrapper.h b/sdk/android/src/jni/video_encoder_wrapper.h
index 65940d6..c140495 100644
--- a/sdk/android/src/jni/video_encoder_wrapper.h
+++ b/sdk/android/src/jni/video_encoder_wrapper.h
@@ -44,8 +44,7 @@
int32_t Encode(const VideoFrame& frame,
const std::vector<VideoFrameType>* frame_types) override;
- int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
- uint32_t framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
EncoderInfo GetEncoderInfo() const override;
diff --git a/test/configurable_frame_size_encoder.cc b/test/configurable_frame_size_encoder.cc
index a0a42f0..ba529cb 100644
--- a/test/configurable_frame_size_encoder.cc
+++ b/test/configurable_frame_size_encoder.cc
@@ -74,11 +74,8 @@
return WEBRTC_VIDEO_CODEC_OK;
}
-int32_t ConfigurableFrameSizeEncoder::SetRateAllocation(
- const VideoBitrateAllocation& allocation,
- uint32_t framerate) {
- return WEBRTC_VIDEO_CODEC_OK;
-}
+void ConfigurableFrameSizeEncoder::SetRates(
+ const RateControlParameters& parameters) {}
int32_t ConfigurableFrameSizeEncoder::SetFrameSize(size_t size) {
RTC_DCHECK_LE(size, max_frame_size_);
diff --git a/test/configurable_frame_size_encoder.h b/test/configurable_frame_size_encoder.h
index 9daf13e..ddf763f 100644
--- a/test/configurable_frame_size_encoder.h
+++ b/test/configurable_frame_size_encoder.h
@@ -44,8 +44,7 @@
int32_t Release() override;
- int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
- uint32_t framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
int32_t SetFrameSize(size_t size);
diff --git a/test/fake_encoder.cc b/test/fake_encoder.cc
index ac59dfd..7c24b84 100644
--- a/test/fake_encoder.cc
+++ b/test/fake_encoder.cc
@@ -51,7 +51,6 @@
FakeEncoder::FakeEncoder(Clock* clock)
: clock_(clock),
callback_(nullptr),
- configured_input_framerate_(-1),
max_target_bitrate_kbps_(-1),
pending_keyframe_(true),
counter_(0),
@@ -65,7 +64,7 @@
RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it.
rtc::CritScope cs(&crit_sect_);
max_target_bitrate_kbps_ = max_kbps;
- SetRateAllocation(target_bitrate_, configured_input_framerate_);
+ SetRates(current_rate_settings_);
}
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
@@ -73,8 +72,8 @@
size_t max_payload_size) {
rtc::CritScope cs(&crit_sect_);
config_ = *config;
- target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000);
- configured_input_framerate_ = config_.maxFramerate;
+ current_rate_settings_.bitrate.SetBitrate(0, 0, config_.startBitrate * 1000);
+ current_rate_settings_.framerate_fps = config_.maxFramerate;
pending_keyframe_ = true;
last_frame_info_ = FrameInfo();
return 0;
@@ -86,8 +85,7 @@
unsigned char num_simulcast_streams;
SimulcastStream simulcast_streams[kMaxSimulcastStreams];
EncodedImageCallback* callback;
- VideoBitrateAllocation target_bitrate;
- int framerate;
+ RateControlParameters rates;
VideoCodecMode mode;
bool keyframe;
uint32_t counter;
@@ -99,12 +97,10 @@
simulcast_streams[i] = config_.simulcastStream[i];
}
callback = callback_;
- target_bitrate = target_bitrate_;
+ rates = current_rate_settings_;
mode = config_.mode;
- if (configured_input_framerate_ > 0) {
- framerate = configured_input_framerate_;
- } else {
- framerate = max_framerate;
+ if (rates.framerate_fps <= 0.0) {
+ rates.framerate_fps = max_framerate;
}
keyframe = pending_keyframe_;
pending_keyframe_ = false;
@@ -112,8 +108,8 @@
}
FrameInfo frame_info =
- NextFrame(frame_types, keyframe, num_simulcast_streams, target_bitrate,
- simulcast_streams, framerate);
+ NextFrame(frame_types, keyframe, num_simulcast_streams, rates.bitrate,
+ simulcast_streams, static_cast<int>(rates.framerate_fps + 0.5));
for (uint8_t i = 0; i < frame_info.layers.size(); ++i) {
constexpr int kMinPayLoadLength = 14;
if (frame_info.layers[i].size < kMinPayLoadLength) {
@@ -237,12 +233,10 @@
return 0;
}
-int32_t FakeEncoder::SetRateAllocation(
- const VideoBitrateAllocation& rate_allocation,
- uint32_t framerate) {
+void FakeEncoder::SetRates(const RateControlParameters& parameters) {
rtc::CritScope cs(&crit_sect_);
- target_bitrate_ = rate_allocation;
- int allocated_bitrate_kbps = target_bitrate_.get_sum_kbps();
+ current_rate_settings_ = parameters;
+ int allocated_bitrate_kbps = parameters.bitrate.get_sum_kbps();
// Scale bitrate allocation to not exceed the given max target bitrate.
if (max_target_bitrate_kbps_ > 0 &&
@@ -251,20 +245,19 @@
++spatial_idx) {
for (uint8_t temporal_idx = 0; temporal_idx < kMaxTemporalStreams;
++temporal_idx) {
- if (target_bitrate_.HasBitrate(spatial_idx, temporal_idx)) {
- uint32_t bitrate =
- target_bitrate_.GetBitrate(spatial_idx, temporal_idx);
+ if (current_rate_settings_.bitrate.HasBitrate(spatial_idx,
+ temporal_idx)) {
+ uint32_t bitrate = current_rate_settings_.bitrate.GetBitrate(
+ spatial_idx, temporal_idx);
bitrate = static_cast<uint32_t>(
(bitrate * int64_t{max_target_bitrate_kbps_}) /
allocated_bitrate_kbps);
- target_bitrate_.SetBitrate(spatial_idx, temporal_idx, bitrate);
+ current_rate_settings_.bitrate.SetBitrate(spatial_idx, temporal_idx,
+ bitrate);
}
}
}
}
-
- configured_input_framerate_ = framerate;
- return 0;
}
const char* FakeEncoder::kImplementationName = "fake_encoder";
@@ -276,7 +269,7 @@
int FakeEncoder::GetConfiguredInputFramerate() const {
rtc::CritScope cs(&crit_sect_);
- return configured_input_framerate_;
+ return static_cast<int>(current_rate_settings_.framerate_fps + 0.5);
}
FakeH264Encoder::FakeH264Encoder(Clock* clock)
diff --git a/test/fake_encoder.h b/test/fake_encoder.h
index 95b4b20..7e1c1a1 100644
--- a/test/fake_encoder.h
+++ b/test/fake_encoder.h
@@ -48,8 +48,7 @@
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override;
int32_t Release() override;
- int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
- uint32_t framerate) override;
+ void SetRates(const RateControlParameters& parameters) override;
int GetConfiguredInputFramerate() const;
EncoderInfo GetEncoderInfo() const override;
@@ -89,8 +88,7 @@
VideoCodec config_ RTC_GUARDED_BY(crit_sect_);
EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_);
- VideoBitrateAllocation target_bitrate_ RTC_GUARDED_BY(crit_sect_);
- int configured_input_framerate_ RTC_GUARDED_BY(crit_sect_);
+ RateControlParameters current_rate_settings_ RTC_GUARDED_BY(crit_sect_);
int max_target_bitrate_kbps_ RTC_GUARDED_BY(crit_sect_);
bool pending_keyframe_ RTC_GUARDED_BY(crit_sect_);
uint32_t counter_ RTC_GUARDED_BY(crit_sect_);
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
index 39d5701..272f80f 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
@@ -63,7 +63,9 @@
bitrate_multiplier_(bitrate_multiplier),
stream_required_spatial_index_(std::move(stream_required_spatial_index)),
injector_(injector),
- analyzer_(analyzer) {}
+ analyzer_(analyzer),
+ mode_(SimulcastMode::kNormal),
+ delegate_callback_(nullptr) {}
QualityAnalyzingVideoEncoder::~QualityAnalyzingVideoEncoder() = default;
int32_t QualityAnalyzingVideoEncoder::InitEncode(
@@ -147,17 +149,11 @@
return result;
}
-int32_t QualityAnalyzingVideoEncoder::SetRates(uint32_t bitrate,
- uint32_t framerate) {
- return delegate_->SetRates(bitrate, framerate);
-}
-
-int32_t QualityAnalyzingVideoEncoder::SetRateAllocation(
- const VideoBitrateAllocation& allocation,
- uint32_t framerate) {
+void QualityAnalyzingVideoEncoder::SetRates(
+ const VideoEncoder::RateControlParameters& parameters) {
RTC_DCHECK_GT(bitrate_multiplier_, 0.0);
if (fabs(bitrate_multiplier_ - kNoMultiplier) < kEps) {
- return delegate_->SetRateAllocation(allocation, framerate);
+ return delegate_->SetRates(parameters);
}
// Simulating encoder overshooting target bitrate, by configuring actual
@@ -166,7 +162,7 @@
VideoBitrateAllocation multiplied_allocation;
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
const uint32_t spatial_layer_bitrate_bps =
- allocation.GetSpatialLayerSum(si);
+ parameters.bitrate.GetSpatialLayerSum(si);
if (spatial_layer_bitrate_bps == 0) {
continue;
}
@@ -185,16 +181,18 @@
}
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
- if (allocation.HasBitrate(si, ti)) {
+ if (parameters.bitrate.HasBitrate(si, ti)) {
multiplied_allocation.SetBitrate(
si, ti,
rtc::checked_cast<uint32_t>(bitrate_multiplier *
- allocation.GetBitrate(si, ti)));
+ parameters.bitrate.GetBitrate(si, ti)));
}
}
}
- return delegate_->SetRateAllocation(multiplied_allocation, framerate);
+ RateControlParameters adjusted_params = parameters;
+ adjusted_params.bitrate = multiplied_allocation;
+ return delegate_->SetRates(adjusted_params);
}
VideoEncoder::EncoderInfo QualityAnalyzingVideoEncoder::GetEncoderInfo() const {
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
index d7dd5d1..4861d4c 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
@@ -70,9 +70,7 @@
int32_t Release() override;
int32_t Encode(const VideoFrame& frame,
const std::vector<VideoFrameType>* frame_types) override;
- int32_t SetRates(uint32_t bitrate, uint32_t framerate) override;
- int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
- uint32_t framerate) override;
+ void SetRates(const VideoEncoder::RateControlParameters& parameters) override;
EncoderInfo GetEncoderInfo() const override;
// Methods of EncodedImageCallback interface.
diff --git a/test/video_encoder_proxy_factory.h b/test/video_encoder_proxy_factory.h
index 55a01a1..49a4e2d 100644
--- a/test/video_encoder_proxy_factory.h
+++ b/test/video_encoder_proxy_factory.h
@@ -75,9 +75,8 @@
return encoder_->RegisterEncodeCompleteCallback(callback);
}
int32_t Release() override { return encoder_->Release(); }
- int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
- uint32_t framerate) override {
- return encoder_->SetRateAllocation(rate_allocation, framerate);
+ void SetRates(const RateControlParameters& parameters) override {
+ encoder_->SetRates(parameters);
}
VideoEncoder::EncoderInfo GetEncoderInfo() const override {
return encoder_->GetEncoderInfo();
diff --git a/video/end_to_end_tests/bandwidth_tests.cc b/video/end_to_end_tests/bandwidth_tests.cc
index 3ee0e2b..163e84d 100644
--- a/video/end_to_end_tests/bandwidth_tests.cc
+++ b/video/end_to_end_tests/bandwidth_tests.cc
@@ -307,15 +307,13 @@
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
}
- int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
- uint32_t framerate) override {
+ void SetRates(const RateControlParameters& parameters) override {
// Make sure not to trigger on any default zero bitrates.
- if (rate_allocation.get_sum_bps() == 0)
- return 0;
+ if (parameters.bitrate.get_sum_bps() == 0)
+ return;
rtc::CritScope lock(&crit_);
- bitrate_kbps_ = rate_allocation.get_sum_kbps();
+ bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
observation_complete_.Set();
- return 0;
}
void PerformTest() override {
diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc
index a097da6..2f0f01d 100644
--- a/video/video_quality_test.cc
+++ b/video/video_quality_test.cc
@@ -149,11 +149,11 @@
}
return encoder_->Encode(frame, frame_types);
}
- int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
- uint32_t framerate) override {
+ void SetRates(const RateControlParameters& parameters) override {
RTC_DCHECK_GT(overshoot_factor_, 0.0);
if (overshoot_factor_ == 1.0) {
- return encoder_->SetRateAllocation(allocation, framerate);
+ encoder_->SetRates(parameters);
+ return;
}
// Simulating encoder overshooting target bitrate, by configuring actual
@@ -162,7 +162,7 @@
VideoBitrateAllocation overshot_allocation;
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
const uint32_t spatial_layer_bitrate_bps =
- allocation.GetSpatialLayerSum(si);
+ parameters.bitrate.GetSpatialLayerSum(si);
if (spatial_layer_bitrate_bps == 0) {
continue;
}
@@ -181,16 +181,18 @@
}
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
- if (allocation.HasBitrate(si, ti)) {
+ if (parameters.bitrate.HasBitrate(si, ti)) {
overshot_allocation.SetBitrate(
si, ti,
- rtc::checked_cast<uint32_t>(overshoot_factor *
- allocation.GetBitrate(si, ti)));
+ rtc::checked_cast<uint32_t>(
+ overshoot_factor * parameters.bitrate.GetBitrate(si, ti)));
}
}
}
- return encoder_->SetRateAllocation(overshot_allocation, framerate);
+ return encoder_->SetRates(
+ RateControlParameters(overshot_allocation, parameters.framerate_fps,
+ parameters.bandwidth_allocation));
}
EncoderInfo GetEncoderInfo() const override {
EncoderInfo info = encoder_->GetEncoderInfo();
diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc
index 0793843..2338997 100644
--- a/video/video_send_stream_tests.cc
+++ b/video/video_send_stream_tests.cc
@@ -2045,11 +2045,11 @@
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
- int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
+ void SetRates(const RateControlParameters& parameters) override {
rtc::CritScope lock(&crit_);
- start_bitrate_kbps_ = new_target_bitrate;
+ start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
start_bitrate_changed_.Set();
- return FakeEncoder::SetRates(new_target_bitrate, framerate);
+ FakeEncoder::SetRates(parameters);
}
int GetStartBitrateKbps() const {
@@ -2118,12 +2118,11 @@
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
}
- int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t framerate) override {
+ void SetRates(const RateControlParameters& parameters) override {
rtc::CritScope lock(&crit_);
- bitrate_kbps_ = bitrate.get_sum_kbps();
+ bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
bitrate_changed_.Set();
- return FakeEncoder::SetRateAllocation(bitrate, framerate);
+ FakeEncoder::SetRates(parameters);
}
bool WaitForEncoderInit() {
@@ -2854,17 +2853,17 @@
maxPayloadSize);
}
- int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t frameRate) override {
+ void SetRates(const RateControlParameters& parameters) override {
{
rtc::CritScope lock(&crit_);
- if (target_bitrate_ == bitrate.get_sum_kbps()) {
- return FakeEncoder::SetRateAllocation(bitrate, frameRate);
+ if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) {
+ FakeEncoder::SetRates(parameters);
+ return;
}
- target_bitrate_ = bitrate.get_sum_kbps();
+ target_bitrate_ = parameters.bitrate.get_sum_kbps();
}
bitrate_changed_event_.Set();
- return FakeEncoder::SetRateAllocation(bitrate, frameRate);
+ FakeEncoder::SetRates(parameters);
}
void WaitForSetRates(uint32_t expected_bitrate) {
@@ -3653,16 +3652,15 @@
max_bitrate_bps_(0),
first_packet_sent_(false) {}
- int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
- uint32_t frameRate) override {
+ void SetRates(const RateControlParameters& parameters) override {
rtc::CritScope lock(&crit_);
// Wait for the first sent packet so that videosendstream knows
// rtp_overhead.
if (first_packet_sent_) {
- max_bitrate_bps_ = bitrate.get_sum_bps();
+ max_bitrate_bps_ = parameters.bitrate.get_sum_bps();
bitrate_changed_event_.Set();
}
- return FakeEncoder::SetRateAllocation(bitrate, frameRate);
+ return FakeEncoder::SetRates(parameters);
}
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index f9b2355..23480e7 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -726,24 +726,24 @@
return FakeEncoder::Release();
}
- int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
- uint32_t framerate) {
+ void SetRates(const RateControlParameters& parameters) {
rtc::CritScope lock(&local_crit_sect_);
VideoBitrateAllocation adjusted_rate_allocation;
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
- if (rate_allocation.HasBitrate(si, ti)) {
+ if (parameters.bitrate.HasBitrate(si, ti)) {
adjusted_rate_allocation.SetBitrate(
si, ti,
- static_cast<uint32_t>(rate_allocation.GetBitrate(si, ti) *
+ static_cast<uint32_t>(parameters.bitrate.GetBitrate(si, ti) *
rate_factor_));
}
}
}
- last_framerate_ = framerate;
- last_bitrate_allocation_ = rate_allocation;
- return FakeEncoder::SetRateAllocation(adjusted_rate_allocation,
- framerate);
+ last_framerate_ = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
+ last_bitrate_allocation_ = parameters.bitrate;
+ RateControlParameters adjusted_paramters = parameters;
+ adjusted_paramters.bitrate = adjusted_rate_allocation;
+ FakeEncoder::SetRates(adjusted_paramters);
}
rtc::CriticalSection local_crit_sect_;