1 /*
2 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h"
12
13 #include <algorithm>
14
15 #include "absl/algorithm/container.h"
16 #include "rtc_base/checks.h"
17
18 namespace webrtc {
19 namespace {
20
OverheadBps(int overhead_bytes_per_packet,int frame_length_ms)21 int OverheadBps(int overhead_bytes_per_packet, int frame_length_ms) {
22 return overhead_bytes_per_packet * 8 * 1000 / frame_length_ms;
23 }
24
25 } // namespace
26
FrameLengthControllerV2(rtc::ArrayView<const int> encoder_frame_lengths_ms,int min_payload_bitrate_bps,bool use_slow_adaptation)27 FrameLengthControllerV2::FrameLengthControllerV2(
28 rtc::ArrayView<const int> encoder_frame_lengths_ms,
29 int min_payload_bitrate_bps,
30 bool use_slow_adaptation)
31 : encoder_frame_lengths_ms_(encoder_frame_lengths_ms.begin(),
32 encoder_frame_lengths_ms.end()),
33 min_payload_bitrate_bps_(min_payload_bitrate_bps),
34 use_slow_adaptation_(use_slow_adaptation) {
35 RTC_CHECK(!encoder_frame_lengths_ms_.empty());
36 absl::c_sort(encoder_frame_lengths_ms_);
37 }
38
UpdateNetworkMetrics(const NetworkMetrics & network_metrics)39 void FrameLengthControllerV2::UpdateNetworkMetrics(
40 const NetworkMetrics& network_metrics) {
41 if (network_metrics.target_audio_bitrate_bps) {
42 target_bitrate_bps_ = network_metrics.target_audio_bitrate_bps;
43 }
44 if (network_metrics.overhead_bytes_per_packet) {
45 overhead_bytes_per_packet_ = network_metrics.overhead_bytes_per_packet;
46 }
47 if (network_metrics.uplink_bandwidth_bps) {
48 uplink_bandwidth_bps_ = network_metrics.uplink_bandwidth_bps;
49 }
50 }
51
MakeDecision(AudioEncoderRuntimeConfig * config)52 void FrameLengthControllerV2::MakeDecision(AudioEncoderRuntimeConfig* config) {
53 if (!target_bitrate_bps_ || !overhead_bytes_per_packet_ ||
54 !uplink_bandwidth_bps_) {
55 return;
56 }
57
58 auto it =
59 absl::c_find_if(encoder_frame_lengths_ms_, [&](int frame_length_ms) {
60 int target = use_slow_adaptation_ ? *uplink_bandwidth_bps_
61 : *target_bitrate_bps_;
62 return target -
63 OverheadBps(*overhead_bytes_per_packet_, frame_length_ms) >
64 min_payload_bitrate_bps_;
65 });
66
67 // Longest frame length is chosen if none match our criteria.
68 config->frame_length_ms = it != encoder_frame_lengths_ms_.end()
69 ? *it
70 : encoder_frame_lengths_ms_.back();
71 }
72
73 } // namespace webrtc
74