Reland "Replace usage of old SetRates/SetRateAllocation methods"
This is a reland of 7ac0d5f348f0b956089c4ed65c46e65bac125508 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,perkj@webrtc.org Bug: webrtc:10481 Change-Id: I2978d5c527a18e885b7845c4e53a2424e8ad5b4b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132551 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27593}
This commit is contained in:
parent
70f80e5962
commit
16cb8f5d74
@ -48,6 +48,7 @@ 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));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -189,7 +189,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::SetRateAllocation(...).
|
// provided into VideoEncoder::SetRates(...).
|
||||||
double video_encoder_bitrate_multiplier = 1.0;
|
double video_encoder_bitrate_multiplier = 1.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -114,10 +114,8 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
|
|||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
uint32_t framerate) override {
|
|
||||||
++set_rates_count_;
|
++set_rates_count_;
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EncoderInfo GetEncoderInfo() const override {
|
EncoderInfo GetEncoderInfo() const override {
|
||||||
@ -205,9 +203,7 @@ 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));
|
||||||
EXPECT_EQ(
|
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
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_;
|
||||||
@ -226,9 +222,7 @@ 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);
|
||||||
EXPECT_EQ(
|
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
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_);
|
||||||
|
|
||||||
@ -302,7 +296,8 @@ 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_->SetRateAllocation(VideoBitrateAllocation(), 1);
|
fallback_wrapper_->SetRates(
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
@ -386,9 +381,8 @@ class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetRateAllocation(uint32_t bitrate_kbps) {
|
void SetRateAllocation(uint32_t bitrate_kbps) {
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->SetRateAllocation(
|
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(
|
rate_allocator_->GetAllocation(bitrate_kbps * 1000, kFramerate),
|
||||||
bitrate_kbps * 1000, kFramerate),
|
|
||||||
kFramerate));
|
kFramerate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,6 +101,13 @@ 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,
|
||||||
|
|||||||
@ -195,6 +195,8 @@ 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);
|
||||||
|
|||||||
@ -88,8 +88,7 @@ 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;
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t framerate) override;
|
|
||||||
EncoderInfo GetEncoderInfo() const override;
|
EncoderInfo GetEncoderInfo() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -122,10 +121,8 @@ 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 bitrate/framerate set, and a flag for noting they are set.
|
// The last rate control settings, if set.
|
||||||
bool rates_set_;
|
absl::optional<RateControlParameters> rate_control_parameters_;
|
||||||
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_;
|
||||||
@ -147,8 +144,6 @@ 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),
|
||||||
@ -181,8 +176,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 (rates_set_)
|
if (rate_control_parameters_)
|
||||||
fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate_);
|
fallback_encoder_->SetRates(*rate_control_parameters_);
|
||||||
|
|
||||||
// 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
|
||||||
@ -201,7 +196,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.
|
||||||
rates_set_ = false;
|
rate_control_parameters_ = absl::nullopt;
|
||||||
ValidateSettingsForForcedFallback();
|
ValidateSettingsForForcedFallback();
|
||||||
|
|
||||||
// Try to reinit forced software codec if it is in use.
|
// Try to reinit forced software codec if it is in use.
|
||||||
@ -264,16 +259,12 @@ int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t VideoEncoderSoftwareFallbackWrapper::SetRateAllocation(
|
void VideoEncoderSoftwareFallbackWrapper::SetRates(
|
||||||
const VideoBitrateAllocation& bitrate_allocation,
|
const RateControlParameters& parameters) {
|
||||||
uint32_t framerate) {
|
rate_control_parameters_ = parameters;
|
||||||
rates_set_ = true;
|
encoder_->SetRates(parameters);
|
||||||
bitrate_allocation_ = bitrate_allocation;
|
|
||||||
framerate_ = framerate;
|
|
||||||
int32_t ret = encoder_->SetRateAllocation(bitrate_allocation_, framerate);
|
|
||||||
if (use_fallback_encoder_)
|
if (use_fallback_encoder_)
|
||||||
return fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate);
|
fallback_encoder_->SetRates(parameters);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo()
|
VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo()
|
||||||
|
|||||||
@ -774,14 +774,13 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
uint32_t framerate) override {
|
last_set_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
|
||||||
last_set_bitrate_kbps_ = rate_allocation.get_sum_kbps();
|
|
||||||
if (encoder_inits_ == 1 &&
|
if (encoder_inits_ == 1 &&
|
||||||
rate_allocation.get_sum_kbps() > kReconfigureThresholdKbps) {
|
parameters.bitrate.get_sum_kbps() > kReconfigureThresholdKbps) {
|
||||||
time_to_reconfigure_.Set();
|
time_to_reconfigure_.Set();
|
||||||
}
|
}
|
||||||
return FakeEncoder::SetRateAllocation(rate_allocation, framerate);
|
FakeEncoder::SetRates(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModifySenderBitrateConfig(
|
void ModifySenderBitrateConfig(
|
||||||
|
|||||||
@ -55,10 +55,8 @@ int EncoderSimulcastProxy::RegisterEncodeCompleteCallback(
|
|||||||
return encoder_->RegisterEncodeCompleteCallback(callback);
|
return encoder_->RegisterEncodeCompleteCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EncoderSimulcastProxy::SetRateAllocation(
|
void EncoderSimulcastProxy::SetRates(const RateControlParameters& parameters) {
|
||||||
const VideoBitrateAllocation& bitrate,
|
return encoder_->SetRates(parameters);
|
||||||
uint32_t new_framerate) {
|
|
||||||
return encoder_->SetRateAllocation(bitrate, new_framerate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncoderSimulcastProxy::OnPacketLossRateUpdate(float packet_loss_rate) {
|
void EncoderSimulcastProxy::OnPacketLossRateUpdate(float packet_loss_rate) {
|
||||||
|
|||||||
@ -48,8 +48,7 @@ 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;
|
||||||
int SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
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;
|
||||||
|
|||||||
@ -165,10 +165,7 @@ int32_t FakeWebRtcVideoEncoder::Release() {
|
|||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeWebRtcVideoEncoder::SetRateAllocation(
|
void FakeWebRtcVideoEncoder::SetRates(const RateControlParameters& parameters) {
|
||||||
const webrtc::VideoBitrateAllocation& allocation,
|
|
||||||
uint32_t framerate) {
|
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo()
|
webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo()
|
||||||
|
|||||||
@ -92,8 +92,7 @@ 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;
|
||||||
int32_t SetRateAllocation(const webrtc::VideoBitrateAllocation& allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t framerate) override;
|
|
||||||
webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override;
|
webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override;
|
||||||
|
|
||||||
bool WaitForInitEncode();
|
bool WaitForInitEncode();
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#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"
|
||||||
|
|
||||||
@ -443,41 +444,54 @@ int SimulcastEncoderAdapter::RegisterEncodeCompleteCallback(
|
|||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SimulcastEncoderAdapter::SetRateAllocation(
|
void SimulcastEncoderAdapter::SetRates(
|
||||||
const VideoBitrateAllocation& bitrate,
|
const RateControlParameters& parameters) {
|
||||||
uint32_t new_framerate) {
|
|
||||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||||
|
|
||||||
if (!Initialized()) {
|
if (!Initialized()) {
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
RTC_LOG(LS_WARNING) << "SetRates while not initialized";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_framerate < 1) {
|
if (parameters.framerate_fps < 1.0) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
RTC_LOG(LS_WARNING) << "Invalid framerate: " << parameters.framerate_fps;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec_.maxBitrate > 0 && bitrate.get_sum_kbps() > codec_.maxBitrate) {
|
if (codec_.maxBitrate > 0 &&
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) {
|
||||||
|
RTC_LOG(LS_WARNING) << "Total bitrate " << parameters.bitrate.get_sum_kbps()
|
||||||
|
<< " exceeds max bitrate: " << codec_.maxBitrate;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitrate.get_sum_bps() > 0) {
|
if (parameters.bitrate.get_sum_bps() > 0) {
|
||||||
// Make sure the bitrate fits the configured min bitrates. 0 is a special
|
// 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 (bitrate.get_sum_kbps() < codec_.minBitrate) {
|
if (parameters.bitrate.get_sum_kbps() < codec_.minBitrate) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
RTC_LOG(LS_WARNING) << "Total bitrate "
|
||||||
|
<< parameters.bitrate.get_sum_kbps()
|
||||||
|
<< " is lower than minimum bitrate: "
|
||||||
|
<< codec_.minBitrate;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec_.numberOfSimulcastStreams > 0 &&
|
if (codec_.numberOfSimulcastStreams > 0 &&
|
||||||
bitrate.get_sum_kbps() < codec_.simulcastStream[0].minBitrate) {
|
parameters.bitrate.get_sum_kbps() <
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
codec_.simulcastStream[0].minBitrate) {
|
||||||
|
RTC_LOG(LS_WARNING) << "Total bitrate "
|
||||||
|
<< parameters.bitrate.get_sum_kbps()
|
||||||
|
<< " is lower than minimum bitrate of base layer: "
|
||||||
|
<< codec_.simulcastStream[0].minBitrate;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
codec_.maxFramerate = new_framerate;
|
codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
|
||||||
|
|
||||||
for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) {
|
for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) {
|
||||||
uint32_t stream_bitrate_kbps =
|
uint32_t stream_bitrate_kbps =
|
||||||
bitrate.GetSpatialLayerSum(stream_idx) / 1000;
|
parameters.bitrate.GetSpatialLayerSum(stream_idx) / 1000;
|
||||||
|
|
||||||
// Need a key frame if we have not sent this stream before.
|
// 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) {
|
||||||
@ -487,17 +501,31 @@ int SimulcastEncoderAdapter::SetRateAllocation(
|
|||||||
|
|
||||||
// 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.
|
||||||
VideoBitrateAllocation stream_allocation;
|
RateControlParameters stream_parameters = parameters;
|
||||||
|
stream_parameters.bitrate = VideoBitrateAllocation();
|
||||||
for (int i = 0; i < kMaxTemporalStreams; ++i) {
|
for (int i = 0; i < kMaxTemporalStreams; ++i) {
|
||||||
if (bitrate.HasBitrate(stream_idx, i)) {
|
if (parameters.bitrate.HasBitrate(stream_idx, i)) {
|
||||||
stream_allocation.SetBitrate(0, i, bitrate.GetBitrate(stream_idx, i));
|
stream_parameters.bitrate.SetBitrate(
|
||||||
|
0, i, parameters.bitrate.GetBitrate(stream_idx, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
streaminfos_[stream_idx].encoder->SetRateAllocation(stream_allocation,
|
|
||||||
new_framerate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
// Assign link allocation proportionally to spatial layer allocation.
|
||||||
|
if (parameters.bandwidth_allocation != DataRate::Zero()) {
|
||||||
|
stream_parameters.bandwidth_allocation =
|
||||||
|
DataRate::bps((parameters.bandwidth_allocation.bps() *
|
||||||
|
stream_parameters.bitrate.get_sum_bps()) /
|
||||||
|
parameters.bitrate.get_sum_bps());
|
||||||
|
// Make sure we don't allocate bandwidth lower than target bitrate.
|
||||||
|
if (stream_parameters.bandwidth_allocation.bps() <
|
||||||
|
stream_parameters.bitrate.get_sum_bps()) {
|
||||||
|
stream_parameters.bandwidth_allocation =
|
||||||
|
DataRate::bps(stream_parameters.bitrate.get_sum_bps());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
streaminfos_[stream_idx].encoder->SetRates(stream_parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(brandtr): Add task checker to this member function, when all encoder
|
// TODO(brandtr): Add task checker to this member function, when all encoder
|
||||||
|
|||||||
@ -48,8 +48,7 @@ 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;
|
||||||
int SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
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
|
||||||
|
|||||||
@ -207,10 +207,8 @@ class MockVideoEncoder : public VideoEncoder {
|
|||||||
|
|
||||||
MOCK_METHOD0(Release, int32_t());
|
MOCK_METHOD0(Release, int32_t());
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
|
void SetRates(const RateControlParameters& parameters) {
|
||||||
uint32_t framerate) {
|
last_set_rates_ = parameters;
|
||||||
last_set_bitrate_ = bitrate_allocation;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EncoderInfo GetEncoderInfo() const override {
|
EncoderInfo GetEncoderInfo() const override {
|
||||||
@ -271,7 +269,7 @@ class MockVideoEncoder : public VideoEncoder {
|
|||||||
fps_allocation_ = fps_allocation;
|
fps_allocation_ = fps_allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
|
RateControlParameters last_set_rates() const { return last_set_rates_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MockVideoEncoderFactory* const factory_;
|
MockVideoEncoderFactory* const factory_;
|
||||||
@ -282,7 +280,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;
|
||||||
VideoBitrateAllocation last_set_bitrate_;
|
VideoEncoder::RateControlParameters last_set_rates_;
|
||||||
FramerateFractions fps_allocation_;
|
FramerateFractions fps_allocation_;
|
||||||
|
|
||||||
VideoCodec codec_;
|
VideoCodec codec_;
|
||||||
@ -500,7 +498,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
|
|||||||
SetupCodec();
|
SetupCodec();
|
||||||
|
|
||||||
// Set bitrates so that we send all layers.
|
// Set bitrates so that we send all layers.
|
||||||
adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
|
rate_allocator_->GetAllocation(1200, 30), 30.0));
|
||||||
|
|
||||||
// At this point, the simulcast encoder adapter should have 3 streams: HD,
|
// 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
|
||||||
@ -560,8 +559,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_->SetRateAllocation(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
|
|
||||||
std::vector<MockVideoEncoder*> original_encoders =
|
std::vector<MockVideoEncoder*> original_encoders =
|
||||||
helper_->factory()->encoders();
|
helper_->factory()->encoders();
|
||||||
@ -587,8 +586,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_->SetRateAllocation(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
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]);
|
||||||
@ -610,8 +609,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_->SetRateAllocation(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
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]);
|
||||||
@ -628,8 +627,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_->SetRateAllocation(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
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.
|
||||||
@ -712,7 +711,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
|
|||||||
// discontinuities.
|
// discontinuities.
|
||||||
TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
|
TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
|
||||||
SetupCodec();
|
SetupCodec();
|
||||||
adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
|
rate_allocator_->GetAllocation(1200, 30), 30.0));
|
||||||
VerifyCodecSettings();
|
VerifyCodecSettings();
|
||||||
|
|
||||||
// Send frames on all streams.
|
// Send frames on all streams.
|
||||||
@ -736,7 +736,8 @@ 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_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
|
rate_allocator_->GetAllocation(1200, 30), 30.0));
|
||||||
|
|
||||||
// Verify that the same encoder sends out frames on the same simulcast index.
|
// Verify that the same encoder sends out frames on the same simulcast index.
|
||||||
encoders[0]->SendEncodedImage(1152, 704);
|
encoders[0]->SendEncodedImage(1152, 704);
|
||||||
@ -780,21 +781,23 @@ 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_->SetRateAllocation(target_bitrate, 30);
|
adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
|
||||||
EXPECT_EQ(target_bitrate,
|
EXPECT_EQ(target_bitrate,
|
||||||
helper_->factory()->encoders()[0]->last_set_bitrate());
|
helper_->factory()->encoders()[0]->last_set_rates().bitrate);
|
||||||
|
|
||||||
// Below min but non-zero should be replaced with the min bitrate.
|
// 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_->SetRateAllocation(too_low_bitrate, 30);
|
adapter_->SetRates(
|
||||||
|
VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
|
||||||
EXPECT_EQ(target_bitrate,
|
EXPECT_EQ(target_bitrate,
|
||||||
helper_->factory()->encoders()[0]->last_set_bitrate());
|
helper_->factory()->encoders()[0]->last_set_rates().bitrate);
|
||||||
|
|
||||||
// Zero should be passed on as is, since it means "pause".
|
// Zero should be passed on as is, since it means "pause".
|
||||||
adapter_->SetRateAllocation(VideoBitrateAllocation(), 30);
|
adapter_->SetRates(
|
||||||
|
VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
|
||||||
EXPECT_EQ(VideoBitrateAllocation(),
|
EXPECT_EQ(VideoBitrateAllocation(),
|
||||||
helper_->factory()->encoders()[0]->last_set_bitrate());
|
helper_->factory()->encoders()[0]->last_set_rates().bitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
|
TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
|
||||||
@ -1157,5 +1160,45 @@ 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
|
||||||
|
|||||||
@ -306,7 +306,8 @@ 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);
|
||||||
return SetRateAllocation(allocation, codec_.maxFramerate);
|
SetRates(RateControlParameters(allocation, codec_.maxFramerate));
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t H264EncoderImpl::Release() {
|
int32_t H264EncoderImpl::Release() {
|
||||||
@ -331,36 +332,40 @@ int32_t H264EncoderImpl::RegisterEncodeCompleteCallback(
|
|||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t H264EncoderImpl::SetRateAllocation(
|
void H264EncoderImpl::SetRates(const RateControlParameters& parameters) {
|
||||||
const VideoBitrateAllocation& bitrate,
|
if (encoders_.empty()) {
|
||||||
uint32_t new_framerate) {
|
RTC_LOG(LS_WARNING) << "SetRates() while uninitialized.";
|
||||||
if (encoders_.empty())
|
return;
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
}
|
||||||
|
|
||||||
if (new_framerate < 1)
|
if (parameters.framerate_fps < 1.0) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
RTC_LOG(LS_WARNING) << "Invalid frame rate: " << parameters.framerate_fps;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (bitrate.get_sum_bps() == 0) {
|
if (parameters.bitrate.get_sum_bps() == 0) {
|
||||||
// Encoder paused, turn off all encoding.
|
// 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 WEBRTC_VIDEO_CODEC_OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(bitrate.get_sum_kbps(), codec_.maxBitrate);
|
RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate);
|
||||||
RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate);
|
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate);
|
||||||
if (codec_.numberOfSimulcastStreams > 0)
|
if (codec_.numberOfSimulcastStreams > 0)
|
||||||
RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate);
|
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(),
|
||||||
|
codec_.simulcastStream[0].minBitrate);
|
||||||
|
|
||||||
codec_.maxFramerate = new_framerate;
|
codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps);
|
||||||
|
|
||||||
size_t stream_idx = encoders_.size() - 1;
|
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 = bitrate.GetSpatialLayerSum(stream_idx);
|
configurations_[i].target_bps =
|
||||||
configurations_[i].max_frame_rate = static_cast<float>(new_framerate);
|
parameters.bitrate.GetSpatialLayerSum(stream_idx);
|
||||||
|
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);
|
||||||
@ -377,8 +382,6 @@ int32_t H264EncoderImpl::SetRateAllocation(
|
|||||||
configurations_[i].SetStreamState(false);
|
configurations_[i].SetStreamState(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t H264EncoderImpl::Encode(
|
int32_t H264EncoderImpl::Encode(
|
||||||
|
|||||||
@ -61,8 +61,7 @@ class H264EncoderImpl : public H264Encoder {
|
|||||||
|
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback) override;
|
EncodedImageCallback* callback) override;
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
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.
|
||||||
|
|||||||
@ -45,8 +45,7 @@ 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;
|
||||||
int SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t new_framerate) override;
|
|
||||||
int Release() override;
|
int Release() override;
|
||||||
EncoderInfo GetEncoderInfo() const override;
|
EncoderInfo GetEncoderInfo() const override;
|
||||||
|
|
||||||
|
|||||||
@ -216,23 +216,21 @@ int MultiplexEncoderAdapter::RegisterEncodeCompleteCallback(
|
|||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MultiplexEncoderAdapter::SetRateAllocation(
|
void MultiplexEncoderAdapter::SetRates(
|
||||||
const VideoBitrateAllocation& bitrate,
|
const RateControlParameters& parameters) {
|
||||||
uint32_t framerate) {
|
VideoBitrateAllocation bitrate_allocation(parameters.bitrate);
|
||||||
VideoBitrateAllocation bitrate_allocation(bitrate);
|
|
||||||
bitrate_allocation.SetBitrate(
|
bitrate_allocation.SetBitrate(
|
||||||
0, 0, bitrate.GetBitrate(0, 0) - augmenting_data_size_);
|
0, 0, parameters.bitrate.GetBitrate(0, 0) - augmenting_data_size_);
|
||||||
for (auto& encoder : encoders_) {
|
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.
|
||||||
const int rv = encoder->SetRateAllocation(
|
encoder->SetRates(RateControlParameters(
|
||||||
bitrate_allocation,
|
bitrate_allocation,
|
||||||
static_cast<uint32_t>(encoders_.size()) * framerate);
|
static_cast<uint32_t>(encoders_.size() * parameters.framerate_fps),
|
||||||
if (rv)
|
parameters.bandwidth_allocation -
|
||||||
return rv;
|
DataRate::bps(augmenting_data_size_)));
|
||||||
}
|
}
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MultiplexEncoderAdapter::Release() {
|
int MultiplexEncoderAdapter::Release() {
|
||||||
|
|||||||
@ -300,10 +300,8 @@ 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_);
|
||||||
const int set_rates_result =
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation_, framerate_fps_);
|
bitrate_allocation_, static_cast<double>(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(
|
||||||
|
|||||||
@ -25,7 +25,10 @@
|
|||||||
#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 {
|
||||||
@ -96,9 +99,11 @@ 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(encoder_mock_, SetRateAllocation(_, kFramerateFps))
|
EXPECT_CALL(
|
||||||
.Times(1)
|
encoder_mock_,
|
||||||
.WillOnce(Return(0));
|
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
|
||||||
|
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())
|
||||||
@ -122,9 +127,11 @@ 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(encoder_mock_, SetRateAllocation(_, kStartFramerateFps))
|
EXPECT_CALL(
|
||||||
.Times(1)
|
encoder_mock_,
|
||||||
.WillOnce(Return(0));
|
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
|
||||||
|
static_cast<double>(kStartFramerateFps))))
|
||||||
|
.Times(1);
|
||||||
q_.SendTask(
|
q_.SendTask(
|
||||||
[=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); });
|
[=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); });
|
||||||
|
|
||||||
@ -136,9 +143,11 @@ 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(encoder_mock_, SetRateAllocation(_, kNewFramerateFps))
|
EXPECT_CALL(
|
||||||
.Times(1)
|
encoder_mock_,
|
||||||
.WillOnce(Return(0));
|
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
|
||||||
|
static_cast<double>(kNewFramerateFps))))
|
||||||
|
.Times(1);
|
||||||
q_.SendTask(
|
q_.SendTask(
|
||||||
[=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); });
|
[=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); });
|
||||||
|
|
||||||
@ -153,21 +162,32 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VideoProcessorTest, SetRates) {
|
TEST_F(VideoProcessorTest, SetRates) {
|
||||||
const int kBitrateKbps = 123;
|
const uint32_t kBitrateKbps = 123;
|
||||||
const int kFramerateFps = 17;
|
const int kFramerateFps = 17;
|
||||||
EXPECT_CALL(encoder_mock_,
|
|
||||||
SetRateAllocation(
|
EXPECT_CALL(
|
||||||
Property(&VideoBitrateAllocation::get_sum_kbps, kBitrateKbps),
|
encoder_mock_,
|
||||||
kFramerateFps))
|
SetRates(AllOf(ResultOf(
|
||||||
|
[](const VideoEncoder::RateControlParameters& params) {
|
||||||
|
return params.bitrate.get_sum_kbps();
|
||||||
|
},
|
||||||
|
kBitrateKbps),
|
||||||
|
Field(&VideoEncoder::RateControlParameters::framerate_fps,
|
||||||
|
static_cast<double>(kFramerateFps)))))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
|
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
|
||||||
|
|
||||||
const int kNewBitrateKbps = 456;
|
const uint32_t kNewBitrateKbps = 456;
|
||||||
const int kNewFramerateFps = 34;
|
const int kNewFramerateFps = 34;
|
||||||
EXPECT_CALL(encoder_mock_,
|
EXPECT_CALL(
|
||||||
SetRateAllocation(Property(&VideoBitrateAllocation::get_sum_kbps,
|
encoder_mock_,
|
||||||
|
SetRates(AllOf(ResultOf(
|
||||||
|
[](const VideoEncoder::RateControlParameters& params) {
|
||||||
|
return params.bitrate.get_sum_kbps();
|
||||||
|
},
|
||||||
kNewBitrateKbps),
|
kNewBitrateKbps),
|
||||||
kNewFramerateFps))
|
Field(&VideoEncoder::RateControlParameters::framerate_fps,
|
||||||
|
static_cast<double>(kNewFramerateFps)))))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
q_.SendTask(
|
q_.SendTask(
|
||||||
[=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); });
|
[=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); });
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#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"
|
||||||
@ -247,33 +248,40 @@ int LibvpxVp8Encoder::Release() {
|
|||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LibvpxVp8Encoder::SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) {
|
||||||
uint32_t new_framerate) {
|
if (!inited_) {
|
||||||
if (!inited_)
|
RTC_LOG(LS_WARNING) << "SetRates() while not initialize";
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (encoders_[0].err)
|
if (encoders_[0].err) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
RTC_LOG(LS_WARNING) << "Encoder in error state.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (new_framerate < 1)
|
if (parameters.framerate_fps < 1.0) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
RTC_LOG(LS_WARNING) << "Unsupported framerate (must be >= 1.0): "
|
||||||
|
<< parameters.framerate_fps;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (bitrate.get_sum_bps() == 0) {
|
if (parameters.bitrate.get_sum_bps() == 0) {
|
||||||
// Encoder paused, turn off all encoding.
|
// 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 WEBRTC_VIDEO_CODEC_OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(bitrate.get_sum_kbps(), codec_.maxBitrate);
|
RTC_DCHECK_LE(parameters.bitrate.get_sum_kbps(), codec_.maxBitrate);
|
||||||
RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate);
|
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(), codec_.minBitrate);
|
||||||
if (codec_.numberOfSimulcastStreams > 0)
|
if (codec_.numberOfSimulcastStreams > 0)
|
||||||
RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate);
|
RTC_DCHECK_GE(parameters.bitrate.get_sum_kbps(),
|
||||||
|
codec_.simulcastStream[0].minBitrate);
|
||||||
|
|
||||||
codec_.maxFramerate = new_framerate;
|
codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
|
||||||
|
|
||||||
if (encoders_.size() > 1) {
|
if (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
|
||||||
@ -282,7 +290,7 @@ int LibvpxVp8Encoder::SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
|||||||
// 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() &&
|
||||||
new_framerate > 20) {
|
parameters.framerate_fps > 20.0) {
|
||||||
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.
|
||||||
@ -293,7 +301,7 @@ int LibvpxVp8Encoder::SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
|||||||
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 =
|
||||||
bitrate.GetSpatialLayerSum(stream_idx) / 1000;
|
parameters.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)
|
||||||
@ -302,18 +310,19 @@ int LibvpxVp8Encoder::SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
|||||||
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, bitrate.GetTemporalLayerAllocation(stream_idx),
|
stream_idx, parameters.bitrate.GetTemporalLayerAllocation(stream_idx),
|
||||||
new_framerate);
|
static_cast<int>(parameters.framerate_fps + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateVpxConfiguration(stream_idx, frame_buffer_controller_.get(),
|
UpdateVpxConfiguration(stream_idx, frame_buffer_controller_.get(),
|
||||||
&configurations_[i]);
|
&configurations_[i]);
|
||||||
|
|
||||||
if (libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i])) {
|
vpx_codec_err_t err =
|
||||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
libvpx_->codec_enc_config_set(&encoders_[i], &configurations_[i]);
|
||||||
|
if (err != VPX_CODEC_OK) {
|
||||||
|
RTC_LOG(LS_WARNING) << "Error configuring codec, error code: " << err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibvpxVp8Encoder::OnPacketLossRateUpdate(float packet_loss_rate) {
|
void LibvpxVp8Encoder::OnPacketLossRateUpdate(float packet_loss_rate) {
|
||||||
|
|||||||
@ -54,8 +54,7 @@ class LibvpxVp8Encoder : public VideoEncoder {
|
|||||||
|
|
||||||
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
||||||
|
|
||||||
int SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t new_framerate) override;
|
|
||||||
|
|
||||||
void OnPacketLossRateUpdate(float packet_loss_rate) override;
|
void OnPacketLossRateUpdate(float packet_loss_rate) override;
|
||||||
|
|
||||||
|
|||||||
@ -110,20 +110,23 @@ class TestVp8Impl : public VideoCodecUnitTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(TestVp8Impl, SetRateAllocation) {
|
TEST_F(TestVp8Impl, SetRates) {
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
|
auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
|
||||||
|
LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
|
||||||
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
|
encoder.InitEncode(&codec_settings_, 1, 1000));
|
||||||
|
|
||||||
const int kBitrateBps = 300000;
|
const uint32_t kBitrateBps = 300000;
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
bitrate_allocation.SetBitrate(0, 0, kBitrateBps);
|
bitrate_allocation.SetBitrate(0, 0, kBitrateBps);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
|
EXPECT_CALL(*vpx, codec_enc_config_set(_, _))
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
.WillOnce(
|
||||||
codec_settings_.maxFramerate));
|
Invoke([&](vpx_codec_ctx_t* ctx, const vpx_codec_enc_cfg_t* cfg) {
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(cfg->rc_target_bitrate, kBitrateBps / 1000);
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
return VPX_CODEC_OK;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
}));
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
encoder.SetRates(VideoEncoder::RateControlParameters(
|
||||||
codec_settings_.maxFramerate));
|
bitrate_allocation, static_cast<double>(codec_settings_.maxFramerate)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestVp8Impl, EncodeFrameAndRelease) {
|
TEST_F(TestVp8Impl, EncodeFrameAndRelease) {
|
||||||
@ -437,7 +440,8 @@ 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_->SetRateAllocation(bitrate_allocation, 5);
|
encoder_->SetRates(
|
||||||
|
VideoEncoder::RateControlParameters(bitrate_allocation, 5.0));
|
||||||
|
|
||||||
EncodedImage encoded_frame;
|
EncodedImage encoded_frame;
|
||||||
CodecSpecificInfo codec_specific_info;
|
CodecSpecificInfo codec_specific_info;
|
||||||
|
|||||||
@ -371,9 +371,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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);
|
||||||
@ -390,9 +389,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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);
|
||||||
@ -422,9 +420,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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));
|
||||||
@ -438,9 +435,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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,9 +471,8 @@ 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) */));
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
codec_settings_.maxFramerate));
|
|
||||||
|
|
||||||
SetWaitForEncodedFramesThreshold(2);
|
SetWaitForEncodedFramesThreshold(2);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
@ -546,9 +541,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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) {
|
||||||
@ -606,9 +600,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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) {
|
||||||
@ -664,9 +657,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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;
|
||||||
@ -683,9 +675,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
codec_settings_.maxFramerate));
|
|
||||||
|
|
||||||
// Encode 1 frame.
|
// Encode 1 frame.
|
||||||
SetWaitForEncodedFramesThreshold(1);
|
SetWaitForEncodedFramesThreshold(1);
|
||||||
@ -702,9 +693,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
codec_settings_.maxFramerate));
|
|
||||||
|
|
||||||
// Encode 1 frame.
|
// Encode 1 frame.
|
||||||
SetWaitForEncodedFramesThreshold(2);
|
SetWaitForEncodedFramesThreshold(2);
|
||||||
@ -742,9 +732,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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;
|
||||||
@ -761,9 +750,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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) {
|
||||||
@ -783,9 +771,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
codec_settings_.maxFramerate));
|
|
||||||
|
|
||||||
// Encode 1 frame.
|
// Encode 1 frame.
|
||||||
SetWaitForEncodedFramesThreshold(2);
|
SetWaitForEncodedFramesThreshold(2);
|
||||||
@ -831,9 +818,8 @@ 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);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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;
|
||||||
@ -851,9 +837,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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);
|
||||||
@ -909,9 +894,8 @@ 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);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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;
|
||||||
@ -940,9 +924,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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;
|
||||||
@ -998,9 +981,8 @@ TEST_F(TestVp9Impl, DisableNewLayerInVideoDelaysSsInfoTillTL0) {
|
|||||||
num_temporal_layers);
|
num_temporal_layers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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;
|
||||||
@ -1016,9 +998,8 @@ 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);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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.
|
||||||
@ -1055,9 +1036,8 @@ 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);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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;
|
||||||
@ -1325,9 +1305,8 @@ 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) */));
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
encoder_->SetRateAllocation(bitrate_allocation,
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
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) {
|
||||||
@ -1380,9 +1359,8 @@ 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) */));
|
||||||
|
|
||||||
EXPECT_EQ(
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
WEBRTC_VIDEO_CODEC_OK,
|
bitrate_allocation, codec_max_framerate_fps));
|
||||||
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) {
|
||||||
|
|||||||
@ -309,29 +309,33 @@ bool VP9EncoderImpl::SetSvcRates(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VP9EncoderImpl::SetRateAllocation(
|
void VP9EncoderImpl::SetRates(const RateControlParameters& parameters) {
|
||||||
const VideoBitrateAllocation& bitrate_allocation,
|
|
||||||
uint32_t frame_rate) {
|
|
||||||
if (!inited_) {
|
if (!inited_) {
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
RTC_LOG(LS_WARNING) << "SetRates() calll while uninitialzied.";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (encoder_->err) {
|
if (encoder_->err) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
RTC_LOG(LS_WARNING) << "Encoder in error state: " << encoder_->err;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (frame_rate < 1) {
|
if (parameters.framerate_fps < 1.0) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
RTC_LOG(LS_WARNING) << "Unsupported framerate: "
|
||||||
|
<< parameters.framerate_fps;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Update bit rate
|
// Update bit rate
|
||||||
if (codec_.maxBitrate > 0 &&
|
if (codec_.maxBitrate > 0 &&
|
||||||
bitrate_allocation.get_sum_kbps() > codec_.maxBitrate) {
|
parameters.bitrate.get_sum_kbps() > codec_.maxBitrate) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
RTC_LOG(LS_WARNING) << "Target bitrate exceeds maximum: "
|
||||||
|
<< parameters.bitrate.get_sum_kbps() << " vs "
|
||||||
|
<< codec_.maxBitrate;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
codec_.maxFramerate = frame_rate;
|
codec_.maxFramerate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
|
||||||
|
requested_bitrate_allocation_ = parameters.bitrate;
|
||||||
|
|
||||||
requested_bitrate_allocation_ = bitrate_allocation;
|
return;
|
||||||
|
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||||
|
|||||||
@ -48,8 +48,7 @@ class VP9EncoderImpl : public VP9Encoder {
|
|||||||
|
|
||||||
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
||||||
|
|
||||||
int SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t frame_rate) override;
|
|
||||||
|
|
||||||
EncoderInfo GetEncoderInfo() const override;
|
EncoderInfo GetEncoderInfo() const override;
|
||||||
|
|
||||||
|
|||||||
@ -288,8 +288,9 @@ void SimulcastTestFixtureImpl::SetUpRateAllocator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SimulcastTestFixtureImpl::SetRates(uint32_t bitrate_kbps, uint32_t fps) {
|
void SimulcastTestFixtureImpl::SetRates(uint32_t bitrate_kbps, uint32_t fps) {
|
||||||
encoder_->SetRateAllocation(
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), fps);
|
rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps),
|
||||||
|
static_cast<double>(fps)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulcastTestFixtureImpl::RunActiveStreamsTest(
|
void SimulcastTestFixtureImpl::RunActiveStreamsTest(
|
||||||
|
|||||||
@ -104,8 +104,7 @@ class MediaCodecVideoEncoder : public VideoEncoder {
|
|||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback) override;
|
EncodedImageCallback* callback) override;
|
||||||
int32_t Release() override;
|
int32_t Release() override;
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
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.
|
||||||
@ -900,17 +899,16 @@ int32_t MediaCodecVideoEncoder::Release() {
|
|||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t MediaCodecVideoEncoder::SetRateAllocation(
|
void MediaCodecVideoEncoder::SetRates(const RateControlParameters& parameters) {
|
||||||
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 = rate_allocation.get_sum_kbps();
|
const uint32_t new_bit_rate = parameters.bitrate.get_sum_kbps();
|
||||||
if (sw_fallback_required_)
|
if (sw_fallback_required_)
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return;
|
||||||
|
uint32_t frame_rate = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
|
||||||
frame_rate =
|
frame_rate =
|
||||||
(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 WEBRTC_VIDEO_CODEC_OK;
|
return;
|
||||||
}
|
}
|
||||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||||
ScopedLocalRefFrame local_ref_frame(jni);
|
ScopedLocalRefFrame local_ref_frame(jni);
|
||||||
@ -926,10 +924,7 @@ int32_t MediaCodecVideoEncoder::SetRateAllocation(
|
|||||||
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 {
|
||||||
|
|||||||
@ -146,16 +146,15 @@ int32_t VideoEncoderWrapper::Encode(
|
|||||||
return HandleReturnCode(jni, ret, "encode");
|
return HandleReturnCode(jni, ret, "encode");
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t VideoEncoderWrapper::SetRateAllocation(
|
void VideoEncoderWrapper::SetRates(const RateControlParameters& parameters) {
|
||||||
const VideoBitrateAllocation& allocation,
|
|
||||||
uint32_t framerate) {
|
|
||||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||||
|
|
||||||
ScopedJavaLocalRef<jobject> j_bitrate_allocation =
|
ScopedJavaLocalRef<jobject> j_bitrate_allocation =
|
||||||
ToJavaBitrateAllocation(jni, allocation);
|
ToJavaBitrateAllocation(jni, parameters.bitrate);
|
||||||
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_setRateAllocation(
|
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_setRateAllocation(
|
||||||
jni, encoder_, j_bitrate_allocation, (jint)framerate);
|
jni, encoder_, j_bitrate_allocation,
|
||||||
return HandleReturnCode(jni, ret, "setRateAllocation");
|
(jint)(parameters.framerate_fps + 0.5));
|
||||||
|
HandleReturnCode(jni, ret, "setRateAllocation");
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoEncoder::EncoderInfo VideoEncoderWrapper::GetEncoderInfo() const {
|
VideoEncoder::EncoderInfo VideoEncoderWrapper::GetEncoderInfo() const {
|
||||||
|
|||||||
@ -44,8 +44,7 @@ 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;
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t framerate) override;
|
|
||||||
|
|
||||||
EncoderInfo GetEncoderInfo() const override;
|
EncoderInfo GetEncoderInfo() const override;
|
||||||
|
|
||||||
|
|||||||
@ -74,11 +74,8 @@ int32_t ConfigurableFrameSizeEncoder::Release() {
|
|||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ConfigurableFrameSizeEncoder::SetRateAllocation(
|
void ConfigurableFrameSizeEncoder::SetRates(
|
||||||
const VideoBitrateAllocation& allocation,
|
const RateControlParameters& parameters) {}
|
||||||
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_);
|
||||||
|
|||||||
@ -44,8 +44,7 @@ class ConfigurableFrameSizeEncoder : public VideoEncoder {
|
|||||||
|
|
||||||
int32_t Release() override;
|
int32_t Release() override;
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t framerate) override;
|
|
||||||
|
|
||||||
int32_t SetFrameSize(size_t size);
|
int32_t SetFrameSize(size_t size);
|
||||||
|
|
||||||
|
|||||||
@ -51,7 +51,6 @@ 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),
|
||||||
@ -65,7 +64,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;
|
||||||
SetRateAllocation(target_bitrate_, configured_input_framerate_);
|
SetRates(current_rate_settings_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
|
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
|
||||||
@ -73,8 +72,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;
|
||||||
target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000);
|
current_rate_settings_.bitrate.SetBitrate(0, 0, config_.startBitrate * 1000);
|
||||||
configured_input_framerate_ = config_.maxFramerate;
|
current_rate_settings_.framerate_fps = config_.maxFramerate;
|
||||||
pending_keyframe_ = true;
|
pending_keyframe_ = true;
|
||||||
last_frame_info_ = FrameInfo();
|
last_frame_info_ = FrameInfo();
|
||||||
return 0;
|
return 0;
|
||||||
@ -86,8 +85,7 @@ 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;
|
||||||
VideoBitrateAllocation target_bitrate;
|
RateControlParameters rates;
|
||||||
int framerate;
|
|
||||||
VideoCodecMode mode;
|
VideoCodecMode mode;
|
||||||
bool keyframe;
|
bool keyframe;
|
||||||
uint32_t counter;
|
uint32_t counter;
|
||||||
@ -99,12 +97,10 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
|
|||||||
simulcast_streams[i] = config_.simulcastStream[i];
|
simulcast_streams[i] = config_.simulcastStream[i];
|
||||||
}
|
}
|
||||||
callback = callback_;
|
callback = callback_;
|
||||||
target_bitrate = target_bitrate_;
|
rates = current_rate_settings_;
|
||||||
mode = config_.mode;
|
mode = config_.mode;
|
||||||
if (configured_input_framerate_ > 0) {
|
if (rates.framerate_fps <= 0.0) {
|
||||||
framerate = configured_input_framerate_;
|
rates.framerate_fps = max_framerate;
|
||||||
} else {
|
|
||||||
framerate = max_framerate;
|
|
||||||
}
|
}
|
||||||
keyframe = pending_keyframe_;
|
keyframe = pending_keyframe_;
|
||||||
pending_keyframe_ = false;
|
pending_keyframe_ = false;
|
||||||
@ -112,8 +108,8 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
FrameInfo frame_info =
|
FrameInfo frame_info =
|
||||||
NextFrame(frame_types, keyframe, num_simulcast_streams, target_bitrate,
|
NextFrame(frame_types, keyframe, num_simulcast_streams, rates.bitrate,
|
||||||
simulcast_streams, framerate);
|
simulcast_streams, static_cast<int>(rates.framerate_fps + 0.5));
|
||||||
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) {
|
||||||
@ -237,12 +233,10 @@ int32_t FakeEncoder::Release() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeEncoder::SetRateAllocation(
|
void FakeEncoder::SetRates(const RateControlParameters& parameters) {
|
||||||
const VideoBitrateAllocation& rate_allocation,
|
|
||||||
uint32_t framerate) {
|
|
||||||
rtc::CritScope cs(&crit_sect_);
|
rtc::CritScope cs(&crit_sect_);
|
||||||
target_bitrate_ = rate_allocation;
|
current_rate_settings_ = parameters;
|
||||||
int allocated_bitrate_kbps = target_bitrate_.get_sum_kbps();
|
int allocated_bitrate_kbps = parameters.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 &&
|
||||||
@ -251,20 +245,19 @@ int32_t FakeEncoder::SetRateAllocation(
|
|||||||
++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 (target_bitrate_.HasBitrate(spatial_idx, temporal_idx)) {
|
if (current_rate_settings_.bitrate.HasBitrate(spatial_idx,
|
||||||
uint32_t bitrate =
|
temporal_idx)) {
|
||||||
target_bitrate_.GetBitrate(spatial_idx, temporal_idx);
|
uint32_t bitrate = current_rate_settings_.bitrate.GetBitrate(
|
||||||
|
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);
|
||||||
target_bitrate_.SetBitrate(spatial_idx, temporal_idx, bitrate);
|
current_rate_settings_.bitrate.SetBitrate(spatial_idx, temporal_idx,
|
||||||
|
bitrate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configured_input_framerate_ = framerate;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* FakeEncoder::kImplementationName = "fake_encoder";
|
const char* FakeEncoder::kImplementationName = "fake_encoder";
|
||||||
@ -276,7 +269,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 configured_input_framerate_;
|
return static_cast<int>(current_rate_settings_.framerate_fps + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
FakeH264Encoder::FakeH264Encoder(Clock* clock)
|
FakeH264Encoder::FakeH264Encoder(Clock* clock)
|
||||||
|
|||||||
@ -48,8 +48,7 @@ class FakeEncoder : public VideoEncoder {
|
|||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback) override;
|
EncodedImageCallback* callback) override;
|
||||||
int32_t Release() override;
|
int32_t Release() override;
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
|
void SetRates(const RateControlParameters& parameters) override;
|
||||||
uint32_t framerate) override;
|
|
||||||
int GetConfiguredInputFramerate() const;
|
int GetConfiguredInputFramerate() const;
|
||||||
EncoderInfo GetEncoderInfo() const override;
|
EncoderInfo GetEncoderInfo() const override;
|
||||||
|
|
||||||
@ -89,8 +88,7 @@ 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_);
|
||||||
VideoBitrateAllocation target_bitrate_ RTC_GUARDED_BY(crit_sect_);
|
RateControlParameters current_rate_settings_ 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_);
|
||||||
|
|||||||
@ -63,7 +63,9 @@ 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(
|
||||||
@ -147,17 +149,11 @@ int32_t QualityAnalyzingVideoEncoder::Encode(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t QualityAnalyzingVideoEncoder::SetRates(uint32_t bitrate,
|
void QualityAnalyzingVideoEncoder::SetRates(
|
||||||
uint32_t framerate) {
|
const VideoEncoder::RateControlParameters& parameters) {
|
||||||
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_->SetRateAllocation(allocation, framerate);
|
return delegate_->SetRates(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulating encoder overshooting target bitrate, by configuring actual
|
// Simulating encoder overshooting target bitrate, by configuring actual
|
||||||
@ -166,7 +162,7 @@ int32_t QualityAnalyzingVideoEncoder::SetRateAllocation(
|
|||||||
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 =
|
||||||
allocation.GetSpatialLayerSum(si);
|
parameters.bitrate.GetSpatialLayerSum(si);
|
||||||
if (spatial_layer_bitrate_bps == 0) {
|
if (spatial_layer_bitrate_bps == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -185,16 +181,18 @@ int32_t QualityAnalyzingVideoEncoder::SetRateAllocation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
|
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
|
||||||
if (allocation.HasBitrate(si, ti)) {
|
if (parameters.bitrate.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 *
|
||||||
allocation.GetBitrate(si, ti)));
|
parameters.bitrate.GetBitrate(si, ti)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return delegate_->SetRateAllocation(multiplied_allocation, framerate);
|
RateControlParameters adjusted_params = parameters;
|
||||||
|
adjusted_params.bitrate = multiplied_allocation;
|
||||||
|
return delegate_->SetRates(adjusted_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoEncoder::EncoderInfo QualityAnalyzingVideoEncoder::GetEncoderInfo() const {
|
VideoEncoder::EncoderInfo QualityAnalyzingVideoEncoder::GetEncoderInfo() const {
|
||||||
|
|||||||
@ -70,9 +70,7 @@ 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;
|
||||||
int32_t SetRates(uint32_t bitrate, uint32_t framerate) override;
|
void SetRates(const VideoEncoder::RateControlParameters& parameters) 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.
|
||||||
|
|||||||
@ -75,9 +75,8 @@ 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(); }
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
uint32_t framerate) override {
|
encoder_->SetRates(parameters);
|
||||||
return encoder_->SetRateAllocation(rate_allocation, framerate);
|
|
||||||
}
|
}
|
||||||
VideoEncoder::EncoderInfo GetEncoderInfo() const override {
|
VideoEncoder::EncoderInfo GetEncoderInfo() const override {
|
||||||
return encoder_->GetEncoderInfo();
|
return encoder_->GetEncoderInfo();
|
||||||
|
|||||||
@ -307,15 +307,13 @@ TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) {
|
|||||||
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
|
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
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 (rate_allocation.get_sum_bps() == 0)
|
if (parameters.bitrate.get_sum_bps() == 0)
|
||||||
return 0;
|
return;
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
bitrate_kbps_ = rate_allocation.get_sum_kbps();
|
bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
|
||||||
observation_complete_.Set();
|
observation_complete_.Set();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerformTest() override {
|
void PerformTest() override {
|
||||||
|
|||||||
@ -149,11 +149,11 @@ class QualityTestVideoEncoder : public VideoEncoder,
|
|||||||
}
|
}
|
||||||
return encoder_->Encode(frame, frame_types);
|
return encoder_->Encode(frame, frame_types);
|
||||||
}
|
}
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
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) {
|
||||||
return encoder_->SetRateAllocation(allocation, framerate);
|
encoder_->SetRates(parameters);
|
||||||
|
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 =
|
||||||
allocation.GetSpatialLayerSum(si);
|
parameters.bitrate.GetSpatialLayerSum(si);
|
||||||
if (spatial_layer_bitrate_bps == 0) {
|
if (spatial_layer_bitrate_bps == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -181,16 +181,18 @@ class QualityTestVideoEncoder : public VideoEncoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
|
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
|
||||||
if (allocation.HasBitrate(si, ti)) {
|
if (parameters.bitrate.HasBitrate(si, ti)) {
|
||||||
overshot_allocation.SetBitrate(
|
overshot_allocation.SetBitrate(
|
||||||
si, ti,
|
si, ti,
|
||||||
rtc::checked_cast<uint32_t>(overshoot_factor *
|
rtc::checked_cast<uint32_t>(
|
||||||
allocation.GetBitrate(si, ti)));
|
overshoot_factor * parameters.bitrate.GetBitrate(si, ti)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoder_->SetRateAllocation(overshot_allocation, framerate);
|
return encoder_->SetRates(
|
||||||
|
RateControlParameters(overshot_allocation, parameters.framerate_fps,
|
||||||
|
parameters.bandwidth_allocation));
|
||||||
}
|
}
|
||||||
EncoderInfo GetEncoderInfo() const override {
|
EncoderInfo GetEncoderInfo() const override {
|
||||||
EncoderInfo info = encoder_->GetEncoderInfo();
|
EncoderInfo info = encoder_->GetEncoderInfo();
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
start_bitrate_kbps_ = new_target_bitrate;
|
start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
|
||||||
start_bitrate_changed_.Set();
|
start_bitrate_changed_.Set();
|
||||||
return FakeEncoder::SetRates(new_target_bitrate, framerate);
|
FakeEncoder::SetRates(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetStartBitrateKbps() const {
|
int GetStartBitrateKbps() const {
|
||||||
@ -2118,12 +2118,11 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
uint32_t framerate) override {
|
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
bitrate_kbps_ = bitrate.get_sum_kbps();
|
bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
|
||||||
bitrate_changed_.Set();
|
bitrate_changed_.Set();
|
||||||
return FakeEncoder::SetRateAllocation(bitrate, framerate);
|
FakeEncoder::SetRates(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitForEncoderInit() {
|
bool WaitForEncoderInit() {
|
||||||
@ -2854,17 +2853,17 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
|
|||||||
maxPayloadSize);
|
maxPayloadSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
uint32_t frameRate) override {
|
|
||||||
{
|
{
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
if (target_bitrate_ == bitrate.get_sum_kbps()) {
|
if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) {
|
||||||
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
|
FakeEncoder::SetRates(parameters);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
target_bitrate_ = bitrate.get_sum_kbps();
|
target_bitrate_ = parameters.bitrate.get_sum_kbps();
|
||||||
}
|
}
|
||||||
bitrate_changed_event_.Set();
|
bitrate_changed_event_.Set();
|
||||||
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
|
FakeEncoder::SetRates(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitForSetRates(uint32_t expected_bitrate) {
|
void WaitForSetRates(uint32_t expected_bitrate) {
|
||||||
@ -3653,16 +3652,15 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
|||||||
max_bitrate_bps_(0),
|
max_bitrate_bps_(0),
|
||||||
first_packet_sent_(false) {}
|
first_packet_sent_(false) {}
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
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_ = bitrate.get_sum_bps();
|
max_bitrate_bps_ = parameters.bitrate.get_sum_bps();
|
||||||
bitrate_changed_event_.Set();
|
bitrate_changed_event_.Set();
|
||||||
}
|
}
|
||||||
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
|
return FakeEncoder::SetRates(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
||||||
|
|||||||
@ -726,24 +726,24 @@ class VideoStreamEncoderTest : public ::testing::Test {
|
|||||||
return FakeEncoder::Release();
|
return FakeEncoder::Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SetRateAllocation(const VideoBitrateAllocation& rate_allocation,
|
void SetRates(const RateControlParameters& parameters) {
|
||||||
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 (rate_allocation.HasBitrate(si, ti)) {
|
if (parameters.bitrate.HasBitrate(si, ti)) {
|
||||||
adjusted_rate_allocation.SetBitrate(
|
adjusted_rate_allocation.SetBitrate(
|
||||||
si, ti,
|
si, ti,
|
||||||
static_cast<uint32_t>(rate_allocation.GetBitrate(si, ti) *
|
static_cast<uint32_t>(parameters.bitrate.GetBitrate(si, ti) *
|
||||||
rate_factor_));
|
rate_factor_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_framerate_ = framerate;
|
last_framerate_ = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
|
||||||
last_bitrate_allocation_ = rate_allocation;
|
last_bitrate_allocation_ = parameters.bitrate;
|
||||||
return FakeEncoder::SetRateAllocation(adjusted_rate_allocation,
|
RateControlParameters adjusted_paramters = parameters;
|
||||||
framerate);
|
adjusted_paramters.bitrate = adjusted_rate_allocation;
|
||||||
|
FakeEncoder::SetRates(adjusted_paramters);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::CriticalSection local_crit_sect_;
|
rtc::CriticalSection local_crit_sect_;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user