1 /* 2 * Copyright (c) 2013 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 #ifndef MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_ 12 #define MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_ 13 14 #include <memory> 15 16 #include "api/neteq/neteq.h" 17 #include "api/neteq/neteq_controller.h" 18 #include "api/neteq/tick_timer.h" 19 #include "modules/audio_coding/neteq/buffer_level_filter.h" 20 #include "modules/audio_coding/neteq/delay_manager.h" 21 #include "modules/audio_coding/neteq/packet_arrival_history.h" 22 #include "rtc_base/experiments/field_trial_parser.h" 23 24 namespace webrtc { 25 26 // This is the class for the decision tree implementation. 27 class DecisionLogic : public NetEqController { 28 public: 29 DecisionLogic(NetEqController::Config config); 30 DecisionLogic(NetEqController::Config config, 31 std::unique_ptr<DelayManager> delay_manager, 32 std::unique_ptr<BufferLevelFilter> buffer_level_filter); 33 34 ~DecisionLogic() override; 35 36 DecisionLogic(const DecisionLogic&) = delete; 37 DecisionLogic& operator=(const DecisionLogic&) = delete; 38 39 // Not used. Reset()40 void Reset() override {} 41 42 // Resets parts of the state. Typically done when switching codecs. 43 void SoftReset() override; 44 45 // Sets the sample rate and the output block size. 46 void SetSampleRate(int fs_hz, size_t output_size_samples) override; 47 48 // Given info about the latest received packet, and current jitter buffer 49 // status, returns the operation. `target_timestamp` and `expand_mutefactor` 50 // are provided for reference. `last_packet_samples` is the number of samples 51 // obtained from the last decoded frame. If there is a packet available, it 52 // should be supplied in `packet`; otherwise it should be NULL. The mode 53 // resulting from the last call to NetEqImpl::GetAudio is supplied in 54 // `last_mode`. If there is a DTMF event to play, `play_dtmf` should be set to 55 // true. The output variable `reset_decoder` will be set to true if a reset is 56 // required; otherwise it is left unchanged (i.e., it can remain true if it 57 // was true before the call). 58 NetEq::Operation GetDecision(const NetEqController::NetEqStatus& status, 59 bool* reset_decoder) override; 60 61 // These methods test the `cng_state_` for different conditions. CngRfc3389On()62 bool CngRfc3389On() const override { return cng_state_ == kCngRfc3389On; } CngOff()63 bool CngOff() const override { return cng_state_ == kCngOff; } 64 65 // Resets the `cng_state_` to kCngOff. SetCngOff()66 void SetCngOff() override { cng_state_ = kCngOff; } 67 ExpandDecision(NetEq::Operation operation)68 void ExpandDecision(NetEq::Operation operation) override {} 69 70 // Adds `value` to `sample_memory_`. AddSampleMemory(int32_t value)71 void AddSampleMemory(int32_t value) override { sample_memory_ += value; } 72 73 int TargetLevelMs() const override; 74 75 int UnlimitedTargetLevelMs() const override; 76 77 absl::optional<int> PacketArrived(int fs_hz, 78 bool should_update_stats, 79 const PacketArrivedInfo& info) override; 80 RegisterEmptyPacket()81 void RegisterEmptyPacket() override {} 82 83 void NotifyMutedState() override; 84 SetMaximumDelay(int delay_ms)85 bool SetMaximumDelay(int delay_ms) override { 86 return delay_manager_->SetMaximumDelay(delay_ms); 87 } SetMinimumDelay(int delay_ms)88 bool SetMinimumDelay(int delay_ms) override { 89 return delay_manager_->SetMinimumDelay(delay_ms); 90 } SetBaseMinimumDelay(int delay_ms)91 bool SetBaseMinimumDelay(int delay_ms) override { 92 return delay_manager_->SetBaseMinimumDelay(delay_ms); 93 } GetBaseMinimumDelay()94 int GetBaseMinimumDelay() const override { 95 return delay_manager_->GetBaseMinimumDelay(); 96 } PeakFound()97 bool PeakFound() const override { return false; } 98 99 int GetFilteredBufferLevel() const override; 100 101 // Accessors and mutators. set_sample_memory(int32_t value)102 void set_sample_memory(int32_t value) override { sample_memory_ = value; } noise_fast_forward()103 size_t noise_fast_forward() const override { return noise_fast_forward_; } packet_length_samples()104 size_t packet_length_samples() const override { 105 return packet_length_samples_; 106 } set_packet_length_samples(size_t value)107 void set_packet_length_samples(size_t value) override { 108 packet_length_samples_ = value; 109 } set_prev_time_scale(bool value)110 void set_prev_time_scale(bool value) override { prev_time_scale_ = value; } 111 112 private: 113 // The value 5 sets maximum time-stretch rate to about 100 ms/s. 114 static const int kMinTimescaleInterval = 5; 115 116 enum CngState { kCngOff, kCngRfc3389On, kCngInternalOn }; 117 118 // Updates the `buffer_level_filter_` with the current buffer level 119 // `buffer_size_samples`. 120 void FilterBufferLevel(size_t buffer_size_samples); 121 122 // Returns the operation given that the next available packet is a comfort 123 // noise payload (RFC 3389 only, not codec-internal). 124 virtual NetEq::Operation CngOperation(NetEqController::NetEqStatus status); 125 126 // Returns the operation given that no packets are available (except maybe 127 // a DTMF event, flagged by setting `play_dtmf` true). 128 virtual NetEq::Operation NoPacket(NetEqController::NetEqStatus status); 129 130 // Returns the operation to do given that the expected packet is available. 131 virtual NetEq::Operation ExpectedPacketAvailable( 132 NetEqController::NetEqStatus status); 133 134 // Returns the operation to do given that the expected packet is not 135 // available, but a packet further into the future is at hand. 136 virtual NetEq::Operation FuturePacketAvailable( 137 NetEqController::NetEqStatus status); 138 139 // Checks if enough time has elapsed since the last successful timescale 140 // operation was done (i.e., accelerate or preemptive expand). TimescaleAllowed()141 bool TimescaleAllowed() const { 142 return !timescale_countdown_ || timescale_countdown_->Finished(); 143 } 144 145 // Checks if the current (filtered) buffer level is under the target level. 146 bool UnderTargetLevel() const; 147 148 // Checks if `timestamp_leap` is so long into the future that a reset due 149 // to exceeding kReinitAfterExpands will be done. 150 bool ReinitAfterExpands(uint32_t timestamp_leap) const; 151 152 // Checks if we still have not done enough expands to cover the distance from 153 // the last decoded packet to the next available packet, the distance beeing 154 // conveyed in `timestamp_leap`. 155 bool PacketTooEarly(uint32_t timestamp_leap) const; 156 157 bool MaxWaitForPacket() const; 158 159 bool ShouldContinueExpand(NetEqController::NetEqStatus status) const; 160 161 int GetNextPacketDelayMs(NetEqController::NetEqStatus status) const; 162 int GetPlayoutDelayMs(NetEqController::NetEqStatus status) const; 163 164 int LowThreshold() const; 165 int HighThreshold() const; 166 int LowThresholdCng() const; 167 int HighThresholdCng() const; 168 169 // Runtime configurable options through field trial 170 // WebRTC-Audio-NetEqDecisionLogicConfig. 171 struct Config { 172 Config(); 173 174 bool enable_stable_playout_delay = false; 175 int reinit_after_expands = 100; 176 int deceleration_target_level_offset_ms = 85; 177 int packet_history_size_ms = 2000; 178 }; 179 Config config_; 180 std::unique_ptr<DelayManager> delay_manager_; 181 std::unique_ptr<BufferLevelFilter> buffer_level_filter_; 182 PacketArrivalHistory packet_arrival_history_; 183 const TickTimer* tick_timer_; 184 int sample_rate_khz_; 185 size_t output_size_samples_; 186 CngState cng_state_ = kCngOff; // Remember if comfort noise is interrupted by 187 // other event (e.g., DTMF). 188 size_t noise_fast_forward_ = 0; 189 size_t packet_length_samples_ = 0; 190 int sample_memory_ = 0; 191 bool prev_time_scale_ = false; 192 bool disallow_time_stretching_; 193 std::unique_ptr<TickTimer::Countdown> timescale_countdown_; 194 int num_consecutive_expands_ = 0; 195 int time_stretched_cn_samples_ = 0; 196 bool buffer_flush_ = false; 197 int last_playout_delay_ms_ = 0; 198 }; 199 200 } // namespace webrtc 201 #endif // MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_ 202