2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_coding/neteq/decision_logic_normal.h"
17 #include "webrtc/modules/audio_coding/neteq/buffer_level_filter.h"
18 #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
19 #include "webrtc/modules/audio_coding/neteq/delay_manager.h"
20 #include "webrtc/modules/audio_coding/neteq/expand.h"
21 #include "webrtc/modules/audio_coding/neteq/packet_buffer.h"
22 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
23 #include "webrtc/modules/interface/module_common_types.h"
27 Operations DecisionLogicNormal::GetDecisionSpecialized(
28 const SyncBuffer& sync_buffer,
30 int decoder_frame_length,
31 const RTPHeader* packet_header,
34 bool* reset_decoder) {
35 assert(playout_mode_ == kPlayoutOn || playout_mode_ == kPlayoutStreaming);
36 // Guard for errors, to avoid getting stuck in error mode.
37 if (prev_mode == kModeError) {
41 return kUndefined; // Use kUndefined to flag for a reset.
45 uint32_t target_timestamp = sync_buffer.end_timestamp();
46 uint32_t available_timestamp = 0;
47 bool is_cng_packet = false;
49 available_timestamp = packet_header->timestamp;
51 decoder_database_->IsComfortNoise(packet_header->payloadType);
55 return CngOperation(prev_mode, target_timestamp, available_timestamp);
58 // Handle the case with no packet at all available (except maybe DTMF).
60 return NoPacket(play_dtmf);
63 // If the expand period was very long, reset NetEQ since it is likely that the
64 // sender was restarted.
65 if (num_consecutive_expands_ > kReinitAfterExpands) {
66 *reset_decoder = true;
70 const uint32_t five_seconds_samples = 5 * 8000 * fs_mult_;
71 // Check if the required packet is available.
72 if (target_timestamp == available_timestamp) {
73 return ExpectedPacketAvailable(prev_mode, play_dtmf);
74 } else if (!PacketBuffer::IsObsoleteTimestamp(
75 available_timestamp, target_timestamp, five_seconds_samples)) {
76 return FuturePacketAvailable(sync_buffer, expand, decoder_frame_length,
77 prev_mode, target_timestamp,
78 available_timestamp, play_dtmf);
80 // This implies that available_timestamp < target_timestamp, which can
81 // happen when a new stream or codec is received. Signal for a reset.
86 Operations DecisionLogicNormal::CngOperation(Modes prev_mode,
87 uint32_t target_timestamp,
88 uint32_t available_timestamp) {
89 // Signed difference between target and available timestamp.
90 int32_t timestamp_diff = (generated_noise_samples_ + target_timestamp) -
92 int32_t optimal_level_samp =
93 (delay_manager_->TargetLevel() * packet_length_samples_) >> 8;
94 int32_t excess_waiting_time_samp = -timestamp_diff - optimal_level_samp;
96 if (excess_waiting_time_samp > optimal_level_samp / 2) {
97 // The waiting time for this packet will be longer than 1.5
98 // times the wanted buffer delay. Advance the clock to cut
99 // waiting time down to the optimal.
100 generated_noise_samples_ += excess_waiting_time_samp;
101 timestamp_diff += excess_waiting_time_samp;
104 if (timestamp_diff < 0 && prev_mode == kModeRfc3389Cng) {
105 // Not time to play this packet yet. Wait another round before using this
106 // packet. Keep on playing CNG from previous CNG parameters.
107 return kRfc3389CngNoPacket;
109 // Otherwise, go for the CNG packet now.
114 Operations DecisionLogicNormal::NoPacket(bool play_dtmf) {
115 if (cng_state_ == kCngRfc3389On) {
116 // Keep on playing comfort noise.
117 return kRfc3389CngNoPacket;
118 } else if (cng_state_ == kCngInternalOn) {
119 // Keep on playing codec internal comfort noise.
120 return kCodecInternalCng;
121 } else if (play_dtmf) {
124 // Nothing to play, do expand.
129 Operations DecisionLogicNormal::ExpectedPacketAvailable(Modes prev_mode,
131 if (prev_mode != kModeExpand && !play_dtmf) {
132 // Check criterion for time-stretching.
133 int low_limit, high_limit;
134 delay_manager_->BufferLimits(&low_limit, &high_limit);
135 if ((buffer_level_filter_->filtered_current_level() >= high_limit &&
136 TimescaleAllowed()) ||
137 buffer_level_filter_->filtered_current_level() >= high_limit << 2) {
138 // Buffer level higher than limit and time-scaling allowed,
139 // or buffer level really high.
141 } else if ((buffer_level_filter_->filtered_current_level() < low_limit)
142 && TimescaleAllowed()) {
143 return kPreemptiveExpand;
149 Operations DecisionLogicNormal::FuturePacketAvailable(
150 const SyncBuffer& sync_buffer,
151 const Expand& expand,
152 int decoder_frame_length,
154 uint32_t target_timestamp,
155 uint32_t available_timestamp,
157 // Required packet is not available, but a future packet is.
158 // Check if we should continue with an ongoing expand because the new packet
159 // is too far into the future.
160 uint32_t timestamp_leap = available_timestamp - target_timestamp;
161 if ((prev_mode == kModeExpand) &&
162 !ReinitAfterExpands(timestamp_leap) &&
163 !MaxWaitForPacket() &&
164 PacketTooEarly(timestamp_leap) &&
165 UnderTargetLevel()) {
167 // Still have DTMF to play, so do not do expand.
175 const int samples_left = static_cast<int>(sync_buffer.FutureLength() -
176 expand.overlap_length());
177 const int cur_size_samples = samples_left +
178 packet_buffer_.NumPacketsInBuffer() * decoder_frame_length;
180 // If previous was comfort noise, then no merge is needed.
181 if (prev_mode == kModeRfc3389Cng ||
182 prev_mode == kModeCodecInternalCng) {
183 // Keep the same delay as before the CNG (or maximum 70 ms in buffer as
184 // safety precaution), but make sure that the number of samples in buffer
185 // is no higher than 4 times the optimal level. (Note that TargetLevel()
187 int32_t timestamp_diff = (generated_noise_samples_ + target_timestamp) -
189 if (timestamp_diff >= 0 ||
191 4 * ((delay_manager_->TargetLevel() * packet_length_samples_) >> 8)) {
192 // Time to play this new packet.
195 // Too early to play this new packet; keep on playing comfort noise.
196 if (prev_mode == kModeRfc3389Cng) {
197 return kRfc3389CngNoPacket;
198 } else { // prevPlayMode == kModeCodecInternalCng.
199 return kCodecInternalCng;
203 // Do not merge unless we have done an expand before.
204 // (Convert kAllowMergeWithoutExpand from ms to samples by multiplying with
205 // fs_mult_ * 8 = fs / 1000.)
206 if (prev_mode == kModeExpand ||
207 (decoder_frame_length < output_size_samples_ &&
208 cur_size_samples > kAllowMergeWithoutExpandMs * fs_mult_ * 8)) {
210 } else if (play_dtmf) {
211 // Play DTMF instead of expand.
218 bool DecisionLogicNormal::UnderTargetLevel() const {
219 return buffer_level_filter_->filtered_current_level() <=
220 delay_manager_->TargetLevel();
223 bool DecisionLogicNormal::ReinitAfterExpands(uint32_t timestamp_leap) const {
224 return timestamp_leap >=
225 static_cast<uint32_t>(output_size_samples_ * kReinitAfterExpands);
228 bool DecisionLogicNormal::PacketTooEarly(uint32_t timestamp_leap) const {
229 return timestamp_leap >
230 static_cast<uint32_t>(output_size_samples_ * num_consecutive_expands_);
233 bool DecisionLogicNormal::MaxWaitForPacket() const {
234 return num_consecutive_expands_ >= kMaxWaitForPacket;
237 } // namespace webrtc