Revert "Replace usage of old SetRates/SetRateAllocation methods"

This reverts commit 7ac0d5f348f0b956089c4ed65c46e65bac125508.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> 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}

TBR=brandtr@webrtc.org,sakal@webrtc.org,nisse@webrtc.org,sprang@webrtc.org,perkj@webrtc.org

Change-Id: I576760b584e3f258013b0279c0c173c895bbb37e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10481
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132561
Reviewed-by: Minyue Li <minyue@webrtc.org>
Commit-Queue: Minyue Li <minyue@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27559}
This commit is contained in:
Minyue Li 2019-04-11 10:50:19 +00:00 committed by Commit Bot
parent 7061e51b48
commit 7ddef1af88
41 changed files with 389 additions and 430 deletions

View File

@ -48,7 +48,6 @@ class MockVideoEncoder : public VideoEncoder {
MOCK_METHOD2(SetRateAllocation, MOCK_METHOD2(SetRateAllocation,
int32_t(const VideoBitrateAllocation& newBitRate, int32_t(const VideoBitrateAllocation& newBitRate,
uint32_t frameRate)); uint32_t frameRate));
MOCK_METHOD1(SetRates, void(const RateControlParameters& parameters));
MOCK_CONST_METHOD0(GetEncoderInfo, EncoderInfo(void)); MOCK_CONST_METHOD0(GetEncoderInfo, EncoderInfo(void));
}; };

View File

@ -186,7 +186,7 @@ class PeerConnectionE2EQualityTestFixture {
// used to emulate overshooting of video encoders. This multiplier will // used to emulate overshooting of video encoders. This multiplier will
// be applied for all video encoder on both sides for all layers. Bitrate // 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 // estimated by WebRTC stack will be multiplied on this multiplier and then
// provided into VideoEncoder::SetRates(...). // provided into VideoEncoder::SetRateAllocation(...).
double video_encoder_bitrate_multiplier = 1.0; double video_encoder_bitrate_multiplier = 1.0;
}; };

View File

@ -114,8 +114,10 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override {
++set_rates_count_; ++set_rates_count_;
return WEBRTC_VIDEO_CODEC_OK;
} }
EncoderInfo GetEncoderInfo() const override { EncoderInfo GetEncoderInfo() const override {
@ -203,7 +205,9 @@ void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize)); fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize));
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(
WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_->SetRateAllocation(
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
int callback_count = callback_.callback_count_; int callback_count = callback_.callback_count_;
@ -222,7 +226,9 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
codec_.VP8()->numberOfTemporalLayers = 1; codec_.VP8()->numberOfTemporalLayers = 1;
rate_allocator_.reset(new SimulcastRateAllocator(codec_)); rate_allocator_.reset(new SimulcastRateAllocator(codec_));
fallback_wrapper_->InitEncode(&codec_, 2, kMaxPayloadSize); fallback_wrapper_->InitEncode(&codec_, 2, kMaxPayloadSize);
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(
WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_->SetRateAllocation(
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
EXPECT_EQ(1, fake_encoder_->init_encode_count_); EXPECT_EQ(1, fake_encoder_->init_encode_count_);
@ -296,8 +302,7 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
SetRatesForwardedDuringFallback) { SetRatesForwardedDuringFallback) {
UtilizeFallbackEncoder(); UtilizeFallbackEncoder();
EXPECT_EQ(1, fake_encoder_->set_rates_count_); EXPECT_EQ(1, fake_encoder_->set_rates_count_);
fallback_wrapper_->SetRates( fallback_wrapper_->SetRateAllocation(VideoBitrateAllocation(), 1);
VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 1));
EXPECT_EQ(2, fake_encoder_->set_rates_count_); EXPECT_EQ(2, fake_encoder_->set_rates_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
@ -381,8 +386,9 @@ class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest {
} }
void SetRateAllocation(uint32_t bitrate_kbps) { void SetRateAllocation(uint32_t bitrate_kbps) {
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->SetRateAllocation(
rate_allocator_->GetAllocation(bitrate_kbps * 1000, kFramerate), rate_allocator_->GetAllocation(
bitrate_kbps * 1000, kFramerate),
kFramerate)); kFramerate));
} }

View File

@ -106,13 +106,6 @@ VideoEncoder::RateControlParameters::RateControlParameters()
framerate_fps(0.0), framerate_fps(0.0),
bandwidth_allocation(DataRate::Zero()) {} bandwidth_allocation(DataRate::Zero()) {}
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( VideoEncoder::RateControlParameters::RateControlParameters(
const VideoBitrateAllocation& bitrate, const VideoBitrateAllocation& bitrate,
double framerate_fps, double framerate_fps,

View File

@ -195,8 +195,6 @@ class RTC_EXPORT VideoEncoder {
struct RateControlParameters { struct RateControlParameters {
RateControlParameters(); RateControlParameters();
RateControlParameters(const VideoBitrateAllocation& bitrate,
double framerate_fps);
RateControlParameters(const VideoBitrateAllocation& bitrate, RateControlParameters(const VideoBitrateAllocation& bitrate,
double framerate_fps, double framerate_fps,
DataRate bandwidth_allocation); DataRate bandwidth_allocation);

View File

@ -88,7 +88,8 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
int32_t Release() override; int32_t Release() override;
int32_t Encode(const VideoFrame& frame, int32_t Encode(const VideoFrame& frame,
const std::vector<VideoFrameType>* frame_types) override; const std::vector<VideoFrameType>* frame_types) override;
void SetRates(const RateControlParameters& parameters) override; int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override;
EncoderInfo GetEncoderInfo() const override; EncoderInfo GetEncoderInfo() const override;
private: private:
@ -121,8 +122,10 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
int32_t number_of_cores_; int32_t number_of_cores_;
size_t max_payload_size_; size_t max_payload_size_;
// The last rate control settings, if set. // The last bitrate/framerate set, and a flag for noting they are set.
absl::optional<RateControlParameters> rate_control_parameters_; bool rates_set_;
VideoBitrateAllocation bitrate_allocation_;
uint32_t framerate_;
// The last channel parameters set, and a flag for noting they are set. // The last channel parameters set, and a flag for noting they are set.
bool channel_parameters_set_; bool channel_parameters_set_;
@ -144,6 +147,8 @@ VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<webrtc::VideoEncoder> hw_encoder) std::unique_ptr<webrtc::VideoEncoder> hw_encoder)
: number_of_cores_(0), : number_of_cores_(0),
max_payload_size_(0), max_payload_size_(0),
rates_set_(false),
framerate_(0),
channel_parameters_set_(false), channel_parameters_set_(false),
packet_loss_(0), packet_loss_(0),
rtt_(0), rtt_(0),
@ -176,8 +181,8 @@ bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() {
// Replay callback, rates, and channel parameters. // Replay callback, rates, and channel parameters.
if (callback_) if (callback_)
fallback_encoder_->RegisterEncodeCompleteCallback(callback_); fallback_encoder_->RegisterEncodeCompleteCallback(callback_);
if (rate_control_parameters_) if (rates_set_)
fallback_encoder_->SetRates(*rate_control_parameters_); fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate_);
// Since we're switching to the fallback encoder, Release the real encoder. It // 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 // may be re-initialized via InitEncode later, and it will continue to get
@ -196,7 +201,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
number_of_cores_ = number_of_cores; number_of_cores_ = number_of_cores;
max_payload_size_ = max_payload_size; max_payload_size_ = max_payload_size;
// Clear stored rate/channel parameters. // Clear stored rate/channel parameters.
rate_control_parameters_ = absl::nullopt; rates_set_ = false;
ValidateSettingsForForcedFallback(); ValidateSettingsForForcedFallback();
// Try to reinit forced software codec if it is in use. // Try to reinit forced software codec if it is in use.
@ -259,12 +264,16 @@ int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
return ret; return ret;
} }
void VideoEncoderSoftwareFallbackWrapper::SetRates( int32_t VideoEncoderSoftwareFallbackWrapper::SetRateAllocation(
const RateControlParameters& parameters) { const VideoBitrateAllocation& bitrate_allocation,
rate_control_parameters_ = parameters; uint32_t framerate) {
encoder_->SetRates(parameters); rates_set_ = true;
bitrate_allocation_ = bitrate_allocation;
framerate_ = framerate;
int32_t ret = encoder_->SetRateAllocation(bitrate_allocation_, framerate);
if (use_fallback_encoder_) if (use_fallback_encoder_)
fallback_encoder_->SetRates(parameters); return fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate);
return ret;
} }
VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo() VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo()

View File

