aboutsummaryrefslogtreecommitdiff
path: root/cast/standalone_sender/streaming_video_encoder.cc
diff options
context:
space:
mode:
authorKennan Gumbs <kennangumbs@google.com>2021-08-10 18:46:42 -0400
committerOpenscreen LUCI CQ <openscreen-scoped@luci-project-accounts.iam.gserviceaccount.com>2021-08-11 17:02:39 +0000
commit65bcc6e2e999734396ed5abef202b1bfe4228e21 (patch)
tree521c5027f7d80f248994d3240b51d9210b3df251 /cast/standalone_sender/streaming_video_encoder.cc
parent8b2ec3ddc163fe9c5216d4869d3b5f0c7efd33b1 (diff)
downloadopenscreen-65bcc6e2e999734396ed5abef202b1bfe4228e21.tar.gz
Enable AV1 codec in standalone sender and receiver
This patch adds support for AV1 using libaom. It also adds documentation for compiling libaom from source, since the version provided by the Linux package manager is too slow for realistic use. Change-Id: Icd0bb3001a1107087749de9e24a9781b3b8b04d4 Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/3066030 Commit-Queue: Jordan Bayles <jophba@chromium.org> Reviewed-by: Jordan Bayles <jophba@chromium.org>
Diffstat (limited to 'cast/standalone_sender/streaming_video_encoder.cc')
-rw-r--r--cast/standalone_sender/streaming_video_encoder.cc57
1 files changed, 57 insertions, 0 deletions
diff --git a/cast/standalone_sender/streaming_video_encoder.cc b/cast/standalone_sender/streaming_video_encoder.cc
new file mode 100644
index 00000000..0e15ab2c
--- /dev/null
+++ b/cast/standalone_sender/streaming_video_encoder.cc
@@ -0,0 +1,57 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cast/standalone_sender/streaming_video_encoder.h"
+
+#include "util/chrono_helpers.h"
+
+namespace openscreen {
+namespace cast {
+
+StreamingVideoEncoder::StreamingVideoEncoder(const Parameters& params,
+ TaskRunner* task_runner,
+ Sender* sender)
+ : params_(params), main_task_runner_(task_runner), sender_(sender) {
+ OSP_DCHECK_LE(1, params_.num_encode_threads);
+ OSP_DCHECK_LE(kMinQuantizer, params_.min_quantizer);
+ OSP_DCHECK_LE(params_.min_quantizer, params_.max_cpu_saver_quantizer);
+ OSP_DCHECK_LE(params_.max_cpu_saver_quantizer, params_.max_quantizer);
+ OSP_DCHECK_LE(params_.max_quantizer, kMaxQuantizer);
+ OSP_DCHECK_LT(0.0, params_.max_time_utilization);
+ OSP_DCHECK_LE(params_.max_time_utilization, 1.0);
+ OSP_DCHECK(main_task_runner_);
+ OSP_DCHECK(sender_);
+}
+
+StreamingVideoEncoder::~StreamingVideoEncoder() {}
+
+void StreamingVideoEncoder::UpdateSpeedSettingForNextFrame(const Stats& stats) {
+ OSP_DCHECK_EQ(std::this_thread::get_id(), encode_thread_.get_id());
+
+ // Combine the speed setting that was used to encode the last frame, and the
+ // quantizer the encoder chose into a single speed metric.
+ const double speed = current_speed_setting_ +
+ kEquivalentEncodingSpeedStepPerQuantizerStep *
+ std::max(0, stats.quantizer - params_.min_quantizer);
+
+ // Like |Stats::perfect_quantizer|, this computes a "hindsight" speed setting
+ // for the last frame, one that may have potentially allowed for a
+ // better-quality quantizer choice by the encoder, while also keeping CPU
+ // utilization within budget.
+ const double perfect_speed =
+ speed * stats.time_utilization() / params_.max_time_utilization;
+
+ // Update the ideal speed setting, to be used for the next frame. An
+ // exponentially-decaying weighted average is used here to smooth-out noise.
+ // The weight is based on the duration of the frame that was encoded.
+ constexpr Clock::duration kDecayHalfLife = milliseconds(120);
+ const double ticks = stats.frame_duration.count();
+ const double weight = ticks / (ticks + kDecayHalfLife.count());
+ ideal_speed_setting_ =
+ weight * perfect_speed + (1.0 - weight) * ideal_speed_setting_;
+ OSP_DCHECK(std::isfinite(ideal_speed_setting_));
+}
+
+} // namespace cast
+} // namespace openscreen