Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2019 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 | |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 11 | #ifndef API_NETEQ_NETEQ_CONTROLLER_H_ |
| 12 | #define API_NETEQ_NETEQ_CONTROLLER_H_ |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 13 | |
| 14 | #include <cstddef> |
| 15 | #include <cstdint> |
| 16 | |
| 17 | #include <functional> |
| 18 | #include <memory> |
| 19 | |
| 20 | #include "absl/types/optional.h" |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 21 | #include "api/neteq/neteq.h" |
| 22 | #include "api/neteq/tick_timer.h" |
Ivo Creusen | 88636c6 | 2020-01-24 11:04:56 +0100 | [diff] [blame] | 23 | #include "system_wrappers/include/clock.h" |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 24 | |
| 25 | namespace webrtc { |
| 26 | |
| 27 | // Decides the actions that NetEq should take. This affects the behavior of the |
| 28 | // jitter buffer, and how it reacts to network conditions. |
| 29 | // This class will undergo substantial refactoring in the near future, and the |
| 30 | // API is expected to undergo significant changes. A target API is given below: |
| 31 | // |
| 32 | // class NetEqController { |
| 33 | // public: |
| 34 | // // Resets object to a clean state. |
| 35 | // void Reset(); |
| 36 | // // Given NetEq status, make a decision. |
| 37 | // Operation GetDecision(NetEqStatus neteq_status); |
| 38 | // // Register every packet received. |
| 39 | // void RegisterPacket(PacketInfo packet_info); |
| 40 | // // Register empty packet. |
| 41 | // void RegisterEmptyPacket(); |
| 42 | // // Register a codec switching. |
| 43 | // void CodecSwithed(); |
| 44 | // // Sets the sample rate. |
| 45 | // void SetSampleRate(int fs_hz); |
| 46 | // // Sets the packet length in samples. |
| 47 | // void SetPacketLengthSamples(); |
| 48 | // // Sets maximum delay. |
| 49 | // void SetMaximumDelay(int delay_ms); |
| 50 | // // Sets mininum delay. |
| 51 | // void SetMinimumDelay(int delay_ms); |
| 52 | // // Sets base mininum delay. |
| 53 | // void SetBaseMinimumDelay(int delay_ms); |
| 54 | // // Gets target buffer level. |
| 55 | // int GetTargetBufferLevelMs() const; |
| 56 | // // Gets filtered buffer level. |
| 57 | // int GetFilteredBufferLevel() const; |
| 58 | // // Gets base minimum delay. |
| 59 | // int GetBaseMinimumDelay() const; |
| 60 | // } |
| 61 | |
| 62 | class NetEqController { |
| 63 | public: |
| 64 | // This struct is used to create a NetEqController. |
| 65 | struct Config { |
| 66 | bool allow_time_stretching; |
| 67 | bool enable_rtx_handling; |
| 68 | int max_packets_in_buffer; |
| 69 | int base_min_delay_ms; |
| 70 | TickTimer* tick_timer; |
Ivo Creusen | 88636c6 | 2020-01-24 11:04:56 +0100 | [diff] [blame] | 71 | webrtc::Clock* clock = nullptr; |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 72 | }; |
| 73 | |
| 74 | struct PacketInfo { |
| 75 | uint32_t timestamp; |
| 76 | bool is_dtx; |
| 77 | bool is_cng; |
| 78 | }; |
| 79 | |
| 80 | struct PacketBufferInfo { |
| 81 | bool dtx_or_cng; |
| 82 | size_t num_samples; |
| 83 | size_t span_samples; |
| 84 | size_t span_samples_no_dtx; |
| 85 | size_t num_packets; |
| 86 | }; |
| 87 | |
| 88 | struct NetEqStatus { |
| 89 | uint32_t target_timestamp; |
| 90 | int16_t expand_mutefactor; |
| 91 | size_t last_packet_samples; |
| 92 | absl::optional<PacketInfo> next_packet; |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 93 | NetEq::Mode last_mode; |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 94 | bool play_dtmf; |
| 95 | size_t generated_noise_samples; |
| 96 | PacketBufferInfo packet_buffer_info; |
Ivo Creusen | 88636c6 | 2020-01-24 11:04:56 +0100 | [diff] [blame] | 97 | size_t sync_buffer_samples; |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 98 | }; |
| 99 | |
Ivo Creusen | a2b31c3 | 2020-10-14 17:54:22 +0200 | [diff] [blame] | 100 | struct PacketArrivedInfo { |
| 101 | size_t packet_length_samples; |
| 102 | uint32_t main_timestamp; |
| 103 | uint16_t main_sequence_number; |
| 104 | bool is_cng_or_dtmf; |
| 105 | bool is_dtx; |
Ivo Creusen | 7b463c5 | 2020-11-25 11:32:40 +0100 | [diff] [blame] | 106 | bool buffer_flush; |
Ivo Creusen | a2b31c3 | 2020-10-14 17:54:22 +0200 | [diff] [blame] | 107 | }; |
| 108 | |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 109 | virtual ~NetEqController() = default; |
| 110 | |
| 111 | // Resets object to a clean state. |
| 112 | virtual void Reset() = 0; |
| 113 | |
| 114 | // Resets parts of the state. Typically done when switching codecs. |
| 115 | virtual void SoftReset() = 0; |
| 116 | |
| 117 | // Given info about the latest received packet, and current jitter buffer |
Artem Titov | 0e61fdd | 2021-07-25 21:50:14 +0200 | [diff] [blame] | 118 | // status, returns the operation. `target_timestamp` and `expand_mutefactor` |
| 119 | // are provided for reference. `last_packet_samples` is the number of samples |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 120 | // obtained from the last decoded frame. If there is a packet available, it |
Artem Titov | 0e61fdd | 2021-07-25 21:50:14 +0200 | [diff] [blame] | 121 | // should be supplied in `packet`. The mode resulting from the last call to |
| 122 | // NetEqImpl::GetAudio is supplied in `last_mode`. If there is a DTMF event to |
| 123 | // play, `play_dtmf` should be set to true. The output variable |
| 124 | // `reset_decoder` will be set to true if a reset is required; otherwise it is |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 125 | // left unchanged (i.e., it can remain true if it was true before the call). |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 126 | virtual NetEq::Operation GetDecision(const NetEqStatus& status, |
| 127 | bool* reset_decoder) = 0; |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 128 | |
| 129 | // Inform NetEqController that an empty packet has arrived. |
| 130 | virtual void RegisterEmptyPacket() = 0; |
| 131 | |
| 132 | // Sets the sample rate and the output block size. |
| 133 | virtual void SetSampleRate(int fs_hz, size_t output_size_samples) = 0; |
| 134 | |
| 135 | // Sets a minimum or maximum delay in millisecond. |
| 136 | // Returns true if the delay bound is successfully applied, otherwise false. |
| 137 | virtual bool SetMaximumDelay(int delay_ms) = 0; |
| 138 | virtual bool SetMinimumDelay(int delay_ms) = 0; |
| 139 | |
| 140 | // Sets a base minimum delay in milliseconds for packet buffer. The effective |
| 141 | // minimum delay can't be lower than base minimum delay, even if a lower value |
| 142 | // is set using SetMinimumDelay. |
| 143 | // Returns true if the base minimum is successfully applied, otherwise false. |
| 144 | virtual bool SetBaseMinimumDelay(int delay_ms) = 0; |
| 145 | virtual int GetBaseMinimumDelay() const = 0; |
| 146 | |
Artem Titov | 0e61fdd | 2021-07-25 21:50:14 +0200 | [diff] [blame] | 147 | // These methods test the `cng_state_` for different conditions. |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 148 | virtual bool CngRfc3389On() const = 0; |
| 149 | virtual bool CngOff() const = 0; |
| 150 | |
Artem Titov | 0e61fdd | 2021-07-25 21:50:14 +0200 | [diff] [blame] | 151 | // Resets the `cng_state_` to kCngOff. |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 152 | virtual void SetCngOff() = 0; |
| 153 | |
| 154 | // Reports back to DecisionLogic whether the decision to do expand remains or |
| 155 | // not. Note that this is necessary, since an expand decision can be changed |
| 156 | // to kNormal in NetEqImpl::GetDecision if there is still enough data in the |
| 157 | // sync buffer. |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 158 | virtual void ExpandDecision(NetEq::Operation operation) = 0; |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 159 | |
Artem Titov | 0e61fdd | 2021-07-25 21:50:14 +0200 | [diff] [blame] | 160 | // Adds `value` to `sample_memory_`. |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 161 | virtual void AddSampleMemory(int32_t value) = 0; |
| 162 | |
| 163 | // Returns the target buffer level in ms. |
Niels Möller | 673027b | 2020-09-11 09:19:30 +0200 | [diff] [blame] | 164 | virtual int TargetLevelMs() const = 0; |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 165 | |
Ivo Creusen | 1a84b56 | 2022-07-19 16:33:10 +0200 | [diff] [blame] | 166 | // Returns the target buffer level in ms as it would be if no minimum or |
| 167 | // maximum delay was set. |
| 168 | // TODO(bugs.webrtc.org/14270): Make pure virtual once all implementations are |
| 169 | // updated. |
| 170 | virtual int UnlimitedTargetLevelMs() const { return 0; } |
| 171 | |
Ivo Creusen | a2b31c3 | 2020-10-14 17:54:22 +0200 | [diff] [blame] | 172 | // Notify the NetEqController that a packet has arrived. Returns the relative |
| 173 | // arrival delay, if it can be computed. |
Ivo Creusen | a2b31c3 | 2020-10-14 17:54:22 +0200 | [diff] [blame] | 174 | virtual absl::optional<int> PacketArrived(int fs_hz, |
| 175 | bool should_update_stats, |
Ivo Creusen | 2963d30 | 2020-10-15 17:13:31 +0200 | [diff] [blame] | 176 | const PacketArrivedInfo& info) = 0; |
| 177 | |
Ivo Creusen | 4354686 | 2020-10-06 17:29:09 +0200 | [diff] [blame] | 178 | // Notify the NetEqController that we are currently in muted state. |
Ivo Creusen | 1a84b56 | 2022-07-19 16:33:10 +0200 | [diff] [blame] | 179 | // TODO(bugs.webrtc.org/14270): Make pure virtual when downstream is updated. |
Ivo Creusen | 4354686 | 2020-10-06 17:29:09 +0200 | [diff] [blame] | 180 | virtual void NotifyMutedState() {} |
| 181 | |
Ivo Creusen | 53a31f7 | 2019-10-24 15:20:39 +0200 | [diff] [blame] | 182 | // Returns true if a peak was found. |
| 183 | virtual bool PeakFound() const = 0; |
| 184 | |
| 185 | // Get the filtered buffer level in samples. |
| 186 | virtual int GetFilteredBufferLevel() const = 0; |
| 187 | |
| 188 | // Accessors and mutators. |
| 189 | virtual void set_sample_memory(int32_t value) = 0; |
| 190 | virtual size_t noise_fast_forward() const = 0; |
| 191 | virtual size_t packet_length_samples() const = 0; |
| 192 | virtual void set_packet_length_samples(size_t value) = 0; |
| 193 | virtual void set_prev_time_scale(bool value) = 0; |
| 194 | }; |
| 195 | |
| 196 | } // namespace webrtc |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 197 | #endif // API_NETEQ_NETEQ_CONTROLLER_H_ |