Reland "Fix minor regression caused by a8336d3"
This is a reland of 809198edfff416fce8d75b574a43afab5e67b1cd
A fix was made in https://webrtc-review.googlesource.com/c/src/+/154343
which fixed the regression issues caused by the original patch.
Original change's description:
> Fix minor regression caused by a8336d3
>
> VideoEncoder::SetRates was being called unnessesarily when the fields
> appended to RateControlParameters were changed. Since SetRates only
> cares about RateControlParameters, it should have only been called if
> the RateControlParameters themselves were actually changed.
>
> Bug: webrtc:10126
> Change-Id: Ic47d67e642a3043307fec950e5fba970d9f95167
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/152829
> Reviewed-by: Erik Språng <sprang@webrtc.org>
> Commit-Queue: Evan Shrubsole <eshr@google.com>
> Cr-Commit-Position: refs/heads/master@{#29208}
Bug: webrtc:10126
Change-Id: Iecc3ab6a5cd1193a1fa8e824dcf4f0b8165f9bf8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/154359
Commit-Queue: Evan Shrubsole <eshr@google.com>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29356}
diff --git a/api/video_codecs/video_encoder.cc b/api/video_codecs/video_encoder.cc
index d3f16a00..3a848f3 100644
--- a/api/video_codecs/video_encoder.cc
+++ b/api/video_codecs/video_encoder.cc
@@ -116,6 +116,17 @@
framerate_fps(framerate_fps),
bandwidth_allocation(bandwidth_allocation) {}
+bool VideoEncoder::RateControlParameters::operator==(
+ const VideoEncoder::RateControlParameters& rhs) const {
+ return std::tie(bitrate, framerate_fps, bandwidth_allocation) ==
+ std::tie(rhs.bitrate, rhs.framerate_fps, rhs.bandwidth_allocation);
+}
+
+bool VideoEncoder::RateControlParameters::operator!=(
+ const VideoEncoder::RateControlParameters& rhs) const {
+ return !(rhs == *this);
+}
+
VideoEncoder::RateControlParameters::~RateControlParameters() = default;
void VideoEncoder::SetFecControllerOverride(
diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h
index 0ee5521..766ea75 100644
--- a/api/video_codecs/video_encoder.h
+++ b/api/video_codecs/video_encoder.h
@@ -239,6 +239,9 @@
// |bitrate.get_sum_bps()|, but may be higher if the application is not
// network constrained.
DataRate bandwidth_allocation;
+
+ bool operator==(const RateControlParameters& rhs) const;
+ bool operator!=(const RateControlParameters& rhs) const;
};
struct LossNotification {
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index d91ee3c..1ae4476 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -441,7 +441,7 @@
};
VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings()
- : VideoEncoder::RateControlParameters(),
+ : rate_control(),
encoder_target(DataRate::Zero()),
stable_encoder_target(DataRate::Zero()) {}
@@ -451,16 +451,13 @@
DataRate bandwidth_allocation,
DataRate encoder_target,
DataRate stable_encoder_target)
- : VideoEncoder::RateControlParameters(bitrate,
- framerate_fps,
- bandwidth_allocation),
+ : rate_control(bitrate, framerate_fps, bandwidth_allocation),
encoder_target(encoder_target),
stable_encoder_target(stable_encoder_target) {}
bool VideoStreamEncoder::EncoderRateSettings::operator==(
const EncoderRateSettings& rhs) const {
- return bitrate == rhs.bitrate && framerate_fps == rhs.framerate_fps &&
- bandwidth_allocation == rhs.bandwidth_allocation &&
+ return rate_control == rhs.rate_control &&
encoder_target == rhs.encoder_target &&
stable_encoder_target == rhs.stable_encoder_target;
}
@@ -972,7 +969,7 @@
// the changes get propagated to all listeners.
EncoderRateSettings rate_settings = *last_encoder_rate_settings_;
last_encoder_rate_settings_.reset();
- rate_settings.framerate_fps = GetInputFramerateFps();
+ rate_settings.rate_control.framerate_fps = GetInputFramerateFps();
SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(rate_settings));
}
@@ -1173,7 +1170,7 @@
if (rate_allocator_ && rate_settings.encoder_target > DataRate::Zero()) {
new_allocation = rate_allocator_->Allocate(VideoBitrateAllocationParameters(
rate_settings.encoder_target, rate_settings.stable_encoder_target,
- rate_settings.framerate_fps));
+ rate_settings.rate_control.framerate_fps));
}
if (bitrate_observer_ && new_allocation.get_sum_bps() > 0) {
@@ -1194,27 +1191,27 @@
}
EncoderRateSettings new_rate_settings = rate_settings;
- new_rate_settings.bitrate = new_allocation;
+ new_rate_settings.rate_control.bitrate = new_allocation;
// VideoBitrateAllocator subclasses may allocate a bitrate higher than the
// target in order to sustain the min bitrate of the video codec. In this
// case, make sure the bandwidth allocation is at least equal the allocation
// as that is part of the document contract for that field.
- new_rate_settings.bandwidth_allocation =
- std::max(new_rate_settings.bandwidth_allocation,
- DataRate::bps(new_rate_settings.bitrate.get_sum_bps()));
+ new_rate_settings.rate_control.bandwidth_allocation = std::max(
+ new_rate_settings.rate_control.bandwidth_allocation,
+ DataRate::bps(new_rate_settings.rate_control.bitrate.get_sum_bps()));
if (bitrate_adjuster_) {
VideoBitrateAllocation adjusted_allocation =
- bitrate_adjuster_->AdjustRateAllocation(new_rate_settings);
+ bitrate_adjuster_->AdjustRateAllocation(new_rate_settings.rate_control);
RTC_LOG(LS_VERBOSE) << "Adjusting allocation, fps = "
- << rate_settings.framerate_fps << ", from "
+ << rate_settings.rate_control.framerate_fps << ", from "
<< new_allocation.ToString() << ", to "
<< adjusted_allocation.ToString();
- new_rate_settings.bitrate = adjusted_allocation;
+ new_rate_settings.rate_control.bitrate = adjusted_allocation;
}
encoder_stats_observer_->OnBitrateAllocationUpdated(
- send_codec_, new_rate_settings.bitrate);
+ send_codec_, new_rate_settings.rate_control.bitrate);
return new_rate_settings;
}
@@ -1231,10 +1228,11 @@
void VideoStreamEncoder::SetEncoderRates(
const EncoderRateSettings& rate_settings) {
- RTC_DCHECK_GT(rate_settings.framerate_fps, 0.0);
- const bool settings_changes = !last_encoder_rate_settings_ ||
- rate_settings != *last_encoder_rate_settings_;
- if (settings_changes) {
+ RTC_DCHECK_GT(rate_settings.rate_control.framerate_fps, 0.0);
+ bool rate_control_changed =
+ (!last_encoder_rate_settings_.has_value() ||
+ last_encoder_rate_settings_->rate_control != rate_settings.rate_control);
+ if (last_encoder_rate_settings_ != rate_settings) {
last_encoder_rate_settings_ = rate_settings;
}
@@ -1250,15 +1248,16 @@
// bitrate.
// TODO(perkj): Make sure all known encoder implementations handle zero
// target bitrate and remove this check.
- if (!HasInternalSource() && rate_settings.bitrate.get_sum_bps() == 0) {
+ if (!HasInternalSource() &&
+ rate_settings.rate_control.bitrate.get_sum_bps() == 0) {
return;
}
- if (settings_changes) {
- encoder_->SetRates(rate_settings);
+ if (rate_control_changed) {
+ encoder_->SetRates(rate_settings.rate_control);
frame_encode_metadata_writer_.OnSetRates(
- rate_settings.bitrate,
- static_cast<uint32_t>(rate_settings.framerate_fps + 0.5));
+ rate_settings.rate_control.bitrate,
+ static_cast<uint32_t>(rate_settings.rate_control.framerate_fps + 0.5));
}
}
@@ -1307,7 +1306,8 @@
// |last_encoder_rate_setings_|, triggering the call to SetRate() on the
// encoder.
EncoderRateSettings new_rate_settings = *last_encoder_rate_settings_;
- new_rate_settings.framerate_fps = static_cast<double>(framerate_fps);
+ new_rate_settings.rate_control.framerate_fps =
+ static_cast<double>(framerate_fps);
SetEncoderRates(
UpdateBitrateAllocationAndNotifyObserver(new_rate_settings));
}
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index f226867..ba9f519 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -121,7 +121,7 @@
int pixel_count() const { return width * height; }
};
- struct EncoderRateSettings : public VideoEncoder::RateControlParameters {
+ struct EncoderRateSettings {
EncoderRateSettings();
EncoderRateSettings(const VideoBitrateAllocation& bitrate,
double framerate_fps,
@@ -131,6 +131,7 @@
bool operator==(const EncoderRateSettings& rhs) const;
bool operator!=(const EncoderRateSettings& rhs) const;
+ VideoEncoder::RateControlParameters rate_control;
// This is the scalar target bitrate before the VideoBitrateAllocator, i.e.
// the |target_bitrate| argument of the OnBitrateUpdated() method. This is
// needed because the bitrate allocator may truncate the total bitrate and a
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 99a4b2b..31d3aa1 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -799,6 +799,11 @@
return num_encoder_initializations_;
}
+ int GetNumSetRates() const {
+ rtc::CritScope lock(&local_crit_sect_);
+ return num_set_rates_;
+ }
+
private:
int32_t Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override {
@@ -865,6 +870,7 @@
void SetRates(const RateControlParameters& parameters) {
rtc::CritScope lock(&local_crit_sect_);
+ num_set_rates_++;
VideoBitrateAllocation adjusted_rate_allocation;
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
@@ -918,6 +924,7 @@
int num_encoder_initializations_ RTC_GUARDED_BY(local_crit_sect_) = 0;
std::vector<ResolutionBitrateLimits> resolution_bitrate_limits_
RTC_GUARDED_BY(local_crit_sect_);
+ int num_set_rates_ RTC_GUARDED_BY(local_crit_sect_) = 0;
};
class TestSink : public VideoStreamEncoder::EncoderSink {
@@ -4881,11 +4888,7 @@
// The rate settings should have been set again even though
// they haven't changed.
ASSERT_TRUE(current_rate_settings.has_value());
- EXPECT_EQ(prev_rate_settings->bitrate, current_rate_settings->bitrate);
- EXPECT_EQ(prev_rate_settings->framerate_fps,
- current_rate_settings->framerate_fps);
- EXPECT_EQ(prev_rate_settings->bandwidth_allocation,
- current_rate_settings->bandwidth_allocation);
+ EXPECT_EQ(prev_rate_settings, current_rate_settings);
video_stream_encoder_->Stop();
}
@@ -4975,4 +4978,75 @@
video_stream_encoder_->Stop();
}
+TEST_F(VideoStreamEncoderTest,
+ AllocationPropegratedToEncoderWhenTargetRateChanged) {
+ const int kFrameWidth = 320;
+ const int kFrameHeight = 180;
+
+ // Set initial rate.
+ auto rate = DataRate::kbps(100);
+ video_stream_encoder_->OnBitrateUpdated(
+ /*target_bitrate=*/rate,
+ /*stable_target_bitrate=*/rate,
+ /*link_allocation=*/rate,
+ /*fraction_lost=*/0,
+ /*rtt_ms=*/0);
+
+ // Insert a first video frame so that encoder gets configured.
+ int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
+ VideoFrame frame = CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight);
+ frame.set_rotation(kVideoRotation_270);
+ video_source_.IncomingCapturedFrame(frame);
+ WaitForEncodedFrame(timestamp_ms);
+ EXPECT_EQ(1, fake_encoder_.GetNumSetRates());
+
+ // Change of target bitrate propagates to the encoder.
+ auto new_stable_rate = rate - DataRate::kbps(5);
+ video_stream_encoder_->OnBitrateUpdated(
+ /*target_bitrate=*/new_stable_rate,
+ /*stable_target_bitrate=*/new_stable_rate,
+ /*link_allocation=*/rate,
+ /*fraction_lost=*/0,
+ /*rtt_ms=*/0);
+ video_stream_encoder_->WaitUntilTaskQueueIsIdle();
+ EXPECT_EQ(2, fake_encoder_.GetNumSetRates());
+ video_stream_encoder_->Stop();
+}
+
+TEST_F(VideoStreamEncoderTest,
+ AllocationNotPropegratedToEncoderWhenTargetRateUnchanged) {
+ const int kFrameWidth = 320;
+ const int kFrameHeight = 180;
+
+ // Set initial rate.
+ auto rate = DataRate::kbps(100);
+ video_stream_encoder_->OnBitrateUpdated(
+ /*target_bitrate=*/rate,
+ /*stable_target_bitrate=*/rate,
+ /*link_allocation=*/rate,
+ /*fraction_lost=*/0,
+ /*rtt_ms=*/0);
+
+ // Insert a first video frame so that encoder gets configured.
+ int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
+ VideoFrame frame = CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight);
+ frame.set_rotation(kVideoRotation_270);
+ video_source_.IncomingCapturedFrame(frame);
+ WaitForEncodedFrame(timestamp_ms);
+ EXPECT_EQ(1, fake_encoder_.GetNumSetRates());
+
+ // Set a higher target rate without changing the link_allocation. Should not
+ // reset encoder's rate.
+ auto new_stable_rate = rate - DataRate::kbps(5);
+ video_stream_encoder_->OnBitrateUpdated(
+ /*target_bitrate=*/rate,
+ /*stable_target_bitrate=*/new_stable_rate,
+ /*link_allocation=*/rate,
+ /*fraction_lost=*/0,
+ /*rtt_ms=*/0);
+ video_stream_encoder_->WaitUntilTaskQueueIsIdle();
+ EXPECT_EQ(1, fake_encoder_.GetNumSetRates());
+ video_stream_encoder_->Stop();
+}
+
} // namespace webrtc