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