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