• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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