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