Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(840)

Unified Diff: webrtc/test/fake_encoder.cc

Issue 2883963002: Periodically update codec bit/frame rate settings. (Closed)
Patch Set: Dumb typo Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/test/fake_encoder.h ('k') | webrtc/video/video_send_stream_tests.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/test/fake_encoder.cc
diff --git a/webrtc/test/fake_encoder.cc b/webrtc/test/fake_encoder.cc
index fce12c61a804c8af841435b001779374b912066c..962cd657a11df2a01c6191ce1e547fb5add45f36 100644
--- a/webrtc/test/fake_encoder.cc
+++ b/webrtc/test/fake_encoder.cc
@@ -24,11 +24,15 @@
namespace webrtc {
namespace test {
+const int kKeyframeSizeFactor = 10;
+
FakeEncoder::FakeEncoder(Clock* clock)
: clock_(clock),
callback_(nullptr),
+ configured_input_framerate_(-1),
max_target_bitrate_kbps_(-1),
- last_encode_time_ms_(0) {
+ pending_keyframe_(true),
+ debt_bytes_(0) {
// Generate some arbitrary not-all-zero data
for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
encoded_buffer_[i] = static_cast<uint8_t>(i);
@@ -47,6 +51,8 @@ int32_t FakeEncoder::InitEncode(const VideoCodec* config,
rtc::CritScope cs(&crit_sect_);
config_ = *config;
target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000);
+ configured_input_framerate_ = config_.maxFramerate;
+ pending_keyframe_ = true;
return 0;
}
@@ -59,9 +65,10 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
EncodedImageCallback* callback;
uint32_t target_bitrate_sum_kbps;
int max_target_bitrate_kbps;
- int64_t last_encode_time_ms;
size_t num_encoded_bytes;
+ int framerate;
VideoCodecMode mode;
+ bool keyframe;
{
rtc::CritScope cs(&crit_sect_);
max_framerate = config_.maxFramerate;
@@ -72,42 +79,33 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
callback = callback_;
target_bitrate_sum_kbps = target_bitrate_.get_sum_kbps();
max_target_bitrate_kbps = max_target_bitrate_kbps_;
- last_encode_time_ms = last_encode_time_ms_;
num_encoded_bytes = sizeof(encoded_buffer_);
mode = config_.mode;
+ if (configured_input_framerate_ > 0) {
+ framerate = configured_input_framerate_;
+ } else {
+ framerate = max_framerate;
+ }
+ keyframe = pending_keyframe_;
+ pending_keyframe_ = false;
}
- int64_t time_now_ms = clock_->TimeInMilliseconds();
- const bool first_encode = (last_encode_time_ms == 0);
- RTC_DCHECK_GT(max_framerate, 0);
- int64_t time_since_last_encode_ms = 1000 / max_framerate;
- if (!first_encode) {
- // For all frames but the first we can estimate the display time by looking
- // at the display time of the previous frame.
- time_since_last_encode_ms = time_now_ms - last_encode_time_ms;
- }
- if (time_since_last_encode_ms > 3 * 1000 / max_framerate) {
- // Rudimentary check to make sure we don't widely overshoot bitrate target
- // when resuming encoding after a suspension.
- time_since_last_encode_ms = 3 * 1000 / max_framerate;
+ for (FrameType frame_type : *frame_types) {
+ if (frame_type == kVideoFrameKey) {
+ keyframe = true;
+ break;
+ }
}
- size_t bits_available =
- static_cast<size_t>(target_bitrate_sum_kbps * time_since_last_encode_ms);
- size_t min_bits = static_cast<size_t>(simulcast_streams[0].minBitrate *
- time_since_last_encode_ms);
+ RTC_DCHECK_GT(max_framerate, 0);
- if (bits_available < min_bits)
- bits_available = min_bits;
- size_t max_bits =
- static_cast<size_t>(max_target_bitrate_kbps * time_since_last_encode_ms);
- if (max_bits > 0 && max_bits < bits_available)
- bits_available = max_bits;
+ size_t bitrate = target_bitrate_sum_kbps;
+ bitrate =
+ std::max(bitrate, static_cast<size_t>(simulcast_streams[0].minBitrate));
+ if (max_target_bitrate_kbps > 0)
+ bitrate = std::min(bitrate, static_cast<size_t>(max_target_bitrate_kbps));
- {
- rtc::CritScope cs(&crit_sect_);
- last_encode_time_ms_ = time_now_ms;
- }
+ size_t bits_available = target_bitrate_sum_kbps * 1000 / framerate;
RTC_DCHECK_GT(num_simulcast_streams, 0);
for (unsigned char i = 0; i < num_simulcast_streams; ++i) {
@@ -116,18 +114,27 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
specifics.codecType = kVideoCodecGeneric;
specifics.codecSpecific.generic.simulcast_idx = i;
size_t min_stream_bits = static_cast<size_t>(
- simulcast_streams[i].minBitrate * time_since_last_encode_ms);
+ (simulcast_streams[i].minBitrate * 1000) / framerate);
size_t max_stream_bits = static_cast<size_t>(
- simulcast_streams[i].maxBitrate * time_since_last_encode_ms);
+ (simulcast_streams[i].maxBitrate * 1000) / framerate);
size_t stream_bits = (bits_available > max_stream_bits) ? max_stream_bits :
bits_available;
size_t stream_bytes = (stream_bits + 7) / 8;
- if (first_encode) {
+ if (keyframe) {
// The first frame is a key frame and should be larger.
- // TODO(holmer): The FakeEncoder should store the bits_available between
- // encodes so that it can compensate for oversized frames.
- stream_bytes *= 10;
+ // Store the overshoot bytes and distribute them over the coming frames,
+ // so that we on average meet the bitrate target.
+ debt_bytes_ += (kKeyframeSizeFactor - 1) * stream_bytes;
+ stream_bytes *= kKeyframeSizeFactor;
+ } else {
+ if (debt_bytes_ > 0) {
+ // Pay at most half of the frame size for old debts.
+ size_t payment_size = std::min(stream_bytes / 2, debt_bytes_);
+ debt_bytes_ -= payment_size;
+ stream_bytes -= payment_size;
+ }
}
+
if (stream_bytes > num_encoded_bytes)
stream_bytes = num_encoded_bytes;
@@ -175,6 +182,7 @@ int32_t FakeEncoder::SetRateAllocation(const BitrateAllocation& rate_allocation,
uint32_t framerate) {
rtc::CritScope cs(&crit_sect_);
target_bitrate_ = rate_allocation;
+ configured_input_framerate_ = framerate;
return 0;
}
@@ -183,6 +191,11 @@ const char* FakeEncoder::ImplementationName() const {
return kImplementationName;
}
+int FakeEncoder::GetConfiguredInputFramerate() const {
+ rtc::CritScope cs(&crit_sect_);
+ return configured_input_framerate_;
+}
+
FakeH264Encoder::FakeH264Encoder(Clock* clock)
: FakeEncoder(clock), callback_(nullptr), idr_counter_(0) {
FakeEncoder::RegisterEncodeCompleteCallback(this);
« no previous file with comments | « webrtc/test/fake_encoder.h ('k') | webrtc/video/video_send_stream_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698