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
25namespace webrtc {
26
27Operations 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. Do Expand instead, and
80    // wait for a newer packet to arrive, or for the buffer to flush (resulting
81    // in a master reset).
82    return kExpand;
83  }
84}
85
86Operations 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) -
91      available_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;
95
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;
102  }
103
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;
108  } else {
109    // Otherwise, go for the CNG packet now.
110    return kRfc3389Cng;
111  }
112}
113
114Operations 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) {
122    return kDtmf;
123  } else {
124    // Nothing to play, do expand.
125    return kExpand;
126  }
127}
128
129Operations DecisionLogicNormal::ExpectedPacketAvailable(Modes prev_mode,
130                                                        bool play_dtmf) {
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.
140      return kAccelerate;
141    } else if ((buffer_level_filter_->filtered_current_level() < low_limit)
142        && TimescaleAllowed()) {
143      return kPreemptiveExpand;
144    }
145  }
146  return kNormal;
147}
148
149Operations DecisionLogicNormal::FuturePacketAvailable(
150    const SyncBuffer& sync_buffer,
151    const Expand& expand,
152    int 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 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;
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    int32_t timestamp_diff = (generated_noise_samples_ + target_timestamp) -
188        available_timestamp;
189    if (timestamp_diff >= 0 ||
190        cur_size_samples >
191        4 * ((delay_manager_->TargetLevel() * packet_length_samples_) >> 8)) {
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 > kAllowMergeWithoutExpandMs * fs_mult_ * 8)) {
209    return kMerge;
210  } else if (play_dtmf) {
211    // Play DTMF instead of expand.
212    return kDtmf;
213  } else {
214    return kExpand;
215  }
216}
217
218bool DecisionLogicNormal::UnderTargetLevel() const {
219  return buffer_level_filter_->filtered_current_level() <=
220      delay_manager_->TargetLevel();
221}
222
223bool DecisionLogicNormal::ReinitAfterExpands(uint32_t timestamp_leap) const {
224  return timestamp_leap >=
225      static_cast<uint32_t>(output_size_samples_ * kReinitAfterExpands);
226}
227
228bool DecisionLogicNormal::PacketTooEarly(uint32_t timestamp_leap) const {
229  return timestamp_leap >
230      static_cast<uint32_t>(output_size_samples_ * num_consecutive_expands_);
231}
232
233bool DecisionLogicNormal::MaxWaitForPacket() const {
234  return num_consecutive_expands_ >= kMaxWaitForPacket;
235}
236
237}  // namespace webrtc
238