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 #include "webrtc/modules/audio_coding/neteq/decision_logic_normal.h"
12
13 #include <assert.h>
14
15 #include <algorithm>
16
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/include/module_common_types.h"
24
25 namespace webrtc {
26
GetDecisionSpecialized(const SyncBuffer & sync_buffer,const Expand & expand,size_t decoder_frame_length,const RTPHeader * packet_header,Modes prev_mode,bool play_dtmf,bool * reset_decoder)27 Operations DecisionLogicNormal::GetDecisionSpecialized(
28 const SyncBuffer& sync_buffer,
29 const Expand& expand,
30 size_t decoder_frame_length,
31 const RTPHeader* packet_header,
32 Modes prev_mode,
33 bool play_dtmf,
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) {
38 if (!packet_header) {
39 return kExpand;
40 } else {
41 return kUndefined; // Use kUndefined to flag for a reset.
42 }
43 }
44
45 uint32_t target_timestamp = sync_buffer.end_timestamp();
46 uint32_t available_timestamp = 0;
47 bool is_cng_packet = false;
48 if (packet_header) {
49 available_timestamp = packet_header->timestamp;
50 is_cng_packet =
51 decoder_database_->IsComfortNoise(packet_header->payloadType);
52 }
53
54 if (is_cng_packet) {
55 return CngOperation(prev_mode, target_timestamp, available_timestamp);
56 }
57
58 // Handle the case with no packet at all available (except maybe DTMF).
59 if (!packet_header) {
60 return NoPacket(play_dtmf);
61 }
62
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;
67 return kNormal;
68 }
69
70 const uint32_t five_seconds_samples =
71 static_cast<uint32_t>(5 * 8000 * fs_mult_);
72 // Check if the required packet is available.
73 if (target_timestamp == available_timestamp) {
74 return ExpectedPacketAvailable(prev_mode, play_dtmf);
75 } else if (!PacketBuffer::IsObsoleteTimestamp(
76 available_timestamp, target_timestamp, five_seconds_samples)) {
77 return FuturePacketAvailable(sync_buffer, expand, decoder_frame_length,
78 prev_mode, target_timestamp,
79 available_timestamp, play_dtmf);
80 } else {
81 // This implies that available_timestamp < target_timestamp, which can
82 // happen when a new stream or codec is received. Signal for a reset.
83 return kUndefined;
84 }
85 }
86
CngOperation(Modes prev_mode,uint32_t target_timestamp,uint32_t available_timestamp)87 Operations DecisionLogicNormal::CngOperation(Modes prev_mode,
88 uint32_t target_timestamp,
89 uint32_t available_timestamp) {
90 // Signed difference between target and available timestamp.
91 int32_t timestamp_diff = static_cast<int32_t>(
92 static_cast<uint32_t>(generated_noise_samples_ + target_timestamp) -
93 available_timestamp);
94 int32_t optimal_level_samp = static_cast<int32_t>(
95 (delay_manager_->TargetLevel() * packet_length_samples_) >> 8);
96 int32_t excess_waiting_time_samp = -timestamp_diff - optimal_level_samp;
97
98 if (excess_waiting_time_samp > optimal_level_samp / 2) {
99 // The waiting time for this packet will be longer than 1.5
100 // times the wanted buffer delay. Advance the clock to cut
101 // waiting time down to the optimal.
102 generated_noise_samples_ += excess_waiting_time_samp;
103 timestamp_diff += excess_waiting_time_samp;
104 }
105
106 if (timestamp_diff < 0 && prev_mode == kModeRfc3389Cng) {
107 // Not time to play this packet yet. Wait another round before using this
108 // packet. Keep on playing CNG from previous CNG parameters.
109 return kRfc3389CngNoPacket;
110 } else {
111 // Otherwise, go for the CNG packet now.
112 return kRfc3389Cng;
113 }
114 }
115
NoPacket(bool play_dtmf)116 Operations DecisionLogicNormal::NoPacket(bool play_dtmf) {
117 if (cng_state_ == kCngRfc3389On) {
118 // Keep on playing comfort noise.
119 return kRfc3389CngNoPacket;
120 } else if (cng_state_ == kCngInternalOn) {
121 // Keep on playing codec internal comfort noise.
122 return kCodecInternalCng;
123 } else if (play_dtmf) {
124 return kDtmf;
125 } else {
126 // Nothing to play, do expand.
127 return kExpand;
128 }
129 }
130
ExpectedPacketAvailable(Modes prev_mode,bool play_dtmf)131 Operations DecisionLogicNormal::ExpectedPacketAvailable(Modes prev_mode,
132 bool play_dtmf) {
133 if (prev_mode != kModeExpand && !play_dtmf) {
134 // Check criterion for time-stretching.
135 int low_limit, high_limit;
136 delay_manager_->BufferLimits(&low_limit, &high_limit);
137 if (buffer_level_filter_->filtered_current_level() >= high_limit << 2)
138 return kFastAccelerate;
139 if (TimescaleAllowed()) {
140 if (buffer_level_filter_->filtered_current_level() >= high_limit)
141 return kAccelerate;
142 if (buffer_level_filter_->filtered_current_level() < low_limit)
143 return kPreemptiveExpand;
144 }
145 }
146 return kNormal;
147 }
148
FuturePacketAvailable(const SyncBuffer & sync_buffer,const Expand & expand,size_t decoder_frame_length,Modes prev_mode,uint32_t target_timestamp,uint32_t available_timestamp,bool play_dtmf)149 Operations DecisionLogicNormal::FuturePacketAvailable(
150 const SyncBuffer& sync_buffer,
151 const Expand& expand,
152 size_t decoder_frame_length,
153 Modes prev_mode,
154 uint32_t target_timestamp,
155 uint32_t available_timestamp,
156 bool play_dtmf) {
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()) {
166 if (play_dtmf) {
167 // Still have DTMF to play, so do not do expand.
168 return kDtmf;
169 } else {
170 // Nothing to play.
171 return kExpand;
172 }
173 }
174
175 const size_t samples_left =
176 sync_buffer.FutureLength() - expand.overlap_length();
177 const size_t cur_size_samples = samples_left +
178 packet_buffer_.NumPacketsInBuffer() * decoder_frame_length;
179
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()
186 // is in Q8.)
187 if (static_cast<uint32_t>(generated_noise_samples_ + target_timestamp) >=
188 available_timestamp ||
189 cur_size_samples >
190 ((delay_manager_->TargetLevel() * packet_length_samples_) >> 8) *
191 4) {
192 // Time to play this new packet.
193 return kNormal;
194 } else {
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;
200 }
201 }
202 }
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 >
209 static_cast<size_t>(kAllowMergeWithoutExpandMs * fs_mult_ * 8))) {
210 return kMerge;
211 } else if (play_dtmf) {
212 // Play DTMF instead of expand.
213 return kDtmf;
214 } else {
215 return kExpand;
216 }
217 }
218
UnderTargetLevel() const219 bool DecisionLogicNormal::UnderTargetLevel() const {
220 return buffer_level_filter_->filtered_current_level() <=
221 delay_manager_->TargetLevel();
222 }
223
ReinitAfterExpands(uint32_t timestamp_leap) const224 bool DecisionLogicNormal::ReinitAfterExpands(uint32_t timestamp_leap) const {
225 return timestamp_leap >=
226 static_cast<uint32_t>(output_size_samples_ * kReinitAfterExpands);
227 }
228
PacketTooEarly(uint32_t timestamp_leap) const229 bool DecisionLogicNormal::PacketTooEarly(uint32_t timestamp_leap) const {
230 return timestamp_leap >
231 static_cast<uint32_t>(output_size_samples_ * num_consecutive_expands_);
232 }
233
MaxWaitForPacket() const234 bool DecisionLogicNormal::MaxWaitForPacket() const {
235 return num_consecutive_expands_ >= kMaxWaitForPacket;
236 }
237
238 } // namespace webrtc
239