@ -774,13 +774,14 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
} }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
last_set_bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); uint32_t framerate) override {
last_set_bitrate_kbps_ = rate_allocation.get_sum_kbps();
if (encoder_inits_ == 1 && if (encoder_inits_ == 1 &&
parameters.bitrate.get_sum_kbps() > kReconfigureThresholdKbps) { rate_allocation.get_sum_kbps() > kReconfigureThresholdKbps) {
time_to_reconfigure_.Set(); time_to_reconfigure_.Set();
} }
FakeEncoder::SetRates(parameters); return FakeEncoder::SetRateAllocation(rate_allocation, framerate);
} }
void ModifySenderBitrateConfig( void ModifySenderBitrateConfig(

View File

@ -55,8 +55,10 @@ int EncoderSimulcastProxy::RegisterEncodeCompleteCallback(
return encoder_->RegisterEncodeCompleteCallback(callback); return encoder_->RegisterEncodeCompleteCallback(callback);
} }
void EncoderSimulcastProxy::SetRates(const RateControlParameters& parameters) { int EncoderSimulcastProxy::SetRateAllocation(
return encoder_->SetRates(parameters); const VideoBitrateAllocation& bitrate,
uint32_t new_framerate) {
return encoder_->SetRateAllocation(bitrate, new_framerate);
} }
void EncoderSimulcastProxy::OnPacketLossRateUpdate(float packet_loss_rate) { void EncoderSimulcastProxy::OnPacketLossRateUpdate(float packet_loss_rate) {

View File

@ -48,7 +48,8 @@ class RTC_EXPORT EncoderSimulcastProxy : public VideoEncoder {
int Encode(const VideoFrame& input_image, int Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override; const std::vector<VideoFrameType>* frame_types) override;
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
void SetRates(const RateControlParameters& parameters) override; int SetRateAllocation(const VideoBitrateAllocation& bitrate,
uint32_t new_framerate) override;
void OnPacketLossRateUpdate(float packet_loss_rate) override; void OnPacketLossRateUpdate(float packet_loss_rate) override;
void OnRttUpdate(int64_t rtt_ms) override; void OnRttUpdate(int64_t rtt_ms) override;
void OnLossNotification(const LossNotification& loss_notification) override; void OnLossNotification(const LossNotification& loss_notification) override;

View File

@ -166,7 +166,10 @@ int32_t FakeWebRtcVideoEncoder::Release() {
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
void FakeWebRtcVideoEncoder::SetRates(const RateControlParameters& parameters) { int32_t FakeWebRtcVideoEncoder::SetRateAllocation(
const webrtc::VideoBitrateAllocation& allocation,
uint32_t framerate) {
return WEBRTC_VIDEO_CODEC_OK;
} }
webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo() webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo()

View File

@ -93,7 +93,8 @@ class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder {
int32_t RegisterEncodeCompleteCallback( int32_t RegisterEncodeCompleteCallback(
webrtc::EncodedImageCallback* callback) override; webrtc::EncodedImageCallback* callback) override;
int32_t Release() override; int32_t Release() override;
void SetRates(const RateControlParameters& parameters) override; int32_t SetRateAllocation(const webrtc::VideoBitrateAllocation& allocation,
uint32_t framerate) override;
webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override; webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override;
bool WaitForInitEncode(); bool WaitForInitEncode();

View File

@ -28,7 +28,6 @@
#include "rtc_base/atomic_ops.h" #include "rtc_base/atomic_ops.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/experiments/rate_control_settings.h"
#include "rtc_base/logging.h"
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
#include "third_party/libyuv/include/libyuv/scale.h" #include "third_party/libyuv/include/libyuv/scale.h"
@ -444,54 +443,41 @@ int SimulcastEncoderAdapter::RegisterEncodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
void SimulcastEncoderAdapter::SetRates( int SimulcastEncoderAdapter::SetRateAllocation(
const RateControlParameters& parameters) { const VideoBitrateAllocation& bitrate,
uint32_t new_framerate) {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(&encoder_queue_);
if (!Initialized()) { if (!Initialized()) {
RTC_LOG(LS_WARNING) << "SetRates while not initialized"; return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
return;
} }
if (parameters.framerate_fps < 1.0) { if (new_framerate < 1) {
RTC_LOG(LS_WARNING) << "Invalid framerate: " << parameters.framerate_fps; return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
return;
} }
if (codec_.maxBitrate > 0 && if (codec_.maxBitrate > 0 && bitrate.get_sum_kbps() > codec_.maxBitrate) {
parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
RTC_LOG(LS_WARNING) << "Total bitrate " << parameters.bitrate.get_sum_kbps()
<< " exceeds max bitrate: " << codec_.maxBitrate;
return;
} }
if (parameters.bitrate.get_sum_bps() > 0) { if (bitrate.get_sum_bps() > 0) {
// Make sure the bitrate fits the configured min bitrates. 0 is a special // Make sure the bitrate fits the configured min bitrates. 0 is a special
// value that means paused, though, so leave it alone. // value that means paused, though, so leave it alone.
if (parameters.bitrate.get_sum_kbps() < codec_.minBitrate) { if (bitrate.get_sum_kbps() < codec_.minBitrate) {
RTC_LOG(LS_WARNING) << "Total bitrate " return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
<< parameters.bitrate.get_sum_kbps()
<< " is lower than minimum bitrate: "
<< codec_.minBitrate;
return;
} }
if (codec_.numberOfSimulcastStreams > 0 && if (codec_.numberOfSimulcastStreams > 0 &&
parameters.bitrate.get_sum_kbps() < bitrate.get_sum_kbps() < codec_.simulcastStream[0].minBitrate) {
codec_.simulcastStream[0].minBitrate) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
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 = static_cast<uint32_t>(parameters.framerate_fps + 0.5); codec_.maxFramerate = new_framerate;
for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) { for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) {
uint32_t stream_bitrate_kbps = uint32_t stream_bitrate_kbps =
parameters.bitrate.GetSpatialLayerSum(stream_idx) / 1000; bitrate.GetSpatialLayerSum(stream_idx) / 1000;
// Need a key frame if we have not sent this stream before. // Need a key frame if we have not sent this stream before.
if (stream_bitrate_kbps > 0 && !streaminfos_[stream_idx].send_stream) { if (stream_bitrate_kbps > 0 && !streaminfos_[stream_idx].send_stream) {
@ -501,31 +487,17 @@ void SimulcastEncoderAdapter::SetRates(
// Slice the temporal layers out of the full allocation and pass it on to // Slice the temporal layers out of the full allocation and pass it on to
// the encoder handling the current simulcast stream. // the encoder handling the current simulcast stream.
RateControlParameters stream_parameters = parameters; VideoBitrateAllocation stream_allocation;
stream_parameters.bitrate = VideoBitrateAllocation();
for (int i = 0; i < kMaxTemporalStreams; ++i) { for (int i = 0; i < kMaxTemporalStreams; ++i) {
if (parameters.bitrate.HasBitrate(stream_idx, i)) { if (bitrate.HasBitrate(stream_idx, i)) {
stream_parameters.bitrate.SetBitrate( stream_allocation.SetBitrate(0, i, bitrate.GetBitrate(stream_idx, i));
0, i, parameters.bitrate.GetBitrate(stream_idx, i));
} }
} }
streaminfos_[stream_idx].encoder->SetRateAllocation(stream_allocation,
new_framerate);
}
// Assign link allocation proportionally to spatial layer allocation. return WEBRTC_VIDEO_CODEC_OK;
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 // TODO(brandtr): Add task checker to this member function, when all encoder

View File

@ -48,7 +48,8 @@ class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder {
int Encode(const VideoFrame& input_image, int Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override; const std::vector<VideoFrameType>* frame_types) override;
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
void SetRates(const RateControlParameters& parameters) override; int SetRateAllocation(const VideoBitrateAllocation& bitrate,
uint32_t new_framerate) override;
// Eventual handler for the contained encoders' EncodedImageCallbacks, but // Eventual handler for the contained encoders' EncodedImageCallbacks, but
// called from an internal helper that also knows the correct stream // called from an internal helper that also knows the correct stream

View File

@ -207,8 +207,10 @@ class MockVideoEncoder : public VideoEncoder {
MOCK_METHOD0(Release, int32_t()); MOCK_METHOD0(Release, int32_t());
void SetRates(const RateControlParameters& parameters) { int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
last_set_rates_ = parameters; uint32_t framerate) {
last_set_bitrate_ = bitrate_allocation;
return 0;
} }
EncoderInfo GetEncoderInfo() const override { EncoderInfo GetEncoderInfo() const override {
@ -269,7 +271,7 @@ class MockVideoEncoder : public VideoEncoder {
fps_allocation_ = fps_allocation; fps_allocation_ = fps_allocation;
} }
RateControlParameters last_set_rates() const { return last_set_rates_; } VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
private: private:
MockVideoEncoderFactory* const factory_; MockVideoEncoderFactory* const factory_;
@ -280,7 +282,7 @@ class MockVideoEncoder : public VideoEncoder {
bool is_hardware_accelerated_ = false; bool is_hardware_accelerated_ = false;
bool has_internal_source_ = false; bool has_internal_source_ = false;
int32_t init_encode_return_value_ = 0; int32_t init_encode_return_value_ = 0;
VideoEncoder::RateControlParameters last_set_rates_; VideoBitrateAllocation last_set_bitrate_;
FramerateFractions fps_allocation_; FramerateFractions fps_allocation_;
VideoCodec codec_; VideoCodec codec_;
@ -498,8 +500,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
SetupCodec(); SetupCodec();
// Set bitrates so that we send all layers. // Set bitrates so that we send all layers.
adapter_->SetRates(VideoEncoder::RateControlParameters( adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
rate_allocator_->GetAllocation(1200, 30), 30.0));
// At this point, the simulcast encoder adapter should have 3 streams: HD, // 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 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
@ -559,8 +560,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
// Encode with three streams. // Encode with three streams.
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
VerifyCodecSettings(); VerifyCodecSettings();
adapter_->SetRates(VideoEncoder::RateControlParameters( adapter_->SetRateAllocation(
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); rate_allocator_->GetAllocation(target_bitrate, 30), 30);
std::vector<MockVideoEncoder*> original_encoders = std::vector<MockVideoEncoder*> original_encoders =
helper_->factory()->encoders(); helper_->factory()->encoders();
@ -586,8 +587,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
codec_.height /= 2; codec_.height /= 2;
codec_.numberOfSimulcastStreams = 2; codec_.numberOfSimulcastStreams = 2;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
adapter_->SetRates(VideoEncoder::RateControlParameters( adapter_->SetRateAllocation(
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); rate_allocator_->GetAllocation(target_bitrate, 30), 30);
std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders(); std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
ASSERT_EQ(2u, new_encoders.size()); ASSERT_EQ(2u, new_encoders.size());
ASSERT_EQ(original_encoders[0], new_encoders[0]); ASSERT_EQ(original_encoders[0], new_encoders[0]);
@ -609,8 +610,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
codec_.height /= 2; codec_.height /= 2;
codec_.numberOfSimulcastStreams = 1; codec_.numberOfSimulcastStreams = 1;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
adapter_->SetRates(VideoEncoder::RateControlParameters( adapter_->SetRateAllocation(
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); rate_allocator_->GetAllocation(target_bitrate, 30), 30);
new_encoders = helper_->factory()->encoders(); new_encoders = helper_->factory()->encoders();
ASSERT_EQ(1u, new_encoders.size()); ASSERT_EQ(1u, new_encoders.size());
ASSERT_EQ(original_encoders[0], new_encoders[0]); ASSERT_EQ(original_encoders[0], new_encoders[0]);
@ -627,8 +628,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
codec_.height *= 4; codec_.height *= 4;
codec_.numberOfSimulcastStreams = 3; codec_.numberOfSimulcastStreams = 3;
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
adapter_->SetRates(VideoEncoder::RateControlParameters( adapter_->SetRateAllocation(
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); rate_allocator_->GetAllocation(target_bitrate, 30), 30);
new_encoders = helper_->factory()->encoders(); new_encoders = helper_->factory()->encoders();
ASSERT_EQ(3u, new_encoders.size()); ASSERT_EQ(3u, new_encoders.size());
// The first encoder is reused. // The first encoder is reused.
@ -711,8 +712,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
// discontinuities. // discontinuities.
TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) { TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
SetupCodec(); SetupCodec();
adapter_->SetRates(VideoEncoder::RateControlParameters( adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
rate_allocator_->GetAllocation(1200, 30), 30.0));
VerifyCodecSettings(); VerifyCodecSettings();
// Send frames on all streams. // Send frames on all streams.
@ -736,8 +736,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
// Reinitialize. // Reinitialize.
EXPECT_EQ(0, adapter_->Release()); EXPECT_EQ(0, adapter_->Release());
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
adapter_->SetRates(VideoEncoder::RateControlParameters( adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
rate_allocator_->GetAllocation(1200, 30), 30.0));
// Verify that the same encoder sends out frames on the same simulcast index. // Verify that the same encoder sends out frames on the same simulcast index.
encoders[0]->SendEncodedImage(1152, 704); encoders[0]->SendEncodedImage(1152, 704);
@ -781,23 +780,21 @@ TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
// Above min should be respected. // Above min should be respected.
VideoBitrateAllocation target_bitrate = VideoBitrateAllocation target_bitrate =
rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30); rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0)); adapter_->SetRateAllocation(target_bitrate, 30);
EXPECT_EQ(target_bitrate, EXPECT_EQ(target_bitrate,
helper_->factory()->encoders()[0]->last_set_rates().bitrate); helper_->factory()->encoders()[0]->last_set_bitrate());
// Below min but non-zero should be replaced with the min bitrate. // Below min but non-zero should be replaced with the min bitrate.
VideoBitrateAllocation too_low_bitrate = VideoBitrateAllocation too_low_bitrate =
rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30); rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
adapter_->SetRates( adapter_->SetRateAllocation(too_low_bitrate, 30);
VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
EXPECT_EQ(target_bitrate, EXPECT_EQ(target_bitrate,
helper_->factory()->encoders()[0]->last_set_rates().bitrate); helper_->factory()->encoders()[0]->last_set_bitrate());
// Zero should be passed on as is, since it means "pause". // Zero should be passed on as is, since it means "pause".
adapter_->SetRates( adapter_->SetRateAllocation(VideoBitrateAllocation(), 30);
VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
EXPECT_EQ(VideoBitrateAllocation(), EXPECT_EQ(VideoBitrateAllocation(),
helper_->factory()->encoders()[0]->last_set_rates().bitrate); helper_->factory()->encoders()[0]->last_set_bitrate());
} }
TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) { TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
@ -1160,45 +1157,5 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
::testing::ElementsAreArray(expected_fps_allocation)); ::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 test
} // namespace webrtc } // namespace webrtc

View File

@ -306,8 +306,7 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst,
SimulcastRateAllocator init_allocator(codec_); SimulcastRateAllocator init_allocator(codec_);
VideoBitrateAllocation allocation = init_allocator.GetAllocation( VideoBitrateAllocation allocation = init_allocator.GetAllocation(
codec_.startBitrate * 1000, codec_.maxFramerate); codec_.startBitrate * 1000, codec_.maxFramerate);
SetRates(RateControlParameters(allocation, codec_.maxFramerate)); return SetRateAllocation(allocation, codec_.maxFramerate);
return WEBRTC_VIDEO_CODEC_OK;
} }
int32_t H264EncoderImpl::Release() { int32_t H264EncoderImpl::Release() {
@ -332,40 +331,36 @@ int32_t H264EncoderImpl::RegisterEncodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
void H264EncoderImpl::SetRates(const RateControlParameters& parameters) { int32_t H264EncoderImpl::SetRateAllocation(
if (encoders_.empty()) { const VideoBitrateAllocation& bitrate,
RTC_LOG(LS_WARNING) << "SetRates() while uninitialized."; uint32_t new_framerate) {
return; if (encoders_.empty())
} return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
if (parameters.framerate_fps < 1.0) { if (new_framerate < 1)
RTC_LOG(LS_WARNING) << "Invalid frame rate: " << parameters.framerate_fps; return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
return;
}
if (parameters.bitrate.get_sum_bps() == 0) { if (bitrate.get_sum_bps() == 0) {
// Encoder paused, turn off all encoding. // Encoder paused, turn off all encoding.
for (size_t i = 0; i < configurations_.size(); ++i) for (size_t i = 0; i < configurations_.size(); ++i)
configurations_[i].SetStreamState(false); configurations_[i].SetStreamState(false);
return; return WEBRTC_VIDEO_CODEC_OK;
} }
// At this point, bitrate allocation should already match codec settings. // At this point, bitrate allocation should already match codec settings.
if (codec_.maxBitrate > 0) if (codec_.maxBitrate > 0)
RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate); RTC_DCHECK_LE(bitrate.get_sum_kbps(), codec_.maxBitrate);
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate); RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate);
if (codec_.numberOfSimulcastStreams > 0) if (codec_.numberOfSimulcastStreams > 0)
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate);
codec_.simulcastStream[0].minBitrate);
codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps); codec_.maxFramerate = new_framerate;
size_t stream_idx = encoders_.size() - 1; size_t stream_idx = encoders_.size() - 1;
for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
// Update layer config. // Update layer config.
configurations_[i].target_bps = configurations_[i].target_bps = bitrate.GetSpatialLayerSum(stream_idx);
parameters.bitrate.GetSpatialLayerSum(stream_idx); configurations_[i].max_frame_rate = static_cast<float>(new_framerate);
configurations_[i].max_frame_rate = parameters.framerate_fps;
if (configurations_[i].target_bps) { if (configurations_[i].target_bps) {
configurations_[i].SetStreamState(true); configurations_[i].SetStreamState(true);
@ -382,6 +377,8 @@ void H264EncoderImpl::SetRates(const RateControlParameters& parameters) {
configurations_[i].SetStreamState(false); configurations_[i].SetStreamState(false);
} }
} }
return WEBRTC_VIDEO_CODEC_OK;
} }
int32_t H264EncoderImpl::Encode( int32_t H264EncoderImpl::Encode(

View File

@ -61,7 +61,8 @@ class H264EncoderImpl : public H264Encoder {
int32_t RegisterEncodeCompleteCallback( int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override; EncodedImageCallback* callback) override;
void SetRates(const RateControlParameters& parameters) override; int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override;
// The result of encoding - an EncodedImage and RTPFragmentationHeader - are // The result of encoding - an EncodedImage and RTPFragmentationHeader - are
// passed to the encode complete callback. // passed to the encode complete callback.

View File

@ -45,7 +45,8 @@ class MultiplexEncoderAdapter : public VideoEncoder {
int Encode(const VideoFrame& input_image, int Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override; const std::vector<VideoFrameType>* frame_types) override;
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
void SetRates(const RateControlParameters& parameters) override; int SetRateAllocation(const VideoBitrateAllocation& bitrate,
uint32_t new_framerate) override;
int Release() override; int Release() override;
EncoderInfo GetEncoderInfo() const override; EncoderInfo GetEncoderInfo() const override;

View File

@ -216,21 +216,23 @@ int MultiplexEncoderAdapter::RegisterEncodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
void MultiplexEncoderAdapter::SetRates( int MultiplexEncoderAdapter::SetRateAllocation(
const RateControlParameters& parameters) { const VideoBitrateAllocation& bitrate,
VideoBitrateAllocation bitrate_allocation(parameters.bitrate); uint32_t framerate) {
VideoBitrateAllocation bitrate_allocation(bitrate);
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
0, 0, parameters.bitrate.GetBitrate(0, 0) - augmenting_data_size_); 0, 0, bitrate.GetBitrate(0, 0) - augmenting_data_size_);
for (auto& encoder : encoders_) { for (auto& encoder : encoders_) {
// TODO(emircan): |framerate| is used to calculate duration in encoder // TODO(emircan): |framerate| is used to calculate duration in encoder
// instances. We report the total frame rate to keep real time for now. // instances. We report the total frame rate to keep real time for now.
// Remove this after refactoring duration logic. // Remove this after refactoring duration logic.
encoder->SetRates(RateControlParameters( const int rv = encoder->SetRateAllocation(
bitrate_allocation, bitrate_allocation,
static_cast<uint32_t>(encoders_.size() * parameters.framerate_fps), static_cast<uint32_t>(encoders_.size()) * framerate);
parameters.bandwidth_allocation - if (rv)
DataRate::bps(augmenting_data_size_))); return rv;
} }
return WEBRTC_VIDEO_CODEC_OK;
} }
int MultiplexEncoderAdapter::Release() { int MultiplexEncoderAdapter::Release() {

View File

@ -300,8 +300,10 @@ void VideoProcessor::SetRates(size_t bitrate_kbps, size_t framerate_fps) {
framerate_fps_ = static_cast<uint32_t>(framerate_fps); framerate_fps_ = static_cast<uint32_t>(framerate_fps);
bitrate_allocation_ = bitrate_allocator_->GetAllocation( bitrate_allocation_ = bitrate_allocator_->GetAllocation(
static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_); static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_);
encoder_->SetRates(VideoEncoder::RateControlParameters( const int set_rates_result =
bitrate_allocation_, static_cast<double>(framerate_fps_))); encoder_->SetRateAllocation(bitrate_allocation_, framerate_fps_);
RTC_DCHECK_GE(set_rates_result, 0)
<< "Failed to update encoder with new rate " << bitrate_kbps << ".";
} }
int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded( int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded(

View File

@ -25,10 +25,7 @@
#include "test/testsupport/mock/mock_frame_reader.h" #include "test/testsupport/mock/mock_frame_reader.h"
using ::testing::_; using ::testing::_;
using ::testing::AllOf;
using ::testing::Field;
using ::testing::Property; using ::testing::Property;
using ::testing::ResultOf;
using ::testing::Return; using ::testing::Return;
namespace webrtc { namespace webrtc {
@ -99,11 +96,9 @@ TEST_F(VideoProcessorTest, InitRelease) {
TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) { TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
const int kBitrateKbps = 456; const int kBitrateKbps = 456;
const int kFramerateFps = 31; const int kFramerateFps = 31;
EXPECT_CALL( EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kFramerateFps))
encoder_mock_, .Times(1)
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, .WillOnce(Return(0));
static_cast<double>(kFramerateFps))))
.Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); }); q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
EXPECT_CALL(frame_reader_mock_, ReadFrame()) EXPECT_CALL(frame_reader_mock_, ReadFrame())
@ -127,11 +122,9 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
const int kBitrateKbps = 456; const int kBitrateKbps = 456;
const int kStartFramerateFps = 27; const int kStartFramerateFps = 27;
const int kStartTimestamp = 90000 / kStartFramerateFps; const int kStartTimestamp = 90000 / kStartFramerateFps;
EXPECT_CALL( EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kStartFramerateFps))
encoder_mock_, .Times(1)
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, .WillOnce(Return(0));
static_cast<double>(kStartFramerateFps))))
.Times(1);
q_.SendTask( q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); }); [=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); });
@ -143,11 +136,9 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
q_.SendTask([this] { video_processor_->ProcessFrame(); }); q_.SendTask([this] { video_processor_->ProcessFrame(); });
const int kNewFramerateFps = 13; const int kNewFramerateFps = 13;
EXPECT_CALL( EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kNewFramerateFps))
encoder_mock_, .Times(1)
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, .WillOnce(Return(0));
static_cast<double>(kNewFramerateFps))))
.Times(1);
q_.SendTask( q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); }); [=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); });
@ -162,32 +153,21 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
} }
TEST_F(VideoProcessorTest, SetRates) { TEST_F(VideoProcessorTest, SetRates) {
const uint32_t kBitrateKbps = 123; const int kBitrateKbps = 123;
const int kFramerateFps = 17; const int kFramerateFps = 17;
EXPECT_CALL(encoder_mock_,
EXPECT_CALL( SetRateAllocation(
encoder_mock_, Property(&VideoBitrateAllocation::get_sum_kbps, kBitrateKbps),
SetRates(AllOf(ResultOf( kFramerateFps))
[](const VideoEncoder::RateControlParameters& params) {
return params.bitrate.get_sum_kbps();
},
kBitrateKbps),
Field(&VideoEncoder::RateControlParameters::framerate_fps,
static_cast<double>(kFramerateFps)))))
.Times(1); .Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); }); q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
const uint32_t kNewBitrateKbps = 456; const int kNewBitrateKbps = 456;
const int kNewFramerateFps = 34; const int kNewFramerateFps = 34;
EXPECT_CALL( EXPECT_CALL(encoder_mock_,
encoder_mock_, SetRateAllocation(Property(&VideoBitrateAllocation::get_sum_kbps,
SetRates(AllOf(ResultOf(
[](const VideoEncoder::RateControlParameters& params) {
return params.bitrate.get_sum_kbps();
},
kNewBitrateKbps), kNewBitrateKbps),
Field(&VideoEncoder::RateControlParameters::framerate_fps, kNewFramerateFps))
static_cast<double>(kNewFramerateFps)))))
.Times(1); .Times(1);
q_.SendTask( q_.SendTask(
[=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); }); [=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); });

