blob: 8688737c3ede1dce25a1c57eb49f52bc5ad6f56e [file] [log] [blame]
henrik.lundin@webrtc.org9a400812013-01-29 12:09:21 +00001/*
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/neteq4/decision_logic_normal.h"
12
13#include <assert.h>
14
15#include <algorithm>
16
17#include "webrtc/modules/audio_coding/neteq4/buffer_level_filter.h"
18#include "webrtc/modules/audio_coding/neteq4/decoder_database.h"
19#include "webrtc/modules/audio_coding/neteq4/delay_manager.h"
20#include "webrtc/modules/audio_coding/neteq4/expand.h"
21#include "webrtc/modules/audio_coding/neteq4/packet_buffer.h"
22#include "webrtc/modules/audio_coding/neteq4/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 int is_cng_packet = 0;
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);
turaj@webrtc.orgbda9cbe2013-10-06 02:21:24 +000073 } else if (IsNewerTimestamp(available_timestamp, target_timestamp)) {
henrik.lundin@webrtc.org9a400812013-01-29 12:09:21 +000074 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
84Operations 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
112Operations 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
127Operations 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
147Operations 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
turaj@webrtc.org045e45e2013-09-20 16:25:28 +0000173 const int samples_left = static_cast<int>(sync_buffer.FutureLength() -
174 expand.overlap_length());
henrik.lundin@webrtc.org9a400812013-01-29 12:09:21 +0000175 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
216bool DecisionLogicNormal::UnderTargetLevel() const {
217 return buffer_level_filter_->filtered_current_level() <=
218 delay_manager_->TargetLevel();
219}
220
221bool DecisionLogicNormal::ReinitAfterExpands(uint32_t timestamp_leap) const {
222 return timestamp_leap >=
223 static_cast<uint32_t>(output_size_samples_ * kReinitAfterExpands);
224}
225
226bool DecisionLogicNormal::PacketTooEarly(uint32_t timestamp_leap) const {
227 return timestamp_leap >
228 static_cast<uint32_t>(output_size_samples_ * num_consecutive_expands_);
229}
230
231bool DecisionLogicNormal::MaxWaitForPacket() const {
232 return num_consecutive_expands_ >= kMaxWaitForPacket;
233}
234
235} // namespace webrtc