diff --git a/api/test/mock_video_encoder.h b/api/test/mock_video_encoder.h index f99f7e325d..d4f7baf99d 100644 --- a/api/test/mock_video_encoder.h +++ b/api/test/mock_video_encoder.h @@ -48,7 +48,6 @@ class MockVideoEncoder : public VideoEncoder { MOCK_METHOD2(SetRateAllocation, int32_t(const VideoBitrateAllocation& newBitRate, uint32_t frameRate)); - MOCK_METHOD1(SetRates, void(const RateControlParameters& parameters)); MOCK_CONST_METHOD0(GetEncoderInfo, EncoderInfo(void)); }; diff --git a/api/test/peerconnection_quality_test_fixture.h b/api/test/peerconnection_quality_test_fixture.h index 289f8504c6..b22b392f1b 100644 --- a/api/test/peerconnection_quality_test_fixture.h +++ b/api/test/peerconnection_quality_test_fixture.h @@ -186,7 +186,7 @@ class PeerConnectionE2EQualityTestFixture { // used to emulate overshooting of video encoders. This multiplier will // be applied for all video encoder on both sides for all layers. Bitrate // estimated by WebRTC stack will be multiplied on this multiplier and then - // provided into VideoEncoder::SetRates(...). + // provided into VideoEncoder::SetRateAllocation(...). double video_encoder_bitrate_multiplier = 1.0; }; diff --git a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc index 2a382efbef..8ccafcc884 100644 --- a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc +++ b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc @@ -114,8 +114,10 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { 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_; + return WEBRTC_VIDEO_CODEC_OK; } EncoderInfo GetEncoderInfo() const override { @@ -203,8 +205,10 @@ void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize)); - fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); + EXPECT_EQ( + WEBRTC_VIDEO_CODEC_OK, + fallback_wrapper_->SetRateAllocation( + rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); int callback_count = callback_.callback_count_; int encode_count = fake_encoder_->encode_count_; @@ -222,8 +226,10 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() { codec_.VP8()->numberOfTemporalLayers = 1; rate_allocator_.reset(new SimulcastRateAllocator(codec_)); fallback_wrapper_->InitEncode(&codec_, 2, kMaxPayloadSize); - fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); + EXPECT_EQ( + WEBRTC_VIDEO_CODEC_OK, + fallback_wrapper_->SetRateAllocation( + rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); EXPECT_EQ(1, fake_encoder_->init_encode_count_); // Have the non-fallback encoder request a software fallback. @@ -296,8 +302,7 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest, SetRatesForwardedDuringFallback) { UtilizeFallbackEncoder(); EXPECT_EQ(1, fake_encoder_->set_rates_count_); - fallback_wrapper_->SetRates( - VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 1)); + fallback_wrapper_->SetRateAllocation(VideoBitrateAllocation(), 1); EXPECT_EQ(2, fake_encoder_->set_rates_count_); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release()); } @@ -381,9 +386,10 @@ class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest { } void SetRateAllocation(uint32_t bitrate_kbps) { - fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(bitrate_kbps * 1000, kFramerate), - kFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->SetRateAllocation( + rate_allocator_->GetAllocation( + bitrate_kbps * 1000, kFramerate), + kFramerate)); } void EncodeFrameAndVerifyLastName(const char* expected_name) { diff --git a/api/video_codecs/video_encoder.cc b/api/video_codecs/video_encoder.cc index d91bb4e5c2..66ba9e4319 100644 --- a/api/video_codecs/video_encoder.cc +++ b/api/video_codecs/video_encoder.cc @@ -106,13 +106,6 @@ VideoEncoder::RateControlParameters::RateControlParameters() framerate_fps(0.0), 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( const VideoBitrateAllocation& bitrate, double framerate_fps, diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h index 3af7dfda11..1c8dfd54d9 100644 --- a/api/video_codecs/video_encoder.h +++ b/api/video_codecs/video_encoder.h @@ -195,8 +195,6 @@ class RTC_EXPORT VideoEncoder { struct RateControlParameters { RateControlParameters(); - RateControlParameters(const VideoBitrateAllocation& bitrate, - double framerate_fps); RateControlParameters(const VideoBitrateAllocation& bitrate, double framerate_fps, DataRate bandwidth_allocation); diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc index a687b84ba6..46659a4e39 100644 --- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc @@ -88,7 +88,8 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder { int32_t Release() override; int32_t Encode(const VideoFrame& frame, const std::vector* frame_types) override; - void SetRates(const RateControlParameters& parameters) override; + int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation, + uint32_t framerate) override; EncoderInfo GetEncoderInfo() const override; private: @@ -121,8 +122,10 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder { int32_t number_of_cores_; size_t max_payload_size_; - // The last rate control settings, if set. - absl::optional rate_control_parameters_; + // The last bitrate/framerate set, and a flag for noting they are set. + bool rates_set_; + VideoBitrateAllocation bitrate_allocation_; + uint32_t framerate_; // The last channel parameters set, and a flag for noting they are set. bool channel_parameters_set_; @@ -144,6 +147,8 @@ VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper( std::unique_ptr hw_encoder) : number_of_cores_(0), max_payload_size_(0), + rates_set_(false), + framerate_(0), channel_parameters_set_(false), packet_loss_(0), rtt_(0), @@ -176,8 +181,8 @@ bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() { // Replay callback, rates, and channel parameters. if (callback_) fallback_encoder_->RegisterEncodeCompleteCallback(callback_); - if (rate_control_parameters_) - fallback_encoder_->SetRates(*rate_control_parameters_); + if (rates_set_) + fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate_); // 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 @@ -196,7 +201,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( number_of_cores_ = number_of_cores; max_payload_size_ = max_payload_size; // Clear stored rate/channel parameters. - rate_control_parameters_ = absl::nullopt; + rates_set_ = false; ValidateSettingsForForcedFallback(); // Try to reinit forced software codec if it is in use. @@ -259,12 +264,16 @@ int32_t VideoEncoderSoftwareFallbackWrapper::Encode( return ret; } -void VideoEncoderSoftwareFallbackWrapper::SetRates( - const RateControlParameters& parameters) { - rate_control_parameters_ = parameters; - encoder_->SetRates(parameters); +int32_t VideoEncoderSoftwareFallbackWrapper::SetRateAllocation( + const VideoBitrateAllocation& bitrate_allocation, + uint32_t framerate) { + rates_set_ = true; + bitrate_allocation_ = bitrate_allocation; + framerate_ = framerate; + int32_t ret = encoder_->SetRateAllocation(bitrate_allocation_, framerate); if (use_fallback_encoder_) - fallback_encoder_->SetRates(parameters); + return fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate); + return ret; } VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo() diff --git a/call/call_perf_tests.cc b/call/call_perf_tests.cc index 4a686edfaa..f3955c90bf 100644 --- a/call/call_perf_tests.cc +++ b/call/call_perf_tests.cc @@ -774,13 +774,14 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); } - void SetRates(const RateControlParameters& parameters) override { - last_set_bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); + int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation, + uint32_t framerate) override { + last_set_bitrate_kbps_ = rate_allocation.get_sum_kbps(); if (encoder_inits_ == 1 && - parameters.bitrate.get_sum_kbps() > kReconfigureThresholdKbps) { + rate_allocation.get_sum_kbps() > kReconfigureThresholdKbps) { time_to_reconfigure_.Set(); } - FakeEncoder::SetRates(parameters); + return FakeEncoder::SetRateAllocation(rate_allocation, framerate); } void ModifySenderBitrateConfig( diff --git a/media/engine/encoder_simulcast_proxy.cc b/media/engine/encoder_simulcast_proxy.cc index f2c87ffb21..8c2f82514b 100644 --- a/media/engine/encoder_simulcast_proxy.cc +++ b/media/engine/encoder_simulcast_proxy.cc @@ -55,8 +55,10 @@ int EncoderSimulcastProxy::RegisterEncodeCompleteCallback( return encoder_->RegisterEncodeCompleteCallback(callback); } -void EncoderSimulcastProxy::SetRates(const RateControlParameters& parameters) { - return encoder_->SetRates(parameters); +int EncoderSimulcastProxy::SetRateAllocation( + const VideoBitrateAllocation& bitrate, + uint32_t new_framerate) { + return encoder_->SetRateAllocation(bitrate, new_framerate); } void EncoderSimulcastProxy::OnPacketLossRateUpdate(float packet_loss_rate) { diff --git a/media/engine/encoder_simulcast_proxy.h b/media/engine/encoder_simulcast_proxy.h index 41ffcba162..1251e58f29 100644 --- a/media/engine/encoder_simulcast_proxy.h +++ b/media/engine/encoder_simulcast_proxy.h @@ -48,7 +48,8 @@ class RTC_EXPORT EncoderSimulcastProxy : public VideoEncoder { int Encode(const VideoFrame& input_image, const std::vector* frame_types) 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 OnRttUpdate(int64_t rtt_ms) override; void OnLossNotification(const LossNotification& loss_notification) override; diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc index 5d657fef45..d4de300e0d 100644 --- a/media/engine/fake_webrtc_video_engine.cc +++ b/media/engine/fake_webrtc_video_engine.cc @@ -166,7 +166,10 @@ int32_t FakeWebRtcVideoEncoder::Release() { 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() diff --git a/media/engine/fake_webrtc_video_engine.h b/media/engine/fake_webrtc_video_engine.h index 662caf1fc9..3265274efd 100644 --- a/media/engine/fake_webrtc_video_engine.h +++ b/media/engine/fake_webrtc_video_engine.h @@ -93,7 +93,8 @@ class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder { int32_t RegisterEncodeCompleteCallback( webrtc::EncodedImageCallback* callback) 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; bool WaitForInitEncode(); diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index 1147d45be8..09b05456c3 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -28,7 +28,6 @@ #include "rtc_base/atomic_ops.h" #include "rtc_base/checks.h" #include "rtc_base/experiments/rate_control_settings.h" -#include "rtc_base/logging.h" #include "system_wrappers/include/field_trial.h" #include "third_party/libyuv/include/libyuv/scale.h" @@ -444,54 +443,41 @@ int SimulcastEncoderAdapter::RegisterEncodeCompleteCallback( return WEBRTC_VIDEO_CODEC_OK; } -void SimulcastEncoderAdapter::SetRates( - const RateControlParameters& parameters) { +int SimulcastEncoderAdapter::SetRateAllocation( + const VideoBitrateAllocation& bitrate, + uint32_t new_framerate) { RTC_DCHECK_RUN_ON(&encoder_queue_); if (!Initialized()) { - RTC_LOG(LS_WARNING) << "SetRates while not initialized"; - return; + return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } - if (parameters.framerate_fps < 1.0) { - RTC_LOG(LS_WARNING) << "Invalid framerate: " << parameters.framerate_fps; - return; + if (new_framerate < 1) { + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } - if (codec_.maxBitrate > 0 && - parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) { - RTC_LOG(LS_WARNING) << "Total bitrate " << parameters.bitrate.get_sum_kbps() - << " exceeds max bitrate: " << codec_.maxBitrate; - return; + if (codec_.maxBitrate > 0 && bitrate.get_sum_kbps() > codec_.maxBitrate) { + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } - 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 // value that means paused, though, so leave it alone. - if (parameters.bitrate.get_sum_kbps() < codec_.minBitrate) { - RTC_LOG(LS_WARNING) << "Total bitrate " - << parameters.bitrate.get_sum_kbps() - << " is lower than minimum bitrate: " - << codec_.minBitrate; - return; + if (bitrate.get_sum_kbps() < codec_.minBitrate) { + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } if (codec_.numberOfSimulcastStreams > 0 && - parameters.bitrate.get_sum_kbps() < - codec_.simulcastStream[0].minBitrate) { - RTC_LOG(LS_WARNING) << "Total bitrate " - << parameters.bitrate.get_sum_kbps() - << " is lower than minimum bitrate of base layer: " - << codec_.simulcastStream[0].minBitrate; - return; + bitrate.get_sum_kbps() < codec_.simulcastStream[0].minBitrate) { + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } } - codec_.maxFramerate = static_cast(parameters.framerate_fps + 0.5); + codec_.maxFramerate = new_framerate; for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) { 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. 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 // the encoder handling the current simulcast stream. - RateControlParameters stream_parameters = parameters; - stream_parameters.bitrate = VideoBitrateAllocation(); + VideoBitrateAllocation stream_allocation; for (int i = 0; i < kMaxTemporalStreams; ++i) { - if (parameters.bitrate.HasBitrate(stream_idx, i)) { - stream_parameters.bitrate.SetBitrate( - 0, i, parameters.bitrate.GetBitrate(stream_idx, i)); + if (bitrate.HasBitrate(stream_idx, i)) { + stream_allocation.SetBitrate(0, i, bitrate.GetBitrate(stream_idx, i)); } } - - // Assign link allocation proportionally to spatial layer allocation. - if (parameters.bandwidth_allocation != DataRate::Zero()) { - stream_parameters.bandwidth_allocation = - DataRate::bps((parameters.bandwidth_allocation.bps() * - stream_parameters.bitrate.get_sum_bps()) / - parameters.bitrate.get_sum_bps()); - // Make sure we don't allocate bandwidth lower than target bitrate. - if (stream_parameters.bandwidth_allocation.bps() < - stream_parameters.bitrate.get_sum_bps()) { - stream_parameters.bandwidth_allocation = - DataRate::bps(stream_parameters.bitrate.get_sum_bps()); - } - } - - streaminfos_[stream_idx].encoder->SetRates(stream_parameters); + streaminfos_[stream_idx].encoder->SetRateAllocation(stream_allocation, + new_framerate); } + + return WEBRTC_VIDEO_CODEC_OK; } // TODO(brandtr): Add task checker to this member function, when all encoder diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h index 5bc0bec994..a7b0361d56 100644 --- a/media/engine/simulcast_encoder_adapter.h +++ b/media/engine/simulcast_encoder_adapter.h @@ -48,7 +48,8 @@ class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder { int Encode(const VideoFrame& input_image, const std::vector* frame_types) 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 // called from an internal helper that also knows the correct stream diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc index 1bab49af8a..8d68fa1fe0 100644 --- a/media/engine/simulcast_encoder_adapter_unittest.cc +++ b/media/engine/simulcast_encoder_adapter_unittest.cc @@ -207,8 +207,10 @@ class MockVideoEncoder : public VideoEncoder { MOCK_METHOD0(Release, int32_t()); - void SetRates(const RateControlParameters& parameters) { - last_set_rates_ = parameters; + int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation, + uint32_t framerate) { + last_set_bitrate_ = bitrate_allocation; + return 0; } EncoderInfo GetEncoderInfo() const override { @@ -269,7 +271,7 @@ class MockVideoEncoder : public VideoEncoder { fps_allocation_ = fps_allocation; } - RateControlParameters last_set_rates() const { return last_set_rates_; } + VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; } private: MockVideoEncoderFactory* const factory_; @@ -280,7 +282,7 @@ class MockVideoEncoder : public VideoEncoder { bool is_hardware_accelerated_ = false; bool has_internal_source_ = false; int32_t init_encode_return_value_ = 0; - VideoEncoder::RateControlParameters last_set_rates_; + VideoBitrateAllocation last_set_bitrate_; FramerateFractions fps_allocation_; VideoCodec codec_; @@ -498,8 +500,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) { SetupCodec(); // Set bitrates so that we send all layers. - adapter_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(1200, 30), 30.0)); + adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30); // 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 @@ -559,8 +560,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { // Encode with three streams. EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); VerifyCodecSettings(); - adapter_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); + adapter_->SetRateAllocation( + rate_allocator_->GetAllocation(target_bitrate, 30), 30); std::vector original_encoders = helper_->factory()->encoders(); @@ -586,8 +587,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { codec_.height /= 2; codec_.numberOfSimulcastStreams = 2; EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); - adapter_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); + adapter_->SetRateAllocation( + rate_allocator_->GetAllocation(target_bitrate, 30), 30); std::vector new_encoders = helper_->factory()->encoders(); ASSERT_EQ(2u, new_encoders.size()); ASSERT_EQ(original_encoders[0], new_encoders[0]); @@ -609,8 +610,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { codec_.height /= 2; codec_.numberOfSimulcastStreams = 1; EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); - adapter_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); + adapter_->SetRateAllocation( + rate_allocator_->GetAllocation(target_bitrate, 30), 30); new_encoders = helper_->factory()->encoders(); ASSERT_EQ(1u, new_encoders.size()); ASSERT_EQ(original_encoders[0], new_encoders[0]); @@ -627,8 +628,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { codec_.height *= 4; codec_.numberOfSimulcastStreams = 3; EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); - adapter_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); + adapter_->SetRateAllocation( + rate_allocator_->GetAllocation(target_bitrate, 30), 30); new_encoders = helper_->factory()->encoders(); ASSERT_EQ(3u, new_encoders.size()); // The first encoder is reused. @@ -711,8 +712,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) { // discontinuities. TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) { SetupCodec(); - adapter_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(1200, 30), 30.0)); + adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30); VerifyCodecSettings(); // Send frames on all streams. @@ -736,8 +736,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) { // Reinitialize. EXPECT_EQ(0, adapter_->Release()); EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); - adapter_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(1200, 30), 30.0)); + adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30); // Verify that the same encoder sends out frames on the same simulcast index. encoders[0]->SendEncodedImage(1152, 704); @@ -781,23 +780,21 @@ TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) { // Above min should be respected. VideoBitrateAllocation target_bitrate = rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30); - adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0)); + adapter_->SetRateAllocation(target_bitrate, 30); 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. VideoBitrateAllocation too_low_bitrate = rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30); - adapter_->SetRates( - VideoEncoder::RateControlParameters(too_low_bitrate, 30.0)); + adapter_->SetRateAllocation(too_low_bitrate, 30); 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". - adapter_->SetRates( - VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0)); + adapter_->SetRateAllocation(VideoBitrateAllocation(), 30); EXPECT_EQ(VideoBitrateAllocation(), - helper_->factory()->encoders()[0]->last_set_rates().bitrate); + helper_->factory()->encoders()[0]->last_set_bitrate()); } TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) { @@ -1160,45 +1157,5 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) { ::testing::ElementsAreArray(expected_fps_allocation)); } -TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) { - SimulcastTestFixtureImpl::DefaultSettings( - &codec_, static_cast(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 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(codec_.numberOfSimulcastStreams) - 1 - ? codec_.simulcastStream[i].targetBitrate - : codec_.simulcastStream[i].minBitrate) * - 1000; - EXPECT_EQ(layer_bitrate_bps, - encoders[i]->last_set_rates().bitrate.get_sum_bps()) - << i; - EXPECT_EQ( - (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(), - encoders[i]->last_set_rates().bandwidth_allocation.bps()) - << i; - } -} - } // namespace test } // namespace webrtc diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc index 495c11ab7f..9d96100def 100644 --- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc +++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc @@ -306,8 +306,7 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst, SimulcastRateAllocator init_allocator(codec_); VideoBitrateAllocation allocation = init_allocator.GetAllocation( codec_.startBitrate * 1000, codec_.maxFramerate); - SetRates(RateControlParameters(allocation, codec_.maxFramerate)); - return WEBRTC_VIDEO_CODEC_OK; + return SetRateAllocation(allocation, codec_.maxFramerate); } int32_t H264EncoderImpl::Release() { @@ -332,40 +331,36 @@ int32_t H264EncoderImpl::RegisterEncodeCompleteCallback( return WEBRTC_VIDEO_CODEC_OK; } -void H264EncoderImpl::SetRates(const RateControlParameters& parameters) { - if (encoders_.empty()) { - RTC_LOG(LS_WARNING) << "SetRates() while uninitialized."; - return; - } +int32_t H264EncoderImpl::SetRateAllocation( + const VideoBitrateAllocation& bitrate, + uint32_t new_framerate) { + if (encoders_.empty()) + return WEBRTC_VIDEO_CODEC_UNINITIALIZED; - if (parameters.framerate_fps < 1.0) { - RTC_LOG(LS_WARNING) << "Invalid frame rate: " << parameters.framerate_fps; - return; - } + if (new_framerate < 1) + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; - if (parameters.bitrate.get_sum_bps() == 0) { + if (bitrate.get_sum_bps() == 0) { // Encoder paused, turn off all encoding. for (size_t i = 0; i < configurations_.size(); ++i) configurations_[i].SetStreamState(false); - return; + return WEBRTC_VIDEO_CODEC_OK; } // At this point, bitrate allocation should already match codec settings. if (codec_.maxBitrate > 0) - RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate); - RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate); + RTC_DCHECK_LE(bitrate.get_sum_kbps(), codec_.maxBitrate); + RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate); if (codec_.numberOfSimulcastStreams > 0) - RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), - codec_.simulcastStream[0].minBitrate); + RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate); - codec_.maxFramerate = static_cast(parameters.framerate_fps); + codec_.maxFramerate = new_framerate; size_t stream_idx = encoders_.size() - 1; for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { // Update layer config. - configurations_[i].target_bps = - parameters.bitrate.GetSpatialLayerSum(stream_idx); - configurations_[i].max_frame_rate = parameters.framerate_fps; + configurations_[i].target_bps = bitrate.GetSpatialLayerSum(stream_idx); + configurations_[i].max_frame_rate = static_cast(new_framerate); if (configurations_[i].target_bps) { configurations_[i].SetStreamState(true); @@ -382,6 +377,8 @@ void H264EncoderImpl::SetRates(const RateControlParameters& parameters) { configurations_[i].SetStreamState(false); } } + + return WEBRTC_VIDEO_CODEC_OK; } int32_t H264EncoderImpl::Encode( diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.h b/modules/video_coding/codecs/h264/h264_encoder_impl.h index 74592efceb..d0cde34c65 100644 --- a/modules/video_coding/codecs/h264/h264_encoder_impl.h +++ b/modules/video_coding/codecs/h264/h264_encoder_impl.h @@ -61,7 +61,8 @@ class H264EncoderImpl : public H264Encoder { int32_t RegisterEncodeCompleteCallback( 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 // passed to the encode complete callback. diff --git a/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h b/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h index bb00b542e1..de010c914e 100644 --- a/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h +++ b/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h @@ -45,7 +45,8 @@ class MultiplexEncoderAdapter : public VideoEncoder { int Encode(const VideoFrame& input_image, const std::vector* frame_types) 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; EncoderInfo GetEncoderInfo() const override; diff --git a/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc b/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc index 8c866995f4..16bcd51345 100644 --- a/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc +++ b/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc @@ -216,21 +216,23 @@ int MultiplexEncoderAdapter::RegisterEncodeCompleteCallback( return WEBRTC_VIDEO_CODEC_OK; } -void MultiplexEncoderAdapter::SetRates( - const RateControlParameters& parameters) { - VideoBitrateAllocation bitrate_allocation(parameters.bitrate); +int MultiplexEncoderAdapter::SetRateAllocation( + const VideoBitrateAllocation& bitrate, + uint32_t framerate) { + VideoBitrateAllocation bitrate_allocation(bitrate); 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_) { // TODO(emircan): |framerate| is used to calculate duration in encoder // instances. We report the total frame rate to keep real time for now. // Remove this after refactoring duration logic. - encoder->SetRates(RateControlParameters( + const int rv = encoder->SetRateAllocation( bitrate_allocation, - static_cast(encoders_.size() * parameters.framerate_fps), - parameters.bandwidth_allocation - - DataRate::bps(augmenting_data_size_))); + static_cast(encoders_.size()) * framerate); + if (rv) + return rv; } + return WEBRTC_VIDEO_CODEC_OK; } int MultiplexEncoderAdapter::Release() { diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc index 8d6d3ad1ec..708f6fe1ab 100644 --- a/modules/video_coding/codecs/test/videoprocessor.cc +++ b/modules/video_coding/codecs/test/videoprocessor.cc @@ -300,8 +300,10 @@ void VideoProcessor::SetRates(size_t bitrate_kbps, size_t framerate_fps) { framerate_fps_ = static_cast(framerate_fps); bitrate_allocation_ = bitrate_allocator_->GetAllocation( static_cast(bitrate_kbps * 1000), framerate_fps_); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation_, static_cast(framerate_fps_))); + const int set_rates_result = + encoder_->SetRateAllocation(bitrate_allocation_, framerate_fps_); + RTC_DCHECK_GE(set_rates_result, 0) + << "Failed to update encoder with new rate " << bitrate_kbps << "."; } int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded( diff --git a/modules/video_coding/codecs/test/videoprocessor_unittest.cc b/modules/video_coding/codecs/test/videoprocessor_unittest.cc index de1d798f1c..842ad7e97d 100644 --- a/modules/video_coding/codecs/test/videoprocessor_unittest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_unittest.cc @@ -25,10 +25,7 @@ #include "test/testsupport/mock/mock_frame_reader.h" using ::testing::_; -using ::testing::AllOf; -using ::testing::Field; using ::testing::Property; -using ::testing::ResultOf; using ::testing::Return; namespace webrtc { @@ -99,11 +96,9 @@ TEST_F(VideoProcessorTest, InitRelease) { TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) { const int kBitrateKbps = 456; const int kFramerateFps = 31; - EXPECT_CALL( - encoder_mock_, - SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, - static_cast(kFramerateFps)))) - .Times(1); + EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kFramerateFps)) + .Times(1) + .WillOnce(Return(0)); q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); }); EXPECT_CALL(frame_reader_mock_, ReadFrame()) @@ -127,11 +122,9 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) { const int kBitrateKbps = 456; const int kStartFramerateFps = 27; const int kStartTimestamp = 90000 / kStartFramerateFps; - EXPECT_CALL( - encoder_mock_, - SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, - static_cast(kStartFramerateFps)))) - .Times(1); + EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kStartFramerateFps)) + .Times(1) + .WillOnce(Return(0)); q_.SendTask( [=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); }); @@ -143,11 +136,9 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) { q_.SendTask([this] { video_processor_->ProcessFrame(); }); const int kNewFramerateFps = 13; - EXPECT_CALL( - encoder_mock_, - SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, - static_cast(kNewFramerateFps)))) - .Times(1); + EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kNewFramerateFps)) + .Times(1) + .WillOnce(Return(0)); q_.SendTask( [=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); }); @@ -162,32 +153,21 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) { } TEST_F(VideoProcessorTest, SetRates) { - const uint32_t kBitrateKbps = 123; + const int kBitrateKbps = 123; const int kFramerateFps = 17; - - EXPECT_CALL( - encoder_mock_, - SetRates(AllOf(ResultOf( - [](const VideoEncoder::RateControlParameters& params) { - return params.bitrate.get_sum_kbps(); - }, - kBitrateKbps), - Field(&VideoEncoder::RateControlParameters::framerate_fps, - static_cast(kFramerateFps))))) + EXPECT_CALL(encoder_mock_, + SetRateAllocation( + Property(&VideoBitrateAllocation::get_sum_kbps, kBitrateKbps), + kFramerateFps)) .Times(1); q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); }); - const uint32_t kNewBitrateKbps = 456; + const int kNewBitrateKbps = 456; const int kNewFramerateFps = 34; - EXPECT_CALL( - encoder_mock_, - SetRates(AllOf(ResultOf( - [](const VideoEncoder::RateControlParameters& params) { - return params.bitrate.get_sum_kbps(); - }, - kNewBitrateKbps), - Field(&VideoEncoder::RateControlParameters::framerate_fps, - static_cast(kNewFramerateFps))))) + EXPECT_CALL(encoder_mock_, + SetRateAllocation(Property(&VideoBitrateAllocation::get_sum_kbps, + kNewBitrateKbps), + kNewFramerateFps)) .Times(1); q_.SendTask( [=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); }); diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index 9329f22452..e2d4089534 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -36,7 +36,6 @@ #include "rtc_base/checks.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_units.h" -#include "rtc_base/logging.h" #include "rtc_base/trace_event.h" #include "system_wrappers/include/field_trial.h" #include "third_party/libyuv/include/libyuv/scale.h" @@ -248,40 +247,33 @@ int LibvpxVp8Encoder::Release() { return ret_val; } -void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) { - if (!inited_) { - RTC_LOG(LS_WARNING) << "SetRates() while not initialize"; - return; - } +int LibvpxVp8Encoder::SetRateAllocation(const VideoBitrateAllocation& bitrate, + uint32_t new_framerate) { + if (!inited_) + return WEBRTC_VIDEO_CODEC_UNINITIALIZED; - if (encoders_[0].err) { - RTC_LOG(LS_WARNING) << "Encoder in error state."; - return; - } + if (encoders_[0].err) + return WEBRTC_VIDEO_CODEC_ERROR; - if (parameters.framerate_fps < 1.0) { - RTC_LOG(LS_WARNING) << "Unsupported framerate (must be >= 1.0): " - << parameters.framerate_fps; - return; - } + if (new_framerate < 1) + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; - if (parameters.bitrate.get_sum_bps() == 0) { + if (bitrate.get_sum_bps() == 0) { // Encoder paused, turn off all encoding. const int num_streams = static_cast(encoders_.size()); for (int i = 0; i < num_streams; ++i) SetStreamState(false, i); - return; + return WEBRTC_VIDEO_CODEC_OK; } // At this point, bitrate allocation should already match codec settings. if (codec_.maxBitrate > 0) - RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate); - RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate); + RTC_DCHECK_LE(bitrate.get_sum_kbps(), codec_.maxBitrate); + RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate); if (codec_.numberOfSimulcastStreams > 0) - RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), - codec_.simulcastStream[0].minBitrate); + RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate); - codec_.maxFramerate = static_cast(parameters.framerate_fps + 0.5); + codec_.maxFramerate = new_framerate; if (encoders_.size() > 1) { // 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). // We may want to condition this on bitrate later. if (rate_control_settings_.Vp8BoostBaseLayerQuality() && - parameters.framerate_fps > 20.0) { + new_framerate > 20) { configurations_[encoders_.size() - 1].rc_max_quantizer = 45; } else { // 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; for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { unsigned int target_bitrate_kbps = - parameters.bitrate.GetSpatialLayerSum(stream_idx) / 1000; + bitrate.GetSpatialLayerSum(stream_idx) / 1000; bool send_stream = target_bitrate_kbps > 0; if (send_stream || encoders_.size() > 1) @@ -310,19 +302,18 @@ void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) { configurations_[i].rc_target_bitrate = target_bitrate_kbps; if (send_stream) { frame_buffer_controller_->OnRatesUpdated( - stream_idx, parameters.bitrate.GetTemporalLayerAllocation(stream_idx), - static_cast(parameters.framerate_fps + 0.5)); + stream_idx, bitrate.GetTemporalLayerAllocation(stream_idx), + new_framerate); } UpdateVpxConfiguration(stream_idx, frame_buffer_controller_.get(), &configurations_[i]); - vpx_codec_err_t err = - libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i]); - if (err != VPX_CODEC_OK) { - RTC_LOG(LS_WARNING) << "Error configuring codec, error code: " << err; + if (libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i])) { + return WEBRTC_VIDEO_CODEC_ERROR; } } + return WEBRTC_VIDEO_CODEC_OK; } void LibvpxVp8Encoder::OnPacketLossRateUpdate(float packet_loss_rate) { diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h index 0913f5bf48..535f032d76 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h @@ -54,7 +54,8 @@ class LibvpxVp8Encoder : public VideoEncoder { 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; diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc index a5381c3c5c..a9248bda63 100644 --- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc +++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc @@ -110,23 +110,20 @@ class TestVp8Impl : public VideoCodecUnitTest { } }; -TEST_F(TestVp8Impl, SetRates) { - auto* const vpx = new NiceMock(); - LibvpxVp8Encoder encoder((std::unique_ptr(vpx))); - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings_, 1, 1000)); +TEST_F(TestVp8Impl, SetRateAllocation) { + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); - const uint32_t kBitrateBps = 300000; + const int kBitrateBps = 300000; VideoBitrateAllocation bitrate_allocation; bitrate_allocation.SetBitrate(0, 0, kBitrateBps); - EXPECT_CALL(*vpx, codec_enc_config_set(_, _)) - .WillOnce( - Invoke([&](vpx_codec_ctx_t* ctx, const vpx_codec_enc_cfg_t* cfg) { - EXPECT_EQ(cfg->rc_target_bitrate, kBitrateBps / 1000); - return VPX_CODEC_OK; - })); - encoder.SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, static_cast(codec_settings_.maxFramerate))); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); } TEST_F(TestVp8Impl, EncodeFrameAndRelease) { @@ -444,8 +441,7 @@ TEST_F(TestVp8Impl, DontDropKeyframes) { VideoBitrateAllocation bitrate_allocation; // Bitrate only enough for TL0. bitrate_allocation.SetBitrate(0, 0, 200000); - encoder_->SetRates( - VideoEncoder::RateControlParameters(bitrate_allocation, 5.0)); + encoder_->SetRateAllocation(bitrate_allocation, 5); EncodedImage encoded_frame; CodecSpecificInfo codec_specific_info; diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc index 3db7c939bc..87f991da48 100644 --- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc +++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc @@ -375,8 +375,9 @@ TEST_F(TestVp9Impl, EnableDisableSpatialLayers) { bitrate_allocation.SetBitrate( sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000 * 2); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) { SetWaitForEncodedFramesThreshold(sl_idx + 1); @@ -393,8 +394,9 @@ TEST_F(TestVp9Impl, EnableDisableSpatialLayers) { for (size_t i = 0; i < num_spatial_layers - 1; ++i) { const size_t sl_idx = num_spatial_layers - i - 1; bitrate_allocation.SetBitrate(sl_idx, 0, 0); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) { SetWaitForEncodedFramesThreshold(sl_idx); @@ -424,8 +426,9 @@ TEST_F(TestVp9Impl, EndOfPicture) { 0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000); bitrate_allocation.SetBitrate( 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); SetWaitForEncodedFramesThreshold(2); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*NextInputFrame(), nullptr)); @@ -439,8 +442,9 @@ TEST_F(TestVp9Impl, EndOfPicture) { // Encode only base layer. Check that end-of-superframe flag is // set on base layer frame. bitrate_allocation.SetBitrate(1, 0, 0); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, 0 /* max payload size (unused) */)); @@ -475,8 +479,9 @@ TEST_F(TestVp9Impl, InterLayerPred) { encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, 0 /* max payload size (unused) */)); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); SetWaitForEncodedFramesThreshold(2); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, @@ -545,8 +550,9 @@ TEST_F(TestVp9Impl, bitrate_allocation.SetBitrate( sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) { @@ -604,8 +610,9 @@ TEST_F(TestVp9Impl, bitrate_allocation.SetBitrate( sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) { @@ -661,8 +668,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) { 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); bitrate_allocation.SetBitrate( 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); std::vector encoded_frame; std::vector codec_specific_info; @@ -679,8 +687,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) { // Disable SL1 layer. bitrate_allocation.SetBitrate(1, 0, 0); bitrate_allocation.SetBitrate(1, 1, 0); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Encode 1 frame. SetWaitForEncodedFramesThreshold(1); @@ -697,8 +706,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) { 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); bitrate_allocation.SetBitrate( 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Encode 1 frame. SetWaitForEncodedFramesThreshold(2); @@ -736,8 +746,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) { 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); bitrate_allocation.SetBitrate( 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); std::vector encoded_frame; std::vector codec_specific_info; @@ -754,8 +765,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) { // Disable SL1 layer. bitrate_allocation.SetBitrate(1, 0, 0); bitrate_allocation.SetBitrate(1, 1, 0); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Encode 11 frames. More than Gof length 2, and odd to end at TL1 frame. for (int i = 0; i < 11; ++i) { @@ -775,8 +787,9 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) { 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); bitrate_allocation.SetBitrate( 1, 1, codec_settings_.spatialLayers[1].targetBitrate * 1000 / 2); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Encode 1 frame. SetWaitForEncodedFramesThreshold(2); @@ -822,8 +835,9 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) { bitrate_allocation.SetBitrate( sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); } - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Encode enough frames to force drop due to framerate capping. for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop; @@ -841,8 +855,9 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) { num_spatial_layers - 1, 0, codec_settings_.spatialLayers[num_spatial_layers - 1].targetBitrate * 1000); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); for (size_t frame_num = 0; frame_num < num_dropped_frames; ++frame_num) { SetWaitForEncodedFramesThreshold(1); @@ -898,8 +913,9 @@ TEST_F(TestVp9Impl, RemovingLayerIsNotDelayedInScreenshareAndAddsSsInfo) { bitrate_allocation.SetBitrate( sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); } - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Encode enough frames to force drop due to framerate capping. for (size_t frame_num = 0; frame_num < num_frames_to_encode_before_drop; @@ -928,8 +944,9 @@ TEST_F(TestVp9Impl, RemovingLayerIsNotDelayedInScreenshareAndAddsSsInfo) { // Disable the last layer. bitrate_allocation.SetBitrate(num_spatial_layers - 1, 0, 0); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Still expected to drop first layer. Last layer has to be disable also. for (size_t frame_num = num_dropped_frames - 2; @@ -985,8 +1002,9 @@ TEST_F(TestVp9Impl, DisableNewLayerInVideoDelaysSsInfoTillTL0) { num_temporal_layers); } } - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); std::vector encoded_frames; std::vector codec_specific_info; @@ -1002,8 +1020,9 @@ TEST_F(TestVp9Impl, DisableNewLayerInVideoDelaysSsInfoTillTL0) { for (size_t tl_idx = 0; tl_idx < num_temporal_layers; ++tl_idx) { bitrate_allocation.SetBitrate(num_spatial_layers - 1, tl_idx, 0); } - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); // Next is TL1 frame. The last layer is disabled immediately, but SS structure // is not provided here. @@ -1040,8 +1059,9 @@ TEST_F(TestVp9Impl, VideoBitrateAllocation bitrate_allocation; bitrate_allocation.SetBitrate( 0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*NextInputFrame(), nullptr)); EncodedImage encoded_frame; @@ -1309,8 +1329,9 @@ TEST_F(TestVp9ImplFrameDropping, DifferentFrameratePerSpatialLayer) { encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, 0 /* max payload size (unused) */)); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_settings_.maxFramerate)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, + codec_settings_.maxFramerate)); VideoFrame* input_frame = NextInputFrame(); 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 */, 0 /* max payload size (unused) */)); - encoder_->SetRates(VideoEncoder::RateControlParameters( - bitrate_allocation, codec_max_framerate_fps)); + EXPECT_EQ( + WEBRTC_VIDEO_CODEC_OK, + encoder_->SetRateAllocation(bitrate_allocation, codec_max_framerate_fps)); VideoFrame* input_frame = NextInputFrame(); for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) { diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc index b012d6bc09..a6c76437d3 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -309,33 +309,29 @@ bool VP9EncoderImpl::SetSvcRates( return true; } -void VP9EncoderImpl::SetRates(const RateControlParameters& parameters) { +int VP9EncoderImpl::SetRateAllocation( + const VideoBitrateAllocation& bitrate_allocation, + uint32_t frame_rate) { if (!inited_) { - RTC_LOG(LS_WARNING) << "SetRates() calll while uninitialzied."; - return; + return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } if (encoder_->err) { - RTC_LOG(LS_WARNING) << "Encoder in error state: " << encoder_->err; - return; + return WEBRTC_VIDEO_CODEC_ERROR; } - if (parameters.framerate_fps < 1.0) { - RTC_LOG(LS_WARNING) << "Unsupported framerate: " - << parameters.framerate_fps; - return; + if (frame_rate < 1) { + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } // Update bit rate if (codec_.maxBitrate > 0 && - parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) { - RTC_LOG(LS_WARNING) << "Target bitrate exceeds maximum: " - << parameters.bitrate.get_sum_kbps() << " vs " - << codec_.maxBitrate; - return; + bitrate_allocation.get_sum_kbps() > codec_.maxBitrate) { + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } - codec_.maxFramerate = static_cast(parameters.framerate_fps + 0.5); - requested_bitrate_allocation_ = parameters.bitrate; + codec_.maxFramerate = frame_rate; - return; + requested_bitrate_allocation_ = bitrate_allocation; + + return WEBRTC_VIDEO_CODEC_OK; } int VP9EncoderImpl::InitEncode(const VideoCodec* inst, diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h index 9fa4750bcc..3fc5398c53 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.h +++ b/modules/video_coding/codecs/vp9/vp9_impl.h @@ -48,7 +48,8 @@ class VP9EncoderImpl : public VP9Encoder { 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; diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc index 0646270261..b745fae1d9 100644 --- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc +++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc @@ -288,9 +288,8 @@ void SimulcastTestFixtureImpl::SetUpRateAllocator() { } void SimulcastTestFixtureImpl::SetRates(uint32_t bitrate_kbps, uint32_t fps) { - encoder_->SetRates(VideoEncoder::RateControlParameters( - rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), - static_cast(fps))); + encoder_->SetRateAllocation( + rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), fps); } void SimulcastTestFixtureImpl::RunActiveStreamsTest( diff --git a/sdk/android/src/jni/android_media_encoder.cc b/sdk/android/src/jni/android_media_encoder.cc index 863b4b2cbb..dbf2b31659 100644 --- a/sdk/android/src/jni/android_media_encoder.cc +++ b/sdk/android/src/jni/android_media_encoder.cc @@ -104,7 +104,8 @@ class MediaCodecVideoEncoder : public VideoEncoder { int32_t RegisterEncodeCompleteCallback( EncodedImageCallback* callback) 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; // 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; } -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_); - 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_) - return; - uint32_t frame_rate = static_cast(parameters.framerate_fps + 0.5); + return WEBRTC_VIDEO_CODEC_OK; frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? frame_rate : MAX_ALLOWED_VIDEO_FPS; if (last_set_bitrate_kbps_ == new_bit_rate && last_set_fps_ == frame_rate) { - return; + return WEBRTC_VIDEO_CODEC_OK; } JNIEnv* jni = AttachCurrentThreadIfNeeded(); ScopedLocalRefFrame local_ref_frame(jni); @@ -924,7 +926,10 @@ void MediaCodecVideoEncoder::SetRates(const RateControlParameters& parameters) { rtc::dchecked_cast(last_set_fps_)); if (CheckException(jni) || !ret) { ProcessHWError(true /* reset_if_fallback_unavailable */); + return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_OK + : WEBRTC_VIDEO_CODEC_ERROR; } + return WEBRTC_VIDEO_CODEC_OK; } VideoEncoder::EncoderInfo MediaCodecVideoEncoder::GetEncoderInfo() const { diff --git a/sdk/android/src/jni/video_encoder_wrapper.cc b/sdk/android/src/jni/video_encoder_wrapper.cc index 6238e94d49..960847fff0 100644 --- a/sdk/android/src/jni/video_encoder_wrapper.cc +++ b/sdk/android/src/jni/video_encoder_wrapper.cc @@ -146,15 +146,16 @@ int32_t VideoEncoderWrapper::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(); ScopedJavaLocalRef j_bitrate_allocation = - ToJavaBitrateAllocation(jni, parameters.bitrate); + ToJavaBitrateAllocation(jni, allocation); ScopedJavaLocalRef ret = Java_VideoEncoder_setRateAllocation( - jni, encoder_, j_bitrate_allocation, - (jint)(parameters.framerate_fps + 0.5)); - HandleReturnCode(jni, ret, "setRateAllocation"); + jni, encoder_, j_bitrate_allocation, (jint)framerate); + return HandleReturnCode(jni, ret, "setRateAllocation"); } VideoEncoder::EncoderInfo VideoEncoderWrapper::GetEncoderInfo() const { diff --git a/sdk/android/src/jni/video_encoder_wrapper.h b/sdk/android/src/jni/video_encoder_wrapper.h index c1404951d1..65940d66e2 100644 --- a/sdk/android/src/jni/video_encoder_wrapper.h +++ b/sdk/android/src/jni/video_encoder_wrapper.h @@ -44,7 +44,8 @@ class VideoEncoderWrapper : public VideoEncoder { int32_t Encode(const VideoFrame& frame, const std::vector* frame_types) override; - void SetRates(const RateControlParameters& parameters) override; + int32_t SetRateAllocation(const VideoBitrateAllocation& allocation, + uint32_t framerate) override; EncoderInfo GetEncoderInfo() const override; diff --git a/test/configurable_frame_size_encoder.cc b/test/configurable_frame_size_encoder.cc index ba529cba51..a0a42f0c14 100644 --- a/test/configurable_frame_size_encoder.cc +++ b/test/configurable_frame_size_encoder.cc @@ -74,8 +74,11 @@ int32_t ConfigurableFrameSizeEncoder::Release() { return WEBRTC_VIDEO_CODEC_OK; } -void ConfigurableFrameSizeEncoder::SetRates( - const RateControlParameters& parameters) {} +int32_t ConfigurableFrameSizeEncoder::SetRateAllocation( + const VideoBitrateAllocation& allocation, + uint32_t framerate) { + return WEBRTC_VIDEO_CODEC_OK; +} int32_t ConfigurableFrameSizeEncoder::SetFrameSize(size_t size) { RTC_DCHECK_LE(size, max_frame_size_); diff --git a/test/configurable_frame_size_encoder.h b/test/configurable_frame_size_encoder.h index ddf763f04e..9daf13ebcb 100644 --- a/test/configurable_frame_size_encoder.h +++ b/test/configurable_frame_size_encoder.h @@ -44,7 +44,8 @@ class ConfigurableFrameSizeEncoder : public VideoEncoder { 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); diff --git a/test/fake_encoder.cc b/test/fake_encoder.cc index 7c24b84705..ac59dfd23b 100644 --- a/test/fake_encoder.cc +++ b/test/fake_encoder.cc @@ -51,6 +51,7 @@ void WriteCounter(unsigned char* payload, uint32_t counter) { FakeEncoder::FakeEncoder(Clock* clock) : clock_(clock), callback_(nullptr), + configured_input_framerate_(-1), max_target_bitrate_kbps_(-1), pending_keyframe_(true), counter_(0), @@ -64,7 +65,7 @@ void FakeEncoder::SetMaxBitrate(int max_kbps) { RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. rtc::CritScope cs(&crit_sect_); max_target_bitrate_kbps_ = max_kbps; - SetRates(current_rate_settings_); + SetRateAllocation(target_bitrate_, configured_input_framerate_); } int32_t FakeEncoder::InitEncode(const VideoCodec* config, @@ -72,8 +73,8 @@ int32_t FakeEncoder::InitEncode(const VideoCodec* config, size_t max_payload_size) { rtc::CritScope cs(&crit_sect_); config_ = *config; - current_rate_settings_.bitrate.SetBitrate(0, 0, config_.startBitrate * 1000); - current_rate_settings_.framerate_fps = config_.maxFramerate; + target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000); + configured_input_framerate_ = config_.maxFramerate; pending_keyframe_ = true; last_frame_info_ = FrameInfo(); return 0; @@ -85,7 +86,8 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image, unsigned char num_simulcast_streams; SimulcastStream simulcast_streams[kMaxSimulcastStreams]; EncodedImageCallback* callback; - RateControlParameters rates; + VideoBitrateAllocation target_bitrate; + int framerate; VideoCodecMode mode; bool keyframe; uint32_t counter; @@ -97,10 +99,12 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image, simulcast_streams[i] = config_.simulcastStream[i]; } callback = callback_; - rates = current_rate_settings_; + target_bitrate = target_bitrate_; mode = config_.mode; - if (rates.framerate_fps <= 0.0) { - rates.framerate_fps = max_framerate; + if (configured_input_framerate_ > 0) { + framerate = configured_input_framerate_; + } else { + framerate = max_framerate; } keyframe = pending_keyframe_; pending_keyframe_ = false; @@ -108,8 +112,8 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image, } FrameInfo frame_info = - NextFrame(frame_types, keyframe, num_simulcast_streams, rates.bitrate, - simulcast_streams, static_cast(rates.framerate_fps + 0.5)); + NextFrame(frame_types, keyframe, num_simulcast_streams, target_bitrate, + simulcast_streams, framerate); for (uint8_t i = 0; i < frame_info.layers.size(); ++i) { constexpr int kMinPayLoadLength = 14; if (frame_info.layers[i].size < kMinPayLoadLength) { @@ -233,10 +237,12 @@ int32_t FakeEncoder::Release() { return 0; } -void FakeEncoder::SetRates(const RateControlParameters& parameters) { +int32_t FakeEncoder::SetRateAllocation( + const VideoBitrateAllocation& rate_allocation, + uint32_t framerate) { rtc::CritScope cs(&crit_sect_); - current_rate_settings_ = parameters; - int allocated_bitrate_kbps = parameters.bitrate.get_sum_kbps(); + target_bitrate_ = rate_allocation; + int allocated_bitrate_kbps = target_bitrate_.get_sum_kbps(); // Scale bitrate allocation to not exceed the given max target bitrate. if (max_target_bitrate_kbps_ > 0 && @@ -245,19 +251,20 @@ void FakeEncoder::SetRates(const RateControlParameters& parameters) { ++spatial_idx) { for (uint8_t temporal_idx = 0; temporal_idx < kMaxTemporalStreams; ++temporal_idx) { - if (current_rate_settings_.bitrate.HasBitrate(spatial_idx, - temporal_idx)) { - uint32_t bitrate = current_rate_settings_.bitrate.GetBitrate( - spatial_idx, temporal_idx); + if (target_bitrate_.HasBitrate(spatial_idx, temporal_idx)) { + uint32_t bitrate = + target_bitrate_.GetBitrate(spatial_idx, temporal_idx); bitrate = static_cast( (bitrate * int64_t{max_target_bitrate_kbps_}) / allocated_bitrate_kbps); - current_rate_settings_.bitrate.SetBitrate(spatial_idx, temporal_idx, - bitrate); + target_bitrate_.SetBitrate(spatial_idx, temporal_idx, bitrate); } } } } + + configured_input_framerate_ = framerate; + return 0; } const char* FakeEncoder::kImplementationName = "fake_encoder"; @@ -269,7 +276,7 @@ VideoEncoder::EncoderInfo FakeEncoder::GetEncoderInfo() const { int FakeEncoder::GetConfiguredInputFramerate() const { rtc::CritScope cs(&crit_sect_); - return static_cast(current_rate_settings_.framerate_fps + 0.5); + return configured_input_framerate_; } FakeH264Encoder::FakeH264Encoder(Clock* clock) diff --git a/test/fake_encoder.h b/test/fake_encoder.h index 7e1c1a1174..95b4b20ec4 100644 --- a/test/fake_encoder.h +++ b/test/fake_encoder.h @@ -48,7 +48,8 @@ class FakeEncoder : public VideoEncoder { int32_t RegisterEncodeCompleteCallback( EncodedImageCallback* callback) 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; EncoderInfo GetEncoderInfo() const override; @@ -88,7 +89,8 @@ class FakeEncoder : public VideoEncoder { VideoCodec config_ 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_); bool pending_keyframe_ RTC_GUARDED_BY(crit_sect_); uint32_t counter_ RTC_GUARDED_BY(crit_sect_); diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc index 272f80f7c9..39d5701774 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc @@ -63,9 +63,7 @@ QualityAnalyzingVideoEncoder::QualityAnalyzingVideoEncoder( bitrate_multiplier_(bitrate_multiplier), stream_required_spatial_index_(std::move(stream_required_spatial_index)), injector_(injector), - analyzer_(analyzer), - mode_(SimulcastMode::kNormal), - delegate_callback_(nullptr) {} + analyzer_(analyzer) {} QualityAnalyzingVideoEncoder::~QualityAnalyzingVideoEncoder() = default; int32_t QualityAnalyzingVideoEncoder::InitEncode( @@ -149,11 +147,17 @@ int32_t QualityAnalyzingVideoEncoder::Encode( return result; } -void QualityAnalyzingVideoEncoder::SetRates( - const VideoEncoder::RateControlParameters& parameters) { +int32_t QualityAnalyzingVideoEncoder::SetRates(uint32_t bitrate, + uint32_t framerate) { + return delegate_->SetRates(bitrate, framerate); +} + +int32_t QualityAnalyzingVideoEncoder::SetRateAllocation( + const VideoBitrateAllocation& allocation, + uint32_t framerate) { RTC_DCHECK_GT(bitrate_multiplier_, 0.0); if (fabs(bitrate_multiplier_ - kNoMultiplier) < kEps) { - return delegate_->SetRates(parameters); + return delegate_->SetRateAllocation(allocation, framerate); } // Simulating encoder overshooting target bitrate, by configuring actual @@ -162,7 +166,7 @@ void QualityAnalyzingVideoEncoder::SetRates( VideoBitrateAllocation multiplied_allocation; for (size_t si = 0; si < kMaxSpatialLayers; ++si) { const uint32_t spatial_layer_bitrate_bps = - parameters.bitrate.GetSpatialLayerSum(si); + allocation.GetSpatialLayerSum(si); if (spatial_layer_bitrate_bps == 0) { continue; } @@ -181,18 +185,16 @@ void QualityAnalyzingVideoEncoder::SetRates( } for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) { - if (parameters.bitrate.HasBitrate(si, ti)) { + if (allocation.HasBitrate(si, ti)) { multiplied_allocation.SetBitrate( si, ti, rtc::checked_cast(bitrate_multiplier * - parameters.bitrate.GetBitrate(si, ti))); + allocation.GetBitrate(si, ti))); } } } - RateControlParameters adjusted_params = parameters; - adjusted_params.bitrate = multiplied_allocation; - return delegate_->SetRates(adjusted_params); + return delegate_->SetRateAllocation(multiplied_allocation, framerate); } VideoEncoder::EncoderInfo QualityAnalyzingVideoEncoder::GetEncoderInfo() const { diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h index 4861d4c989..d7dd5d1da3 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h @@ -70,7 +70,9 @@ class QualityAnalyzingVideoEncoder : public VideoEncoder, int32_t Release() override; int32_t Encode(const VideoFrame& frame, const std::vector* 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; // Methods of EncodedImageCallback interface. diff --git a/test/video_encoder_proxy_factory.h b/test/video_encoder_proxy_factory.h index 49a4e2d4e7..55a01a1e0e 100644 --- a/test/video_encoder_proxy_factory.h +++ b/test/video_encoder_proxy_factory.h @@ -75,8 +75,9 @@ class VideoEncoderProxyFactory final : public VideoEncoderFactory { return encoder_->RegisterEncodeCompleteCallback(callback); } int32_t Release() override { return encoder_->Release(); } - void SetRates(const RateControlParameters& parameters) override { - encoder_->SetRates(parameters); + int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation, + uint32_t framerate) override { + return encoder_->SetRateAllocation(rate_allocation, framerate); } VideoEncoder::EncoderInfo GetEncoderInfo() const override { return encoder_->GetEncoderInfo(); diff --git a/video/end_to_end_tests/bandwidth_tests.cc b/video/end_to_end_tests/bandwidth_tests.cc index 163e84d4b4..3ee0e2b7ac 100644 --- a/video/end_to_end_tests/bandwidth_tests.cc +++ b/video/end_to_end_tests/bandwidth_tests.cc @@ -307,13 +307,15 @@ TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) { 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. - if (parameters.bitrate.get_sum_bps() == 0) - return; + if (rate_allocation.get_sum_bps() == 0) + return 0; rtc::CritScope lock(&crit_); - bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); + bitrate_kbps_ = rate_allocation.get_sum_kbps(); observation_complete_.Set(); + return 0; } void PerformTest() override { diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc index e6760ee70e..5aead68e18 100644 --- a/video/video_quality_test.cc +++ b/video/video_quality_test.cc @@ -149,11 +149,11 @@ class QualityTestVideoEncoder : public VideoEncoder, } 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); if (overshoot_factor_ == 1.0) { - encoder_->SetRates(parameters); - return; + return encoder_->SetRateAllocation(allocation, framerate); } // Simulating encoder overshooting target bitrate, by configuring actual @@ -162,7 +162,7 @@ class QualityTestVideoEncoder : public VideoEncoder, VideoBitrateAllocation overshot_allocation; for (size_t si = 0; si < kMaxSpatialLayers; ++si) { const uint32_t spatial_layer_bitrate_bps = - parameters.bitrate.GetSpatialLayerSum(si); + allocation.GetSpatialLayerSum(si); if (spatial_layer_bitrate_bps == 0) { continue; } @@ -181,18 +181,16 @@ class QualityTestVideoEncoder : public VideoEncoder, } for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) { - if (parameters.bitrate.HasBitrate(si, ti)) { + if (allocation.HasBitrate(si, ti)) { overshot_allocation.SetBitrate( si, ti, - rtc::checked_cast( - overshoot_factor * parameters.bitrate.GetBitrate(si, ti))); + rtc::checked_cast(overshoot_factor * + allocation.GetBitrate(si, ti))); } } } - return encoder_->SetRates( - RateControlParameters(overshot_allocation, parameters.framerate_fps, - parameters.bandwidth_allocation)); + return encoder_->SetRateAllocation(overshot_allocation, framerate); } EncoderInfo GetEncoderInfo() const override { EncoderInfo info = encoder_->GetEncoderInfo(); diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc index 23389973a2..0793843940 100644 --- a/video/video_send_stream_tests.cc +++ b/video/video_send_stream_tests.cc @@ -2045,11 +2045,11 @@ TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) { 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_); - start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); + start_bitrate_kbps_ = new_target_bitrate; start_bitrate_changed_.Set(); - FakeEncoder::SetRates(parameters); + return FakeEncoder::SetRates(new_target_bitrate, framerate); } int GetStartBitrateKbps() const { @@ -2118,11 +2118,12 @@ class StartStopBitrateObserver : public test::FakeEncoder { 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_); - bitrate_kbps_ = parameters.bitrate.get_sum_kbps(); + bitrate_kbps_ = bitrate.get_sum_kbps(); bitrate_changed_.Set(); - FakeEncoder::SetRates(parameters); + return FakeEncoder::SetRateAllocation(bitrate, framerate); } bool WaitForEncoderInit() { @@ -2853,17 +2854,17 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { maxPayloadSize); } - void SetRates(const RateControlParameters& parameters) override { + int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate, + uint32_t frameRate) override { { rtc::CritScope lock(&crit_); - if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) { - FakeEncoder::SetRates(parameters); - return; + if (target_bitrate_ == bitrate.get_sum_kbps()) { + return FakeEncoder::SetRateAllocation(bitrate, frameRate); } - target_bitrate_ = parameters.bitrate.get_sum_kbps(); + target_bitrate_ = bitrate.get_sum_kbps(); } bitrate_changed_event_.Set(); - FakeEncoder::SetRates(parameters); + return FakeEncoder::SetRateAllocation(bitrate, frameRate); } void WaitForSetRates(uint32_t expected_bitrate) { @@ -3652,15 +3653,16 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) { max_bitrate_bps_(0), first_packet_sent_(false) {} - void SetRates(const RateControlParameters& parameters) override { + int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate, + uint32_t frameRate) override { rtc::CritScope lock(&crit_); // Wait for the first sent packet so that videosendstream knows // rtp_overhead. if (first_packet_sent_) { - max_bitrate_bps_ = parameters.bitrate.get_sum_bps(); + max_bitrate_bps_ = bitrate.get_sum_bps(); bitrate_changed_event_.Set(); } - return FakeEncoder::SetRates(parameters); + return FakeEncoder::SetRateAllocation(bitrate, frameRate); } void OnCallsCreated(Call* sender_call, Call* receiver_call) override { diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc index 23480e7149..f9b23555ba 100644 --- a/video/video_stream_encoder_unittest.cc +++ b/video/video_stream_encoder_unittest.cc @@ -726,24 +726,24 @@ class VideoStreamEncoderTest : public ::testing::Test { return FakeEncoder::Release(); } - void SetRates(const RateControlParameters& parameters) { + int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation, + uint32_t framerate) { rtc::CritScope lock(&local_crit_sect_); VideoBitrateAllocation adjusted_rate_allocation; for (size_t si = 0; si < kMaxSpatialLayers; ++si) { for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) { - if (parameters.bitrate.HasBitrate(si, ti)) { + if (rate_allocation.HasBitrate(si, ti)) { adjusted_rate_allocation.SetBitrate( si, ti, - static_cast(parameters.bitrate.GetBitrate(si, ti) * + static_cast(rate_allocation.GetBitrate(si, ti) * rate_factor_)); } } } - last_framerate_ = static_cast(parameters.framerate_fps + 0.5); - last_bitrate_allocation_ = parameters.bitrate; - RateControlParameters adjusted_paramters = parameters; - adjusted_paramters.bitrate = adjusted_rate_allocation; - FakeEncoder::SetRates(adjusted_paramters); + last_framerate_ = framerate; + last_bitrate_allocation_ = rate_allocation; + return FakeEncoder::SetRateAllocation(adjusted_rate_allocation, + framerate); } rtc::CriticalSection local_crit_sect_;