Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / decision_logic_normal.cc
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/interface/module_common_types.h"
24
25 namespace webrtc {
26
27 Operations DecisionLogicNormal::GetDecisionSpecialized(
28     const SyncBuffer& sync_buffer,
29     const Expand& expand,
30     int 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   // Check if the required packet is available.
71   if (target_timestamp == available_timestamp) {
72     return ExpectedPacketAvailable(prev_mode, play_dtmf);
73   } else if (IsNewerTimestamp(available_timestamp, target_timestamp)) {
74     return FuturePacketAvailable(sync_buffer, expand, decoder_frame_length,
75                                  prev_mode, target_timestamp,
76                                  available_timestamp, play_dtmf);
77   } else {
78     // This implies that available_timestamp < target_timestamp, which can
79     // happen when a new stream or codec is received. Signal for a reset.
80     return kUndefined;
81   }
82 }
83
84 Operations DecisionLogicNormal::CngOperation(Modes prev_mode,
85                                              uint32_t target_timestamp,
86                                              uint32_t available_timestamp) {
87   // Signed difference between target and available timestamp.
88   int32_t timestamp_diff = (generated_noise_samples_ + target_timestamp) -
89       available_timestamp;
90   int32_t optimal_level_samp =
91       (delay_manager_->TargetLevel() * packet_length_samples_) >> 8;
92   int32_t excess_waiting_time_samp = -timestamp_diff - optimal_level_samp;
93
94   if (excess_waiting_time_samp > optimal_level_samp / 2) {
95     // The waiting time for this packet will be longer than 1.5
96     // times the wanted buffer delay. Advance the clock to cut
97     // waiting time down to the optimal.
98     generated_noise_samples_ += excess_waiting_time_samp;
99     timestamp_diff += excess_waiting_time_samp;
100   }
101
102   if (timestamp_diff < 0 && prev_mode == kModeRfc3389Cng) {
103     // Not time to play this packet yet. Wait another round before using this
104     // packet. Keep on playing CNG from previous CNG parameters.
105     return kRfc3389CngNoPacket;
106   } else {
107     // Otherwise, go for the CNG packet now.
108     return kRfc3389Cng;
109   }
110 }
111
112 Operations DecisionLogicNormal::NoPacket(bool play_dtmf) {
113   if (cng_state_ == kCngRfc3389On) {
114     // Keep on playing comfort noise.
115     return kRfc3389CngNoPacket;
116   } else if (cng_state_ == kCngInternalOn) {
117     // Keep on playing codec internal comfort noise.
118     return kCodecInternalCng;
119   } else if (play_dtmf) {
120     return kDtmf;
121   } else {
122     // Nothing to play, do expand.
123     return kExpand;
124   }
125 }
126
127 Operations DecisionLogicNormal::ExpectedPacketAvailable(Modes prev_mode,
128                                                         bool play_dtmf) {
129   if (prev_mode != kModeExpand && !play_dtmf) {
130     // Check criterion for time-stretching.
131     int low_limit, high_limit;
132     delay_manager_->BufferLimits(&low_limit, &high_limit);
133     if ((buffer_level_filter_->filtered_current_level() >= high_limit &&
134         TimescaleAllowed()) ||
135         buffer_level_filter_->filtered_current_level() >= high_limit << 2) {
136       // Buffer level higher than limit and time-scaling allowed,
137       // or buffer level really high.
138       return kAccelerate;
139     } else if ((buffer_level_filter_->filtered_current_level() < low_limit)
140         && TimescaleAllowed()) {
141       return kPreemptiveExpand;
142     }
143   }
144   return kNormal;
145 }
146
147 Operations DecisionLogicNormal::FuturePacketAvailable(
148     const SyncBuffer& sync_buffer,
149     const Expand& expand,
150     int decoder_frame_length,
151     Modes prev_mode,
152     uint32_t target_timestamp,
153     uint32_t available_timestamp,
154     bool play_dtmf) {
155   // Required packet is not available, but a future packet is.
156   // Check if we should continue with an ongoing expand because the new packet
157   // is too far into the future.
158   uint32_t timestamp_leap = available_timestamp - target_timestamp;
159   if ((prev_mode == kModeExpand) &&
160       !ReinitAfterExpands(timestamp_leap) &&
161       !MaxWaitForPacket() &&
162       PacketTooEarly(timestamp_leap) &&
163       UnderTargetLevel()) {
164     if (play_dtmf) {
165       // Still have DTMF to play, so do not do expand.
166       return kDtmf;
167     } else {
168       // Nothing to play.
169       return kExpand;
170     }
171   }
172
173   const int samples_left = static_cast<int>(sync_buffer.FutureLength() -
174       expand.overlap_length());
175   const int cur_size_samples = samples_left +
176       packet_buffer_.NumPacketsInBuffer() * decoder_frame_length;
177
178   // If previous was comfort noise, then no merge is needed.
179   if (prev_mode == kModeRfc3389Cng ||
180       prev_mode == kModeCodecInternalCng) {
181     // Keep the same delay as before the CNG (or maximum 70 ms in buffer as
182     // safety precaution), but make sure that the number of samples in buffer
183     // is no higher than 4 times the optimal level. (Note that TargetLevel()
184     // is in Q8.)
185     int32_t timestamp_diff = (generated_noise_samples_ + target_timestamp) -
186         available_timestamp;
187     if (timestamp_diff >= 0 ||
188         cur_size_samples >
189         4 * ((delay_manager_->TargetLevel() * packet_length_samples_) >> 8)) {
190       // Time to play this new packet.
191       return kNormal;
192     } else {
193       // Too early to play this new packet; keep on playing comfort noise.
194       if (prev_mode == kModeRfc3389Cng) {
195         return kRfc3389CngNoPacket;
196       } else {  // prevPlayMode == kModeCodecInternalCng.
197         return kCodecInternalCng;
198       }
199     }
200   }
201   // Do not merge unless we have done an expand before.
202   // (Convert kAllowMergeWithoutExpand from ms to samples by multiplying with
203   // fs_mult_ * 8 = fs / 1000.)
204   if (prev_mode == kModeExpand ||
205       (decoder_frame_length < output_size_samples_ &&
206        cur_size_samples > kAllowMergeWithoutExpandMs * fs_mult_ * 8)) {
207     return kMerge;
208   } else if (play_dtmf) {
209     // Play DTMF instead of expand.
210     return kDtmf;
211   } else {
212     return kExpand;
213   }
214 }
215
216 bool DecisionLogicNormal::UnderTargetLevel() const {
217   return buffer_level_filter_->filtered_current_level() <=
218       delay_manager_->TargetLevel();
219 }
220
221 bool DecisionLogicNormal::ReinitAfterExpands(uint32_t timestamp_leap) const {
222   return timestamp_leap >=
223       static_cast<uint32_t>(output_size_samples_ * kReinitAfterExpands);
224 }
225
226 bool DecisionLogicNormal::PacketTooEarly(uint32_t timestamp_leap) const {
227   return timestamp_leap >
228       static_cast<uint32_t>(output_size_samples_ * num_consecutive_expands_);
229 }
230
231 bool DecisionLogicNormal::MaxWaitForPacket() const {
232   return num_consecutive_expands_ >= kMaxWaitForPacket;
233 }
234
235 }  // namespace webrtc