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

Unified Diff: webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc

Issue 2335163002: Adding FrameLengthController to audio network adaptor. (Closed)
Patch Set: fixing windows bots Created 4 years, 3 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
Index: webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ff271d58b62315decac9b538eb1fc2e9112daab4
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h"
+
+#include <iterator>
+#include <utility>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+
+namespace webrtc {
+
+FrameLengthController::Config::Config(
+ const std::vector<int>& encoder_frame_lengths_ms,
+ int initial_frame_length_ms,
+ float fl_increasing_packet_loss_fraction,
+ float fl_decreasing_packet_loss_fraction,
+ int fl_20ms_to_60ms_bandwidth_bps,
+ int fl_60ms_to_20ms_bandwidth_bps)
+ : encoder_frame_lengths_ms(encoder_frame_lengths_ms),
+ initial_frame_length_ms(initial_frame_length_ms),
+ fl_increasing_packet_loss_fraction(fl_increasing_packet_loss_fraction),
+ fl_decreasing_packet_loss_fraction(fl_decreasing_packet_loss_fraction),
+ fl_20ms_to_60ms_bandwidth_bps(fl_20ms_to_60ms_bandwidth_bps),
+ fl_60ms_to_20ms_bandwidth_bps(fl_60ms_to_20ms_bandwidth_bps) {}
+
+FrameLengthController::Config::Config(const Config& other) = default;
+
+FrameLengthController::Config::~Config() = default;
+
+FrameLengthController::FrameLengthController(const Config& config)
+ : config_(config) {
+ // |encoder_frame_lengths_ms| must contain |initial_frame_length_ms|.
+ RTC_DCHECK(config_.encoder_frame_lengths_ms.end() !=
+ std::find(config_.encoder_frame_lengths_ms.begin(),
+ config_.encoder_frame_lengths_ms.end(),
+ config_.initial_frame_length_ms));
+
+ // We start with assuming that the receiver only accepts
+ // |config_.initial_frame_length_ms|.
+ run_time_frame_lengths_ms_.push_back(config_.initial_frame_length_ms);
+ frame_length_ms_ = run_time_frame_lengths_ms_.begin();
+
+ frame_length_change_criteria_.insert(std::make_pair(
+ FrameLengthChange(20, 60), config_.fl_20ms_to_60ms_bandwidth_bps));
+ frame_length_change_criteria_.insert(std::make_pair(
+ FrameLengthChange(60, 20), config_.fl_60ms_to_20ms_bandwidth_bps));
+}
+
+FrameLengthController::~FrameLengthController() = default;
+
+void FrameLengthController::MakeDecision(
+ const NetworkMetrics& metrics,
+ AudioNetworkAdaptor::EncoderRuntimeConfig* config) {
+ // Decision on |frame_length_ms| should not have been made.
+ RTC_DCHECK(!config->frame_length_ms);
+
+ if (FrameLengthIncreasingDecision(metrics, *config)) {
+ ++frame_length_ms_;
+ } else if (FrameLengthDecreasingDecision(metrics, *config)) {
+ --frame_length_ms_;
+ }
+ config->frame_length_ms = rtc::Optional<int>(*frame_length_ms_);
+}
+
+void FrameLengthController::SetConstraints(const Constraints& constraints) {
+ if (constraints.receiver_frame_length_range) {
+ SetReceiverFrameLengthRange(
+ constraints.receiver_frame_length_range->min_frame_length_ms,
+ constraints.receiver_frame_length_range->max_frame_length_ms);
+ }
+}
+
+FrameLengthController::FrameLengthChange::FrameLengthChange(
+ int from_frame_length_ms,
+ int to_frame_length_ms)
+ : from_frame_length_ms(from_frame_length_ms),
+ to_frame_length_ms(to_frame_length_ms) {}
+
+FrameLengthController::FrameLengthChange::~FrameLengthChange() = default;
+
+bool FrameLengthController::FrameLengthChange::operator<(
+ const FrameLengthChange& rhs) const {
+ return from_frame_length_ms < rhs.from_frame_length_ms ||
+ (from_frame_length_ms == rhs.from_frame_length_ms &&
+ to_frame_length_ms < rhs.to_frame_length_ms);
+}
+
+void FrameLengthController::SetReceiverFrameLengthRange(
+ int min_frame_length_ms,
+ int max_frame_length_ms) {
+ int frame_length_ms = *frame_length_ms_;
+ // Reset |run_time_frame_lengths_ms_| by filtering |config_.frame_lengths_ms|
+ // with the receiver frame length range.
+ run_time_frame_lengths_ms_.clear();
+ std::copy_if(config_.encoder_frame_lengths_ms.begin(),
+ config_.encoder_frame_lengths_ms.end(),
+ std::back_inserter(run_time_frame_lengths_ms_),
+ [&](int frame_length_ms) {
+ return frame_length_ms >= min_frame_length_ms &&
+ frame_length_ms <= max_frame_length_ms;
+ });
+ RTC_DCHECK(std::is_sorted(run_time_frame_lengths_ms_.begin(),
+ run_time_frame_lengths_ms_.end()));
+
+ // Keep the current frame length. If it has gone out of the new range, use
+ // the smallest available frame length.
+ frame_length_ms_ =
+ std::find(run_time_frame_lengths_ms_.begin(),
+ run_time_frame_lengths_ms_.end(), frame_length_ms);
+ if (frame_length_ms_ == run_time_frame_lengths_ms_.end()) {
+ LOG(LS_WARNING)
+ << "Actual frame length not in frame length range of the receiver";
+ frame_length_ms_ = run_time_frame_lengths_ms_.begin();
+ }
+}
+
+bool FrameLengthController::FrameLengthIncreasingDecision(
+ const NetworkMetrics& metrics,
+ const AudioNetworkAdaptor::EncoderRuntimeConfig& config) const {
+ // Increase frame length if
+ // 1. longer frame length is available AND
+ // 2. |uplink_bandwidth_bps| is known to be smaller than a threshold AND
+ // 3. |uplink_packet_loss_fraction| is known to be smaller than a threshold
+ // AND
+ // 4. FEC is not decided or is OFF.
+ auto longer_frame_length_ms = std::next(frame_length_ms_);
+ if (longer_frame_length_ms == run_time_frame_lengths_ms_.end())
+ return false;
+
+ auto increase_threshold = frame_length_change_criteria_.find(
+ FrameLengthChange(*frame_length_ms_, *longer_frame_length_ms));
+
+ if (increase_threshold == frame_length_change_criteria_.end())
+ return false;
+
+ return (metrics.uplink_bandwidth_bps &&
+ *metrics.uplink_bandwidth_bps <= increase_threshold->second) &&
+ (metrics.uplink_packet_loss_fraction &&
+ *metrics.uplink_packet_loss_fraction <=
+ config_.fl_increasing_packet_loss_fraction) &&
+ !config.enable_fec.value_or(false);
+}
+
+bool FrameLengthController::FrameLengthDecreasingDecision(
+ const NetworkMetrics& metrics,
+ const AudioNetworkAdaptor::EncoderRuntimeConfig& config) const {
+ // Decrease frame length if
+ // 1. shorter frame length is available AND one or more of the followings:
+ // 2. |uplink_bandwidth_bps| is known to be larger than a threshold,
+ // 3. |uplink_packet_loss_fraction| is known to be larger than a threshold,
+ // 4. FEC is decided ON.
+ if (frame_length_ms_ == run_time_frame_lengths_ms_.begin())
+ return false;
+
+ auto shorter_frame_length_ms = std::prev(frame_length_ms_);
+ auto decrease_threshold = frame_length_change_criteria_.find(
+ FrameLengthChange(*frame_length_ms_, *shorter_frame_length_ms));
+
+ if (decrease_threshold == frame_length_change_criteria_.end())
+ return false;
+
+ return (metrics.uplink_bandwidth_bps &&
+ *metrics.uplink_bandwidth_bps >= decrease_threshold->second) ||
+ (metrics.uplink_packet_loss_fraction &&
+ *metrics.uplink_packet_loss_fraction >=
+ config_.fl_decreasing_packet_loss_fraction) ||
+ config.enable_fec.value_or(false);
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698