View File

@ -36,7 +36,6 @@
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/experiments/field_trial_units.h" #include "rtc_base/experiments/field_trial_units.h"
#include "rtc_base/logging.h"
#include "rtc_base/trace_event.h" #include "rtc_base/trace_event.h"
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
#include "third_party/libyuv/include/libyuv/scale.h" #include "third_party/libyuv/include/libyuv/scale.h"
@ -248,40 +247,33 @@ int LibvpxVp8Encoder::Release() {
return ret_val; return ret_val;
} }
void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) { int LibvpxVp8Encoder::SetRateAllocation(const VideoBitrateAllocation& bitrate,
if (!inited_) { uint32_t new_framerate) {
RTC_LOG(LS_WARNING) << "SetRates() while not initialize"; if (!inited_)
return; return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
if (encoders_[0].err) { if (encoders_[0].err)
RTC_LOG(LS_WARNING) << "Encoder in error state."; return WEBRTC_VIDEO_CODEC_ERROR;
return;
}
if (parameters.framerate_fps < 1.0) { if (new_framerate < 1)
RTC_LOG(LS_WARNING) << "Unsupported framerate (must be >= 1.0): " return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
<< parameters.framerate_fps;
return;
}
if (parameters.bitrate.get_sum_bps() == 0) { if (bitrate.get_sum_bps() == 0) {
// Encoder paused, turn off all encoding. // Encoder paused, turn off all encoding.
const int num_streams = static_cast<size_t>(encoders_.size()); const int num_streams = static_cast<size_t>(encoders_.size());
for (int i = 0; i < num_streams; ++i) for (int i = 0; i < num_streams; ++i)
SetStreamState(false, i); SetStreamState(false, i);
return; return WEBRTC_VIDEO_CODEC_OK;
} }
// At this point, bitrate allocation should already match codec settings. // At this point, bitrate allocation should already match codec settings.
if (codec_.maxBitrate > 0) if (codec_.maxBitrate > 0)
RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate); RTC_DCHECK_LE(bitrate.get_sum_kbps(), codec_.maxBitrate);
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate); RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate);
if (codec_.numberOfSimulcastStreams > 0) if (codec_.numberOfSimulcastStreams > 0)
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate);
codec_.simulcastStream[0].minBitrate);
codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5); codec_.maxFramerate = new_framerate;
if (encoders_.size() > 1) { if (encoders_.size() > 1) {
// If we have more than 1 stream, reduce the qp_max for the low resolution // If we have more than 1 stream, reduce the qp_max for the low resolution
@ -290,7 +282,7 @@ void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) {
// above some threshold (base temporal layer is down to 1/4 for 3 layers). // above some threshold (base temporal layer is down to 1/4 for 3 layers).
// We may want to condition this on bitrate later. // We may want to condition this on bitrate later.
if (rate_control_settings_.Vp8BoostBaseLayerQuality() && if (rate_control_settings_.Vp8BoostBaseLayerQuality() &&
parameters.framerate_fps > 20.0) { new_framerate > 20) {
configurations_[encoders_.size() - 1].rc_max_quantizer = 45; configurations_[encoders_.size() - 1].rc_max_quantizer = 45;
} else { } else {
// Go back to default value set in InitEncode. // Go back to default value set in InitEncode.
@ -301,7 +293,7 @@ void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) {
size_t stream_idx = encoders_.size() - 1; size_t stream_idx = encoders_.size() - 1;
for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
unsigned int target_bitrate_kbps = unsigned int target_bitrate_kbps =
parameters.bitrate.GetSpatialLayerSum(stream_idx) / 1000; bitrate.GetSpatialLayerSum(stream_idx) / 1000;
bool send_stream = target_bitrate_kbps > 0; bool send_stream = target_bitrate_kbps > 0;
if (send_stream || encoders_.size() > 1) if (send_stream || encoders_.size() > 1)
@ -310,19 +302,18 @@ void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) {
configurations_[i].rc_target_bitrate = target_bitrate_kbps; configurations_[i].rc_target_bitrate = target_bitrate_kbps;
if (send_stream) { if (send_stream) {
frame_buffer_controller_->OnRatesUpdated( frame_buffer_controller_->OnRatesUpdated(
stream_idx, parameters.bitrate.GetTemporalLayerAllocation(stream_idx), stream_idx, bitrate.GetTemporalLayerAllocation(stream_idx),
static_cast<int>(parameters.framerate_fps + 0.5)); new_framerate);
} }
UpdateVpxConfiguration(stream_idx, frame_buffer_controller_.get(), UpdateVpxConfiguration(stream_idx, frame_buffer_controller_.get(),
&configurations_[i]); &configurations_[i]);
vpx_codec_err_t err = if (libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i])) {
libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i]); return WEBRTC_VIDEO_CODEC_ERROR;
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) { void LibvpxVp8Encoder::OnPacketLossRateUpdate(float packet_loss_rate) {

View File

@ -54,7 +54,8 @@ class LibvpxVp8Encoder : public VideoEncoder {
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
void SetRates(const RateControlParameters& parameters) override; int SetRateAllocation(const VideoBitrateAllocation& bitrate,
uint32_t new_framerate) override;
void OnPacketLossRateUpdate(float packet_loss_rate) override; void OnPacketLossRateUpdate(float packet_loss_rate) override;

View File

@ -110,23 +110,20 @@ class TestVp8Impl : public VideoCodecUnitTest {
} }
}; };
TEST_F(TestVp8Impl, SetRates) { TEST_F(TestVp8Impl, SetRateAllocation) {
auto* const vpx = new NiceMock<MockLibvpxVp8Interface>(); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder.InitEncode(&codec_settings_, 1, 1000));
const uint32_t kBitrateBps = 300000; const int kBitrateBps = 300000;
VideoBitrateAllocation bitrate_allocation; VideoBitrateAllocation bitrate_allocation;
bitrate_allocation.SetBitrate(0, 0, kBitrateBps); bitrate_allocation.SetBitrate(0, 0, kBitrateBps);
EXPECT_CALL(*vpx, codec_enc_config_set(_, _)) EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
.WillOnce( encoder_->SetRateAllocation(bitrate_allocation,
Invoke([&](vpx_codec_ctx_t* ctx, const vpx_codec_enc_cfg_t* cfg) { codec_settings_.maxFramerate));
EXPECT_EQ(cfg->rc_target_bitrate, kBitrateBps / 1000); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
return VPX_CODEC_OK; encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
})); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder.SetRates(VideoEncoder::RateControlParameters( encoder_->SetRateAllocation(bitrate_allocation,
bitrate_allocation, static_cast<double>(codec_settings_.maxFramerate))); codec_settings_.maxFramerate));
} }
TEST_F(TestVp8Impl, EncodeFrameAndRelease) { TEST_F(TestVp8Impl, EncodeFrameAndRelease) {
@ -444,8 +441,7 @@ TEST_F(TestVp8Impl, DontDropKeyframes) {
VideoBitrateAllocation bitrate_allocation; VideoBitrateAllocation bitrate_allocation;
// Bitrate only enough for TL0. // Bitrate only enough for TL0.
bitrate_allocation.SetBitrate(0, 0, 200000); bitrate_allocation.SetBitrate(0, 0, 200000);
encoder_->SetRates( encoder_->SetRateAllocation(bitrate_allocation, 5);
VideoEncoder::RateControlParameters(bitrate_allocation, 5.0));
EncodedImage encoded_frame; EncodedImage encoded_frame;
CodecSpecificInfo codec_specific_info; CodecSpecificInfo codec_specific_info;

View File

@ -375,8 +375,9 @@ TEST_F(TestVp9Impl, EnableDisableSpatialLayers) {
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
sl_idx, 0, sl_idx, 0,
codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000 * 2); codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000 * 2);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) { for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
SetWaitForEncodedFramesThreshold(sl_idx + 1); SetWaitForEncodedFramesThreshold(sl_idx + 1);
@ -393,8 +394,9 @@ TEST_F(TestVp9Impl, EnableDisableSpatialLayers) {
for (size_t i = 0; i < num_spatial_layers - 1; ++i) { for (size_t i = 0; i < num_spatial_layers - 1; ++i) {
const size_t sl_idx = num_spatial_layers - i - 1; const size_t sl_idx = num_spatial_layers - i - 1;
bitrate_allocation.SetBitrate(sl_idx, 0, 0); bitrate_allocation.SetBitrate(sl_idx, 0, 0);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) { for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
SetWaitForEncodedFramesThreshold(sl_idx); SetWaitForEncodedFramesThreshold(sl_idx);
@ -424,8 +426,9 @@ TEST_F(TestVp9Impl, EndOfPicture) {
0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000); 0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000);
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000); 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
SetWaitForEncodedFramesThreshold(2); SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr)); encoder_->Encode(*NextInputFrame(), nullptr));
@ -439,8 +442,9 @@ TEST_F(TestVp9Impl, EndOfPicture) {
// Encode only base layer. Check that end-of-superframe flag is // Encode only base layer. Check that end-of-superframe flag is
// set on base layer frame. // set on base layer frame.
bitrate_allocation.SetBitrate(1, 0, 0); bitrate_allocation.SetBitrate(1, 0, 0);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */)); 0 /* max payload size (unused) */));
@ -475,8 +479,9 @@ TEST_F(TestVp9Impl, InterLayerPred) {
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */)); 0 /* max payload size (unused) */));
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
SetWaitForEncodedFramesThreshold(2); SetWaitForEncodedFramesThreshold(2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
@ -545,8 +550,9 @@ TEST_F(TestVp9Impl,
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
sl_idx, 0, sl_idx, 0,
codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode; for (size_t frame_num = 0; frame_num < num_frames_to_encode;
++frame_num) { ++frame_num) {
@ -604,8 +610,9 @@ TEST_F(TestVp9Impl,
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
sl_idx, 0, sl_idx, 0,
codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_frames_to_encode; for (size_t frame_num = 0; frame_num < num_frames_to_encode;
++frame_num) { ++frame_num) {
@ -661,8 +668,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) {
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frame; std::vector<EncodedImage> encoded_frame;
std::vector<CodecSpecificInfo> codec_specific_info; std::vector<CodecSpecificInfo> codec_specific_info;
@ -679,8 +687,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) {
// Disable SL1 layer. // Disable SL1 layer.
bitrate_allocation.SetBitrate(1, 0, 0); bitrate_allocation.SetBitrate(1, 0, 0);
bitrate_allocation.SetBitrate(1, 1, 0); bitrate_allocation.SetBitrate(1, 1, 0);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 1 frame. // Encode 1 frame.
SetWaitForEncodedFramesThreshold(1); SetWaitForEncodedFramesThreshold(1);
@ -697,8 +706,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) {
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 1 frame. // Encode 1 frame.
SetWaitForEncodedFramesThreshold(2); SetWaitForEncodedFramesThreshold(2);
@ -736,8 +746,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) {
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frame; std::vector<EncodedImage> encoded_frame;
std::vector<CodecSpecificInfo> codec_specific_info; std::vector<CodecSpecificInfo> codec_specific_info;
@ -754,8 +765,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) {
// Disable SL1 layer. // Disable SL1 layer.
bitrate_allocation.SetBitrate(1, 0, 0); bitrate_allocation.SetBitrate(1, 0, 0);
bitrate_allocation.SetBitrate(1, 1, 0); bitrate_allocation.SetBitrate(1, 1, 0);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 11 frames. More than Gof length 2, and odd to end at TL1 frame. // Encode 11 frames. More than Gof length 2, and odd to end at TL1 frame.
for (int i = 0; i < 11; ++i) { for (int i = 0; i < 11; ++i) {
@ -775,8 +787,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) {
1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode 1 frame. // Encode 1 frame.
SetWaitForEncodedFramesThreshold(2); SetWaitForEncodedFramesThreshold(2);
@ -822,8 +835,9 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) {
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
} }
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode enough frames to force drop due to framerate capping. // Encode enough frames to force drop due to framerate capping.
for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop; for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop;
@ -841,8 +855,9 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) {
num_spatial_layers - 1, 0, num_spatial_layers - 1, 0,
codec_settings_.spatialLayers[num_spatial_layers - 1].targetBitrate * codec_settings_.spatialLayers[num_spatial_layers - 1].targetBitrate *
1000); 1000);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
for (size_t frame_num = 0; frame_num < num_dropped_frames; ++frame_num) { for (size_t frame_num = 0; frame_num < num_dropped_frames; ++frame_num) {
SetWaitForEncodedFramesThreshold(1); SetWaitForEncodedFramesThreshold(1);
@ -898,8 +913,9 @@ TEST_F(TestVp9Impl, RemovingLayerIsNotDelayedInScreenshareAndAddsSsInfo) {
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000);
} }
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Encode enough frames to force drop due to framerate capping. // Encode enough frames to force drop due to framerate capping.
for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop; for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop;
@ -928,8 +944,9 @@ TEST_F(TestVp9Impl, RemovingLayerIsNotDelayedInScreenshareAndAddsSsInfo) {
// Disable the last layer. // Disable the last layer.
bitrate_allocation.SetBitrate(num_spatial_layers - 1, 0, 0); bitrate_allocation.SetBitrate(num_spatial_layers - 1, 0, 0);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Still expected to drop first layer. Last layer has to be disable also. // Still expected to drop first layer. Last layer has to be disable also.
for (size_t frame_num = num_dropped_frames - 2; for (size_t frame_num = num_dropped_frames - 2;
@ -985,8 +1002,9 @@ TEST_F(TestVp9Impl, DisableNewLayerInVideoDelaysSsInfoTillTL0) {
num_temporal_layers); num_temporal_layers);
} }
} }
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
std::vector<EncodedImage> encoded_frames; std::vector<EncodedImage> encoded_frames;
std::vector<CodecSpecificInfo> codec_specific_info; std::vector<CodecSpecificInfo> codec_specific_info;
@ -1002,8 +1020,9 @@ TEST_F(TestVp9Impl, DisableNewLayerInVideoDelaysSsInfoTillTL0) {
for (size_t tl_idx = 0; tl_idx < num_temporal_layers; ++tl_idx) { for (size_t tl_idx = 0; tl_idx < num_temporal_layers; ++tl_idx) {
bitrate_allocation.SetBitrate(num_spatial_layers - 1, tl_idx, 0); bitrate_allocation.SetBitrate(num_spatial_layers - 1, tl_idx, 0);
} }
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
// Next is TL1 frame. The last layer is disabled immediately, but SS structure // Next is TL1 frame. The last layer is disabled immediately, but SS structure
// is not provided here. // is not provided here.
@ -1040,8 +1059,9 @@ TEST_F(TestVp9Impl,
VideoBitrateAllocation bitrate_allocation; VideoBitrateAllocation bitrate_allocation;
bitrate_allocation.SetBitrate( bitrate_allocation.SetBitrate(
0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000); 0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000);
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->Encode(*NextInputFrame(), nullptr)); encoder_->Encode(*NextInputFrame(), nullptr));
EncodedImage encoded_frame; EncodedImage encoded_frame;
@ -1309,8 +1329,9 @@ TEST_F(TestVp9ImplFrameDropping, DifferentFrameratePerSpatialLayer) {
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */)); 0 /* max payload size (unused) */));
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
bitrate_allocation, codec_settings_.maxFramerate)); encoder_->SetRateAllocation(bitrate_allocation,
codec_settings_.maxFramerate));
VideoFrame* input_frame = NextInputFrame(); VideoFrame* input_frame = NextInputFrame();
for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) { for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
@ -1363,8 +1384,9 @@ TEST_F(TestVp9ImplFrameDropping, LayerMaxFramerateIsCappedByCodecMaxFramerate) {
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
0 /* max payload size (unused) */)); 0 /* max payload size (unused) */));
encoder_->SetRates(VideoEncoder::RateControlParameters( EXPECT_EQ(
bitrate_allocation, codec_max_framerate_fps)); WEBRTC_VIDEO_CODEC_OK,
encoder_->SetRateAllocation(bitrate_allocation, codec_max_framerate_fps));
VideoFrame* input_frame = NextInputFrame(); VideoFrame* input_frame = NextInputFrame();
for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) { for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {

View File

@ -309,33 +309,29 @@ bool VP9EncoderImpl::SetSvcRates(
return true; return true;
} }
void VP9EncoderImpl::SetRates(const RateControlParameters& parameters) { int VP9EncoderImpl::SetRateAllocation(
const VideoBitrateAllocation& bitrate_allocation,
uint32_t frame_rate) {
if (!inited_) { if (!inited_) {
RTC_LOG(LS_WARNING) << "SetRates() calll while uninitialzied."; return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
return;
} }
if (encoder_->err) { if (encoder_->err) {
RTC_LOG(LS_WARNING) << "Encoder in error state: " << encoder_->err; return WEBRTC_VIDEO_CODEC_ERROR;
return;
} }
if (parameters.framerate_fps < 1.0) { if (frame_rate < 1) {
RTC_LOG(LS_WARNING) << "Unsupported framerate: " return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
<< parameters.framerate_fps;
return;
} }
// Update bit rate // Update bit rate
if (codec_.maxBitrate > 0 && if (codec_.maxBitrate > 0 &&
parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) { bitrate_allocation.get_sum_kbps() > codec_.maxBitrate) {
RTC_LOG(LS_WARNING) << "Target bitrate exceeds maximum: " return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
<< parameters.bitrate.get_sum_kbps() << " vs "
<< codec_.maxBitrate;
return;
} }
codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5); codec_.maxFramerate = frame_rate;
requested_bitrate_allocation_ = parameters.bitrate;
return; requested_bitrate_allocation_ = bitrate_allocation;
return WEBRTC_VIDEO_CODEC_OK;
} }
int VP9EncoderImpl::InitEncode(const VideoCodec* inst, int VP9EncoderImpl::InitEncode(const VideoCodec* inst,

View File

@ -48,7 +48,8 @@ class VP9EncoderImpl : public VP9Encoder {
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
void SetRates(const RateControlParameters& parameters) override; int SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
uint32_t frame_rate) override;
EncoderInfo GetEncoderInfo() const override; EncoderInfo GetEncoderInfo() const override;

View File

@ -288,9 +288,8 @@ void SimulcastTestFixtureImpl::SetUpRateAllocator() {
} }
void SimulcastTestFixtureImpl::SetRates(uint32_t bitrate_kbps, uint32_t fps) { void SimulcastTestFixtureImpl::SetRates(uint32_t bitrate_kbps, uint32_t fps) {
encoder_->SetRates(VideoEncoder::RateControlParameters( encoder_->SetRateAllocation(
rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), fps);
static_cast<double>(fps)));
} }
void SimulcastTestFixtureImpl::RunActiveStreamsTest( void SimulcastTestFixtureImpl::RunActiveStreamsTest(

View File

@ -104,7 +104,8 @@ class MediaCodecVideoEncoder : public VideoEncoder {
int32_t RegisterEncodeCompleteCallback( int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override; EncodedImageCallback* callback) override;
int32_t Release() override; int32_t Release() override;
void SetRates(const RateControlParameters& parameters) override; int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
uint32_t frame_rate) override;
EncoderInfo GetEncoderInfo() const override; EncoderInfo GetEncoderInfo() const override;
// Fills the input buffer with data from the buffers passed as parameters. // Fills the input buffer with data from the buffers passed as parameters.
@ -899,16 +900,17 @@ int32_t MediaCodecVideoEncoder::Release() {
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
void MediaCodecVideoEncoder::SetRates(const RateControlParameters& parameters) { int32_t MediaCodecVideoEncoder::SetRateAllocation(
const VideoBitrateAllocation& rate_allocation,
uint32_t frame_rate) {
RTC_DCHECK_RUN_ON(&encoder_queue_checker_); RTC_DCHECK_RUN_ON(&encoder_queue_checker_);
const uint32_t new_bit_rate = parameters.bitrate.get_sum_kbps(); const uint32_t new_bit_rate = rate_allocation.get_sum_kbps();
if (sw_fallback_required_) if (sw_fallback_required_)
return; return WEBRTC_VIDEO_CODEC_OK;
uint32_t frame_rate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
frame_rate = frame_rate =
(frame_rate < MAX_ALLOWED_VIDEO_FPS) ? frame_rate : MAX_ALLOWED_VIDEO_FPS; (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) { if (last_set_bitrate_kbps_ == new_bit_rate && last_set_fps_ == frame_rate) {
return; return WEBRTC_VIDEO_CODEC_OK;
} }
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); ScopedLocalRefFrame local_ref_frame(jni);
@ -924,7 +926,10 @@ void MediaCodecVideoEncoder::SetRates(const RateControlParameters& parameters) {
rtc::dchecked_cast<int>(last_set_fps_)); rtc::dchecked_cast<int>(last_set_fps_));
if (CheckException(jni) || !ret) { if (CheckException(jni) || !ret) {
ProcessHWError(true /* reset_if_fallback_unavailable */); 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 { VideoEncoder::EncoderInfo MediaCodecVideoEncoder::GetEncoderInfo() const {

View File

@ -146,15 +146,16 @@ int32_t VideoEncoderWrapper::Encode(
return HandleReturnCode(jni, ret, "encode"); return HandleReturnCode(jni, ret, "encode");
} }
void VideoEncoderWrapper::SetRates(const RateControlParameters& parameters) { int32_t VideoEncoderWrapper::SetRateAllocation(
const VideoBitrateAllocation& allocation,
uint32_t framerate) {
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedJavaLocalRef<jobject> j_bitrate_allocation = ScopedJavaLocalRef<jobject> j_bitrate_allocation =
ToJavaBitrateAllocation(jni, parameters.bitrate); ToJavaBitrateAllocation(jni, allocation);
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_setRateAllocation( ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_setRateAllocation(
jni, encoder_, j_bitrate_allocation, jni, encoder_, j_bitrate_allocation, (jint)framerate);
(jint)(parameters.framerate_fps + 0.5)); return HandleReturnCode(jni, ret, "setRateAllocation");
HandleReturnCode(jni, ret, "setRateAllocation");
} }
VideoEncoder::EncoderInfo VideoEncoderWrapper::GetEncoderInfo() const { VideoEncoder::EncoderInfo VideoEncoderWrapper::GetEncoderInfo() const {

View File

@ -44,7 +44,8 @@ class VideoEncoderWrapper : public VideoEncoder {
int32_t Encode(const VideoFrame& frame, int32_t Encode(const VideoFrame& frame,
const std::vector<VideoFrameType>* frame_types) override; const std::vector<VideoFrameType>* frame_types) override;
void SetRates(const RateControlParameters& parameters) override; int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
uint32_t framerate) override;
EncoderInfo GetEncoderInfo() const override; EncoderInfo GetEncoderInfo() const override;

View File

@ -74,8 +74,11 @@ int32_t ConfigurableFrameSizeEncoder::Release() {
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
void ConfigurableFrameSizeEncoder::SetRates( int32_t ConfigurableFrameSizeEncoder::SetRateAllocation(
const RateControlParameters& parameters) {} const VideoBitrateAllocation& allocation,
uint32_t framerate) {
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t ConfigurableFrameSizeEncoder::SetFrameSize(size_t size) { int32_t ConfigurableFrameSizeEncoder::SetFrameSize(size_t size) {
RTC_DCHECK_LE(size, max_frame_size_); RTC_DCHECK_LE(size, max_frame_size_);

View File

@ -44,7 +44,8 @@ class ConfigurableFrameSizeEncoder : public VideoEncoder {
int32_t Release() override; int32_t Release() override;
void SetRates(const RateControlParameters& parameters) override; int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
uint32_t framerate) override;
int32_t SetFrameSize(size_t size); int32_t SetFrameSize(size_t size);

View File

@ -51,6 +51,7 @@ void WriteCounter(unsigned char* payload, uint32_t counter) {
FakeEncoder::FakeEncoder(Clock* clock) FakeEncoder::FakeEncoder(Clock* clock)
: clock_(clock), : clock_(clock),
callback_(nullptr), callback_(nullptr),
configured_input_framerate_(-1),
max_target_bitrate_kbps_(-1), max_target_bitrate_kbps_(-1),
pending_keyframe_(true), pending_keyframe_(true),
counter_(0), counter_(0),
@ -64,7 +65,7 @@ void FakeEncoder::SetMaxBitrate(int max_kbps) {
RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it.
rtc::CritScope cs(&crit_sect_); rtc::CritScope cs(&crit_sect_);
max_target_bitrate_kbps_ = max_kbps; max_target_bitrate_kbps_ = max_kbps;
SetRates(current_rate_settings_); SetRateAllocation(target_bitrate_, configured_input_framerate_);
} }
int32_t FakeEncoder::InitEncode(const VideoCodec* config, int32_t FakeEncoder::InitEncode(const VideoCodec* config,
@ -72,8 +73,8 @@ int32_t FakeEncoder::InitEncode(const VideoCodec* config,
size_t max_payload_size) { size_t max_payload_size) {
rtc::CritScope cs(&crit_sect_); rtc::CritScope cs(&crit_sect_);
config_ = *config; config_ = *config;
current_rate_settings_.bitrate.SetBitrate(0, 0, config_.startBitrate * 1000); target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000);
current_rate_settings_.framerate_fps = config_.maxFramerate; configured_input_framerate_ = config_.maxFramerate;
pending_keyframe_ = true; pending_keyframe_ = true;
last_frame_info_ = FrameInfo(); last_frame_info_ = FrameInfo();
return 0; return 0;
@ -85,7 +86,8 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
unsigned char num_simulcast_streams; unsigned char num_simulcast_streams;
SimulcastStream simulcast_streams[kMaxSimulcastStreams]; SimulcastStream simulcast_streams[kMaxSimulcastStreams];
EncodedImageCallback* callback; EncodedImageCallback* callback;
RateControlParameters rates; VideoBitrateAllocation target_bitrate;
int framerate;
VideoCodecMode mode; VideoCodecMode mode;
bool keyframe; bool keyframe;
uint32_t counter; uint32_t counter;
@ -97,10 +99,12 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
simulcast_streams[i] = config_.simulcastStream[i]; simulcast_streams[i] = config_.simulcastStream[i];
} }
callback = callback_; callback = callback_;
rates = current_rate_settings_; target_bitrate = target_bitrate_;
mode = config_.mode; mode = config_.mode;
if (rates.framerate_fps <= 0.0) { if (configured_input_framerate_ > 0) {
rates.framerate_fps = max_framerate; framerate = configured_input_framerate_;
} else {
framerate = max_framerate;
} }
keyframe = pending_keyframe_; keyframe = pending_keyframe_;
pending_keyframe_ = false; pending_keyframe_ = false;
@ -108,8 +112,8 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
} }
FrameInfo frame_info = FrameInfo frame_info =
NextFrame(frame_types, keyframe, num_simulcast_streams, rates.bitrate, NextFrame(frame_types, keyframe, num_simulcast_streams, target_bitrate,
simulcast_streams, static_cast<int>(rates.framerate_fps + 0.5)); simulcast_streams, framerate);
for (uint8_t i = 0; i < frame_info.layers.size(); ++i) { for (uint8_t i = 0; i < frame_info.layers.size(); ++i) {
constexpr int kMinPayLoadLength = 14; constexpr int kMinPayLoadLength = 14;
if (frame_info.layers[i].size < kMinPayLoadLength) { if (frame_info.layers[i].size < kMinPayLoadLength) {
@ -233,10 +237,12 @@ int32_t FakeEncoder::Release() {
return 0; return 0;
} }
void FakeEncoder::SetRates(const RateControlParameters& parameters) { int32_t FakeEncoder::SetRateAllocation(
const VideoBitrateAllocation& rate_allocation,
uint32_t framerate) {
rtc::CritScope cs(&crit_sect_); rtc::CritScope cs(&crit_sect_);
current_rate_settings_ = parameters; target_bitrate_ = rate_allocation;
int allocated_bitrate_kbps = parameters.bitrate.get_sum_kbps(); int allocated_bitrate_kbps = target_bitrate_.get_sum_kbps();
// Scale bitrate allocation to not exceed the given max target bitrate. // Scale bitrate allocation to not exceed the given max target bitrate.
if (max_target_bitrate_kbps_ > 0 && if (max_target_bitrate_kbps_ > 0 &&
@ -245,19 +251,20 @@ void FakeEncoder::SetRates(const RateControlParameters& parameters) {
++spatial_idx) { ++spatial_idx) {
for (uint8_t temporal_idx = 0; temporal_idx < kMaxTemporalStreams; for (uint8_t temporal_idx = 0; temporal_idx < kMaxTemporalStreams;
++temporal_idx) { ++temporal_idx) {
if (current_rate_settings_.bitrate.HasBitrate(spatial_idx, if (target_bitrate_.HasBitrate(spatial_idx, temporal_idx)) {
temporal_idx)) { uint32_t bitrate =
uint32_t bitrate = current_rate_settings_.bitrate.GetBitrate( target_bitrate_.GetBitrate(spatial_idx, temporal_idx);
spatial_idx, temporal_idx);
bitrate = static_cast<uint32_t>( bitrate = static_cast<uint32_t>(
(bitrate * int64_t{max_target_bitrate_kbps_}) / (bitrate * int64_t{max_target_bitrate_kbps_}) /
allocated_bitrate_kbps); allocated_bitrate_kbps);
current_rate_settings_.bitrate.SetBitrate(spatial_idx, temporal_idx, target_bitrate_.SetBitrate(spatial_idx, temporal_idx, bitrate);
bitrate);
} }
} }
} }
} }
configured_input_framerate_ = framerate;
return 0;
} }
const char* FakeEncoder::kImplementationName = "fake_encoder"; const char* FakeEncoder::kImplementationName = "fake_encoder";
@ -269,7 +276,7 @@ VideoEncoder::EncoderInfo FakeEncoder::GetEncoderInfo() const {
int FakeEncoder::GetConfiguredInputFramerate() const { int FakeEncoder::GetConfiguredInputFramerate() const {
rtc::CritScope cs(&crit_sect_); rtc::CritScope cs(&crit_sect_);
return static_cast<int>(current_rate_settings_.framerate_fps + 0.5); return configured_input_framerate_;
} }
FakeH264Encoder::FakeH264Encoder(Clock* clock) FakeH264Encoder::FakeH264Encoder(Clock* clock)

View File

@ -48,7 +48,8 @@ class FakeEncoder : public VideoEncoder {
int32_t RegisterEncodeCompleteCallback( int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override; EncodedImageCallback* callback) override;
int32_t Release() override; int32_t Release() override;
void SetRates(const RateControlParameters& parameters) override; int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
uint32_t framerate) override;
int GetConfiguredInputFramerate() const; int GetConfiguredInputFramerate() const;
EncoderInfo GetEncoderInfo() const override; EncoderInfo GetEncoderInfo() const override;
@ -88,7 +89,8 @@ class FakeEncoder : public VideoEncoder {
VideoCodec config_ RTC_GUARDED_BY(crit_sect_); VideoCodec config_ RTC_GUARDED_BY(crit_sect_);
EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_); EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_);
RateControlParameters current_rate_settings_ RTC_GUARDED_BY(crit_sect_); VideoBitrateAllocation target_bitrate_ RTC_GUARDED_BY(crit_sect_);
int configured_input_framerate_ RTC_GUARDED_BY(crit_sect_);
int max_target_bitrate_kbps_ RTC_GUARDED_BY(crit_sect_); int max_target_bitrate_kbps_ RTC_GUARDED_BY(crit_sect_);
bool pending_keyframe_ RTC_GUARDED_BY(crit_sect_); bool pending_keyframe_ RTC_GUARDED_BY(crit_sect_);
uint32_t counter_ RTC_GUARDED_BY(crit_sect_); uint32_t counter_ RTC_GUARDED_BY(crit_sect_);

View File

@ -63,9 +63,7 @@ QualityAnalyzingVideoEncoder::QualityAnalyzingVideoEncoder(
bitrate_multiplier_(bitrate_multiplier), bitrate_multiplier_(bitrate_multiplier),
stream_required_spatial_index_(std::move(stream_required_spatial_index)), stream_required_spatial_index_(std::move(stream_required_spatial_index)),
injector_(injector), injector_(injector),
analyzer_(analyzer), analyzer_(analyzer) {}
mode_(SimulcastMode::kNormal),
delegate_callback_(nullptr) {}
QualityAnalyzingVideoEncoder::~QualityAnalyzingVideoEncoder() = default; QualityAnalyzingVideoEncoder::~QualityAnalyzingVideoEncoder() = default;
int32_t QualityAnalyzingVideoEncoder::InitEncode( int32_t QualityAnalyzingVideoEncoder::InitEncode(
@ -149,11 +147,17 @@ int32_t QualityAnalyzingVideoEncoder::Encode(
return result; return result;
} }
void QualityAnalyzingVideoEncoder::SetRates( int32_t QualityAnalyzingVideoEncoder::SetRates(uint32_t bitrate,
const VideoEncoder::RateControlParameters& parameters) { uint32_t framerate) {
return delegate_->SetRates(bitrate, framerate);
}
int32_t QualityAnalyzingVideoEncoder::SetRateAllocation(
const VideoBitrateAllocation& allocation,
uint32_t framerate) {
RTC_DCHECK_GT(bitrate_multiplier_, 0.0); RTC_DCHECK_GT(bitrate_multiplier_, 0.0);
if (fabs(bitrate_multiplier_ - kNoMultiplier) < kEps) { if (fabs(bitrate_multiplier_ - kNoMultiplier) < kEps) {
return delegate_->SetRates(parameters); return delegate_->SetRateAllocation(allocation, framerate);
} }
// Simulating encoder overshooting target bitrate, by configuring actual // Simulating encoder overshooting target bitrate, by configuring actual
@ -162,7 +166,7 @@ void QualityAnalyzingVideoEncoder::SetRates(
VideoBitrateAllocation multiplied_allocation; VideoBitrateAllocation multiplied_allocation;
for (size_t si = 0; si < kMaxSpatialLayers; ++si) { for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
const uint32_t spatial_layer_bitrate_bps = const uint32_t spatial_layer_bitrate_bps =
parameters.bitrate.GetSpatialLayerSum(si); allocation.GetSpatialLayerSum(si);
if (spatial_layer_bitrate_bps == 0) { if (spatial_layer_bitrate_bps == 0) {
continue; continue;
} }
@ -181,18 +185,16 @@ void QualityAnalyzingVideoEncoder::SetRates(
} }
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) { for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
if (parameters.bitrate.HasBitrate(si, ti)) { if (allocation.HasBitrate(si, ti)) {
multiplied_allocation.SetBitrate( multiplied_allocation.SetBitrate(
si, ti, si, ti,
rtc::checked_cast<uint32_t>(bitrate_multiplier * rtc::checked_cast<uint32_t>(bitrate_multiplier *
parameters.bitrate.GetBitrate(si, ti))); allocation.GetBitrate(si, ti)));
} }
} }
} }
RateControlParameters adjusted_params = parameters; return delegate_->SetRateAllocation(multiplied_allocation, framerate);
adjusted_params.bitrate = multiplied_allocation;
return delegate_->SetRates(adjusted_params);
} }
VideoEncoder::EncoderInfo QualityAnalyzingVideoEncoder::GetEncoderInfo() const { VideoEncoder::EncoderInfo QualityAnalyzingVideoEncoder::GetEncoderInfo() const {

View File

@ -70,7 +70,9 @@ class QualityAnalyzingVideoEncoder : public VideoEncoder,
int32_t Release() override; int32_t Release() override;
int32_t Encode(const VideoFrame& frame, int32_t Encode(const VideoFrame& frame,
const std::vector<VideoFrameType>* frame_types) override; const std::vector<VideoFrameType>* frame_types) override;
void SetRates(const VideoEncoder::RateControlParameters& parameters) override; int32_t SetRates(uint32_t bitrate, uint32_t framerate) override;
int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
uint32_t framerate) override;
EncoderInfo GetEncoderInfo() const override; EncoderInfo GetEncoderInfo() const override;
// Methods of EncodedImageCallback interface. // Methods of EncodedImageCallback interface.

View File

@ -75,8 +75,9 @@ class VideoEncoderProxyFactory final : public VideoEncoderFactory {
return encoder_->RegisterEncodeCompleteCallback(callback); return encoder_->RegisterEncodeCompleteCallback(callback);
} }
int32_t Release() override { return encoder_->Release(); } int32_t Release() override { return encoder_->Release(); }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
encoder_->SetRates(parameters); uint32_t framerate) override {
return encoder_->SetRateAllocation(rate_allocation, framerate);
} }
VideoEncoder::EncoderInfo GetEncoderInfo() const override { VideoEncoder::EncoderInfo GetEncoderInfo() const override {
return encoder_->GetEncoderInfo(); return encoder_->GetEncoderInfo();

View File

@ -307,13 +307,15 @@ TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) {
RTC_DCHECK_EQ(1, encoder_config->number_of_streams); RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
} }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
uint32_t framerate) override {
// Make sure not to trigger on any default zero bitrates. // Make sure not to trigger on any default zero bitrates.
if (parameters.bitrate.get_sum_bps() == 0) if (rate_allocation.get_sum_bps() == 0)
return; return 0;
rtc::CritScope lock(&crit_); rtc::CritScope lock(&crit_);
bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); bitrate_kbps_ = rate_allocation.get_sum_kbps();
observation_complete_.Set(); observation_complete_.Set();
return 0;
} }
void PerformTest() override { void PerformTest() override {

View File

@ -149,11 +149,11 @@ class QualityTestVideoEncoder : public VideoEncoder,
} }
return encoder_->Encode(frame, frame_types); return encoder_->Encode(frame, frame_types);
} }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
uint32_t framerate) override {
RTC_DCHECK_GT(overshoot_factor_, 0.0); RTC_DCHECK_GT(overshoot_factor_, 0.0);
if (overshoot_factor_ == 1.0) { if (overshoot_factor_ == 1.0) {
encoder_->SetRates(parameters); return encoder_->SetRateAllocation(allocation, framerate);
return;
} }
// Simulating encoder overshooting target bitrate, by configuring actual // Simulating encoder overshooting target bitrate, by configuring actual
@ -162,7 +162,7 @@ class QualityTestVideoEncoder : public VideoEncoder,
VideoBitrateAllocation overshot_allocation; VideoBitrateAllocation overshot_allocation;
for (size_t si = 0; si < kMaxSpatialLayers; ++si) { for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
const uint32_t spatial_layer_bitrate_bps = const uint32_t spatial_layer_bitrate_bps =
parameters.bitrate.GetSpatialLayerSum(si); allocation.GetSpatialLayerSum(si);
if (spatial_layer_bitrate_bps == 0) { if (spatial_layer_bitrate_bps == 0) {
continue; continue;
} }
@ -181,18 +181,16 @@ class QualityTestVideoEncoder : public VideoEncoder,
} }
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) { for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
if (parameters.bitrate.HasBitrate(si, ti)) { if (allocation.HasBitrate(si, ti)) {
overshot_allocation.SetBitrate( overshot_allocation.SetBitrate(
si, ti, si, ti,
rtc::checked_cast<uint32_t>( rtc::checked_cast<uint32_t>(overshoot_factor *
overshoot_factor * parameters.bitrate.GetBitrate(si, ti))); allocation.GetBitrate(si, ti)));
} }
} }
} }
return encoder_->SetRates( return encoder_->SetRateAllocation(overshot_allocation, framerate);
RateControlParameters(overshot_allocation, parameters.framerate_fps,
parameters.bandwidth_allocation));
} }
EncoderInfo GetEncoderInfo() const override { EncoderInfo GetEncoderInfo() const override {
EncoderInfo info = encoder_->GetEncoderInfo(); EncoderInfo info = encoder_->GetEncoderInfo();

View File

@ -2045,11 +2045,11 @@ TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
} }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
rtc::CritScope lock(&crit_); rtc::CritScope lock(&crit_);
start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); start_bitrate_kbps_ = new_target_bitrate;
start_bitrate_changed_.Set(); start_bitrate_changed_.Set();
FakeEncoder::SetRates(parameters); return FakeEncoder::SetRates(new_target_bitrate, framerate);
} }
int GetStartBitrateKbps() const { int GetStartBitrateKbps() const {
@ -2118,11 +2118,12 @@ class StartStopBitrateObserver : public test::FakeEncoder {
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
} }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
uint32_t framerate) override {
rtc::CritScope lock(&crit_); rtc::CritScope lock(&crit_);
bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); bitrate_kbps_ = bitrate.get_sum_kbps();
bitrate_changed_.Set(); bitrate_changed_.Set();
FakeEncoder::SetRates(parameters); return FakeEncoder::SetRateAllocation(bitrate, framerate);
} }
bool WaitForEncoderInit() { bool WaitForEncoderInit() {
@ -2853,17 +2854,17 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
maxPayloadSize); maxPayloadSize);
} }
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
uint32_t frameRate) override {
{ {
rtc::CritScope lock(&crit_); rtc::CritScope lock(&crit_);
if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) { if (target_bitrate_ == bitrate.get_sum_kbps()) {
FakeEncoder::SetRates(parameters); return FakeEncoder::SetRateAllocation(bitrate, frameRate);
return;
} }
target_bitrate_ = parameters.bitrate.get_sum_kbps(); target_bitrate_ = bitrate.get_sum_kbps();
} }
bitrate_changed_event_.Set(); bitrate_changed_event_.Set();
FakeEncoder::SetRates(parameters); return FakeEncoder::SetRateAllocation(bitrate, frameRate);
} }
void WaitForSetRates(uint32_t expected_bitrate) { void WaitForSetRates(uint32_t expected_bitrate) {
@ -3652,15 +3653,16 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
max_bitrate_bps_(0), max_bitrate_bps_(0),
first_packet_sent_(false) {} first_packet_sent_(false) {}
void SetRates(const RateControlParameters& parameters) override { int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
uint32_t frameRate) override {
rtc::CritScope lock(&crit_); rtc::CritScope lock(&crit_);
// Wait for the first sent packet so that videosendstream knows // Wait for the first sent packet so that videosendstream knows
// rtp_overhead. // rtp_overhead.
if (first_packet_sent_) { if (first_packet_sent_) {
max_bitrate_bps_ = parameters.bitrate.get_sum_bps(); max_bitrate_bps_ = bitrate.get_sum_bps();
bitrate_changed_event_.Set(); bitrate_changed_event_.Set();
} }
return FakeEncoder::SetRates(parameters); return FakeEncoder::SetRateAllocation(bitrate, frameRate);
} }
void OnCallsCreated(Call* sender_call, Call* receiver_call) override { void OnCallsCreated(Call* sender_call, Call* receiver_call) override {

View File

@ -726,24 +726,24 @@ class VideoStreamEncoderTest : public ::testing::Test {
return FakeEncoder::Release(); return FakeEncoder::Release();
} }
void SetRates(const RateControlParameters& parameters) { int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
uint32_t framerate) {
rtc::CritScope lock(&local_crit_sect_); rtc::CritScope lock(&local_crit_sect_);
VideoBitrateAllocation adjusted_rate_allocation; VideoBitrateAllocation adjusted_rate_allocation;
for (size_t si = 0; si < kMaxSpatialLayers; ++si) { for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) { for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
if (parameters.bitrate.HasBitrate(si, ti)) { if (rate_allocation.HasBitrate(si, ti)) {
adjusted_rate_allocation.SetBitrate( adjusted_rate_allocation.SetBitrate(
si, ti, si, ti,
static_cast<uint32_t>(parameters.bitrate.GetBitrate(si, ti) * static_cast<uint32_t>(rate_allocation.GetBitrate(si, ti) *
rate_factor_)); rate_factor_));
} }
} }
} }
last_framerate_ = static_cast<uint32_t>(parameters.framerate_fps + 0.5); last_framerate_ = framerate;
last_bitrate_allocation_ = parameters.bitrate; last_bitrate_allocation_ = rate_allocation;
RateControlParameters adjusted_paramters = parameters; return FakeEncoder::SetRateAllocation(adjusted_rate_allocation,
adjusted_paramters.bitrate = adjusted_rate_allocation; framerate);
FakeEncoder::SetRates(adjusted_paramters);
} }
rtc::CriticalSection local_crit_sect_; rtc::CriticalSection local_crit_sect_;