blob: b107626439f3991af5a65a5bf60d758ba13d61f1 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
2 * Copyright (c) 2012 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_coding/neteq/neteq_impl.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000012
13#include <assert.h>
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000014
15#include <algorithm>
ossu61a208b2016-09-20 01:38:00 -070016#include <utility>
ossu97ba30e2016-04-25 07:55:58 -070017#include <vector>
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "api/audio_codecs/audio_decoder.h"
20#include "common_audio/signal_processing/include/signal_processing_library.h"
21#include "modules/audio_coding/neteq/accelerate.h"
22#include "modules/audio_coding/neteq/background_noise.h"
23#include "modules/audio_coding/neteq/buffer_level_filter.h"
24#include "modules/audio_coding/neteq/comfort_noise.h"
25#include "modules/audio_coding/neteq/decision_logic.h"
26#include "modules/audio_coding/neteq/decoder_database.h"
27#include "modules/audio_coding/neteq/defines.h"
28#include "modules/audio_coding/neteq/delay_manager.h"
29#include "modules/audio_coding/neteq/delay_peak_detector.h"
30#include "modules/audio_coding/neteq/dtmf_buffer.h"
31#include "modules/audio_coding/neteq/dtmf_tone_generator.h"
32#include "modules/audio_coding/neteq/expand.h"
33#include "modules/audio_coding/neteq/merge.h"
34#include "modules/audio_coding/neteq/nack_tracker.h"
35#include "modules/audio_coding/neteq/normal.h"
36#include "modules/audio_coding/neteq/packet.h"
37#include "modules/audio_coding/neteq/packet_buffer.h"
38#include "modules/audio_coding/neteq/post_decode_vad.h"
39#include "modules/audio_coding/neteq/preemptive_expand.h"
40#include "modules/audio_coding/neteq/red_payload_splitter.h"
41#include "modules/audio_coding/neteq/sync_buffer.h"
42#include "modules/audio_coding/neteq/tick_timer.h"
43#include "modules/audio_coding/neteq/timestamp_scaler.h"
44#include "modules/include/module_common_types.h"
45#include "rtc_base/checks.h"
46#include "rtc_base/logging.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010047#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020048#include "rtc_base/sanitizer.h"
Karl Wiberg80ba3332018-02-05 10:33:35 +010049#include "rtc_base/system/fallthrough.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020050#include "rtc_base/trace_event.h"
Henrik Lundin18036282017-11-02 12:09:06 +010051#include "system_wrappers/include/field_trial.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000052
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000053namespace webrtc {
54
ossue3525782016-05-25 07:37:43 -070055NetEqImpl::Dependencies::Dependencies(
56 const NetEq::Config& config,
57 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory)
henrik.lundin1d9061e2016-04-26 12:19:34 -070058 : tick_timer(new TickTimer),
59 buffer_level_filter(new BufferLevelFilter),
ossue3525782016-05-25 07:37:43 -070060 decoder_database(new DecoderDatabase(decoder_factory)),
henrik.lundinf3933702016-04-28 01:53:52 -070061 delay_peak_detector(new DelayPeakDetector(tick_timer.get())),
henrik.lundin1d9061e2016-04-26 12:19:34 -070062 delay_manager(new DelayManager(config.max_packets_in_buffer,
henrik.lundin8f8c96d2016-04-28 23:19:20 -070063 delay_peak_detector.get(),
64 tick_timer.get())),
henrik.lundin1d9061e2016-04-26 12:19:34 -070065 dtmf_buffer(new DtmfBuffer(config.sample_rate_hz)),
66 dtmf_tone_generator(new DtmfToneGenerator),
67 packet_buffer(
68 new PacketBuffer(config.max_packets_in_buffer, tick_timer.get())),
ossua70695a2016-09-22 02:06:28 -070069 red_payload_splitter(new RedPayloadSplitter),
henrik.lundin1d9061e2016-04-26 12:19:34 -070070 timestamp_scaler(new TimestampScaler(*decoder_database)),
71 accelerate_factory(new AccelerateFactory),
72 expand_factory(new ExpandFactory),
73 preemptive_expand_factory(new PreemptiveExpandFactory) {}
74
75NetEqImpl::Dependencies::~Dependencies() = default;
76
henrik.lundin@webrtc.orgea257842014-08-07 12:27:37 +000077NetEqImpl::NetEqImpl(const NetEq::Config& config,
henrik.lundin1d9061e2016-04-26 12:19:34 -070078 Dependencies&& deps,
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +000079 bool create_components)
henrik.lundin1d9061e2016-04-26 12:19:34 -070080 : tick_timer_(std::move(deps.tick_timer)),
81 buffer_level_filter_(std::move(deps.buffer_level_filter)),
82 decoder_database_(std::move(deps.decoder_database)),
83 delay_manager_(std::move(deps.delay_manager)),
84 delay_peak_detector_(std::move(deps.delay_peak_detector)),
85 dtmf_buffer_(std::move(deps.dtmf_buffer)),
86 dtmf_tone_generator_(std::move(deps.dtmf_tone_generator)),
87 packet_buffer_(std::move(deps.packet_buffer)),
ossua70695a2016-09-22 02:06:28 -070088 red_payload_splitter_(std::move(deps.red_payload_splitter)),
henrik.lundin1d9061e2016-04-26 12:19:34 -070089 timestamp_scaler_(std::move(deps.timestamp_scaler)),
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000090 vad_(new PostDecodeVad()),
henrik.lundin1d9061e2016-04-26 12:19:34 -070091 expand_factory_(std::move(deps.expand_factory)),
92 accelerate_factory_(std::move(deps.accelerate_factory)),
93 preemptive_expand_factory_(std::move(deps.preemptive_expand_factory)),
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000094 last_mode_(kModeNormal),
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000095 decoded_buffer_length_(kMaxFrameSize),
96 decoded_buffer_(new int16_t[decoded_buffer_length_]),
97 playout_timestamp_(0),
98 new_codec_(false),
99 timestamp_(0),
100 reset_decoder_(false),
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000101 ssrc_(0),
102 first_packet_(true),
henrik.lundin@webrtc.orgea257842014-08-07 12:27:37 +0000103 background_noise_mode_(config.background_noise_mode),
henrik.lundin@webrtc.org7cbc4f92014-10-07 06:37:39 +0000104 playout_mode_(config.playout_mode),
Henrik Lundincf808d22015-05-27 14:33:29 +0200105 enable_fast_accelerate_(config.enable_fast_accelerate),
henrik.lundin7a926812016-05-12 13:51:28 -0700106 nack_enabled_(false),
Henrik Lundin4f2a4a12018-01-26 17:32:56 +0100107 enable_muted_state_(config.enable_muted_state) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100108 RTC_LOG(LS_INFO) << "NetEq config: " << config.ToString();
henrik.lundin@webrtc.orgea257842014-08-07 12:27:37 +0000109 int fs = config.sample_rate_hz;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000110 if (fs != 8000 && fs != 16000 && fs != 32000 && fs != 48000) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100111 RTC_LOG(LS_ERROR) << "Sample rate " << fs << " Hz not supported. "
112 << "Changing to 8000 Hz.";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000113 fs = 8000;
114 }
henrik.lundin1d9061e2016-04-26 12:19:34 -0700115 delay_manager_->SetMaximumDelay(config.max_delay_ms);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000116 fs_hz_ = fs;
117 fs_mult_ = fs / 8000;
henrik.lundind89814b2015-11-23 06:49:25 -0800118 last_output_sample_rate_hz_ = fs;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700119 output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000120 decoder_frame_length_ = 3 * output_size_samples_;
121 WebRtcSpl_Init();
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +0000122 if (create_components) {
123 SetSampleRateAndChannels(fs, 1); // Default is 1 channel.
124 }
henrik.lundin9bc26672015-11-02 03:25:57 -0800125 RTC_DCHECK(!vad_->enabled());
126 if (config.enable_post_decode_vad) {
127 vad_->Enable();
128 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000129}
130
Henrik Lundind67a2192015-08-03 12:54:37 +0200131NetEqImpl::~NetEqImpl() = default;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000132
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200133int NetEqImpl::InsertPacket(const RTPHeader& rtp_header,
kwibergee2bac22015-11-11 10:34:00 -0800134 rtc::ArrayView<const uint8_t> payload,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000135 uint32_t receive_timestamp) {
kwibergac554ee2016-09-02 00:39:33 -0700136 rtc::MsanCheckInitialized(payload);
henrik.lundina689b442015-12-17 03:50:05 -0800137 TRACE_EVENT0("webrtc", "NetEqImpl::InsertPacket");
Tommi9090e0b2016-01-20 13:39:36 +0100138 rtc::CritScope lock(&crit_sect_);
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200139 if (InsertPacketInternal(rtp_header, payload, receive_timestamp) != 0) {
henrik.lundin@webrtc.orge7ce4372014-01-09 14:01:55 +0000140 return kFail;
141 }
142 return kOK;
turaj@webrtc.org7b75ac62013-09-26 00:27:56 +0000143}
144
henrik.lundinb8c55b12017-05-10 07:38:01 -0700145void NetEqImpl::InsertEmptyPacket(const RTPHeader& /*rtp_header*/) {
146 // TODO(henrik.lundin) Handle NACK as well. This will make use of the
147 // rtp_header parameter.
148 // https://bugs.chromium.org/p/webrtc/issues/detail?id=7611
149 rtc::CritScope lock(&crit_sect_);
150 delay_manager_->RegisterEmptyPacket();
151}
152
henrik.lundin500c04b2016-03-08 02:36:04 -0800153namespace {
154void SetAudioFrameActivityAndType(bool vad_enabled,
henrik.lundin55480f52016-03-08 02:37:57 -0800155 NetEqImpl::OutputType type,
henrik.lundin500c04b2016-03-08 02:36:04 -0800156 AudioFrame::VADActivity last_vad_activity,
157 AudioFrame* audio_frame) {
158 switch (type) {
henrik.lundin55480f52016-03-08 02:37:57 -0800159 case NetEqImpl::OutputType::kNormalSpeech: {
henrik.lundin500c04b2016-03-08 02:36:04 -0800160 audio_frame->speech_type_ = AudioFrame::kNormalSpeech;
161 audio_frame->vad_activity_ = AudioFrame::kVadActive;
162 break;
163 }
henrik.lundin55480f52016-03-08 02:37:57 -0800164 case NetEqImpl::OutputType::kVadPassive: {
henrik.lundin500c04b2016-03-08 02:36:04 -0800165 // This should only be reached if the VAD is enabled.
166 RTC_DCHECK(vad_enabled);
167 audio_frame->speech_type_ = AudioFrame::kNormalSpeech;
168 audio_frame->vad_activity_ = AudioFrame::kVadPassive;
169 break;
170 }
henrik.lundin55480f52016-03-08 02:37:57 -0800171 case NetEqImpl::OutputType::kCNG: {
henrik.lundin500c04b2016-03-08 02:36:04 -0800172 audio_frame->speech_type_ = AudioFrame::kCNG;
173 audio_frame->vad_activity_ = AudioFrame::kVadPassive;
174 break;
175 }
henrik.lundin55480f52016-03-08 02:37:57 -0800176 case NetEqImpl::OutputType::kPLC: {
henrik.lundin500c04b2016-03-08 02:36:04 -0800177 audio_frame->speech_type_ = AudioFrame::kPLC;
178 audio_frame->vad_activity_ = last_vad_activity;
179 break;
180 }
henrik.lundin55480f52016-03-08 02:37:57 -0800181 case NetEqImpl::OutputType::kPLCCNG: {
henrik.lundin500c04b2016-03-08 02:36:04 -0800182 audio_frame->speech_type_ = AudioFrame::kPLCCNG;
183 audio_frame->vad_activity_ = AudioFrame::kVadPassive;
184 break;
185 }
186 default:
187 RTC_NOTREACHED();
188 }
189 if (!vad_enabled) {
190 // Always set kVadUnknown when receive VAD is inactive.
191 audio_frame->vad_activity_ = AudioFrame::kVadUnknown;
192 }
193}
henrik.lundinbc89de32016-03-08 05:20:14 -0800194} // namespace
henrik.lundin500c04b2016-03-08 02:36:04 -0800195
henrik.lundin7a926812016-05-12 13:51:28 -0700196int NetEqImpl::GetAudio(AudioFrame* audio_frame, bool* muted) {
henrik.lundine1ca1672016-01-08 03:50:08 -0800197 TRACE_EVENT0("webrtc", "NetEqImpl::GetAudio");
Tommi9090e0b2016-01-20 13:39:36 +0100198 rtc::CritScope lock(&crit_sect_);
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200199 if (GetAudioInternal(audio_frame, muted) != 0) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000200 return kFail;
201 }
henrik.lundin5fac3f02016-08-24 11:18:49 -0700202 RTC_DCHECK_EQ(
203 audio_frame->sample_rate_hz_,
kwibergd3edd772017-03-01 18:52:48 -0800204 rtc::dchecked_cast<int>(audio_frame->samples_per_channel_ * 100));
henrik.lundina4491072017-07-06 05:23:53 -0700205 RTC_DCHECK_EQ(*muted, audio_frame->muted());
henrik.lundin500c04b2016-03-08 02:36:04 -0800206 SetAudioFrameActivityAndType(vad_->enabled(), LastOutputType(),
207 last_vad_activity_, audio_frame);
208 last_vad_activity_ = audio_frame->vad_activity_;
henrik.lundin6d8e0112016-03-04 10:34:21 -0800209 last_output_sample_rate_hz_ = audio_frame->sample_rate_hz_;
henrik.lundind89814b2015-11-23 06:49:25 -0800210 RTC_DCHECK(last_output_sample_rate_hz_ == 8000 ||
211 last_output_sample_rate_hz_ == 16000 ||
212 last_output_sample_rate_hz_ == 32000 ||
213 last_output_sample_rate_hz_ == 48000)
214 << "Unexpected sample rate " << last_output_sample_rate_hz_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000215 return kOK;
216}
217
kwiberg1c07c702017-03-27 07:15:49 -0700218void NetEqImpl::SetCodecs(const std::map<int, SdpAudioFormat>& codecs) {
219 rtc::CritScope lock(&crit_sect_);
220 const std::vector<int> changed_payload_types =
221 decoder_database_->SetCodecs(codecs);
222 for (const int pt : changed_payload_types) {
minyue-webrtcfae474c2017-07-05 11:17:40 +0200223 packet_buffer_->DiscardPacketsWithPayloadType(pt, &stats_);
kwiberg1c07c702017-03-27 07:15:49 -0700224 }
225}
226
kwibergee1879c2015-10-29 06:20:28 -0700227int NetEqImpl::RegisterPayloadType(NetEqDecoder codec,
henrik.lundin4cf61dd2015-12-09 06:20:58 -0800228 const std::string& name,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000229 uint8_t rtp_payload_type) {
Tommi9090e0b2016-01-20 13:39:36 +0100230 rtc::CritScope lock(&crit_sect_);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100231 RTC_LOG(LS_VERBOSE) << "RegisterPayloadType "
232 << static_cast<int>(rtp_payload_type) << " "
233 << static_cast<int>(codec);
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200234 if (decoder_database_->RegisterPayload(rtp_payload_type, codec, name) !=
235 DecoderDatabase::kOK) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000236 return kFail;
237 }
238 return kOK;
239}
240
241int NetEqImpl::RegisterExternalDecoder(AudioDecoder* decoder,
kwibergee1879c2015-10-29 06:20:28 -0700242 NetEqDecoder codec,
henrik.lundin4cf61dd2015-12-09 06:20:58 -0800243 const std::string& codec_name,
kwiberg342f7402016-06-16 03:18:00 -0700244 uint8_t rtp_payload_type) {
Tommi9090e0b2016-01-20 13:39:36 +0100245 rtc::CritScope lock(&crit_sect_);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100246 RTC_LOG(LS_VERBOSE) << "RegisterExternalDecoder "
247 << static_cast<int>(rtp_payload_type) << " "
248 << static_cast<int>(codec);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000249 if (!decoder) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100250 RTC_LOG(LS_ERROR) << "Cannot register external decoder with NULL pointer";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000251 assert(false);
252 return kFail;
253 }
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200254 if (decoder_database_->InsertExternal(rtp_payload_type, codec, codec_name,
255 decoder) != DecoderDatabase::kOK) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000256 return kFail;
257 }
258 return kOK;
259}
260
kwiberg5adaf732016-10-04 09:33:27 -0700261bool NetEqImpl::RegisterPayloadType(int rtp_payload_type,
262 const SdpAudioFormat& audio_format) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100263 RTC_LOG(LS_VERBOSE) << "NetEqImpl::RegisterPayloadType: payload type "
264 << rtp_payload_type << ", codec " << audio_format;
kwiberg5adaf732016-10-04 09:33:27 -0700265 rtc::CritScope lock(&crit_sect_);
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200266 return decoder_database_->RegisterPayload(rtp_payload_type, audio_format) ==
267 DecoderDatabase::kOK;
kwiberg5adaf732016-10-04 09:33:27 -0700268}
269
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000270int NetEqImpl::RemovePayloadType(uint8_t rtp_payload_type) {
Tommi9090e0b2016-01-20 13:39:36 +0100271 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000272 int ret = decoder_database_->Remove(rtp_payload_type);
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200273 if (ret == DecoderDatabase::kOK || ret == DecoderDatabase::kDecoderNotFound) {
minyue-webrtcfae474c2017-07-05 11:17:40 +0200274 packet_buffer_->DiscardPacketsWithPayloadType(rtp_payload_type, &stats_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000275 return kOK;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000276 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000277 return kFail;
278}
279
kwiberg6b19b562016-09-20 04:02:25 -0700280void NetEqImpl::RemoveAllPayloadTypes() {
281 rtc::CritScope lock(&crit_sect_);
282 decoder_database_->RemoveAll();
283}
284
turaj@webrtc.orgf1efc572013-08-16 23:44:24 +0000285bool NetEqImpl::SetMinimumDelay(int delay_ms) {
Tommi9090e0b2016-01-20 13:39:36 +0100286 rtc::CritScope lock(&crit_sect_);
Gustaf Ullberg48d96c02017-09-15 13:59:52 +0200287 if (delay_ms >= 0 && delay_ms <= 10000) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000288 assert(delay_manager_.get());
turaj@webrtc.orgf1efc572013-08-16 23:44:24 +0000289 return delay_manager_->SetMinimumDelay(delay_ms);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000290 }
291 return false;
292}
293
turaj@webrtc.orgf1efc572013-08-16 23:44:24 +0000294bool NetEqImpl::SetMaximumDelay(int delay_ms) {
Tommi9090e0b2016-01-20 13:39:36 +0100295 rtc::CritScope lock(&crit_sect_);
Gustaf Ullberg48d96c02017-09-15 13:59:52 +0200296 if (delay_ms >= 0 && delay_ms <= 10000) {
turaj@webrtc.orgf1efc572013-08-16 23:44:24 +0000297 assert(delay_manager_.get());
298 return delay_manager_->SetMaximumDelay(delay_ms);
299 }
300 return false;
301}
302
303int NetEqImpl::LeastRequiredDelayMs() const {
Tommi9090e0b2016-01-20 13:39:36 +0100304 rtc::CritScope lock(&crit_sect_);
turaj@webrtc.orgf1efc572013-08-16 23:44:24 +0000305 assert(delay_manager_.get());
306 return delay_manager_->least_required_delay_ms();
307}
308
Karl Wiberg7f6c4d42015-04-09 15:44:22 +0200309int NetEqImpl::SetTargetDelay() {
310 return kNotImplemented;
311}
312
Henrik Lundinabbff892017-11-29 09:14:04 +0100313int NetEqImpl::TargetDelayMs() const {
henrik.lundin114c1b32017-04-26 07:47:32 -0700314 rtc::CritScope lock(&crit_sect_);
315 RTC_DCHECK(delay_manager_.get());
316 // The value from TargetLevel() is in number of packets, represented in Q8.
317 const size_t target_delay_samples =
318 (delay_manager_->TargetLevel() * decoder_frame_length_) >> 8;
319 return static_cast<int>(target_delay_samples) /
320 rtc::CheckedDivExact(fs_hz_, 1000);
Karl Wiberg7f6c4d42015-04-09 15:44:22 +0200321}
322
henrik.lundin9c3efd02015-08-27 13:12:22 -0700323int NetEqImpl::CurrentDelayMs() const {
Tommi9090e0b2016-01-20 13:39:36 +0100324 rtc::CritScope lock(&crit_sect_);
henrik.lundin9c3efd02015-08-27 13:12:22 -0700325 if (fs_hz_ == 0)
326 return 0;
327 // Sum up the samples in the packet buffer with the future length of the sync
328 // buffer, and divide the sum by the sample rate.
329 const size_t delay_samples =
ossu61a208b2016-09-20 01:38:00 -0700330 packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) +
henrik.lundin9c3efd02015-08-27 13:12:22 -0700331 sync_buffer_->FutureLength();
332 // The division below will truncate.
333 const int delay_ms =
334 static_cast<int>(delay_samples) / rtc::CheckedDivExact(fs_hz_, 1000);
335 return delay_ms;
Karl Wiberg7f6c4d42015-04-09 15:44:22 +0200336}
337
henrik.lundinb3f1c5d2016-08-22 15:39:53 -0700338int NetEqImpl::FilteredCurrentDelayMs() const {
339 rtc::CritScope lock(&crit_sect_);
340 // Calculate the filtered packet buffer level in samples. The value from
341 // |buffer_level_filter_| is in number of packets, represented in Q8.
342 const size_t packet_buffer_samples =
343 (buffer_level_filter_->filtered_current_level() *
344 decoder_frame_length_) >>
345 8;
346 // Sum up the filtered packet buffer level with the future length of the sync
347 // buffer, and divide the sum by the sample rate.
348 const size_t delay_samples =
349 packet_buffer_samples + sync_buffer_->FutureLength();
350 // The division below will truncate. The return value is in ms.
351 return static_cast<int>(delay_samples) / rtc::CheckedDivExact(fs_hz_, 1000);
352}
353
henrik.lundin@webrtc.org7cbc4f92014-10-07 06:37:39 +0000354// Deprecated.
355// TODO(henrik.lundin) Delete.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000356void NetEqImpl::SetPlayoutMode(NetEqPlayoutMode mode) {
Tommi9090e0b2016-01-20 13:39:36 +0100357 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.org7cbc4f92014-10-07 06:37:39 +0000358 if (mode != playout_mode_) {
359 playout_mode_ = mode;
360 CreateDecisionLogic();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000361 }
362}
363
henrik.lundin@webrtc.org7cbc4f92014-10-07 06:37:39 +0000364// Deprecated.
365// TODO(henrik.lundin) Delete.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000366NetEqPlayoutMode NetEqImpl::PlayoutMode() const {
Tommi9090e0b2016-01-20 13:39:36 +0100367 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.org7cbc4f92014-10-07 06:37:39 +0000368 return playout_mode_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000369}
370
371int NetEqImpl::NetworkStatistics(NetEqNetworkStatistics* stats) {
Tommi9090e0b2016-01-20 13:39:36 +0100372 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000373 assert(decoder_database_.get());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700374 const size_t total_samples_in_buffers =
ossu61a208b2016-09-20 01:38:00 -0700375 packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) +
Peter Kastingdce40cf2015-08-24 14:52:23 -0700376 sync_buffer_->FutureLength();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000377 assert(delay_manager_.get());
378 assert(decision_logic_.get());
Henrik Lundindccfc402017-09-25 12:30:58 +0200379 const int ms_per_packet = rtc::dchecked_cast<int>(
380 decision_logic_->packet_length_samples() / (fs_hz_ / 1000));
381 stats_.PopulateDelayManagerStats(ms_per_packet, *delay_manager_.get(), stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000382 stats_.GetNetworkStatistics(fs_hz_, total_samples_in_buffers,
Henrik Lundindccfc402017-09-25 12:30:58 +0200383 decoder_frame_length_, stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000384 return 0;
385}
386
Steve Anton2dbc69f2017-08-24 17:15:13 -0700387NetEqLifetimeStatistics NetEqImpl::GetLifetimeStatistics() const {
388 rtc::CritScope lock(&crit_sect_);
389 return stats_.GetLifetimeStatistics();
390}
391
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000392void NetEqImpl::GetRtcpStatistics(RtcpStatistics* stats) {
Tommi9090e0b2016-01-20 13:39:36 +0100393 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000394 if (stats) {
395 rtcp_.GetStatistics(false, stats);
396 }
397}
398
399void NetEqImpl::GetRtcpStatisticsNoReset(RtcpStatistics* stats) {
Tommi9090e0b2016-01-20 13:39:36 +0100400 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000401 if (stats) {
402 rtcp_.GetStatistics(true, stats);
403 }
404}
405
406void NetEqImpl::EnableVad() {
Tommi9090e0b2016-01-20 13:39:36 +0100407 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000408 assert(vad_.get());
409 vad_->Enable();
410}
411
412void NetEqImpl::DisableVad() {
Tommi9090e0b2016-01-20 13:39:36 +0100413 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000414 assert(vad_.get());
415 vad_->Disable();
416}
417
henrik.lundin15c51e32016-04-06 08:38:56 -0700418rtc::Optional<uint32_t> NetEqImpl::GetPlayoutTimestamp() const {
Tommi9090e0b2016-01-20 13:39:36 +0100419 rtc::CritScope lock(&crit_sect_);
henrik.lundin0d96ab72016-04-06 12:28:26 -0700420 if (first_packet_ || last_mode_ == kModeRfc3389Cng ||
421 last_mode_ == kModeCodecInternalCng) {
wu@webrtc.org94454b72014-06-05 20:34:08 +0000422 // We don't have a valid RTP timestamp until we have decoded our first
henrik.lundin0d96ab72016-04-06 12:28:26 -0700423 // RTP packet. Also, the RTP timestamp is not accurate while playing CNG,
424 // which is indicated by returning an empty value.
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100425 return rtc::nullopt;
wu@webrtc.org94454b72014-06-05 20:34:08 +0000426 }
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100427 return timestamp_scaler_->ToExternal(playout_timestamp_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000428}
429
henrik.lundind89814b2015-11-23 06:49:25 -0800430int NetEqImpl::last_output_sample_rate_hz() const {
Tommi9090e0b2016-01-20 13:39:36 +0100431 rtc::CritScope lock(&crit_sect_);
henrik.lundind89814b2015-11-23 06:49:25 -0800432 return last_output_sample_rate_hz_;
433}
434
kwiberg6f0f6162016-09-20 03:07:46 -0700435rtc::Optional<CodecInst> NetEqImpl::GetDecoder(int payload_type) const {
436 rtc::CritScope lock(&crit_sect_);
437 const DecoderDatabase::DecoderInfo* di =
438 decoder_database_->GetDecoderInfo(payload_type);
439 if (!di) {
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100440 return rtc::nullopt;
kwiberg6f0f6162016-09-20 03:07:46 -0700441 }
442
443 // Create a CodecInst with some fields set. The remaining fields are zeroed,
444 // but we tell MSan to consider them uninitialized.
445 CodecInst ci = {0};
446 rtc::MsanMarkUninitialized(rtc::MakeArrayView(&ci, 1));
447 ci.pltype = payload_type;
kwiberge9413062016-11-03 05:29:05 -0700448 std::strncpy(ci.plname, di->get_name().c_str(), sizeof(ci.plname));
kwiberg6f0f6162016-09-20 03:07:46 -0700449 ci.plname[sizeof(ci.plname) - 1] = '\0';
solenberg2779bab2016-11-17 04:45:19 -0800450 ci.plfreq = di->IsRed() ? 8000 : di->SampleRateHz();
kwiberg6f0f6162016-09-20 03:07:46 -0700451 AudioDecoder* const decoder = di->GetDecoder();
452 ci.channels = decoder ? decoder->Channels() : 1;
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100453 return ci;
kwiberg6f0f6162016-09-20 03:07:46 -0700454}
455
ossuf1b08da2016-09-23 02:19:43 -0700456rtc::Optional<SdpAudioFormat> NetEqImpl::GetDecoderFormat(
457 int payload_type) const {
kwibergc4ccd4d2016-09-21 10:55:15 -0700458 rtc::CritScope lock(&crit_sect_);
459 const DecoderDatabase::DecoderInfo* const di =
460 decoder_database_->GetDecoderInfo(payload_type);
461 if (!di) {
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100462 return rtc::nullopt; // Payload type not registered.
kwibergc4ccd4d2016-09-21 10:55:15 -0700463 }
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100464 return di->GetFormat();
kwibergc4ccd4d2016-09-21 10:55:15 -0700465}
466
Karl Wiberg7f6c4d42015-04-09 15:44:22 +0200467int NetEqImpl::SetTargetNumberOfChannels() {
468 return kNotImplemented;
469}
470
471int NetEqImpl::SetTargetSampleRate() {
472 return kNotImplemented;
473}
474
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000475void NetEqImpl::FlushBuffers() {
Tommi9090e0b2016-01-20 13:39:36 +0100476 rtc::CritScope lock(&crit_sect_);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100477 RTC_LOG(LS_VERBOSE) << "FlushBuffers";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000478 packet_buffer_->Flush();
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +0000479 assert(sync_buffer_.get());
480 assert(expand_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000481 sync_buffer_->Flush();
482 sync_buffer_->set_next_index(sync_buffer_->next_index() -
483 expand_->overlap_length());
484 // Set to wait for new codec.
485 first_packet_ = true;
486}
487
turaj@webrtc.org3170b572013-08-30 15:36:53 +0000488void NetEqImpl::PacketBufferStatistics(int* current_num_packets,
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +0000489 int* max_num_packets) const {
Tommi9090e0b2016-01-20 13:39:36 +0100490 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +0000491 packet_buffer_->BufferStat(current_num_packets, max_num_packets);
turaj@webrtc.org3170b572013-08-30 15:36:53 +0000492}
493
henrik.lundin48ed9302015-10-29 05:36:24 -0700494void NetEqImpl::EnableNack(size_t max_nack_list_size) {
Tommi9090e0b2016-01-20 13:39:36 +0100495 rtc::CritScope lock(&crit_sect_);
henrik.lundin48ed9302015-10-29 05:36:24 -0700496 if (!nack_enabled_) {
497 const int kNackThresholdPackets = 2;
henrik.lundin91951862016-06-08 06:43:41 -0700498 nack_.reset(NackTracker::Create(kNackThresholdPackets));
henrik.lundin48ed9302015-10-29 05:36:24 -0700499 nack_enabled_ = true;
500 nack_->UpdateSampleRate(fs_hz_);
501 }
502 nack_->SetMaxNackListSize(max_nack_list_size);
503}
504
505void NetEqImpl::DisableNack() {
Tommi9090e0b2016-01-20 13:39:36 +0100506 rtc::CritScope lock(&crit_sect_);
henrik.lundin48ed9302015-10-29 05:36:24 -0700507 nack_.reset();
508 nack_enabled_ = false;
509}
510
511std::vector<uint16_t> NetEqImpl::GetNackList(int64_t round_trip_time_ms) const {
Tommi9090e0b2016-01-20 13:39:36 +0100512 rtc::CritScope lock(&crit_sect_);
henrik.lundin48ed9302015-10-29 05:36:24 -0700513 if (!nack_enabled_) {
514 return std::vector<uint16_t>();
515 }
516 RTC_DCHECK(nack_.get());
517 return nack_->GetNackList(round_trip_time_ms);
minyue@webrtc.orgd7301772013-08-29 00:58:14 +0000518}
519
henrik.lundin114c1b32017-04-26 07:47:32 -0700520std::vector<uint32_t> NetEqImpl::LastDecodedTimestamps() const {
521 rtc::CritScope lock(&crit_sect_);
522 return last_decoded_timestamps_;
523}
524
525int NetEqImpl::SyncBufferSizeMs() const {
526 rtc::CritScope lock(&crit_sect_);
527 return rtc::dchecked_cast<int>(sync_buffer_->FutureLength() /
528 rtc::CheckedDivExact(fs_hz_, 1000));
529}
530
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000531const SyncBuffer* NetEqImpl::sync_buffer_for_test() const {
Tommi9090e0b2016-01-20 13:39:36 +0100532 rtc::CritScope lock(&crit_sect_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000533 return sync_buffer_.get();
534}
535
minyue5bd33972016-05-02 04:46:11 -0700536Operations NetEqImpl::last_operation_for_test() const {
537 rtc::CritScope lock(&crit_sect_);
538 return last_operation_;
539}
540
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000541// Methods below this line are private.
542
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200543int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header,
kwibergee2bac22015-11-11 10:34:00 -0800544 rtc::ArrayView<const uint8_t> payload,
ossu17e3fa12016-09-08 04:52:55 -0700545 uint32_t receive_timestamp) {
kwibergee2bac22015-11-11 10:34:00 -0800546 if (payload.empty()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100547 RTC_LOG_F(LS_ERROR) << "payload is empty";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000548 return kInvalidPointer;
549 }
ossu17e3fa12016-09-08 04:52:55 -0700550
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000551 PacketList packet_list;
ossua73f6c92016-10-24 08:25:28 -0700552 // Insert packet in a packet list.
553 packet_list.push_back([&rtp_header, &payload] {
henrik.lundin@webrtc.orge1d468c2013-01-30 07:37:20 +0000554 // Convert to Packet.
ossua73f6c92016-10-24 08:25:28 -0700555 Packet packet;
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200556 packet.payload_type = rtp_header.payloadType;
557 packet.sequence_number = rtp_header.sequenceNumber;
558 packet.timestamp = rtp_header.timestamp;
ossua73f6c92016-10-24 08:25:28 -0700559 packet.payload.SetData(payload.data(), payload.size());
henrik.lundin84f8cd62016-04-26 07:45:16 -0700560 // Waiting time will be set upon inserting the packet in the buffer.
ossua73f6c92016-10-24 08:25:28 -0700561 RTC_DCHECK(!packet.waiting_time);
562 return packet;
563 }());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000564
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200565 bool update_sample_rate_and_channels =
566 first_packet_ || (rtp_header.ssrc != ssrc_);
dkirovbroadsofte851a9a2017-03-14 10:00:27 -0700567
568 if (update_sample_rate_and_channels) {
569 // Reset timestamp scaling.
570 timestamp_scaler_->Reset();
571 }
572
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200573 if (!decoder_database_->IsRed(rtp_header.payloadType)) {
dkirovbroadsofte851a9a2017-03-14 10:00:27 -0700574 // Scale timestamp to internal domain (only for some codecs).
575 timestamp_scaler_->ToInternal(&packet_list);
576 }
577
578 // Store these for later use, since the first packet may very well disappear
579 // before we need these values.
580 uint32_t main_timestamp = packet_list.front().timestamp;
581 uint8_t main_payload_type = packet_list.front().payload_type;
582 uint16_t main_sequence_number = packet_list.front().sequence_number;
583
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000584 // Reinitialize NetEq if it's needed (changed SSRC or first call).
dkirovbroadsofte851a9a2017-03-14 10:00:27 -0700585 if (update_sample_rate_and_channels) {
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000586 // Note: |first_packet_| will be cleared further down in this method, once
587 // the packet has been successfully inserted into the packet buffer.
588
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200589 rtcp_.Init(rtp_header.sequenceNumber);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000590
591 // Flush the packet buffer and DTMF buffer.
592 packet_buffer_->Flush();
593 dtmf_buffer_->Flush();
594
595 // Store new SSRC.
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200596 ssrc_ = rtp_header.ssrc;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000597
turaj@webrtc.org4d06db52013-03-27 18:31:42 +0000598 // Update audio buffer timestamp.
dkirovbroadsofte851a9a2017-03-14 10:00:27 -0700599 sync_buffer_->IncreaseEndTimestamp(main_timestamp - timestamp_);
turaj@webrtc.org4d06db52013-03-27 18:31:42 +0000600
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000601 // Update codecs.
dkirovbroadsofte851a9a2017-03-14 10:00:27 -0700602 timestamp_ = main_timestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000603 }
604
turaj@webrtc.org7b75ac62013-09-26 00:27:56 +0000605 // Update RTCP statistics, only for regular packets.
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200606 rtcp_.Update(rtp_header, receive_timestamp);
ossu7a377612016-10-18 04:06:13 -0700607
608 if (nack_enabled_) {
609 RTC_DCHECK(nack_);
610 if (update_sample_rate_and_channels) {
611 nack_->Reset();
612 }
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200613 nack_->UpdateLastReceivedPacket(rtp_header.sequenceNumber,
614 rtp_header.timestamp);
ossu7a377612016-10-18 04:06:13 -0700615 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000616
617 // Check for RED payload type, and separate payloads into several packets.
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200618 if (decoder_database_->IsRed(rtp_header.payloadType)) {
ossua70695a2016-09-22 02:06:28 -0700619 if (!red_payload_splitter_->SplitRed(&packet_list)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000620 return kRedundancySplitError;
621 }
622 // Only accept a few RED payloads of the same type as the main data,
623 // DTMF events and CNG.
ossua70695a2016-09-22 02:06:28 -0700624 red_payload_splitter_->CheckRedPayloads(&packet_list, *decoder_database_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000625 }
626
627 // Check payload types.
628 if (decoder_database_->CheckPayloadTypes(packet_list) ==
629 DecoderDatabase::kDecoderNotFound) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000630 return kUnknownRtpPayloadType;
631 }
632
ossu7a377612016-10-18 04:06:13 -0700633 RTC_DCHECK(!packet_list.empty());
ossu7a377612016-10-18 04:06:13 -0700634
dkirovbroadsofte851a9a2017-03-14 10:00:27 -0700635 // Update main_timestamp, if new packets appear in the list
636 // after RED splitting.
Henrik Lundin70c09bd2017-04-24 15:56:56 +0200637 if (decoder_database_->IsRed(rtp_header.payloadType)) {
dkirovbroadsofte851a9a2017-03-14 10:00:27 -0700638 timestamp_scaler_->ToInternal(&packet_list);
639 main_timestamp = packet_list.front().timestamp;
640 main_payload_type = packet_list.front().payload_type;
641 main_sequence_number = packet_list.front().sequence_number;
642 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000643
644 // Process DTMF payloads. Cycle through the list of packets, and pick out any
645 // DTMF payloads found.
646 PacketList::iterator it = packet_list.begin();
647 while (it != packet_list.end()) {
ossua73f6c92016-10-24 08:25:28 -0700648 const Packet& current_packet = (*it);
649 RTC_DCHECK(!current_packet.payload.empty());
650 if (decoder_database_->IsDtmf(current_packet.payload_type)) {
minyue@webrtc.org9721db72013-08-06 05:36:26 +0000651 DtmfEvent event;
ossua73f6c92016-10-24 08:25:28 -0700652 int ret = DtmfBuffer::ParseEvent(current_packet.timestamp,
653 current_packet.payload.data(),
654 current_packet.payload.size(), &event);
minyue@webrtc.org9721db72013-08-06 05:36:26 +0000655 if (ret != DtmfBuffer::kOK) {
minyue@webrtc.org9721db72013-08-06 05:36:26 +0000656 return kDtmfParsingError;
657 }
658 if (dtmf_buffer_->InsertEvent(event) != DtmfBuffer::kOK) {
minyue@webrtc.org9721db72013-08-06 05:36:26 +0000659 return kDtmfInsertError;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000660 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000661 it = packet_list.erase(it);
662 } else {
663 ++it;
664 }
665 }
666
ossu17e3fa12016-09-08 04:52:55 -0700667 // Update bandwidth estimate, if the packet is not comfort noise.
668 if (!packet_list.empty() &&
ossu7a377612016-10-18 04:06:13 -0700669 !decoder_database_->IsComfortNoise(main_payload_type)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000670 // The list can be empty here if we got nothing but DTMF payloads.
ossu7a377612016-10-18 04:06:13 -0700671 AudioDecoder* decoder = decoder_database_->GetDecoder(main_payload_type);
672 RTC_DCHECK(decoder); // Should always get a valid object, since we have
673 // already checked that the payload types are known.
ossua73f6c92016-10-24 08:25:28 -0700674 decoder->IncomingPacket(packet_list.front().payload.data(),
675 packet_list.front().payload.size(),
676 packet_list.front().sequence_number,
677 packet_list.front().timestamp,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000678 receive_timestamp);
679 }
680
ossu61a208b2016-09-20 01:38:00 -0700681 PacketList parsed_packet_list;
682 while (!packet_list.empty()) {
ossua73f6c92016-10-24 08:25:28 -0700683 Packet& packet = packet_list.front();
ossu61a208b2016-09-20 01:38:00 -0700684 const DecoderDatabase::DecoderInfo* info =
ossua73f6c92016-10-24 08:25:28 -0700685 decoder_database_->GetDecoderInfo(packet.payload_type);
ossu61a208b2016-09-20 01:38:00 -0700686 if (!info) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100687 RTC_LOG(LS_WARNING) << "SplitAudio unknown payload type";
ossu61a208b2016-09-20 01:38:00 -0700688 return kUnknownRtpPayloadType;
689 }
690
691 if (info->IsComfortNoise()) {
692 // Carry comfort noise packets along.
ossua73f6c92016-10-24 08:25:28 -0700693 parsed_packet_list.splice(parsed_packet_list.end(), packet_list,
694 packet_list.begin());
ossu61a208b2016-09-20 01:38:00 -0700695 } else {
ossua73f6c92016-10-24 08:25:28 -0700696 const auto sequence_number = packet.sequence_number;
697 const auto payload_type = packet.payload_type;
698 const Packet::Priority original_priority = packet.priority;
699 auto packet_from_result = [&] (AudioDecoder::ParseResult& result) {
700 Packet new_packet;
701 new_packet.sequence_number = sequence_number;
702 new_packet.payload_type = payload_type;
703 new_packet.timestamp = result.timestamp;
704 new_packet.priority.codec_level = result.priority;
705 new_packet.priority.red_level = original_priority.red_level;
706 new_packet.frame = std::move(result.frame);
707 return new_packet;
708 };
709
ossu61a208b2016-09-20 01:38:00 -0700710 std::vector<AudioDecoder::ParseResult> results =
ossua73f6c92016-10-24 08:25:28 -0700711 info->GetDecoder()->ParsePayload(std::move(packet.payload),
712 packet.timestamp);
713 if (results.empty()) {
714 packet_list.pop_front();
715 } else {
716 bool first = true;
717 for (auto& result : results) {
718 RTC_DCHECK(result.frame);
719 RTC_DCHECK_GE(result.priority, 0);
720 if (first) {
721 // Re-use the node and move it to parsed_packet_list.
722 packet_list.front() = packet_from_result(result);
723 parsed_packet_list.splice(parsed_packet_list.end(), packet_list,
724 packet_list.begin());
725 first = false;
726 } else {
727 parsed_packet_list.push_back(packet_from_result(result));
728 }
ossu61a208b2016-09-20 01:38:00 -0700729 }
ossu61a208b2016-09-20 01:38:00 -0700730 }
731 }
732 }
733
Ivo Creusenfd7c0a52017-10-20 12:35:04 +0200734 // Calculate the number of primary (non-FEC/RED) packets.
735 const int number_of_primary_packets = std::count_if(
736 parsed_packet_list.begin(), parsed_packet_list.end(),
737 [](const Packet& in) { return in.priority.codec_level == 0; });
738
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000739 // Insert packets in buffer.
ossua70695a2016-09-22 02:06:28 -0700740 const int ret = packet_buffer_->InsertPacketList(
ossu61a208b2016-09-20 01:38:00 -0700741 &parsed_packet_list, *decoder_database_, &current_rtp_payload_type_,
minyue-webrtc12d30842017-07-19 11:44:06 +0200742 &current_cng_rtp_payload_type_, &stats_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000743 if (ret == PacketBuffer::kFlushed) {
744 // Reset DSP timestamp etc. if packet buffer flushed.
745 new_codec_ = true;
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000746 update_sample_rate_and_channels = true;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000747 } else if (ret != PacketBuffer::kOK) {
minyue@webrtc.org7bb54362013-08-06 05:40:57 +0000748 return kOtherError;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000749 }
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000750
751 if (first_packet_) {
752 first_packet_ = false;
753 // Update the codec on the next GetAudio call.
754 new_codec_ = true;
755 }
756
henrik.lundinda8bbf62016-08-31 03:14:11 -0700757 if (current_rtp_payload_type_) {
758 RTC_DCHECK(decoder_database_->GetDecoderInfo(*current_rtp_payload_type_))
759 << "Payload type " << static_cast<int>(*current_rtp_payload_type_)
760 << " is unknown where it shouldn't be";
761 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000762
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000763 if (update_sample_rate_and_channels && !packet_buffer_->Empty()) {
764 // We do not use |current_rtp_payload_type_| to |set payload_type|, but
765 // get the next RTP header from |packet_buffer_| to obtain the payload type.
766 // The reason for it is the following corner case. If NetEq receives a
767 // CNG packet with a sample rate different than the current CNG then it
768 // flushes its buffer, assuming send codec must have been changed. However,
769 // payload type of the hypothetically new send codec is not known.
ossu7a377612016-10-18 04:06:13 -0700770 const Packet* next_packet = packet_buffer_->PeekNextPacket();
771 RTC_DCHECK(next_packet);
772 const int payload_type = next_packet->payload_type;
ossu97ba30e2016-04-25 07:55:58 -0700773 size_t channels = 1;
774 if (!decoder_database_->IsComfortNoise(payload_type)) {
775 AudioDecoder* decoder = decoder_database_->GetDecoder(payload_type);
776 assert(decoder); // Payloads are already checked to be valid.
777 channels = decoder->Channels();
778 }
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000779 const DecoderDatabase::DecoderInfo* decoder_info =
780 decoder_database_->GetDecoderInfo(payload_type);
781 assert(decoder_info);
kwibergc0f2dcf2016-05-31 06:28:03 -0700782 if (decoder_info->SampleRateHz() != fs_hz_ ||
ossu97ba30e2016-04-25 07:55:58 -0700783 channels != algorithm_buffer_->Channels()) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700784 SetSampleRateAndChannels(decoder_info->SampleRateHz(),
785 channels);
henrik.lundin48ed9302015-10-29 05:36:24 -0700786 }
787 if (nack_enabled_) {
788 RTC_DCHECK(nack_);
789 // Update the sample rate even if the rate is not new, because of Reset().
790 nack_->UpdateSampleRate(fs_hz_);
791 }
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000792 }
793
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000794 // TODO(hlundin): Move this code to DelayManager class.
795 const DecoderDatabase::DecoderInfo* dec_info =
ossu7a377612016-10-18 04:06:13 -0700796 decoder_database_->GetDecoderInfo(main_payload_type);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000797 assert(dec_info); // Already checked that the payload type is known.
ossuf1b08da2016-09-23 02:19:43 -0700798 delay_manager_->LastDecodedWasCngOrDtmf(dec_info->IsComfortNoise() ||
799 dec_info->IsDtmf());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000800 if (delay_manager_->last_pack_cng_or_dtmf() == 0) {
801 // Calculate the total speech length carried in each packet.
Ivo Creusenfd7c0a52017-10-20 12:35:04 +0200802 if (number_of_primary_packets > 0) {
henrik.lundin116c84e2015-08-27 13:14:48 -0700803 const size_t packet_length_samples =
Ivo Creusenfd7c0a52017-10-20 12:35:04 +0200804 number_of_primary_packets * decoder_frame_length_;
henrik.lundin116c84e2015-08-27 13:14:48 -0700805 if (packet_length_samples != decision_logic_->packet_length_samples()) {
806 decision_logic_->set_packet_length_samples(packet_length_samples);
807 delay_manager_->SetPacketAudioLength(
kwibergd3edd772017-03-01 18:52:48 -0800808 rtc::dchecked_cast<int>((1000 * packet_length_samples) / fs_hz_));
henrik.lundin116c84e2015-08-27 13:14:48 -0700809 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000810 }
811
812 // Update statistics.
ossu7a377612016-10-18 04:06:13 -0700813 if ((int32_t)(main_timestamp - timestamp_) >= 0 && !new_codec_) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000814 // Only update statistics if incoming packet is not older than last played
815 // out packet, and if new codec flag is not set.
ossu7a377612016-10-18 04:06:13 -0700816 delay_manager_->Update(main_sequence_number, main_timestamp, fs_hz_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000817 }
818 } else if (delay_manager_->last_pack_cng_or_dtmf() == -1) {
819 // This is first "normal" packet after CNG or DTMF.
820 // Reset packet time counter and measure time until next packet,
821 // but don't update statistics.
822 delay_manager_->set_last_pack_cng_or_dtmf(0);
823 delay_manager_->ResetPacketIatCount();
824 }
825 return 0;
826}
827
henrik.lundin7a926812016-05-12 13:51:28 -0700828int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, bool* muted) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000829 PacketList packet_list;
830 DtmfEvent dtmf_event;
831 Operations operation;
832 bool play_dtmf;
henrik.lundin7a926812016-05-12 13:51:28 -0700833 *muted = false;
henrik.lundin114c1b32017-04-26 07:47:32 -0700834 last_decoded_timestamps_.clear();
henrik.lundined497212016-04-25 10:11:38 -0700835 tick_timer_->Increment();
henrik.lundin60f6ce22016-05-10 03:52:04 -0700836 stats_.IncreaseCounter(output_size_samples_, fs_hz_);
henrik.lundin7a926812016-05-12 13:51:28 -0700837
838 // Check for muted state.
839 if (enable_muted_state_ && expand_->Muted() && packet_buffer_->Empty()) {
840 RTC_DCHECK_EQ(last_mode_, kModeExpand);
henrik.lundina4491072017-07-06 05:23:53 -0700841 audio_frame->Reset();
842 RTC_DCHECK(audio_frame->muted()); // Reset() should mute the frame.
henrik.lundin7a926812016-05-12 13:51:28 -0700843 playout_timestamp_ += static_cast<uint32_t>(output_size_samples_);
844 audio_frame->sample_rate_hz_ = fs_hz_;
845 audio_frame->samples_per_channel_ = output_size_samples_;
846 audio_frame->timestamp_ =
847 first_packet_
848 ? 0
849 : timestamp_scaler_->ToExternal(playout_timestamp_) -
850 static_cast<uint32_t>(audio_frame->samples_per_channel_);
851 audio_frame->num_channels_ = sync_buffer_->Channels();
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200852 stats_.ExpandedNoiseSamples(output_size_samples_, false);
henrik.lundin7a926812016-05-12 13:51:28 -0700853 *muted = true;
854 return 0;
855 }
856
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000857 int return_value = GetDecision(&operation, &packet_list, &dtmf_event,
858 &play_dtmf);
859 if (return_value != 0) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000860 last_mode_ = kModeError;
861 return return_value;
862 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000863
864 AudioDecoder::SpeechType speech_type;
865 int length = 0;
Henrik Lundin18036282017-11-02 12:09:06 +0100866 const size_t start_num_packets = packet_list.size();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000867 int decode_return_value = Decode(&packet_list, &operation,
868 &length, &speech_type);
869
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000870 assert(vad_.get());
871 bool sid_frame_available =
872 (operation == kRfc3389Cng && !packet_list.empty());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700873 vad_->Update(decoded_buffer_.get(), static_cast<size_t>(length), speech_type,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000874 sid_frame_available, fs_hz_);
875
Henrik Lundin18036282017-11-02 12:09:06 +0100876 // This is the criterion that we did decode some data through the speech
877 // decoder, and the operation resulted in comfort noise.
878 const bool codec_internal_sid_frame =
Henrik Lundin4f2a4a12018-01-26 17:32:56 +0100879 (speech_type == AudioDecoder::kComfortNoise &&
880 start_num_packets > packet_list.size());
Henrik Lundin18036282017-11-02 12:09:06 +0100881
882 if (sid_frame_available || codec_internal_sid_frame) {
henrik.lundinb1fb72b2016-05-03 08:18:47 -0700883 // Start a new stopwatch since we are decoding a new CNG packet.
884 generated_noise_stopwatch_ = tick_timer_->GetNewStopwatch();
885 }
886
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000887 algorithm_buffer_->Clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000888 switch (operation) {
889 case kNormal: {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000890 DoNormal(decoded_buffer_.get(), length, speech_type, play_dtmf);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000891 break;
892 }
893 case kMerge: {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000894 DoMerge(decoded_buffer_.get(), length, speech_type, play_dtmf);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000895 break;
896 }
897 case kExpand: {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000898 return_value = DoExpand(play_dtmf);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000899 break;
900 }
Henrik Lundincf808d22015-05-27 14:33:29 +0200901 case kAccelerate:
902 case kFastAccelerate: {
903 const bool fast_accelerate =
904 enable_fast_accelerate_ && (operation == kFastAccelerate);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000905 return_value = DoAccelerate(decoded_buffer_.get(), length, speech_type,
Henrik Lundincf808d22015-05-27 14:33:29 +0200906 play_dtmf, fast_accelerate);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000907 break;
908 }
909 case kPreemptiveExpand: {
910 return_value = DoPreemptiveExpand(decoded_buffer_.get(), length,
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000911 speech_type, play_dtmf);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000912 break;
913 }
914 case kRfc3389Cng:
915 case kRfc3389CngNoPacket: {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000916 return_value = DoRfc3389Cng(&packet_list, play_dtmf);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000917 break;
918 }
919 case kCodecInternalCng: {
920 // This handles the case when there is no transmission and the decoder
921 // should produce internal comfort noise.
922 // TODO(hlundin): Write test for codec-internal CNG.
minyuel6d92bf52015-09-23 15:20:39 +0200923 DoCodecInternalCng(decoded_buffer_.get(), length);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000924 break;
925 }
926 case kDtmf: {
927 // TODO(hlundin): Write test for this.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000928 return_value = DoDtmf(dtmf_event, &play_dtmf);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000929 break;
930 }
931 case kAlternativePlc: {
932 // TODO(hlundin): Write test for this.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000933 DoAlternativePlc(false);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000934 break;
935 }
936 case kAlternativePlcIncreaseTimestamp: {
937 // TODO(hlundin): Write test for this.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000938 DoAlternativePlc(true);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000939 break;
940 }
941 case kAudioRepetitionIncreaseTimestamp: {
942 // TODO(hlundin): Write test for this.
Peter Kastingb7e50542015-06-11 12:55:50 -0700943 sync_buffer_->IncreaseEndTimestamp(
944 static_cast<uint32_t>(output_size_samples_));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000945 // Skipping break on purpose. Execution should move on into the
946 // next case.
Karl Wiberg80ba3332018-02-05 10:33:35 +0100947 RTC_FALLTHROUGH();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000948 }
949 case kAudioRepetition: {
950 // TODO(hlundin): Write test for this.
951 // Copy last |output_size_samples_| from |sync_buffer_| to
952 // |algorithm_buffer|.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000953 algorithm_buffer_->PushBackFromIndex(
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000954 *sync_buffer_, sync_buffer_->Size() - output_size_samples_);
955 expand_->Reset();
956 break;
957 }
958 case kUndefined: {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100959 RTC_LOG(LS_ERROR) << "Invalid operation kUndefined.";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000960 assert(false); // This should not happen.
961 last_mode_ = kModeError;
962 return kInvalidOperation;
963 }
964 } // End of switch.
minyue5bd33972016-05-02 04:46:11 -0700965 last_operation_ = operation;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000966 if (return_value < 0) {
967 return return_value;
968 }
969
970 if (last_mode_ != kModeRfc3389Cng) {
971 comfort_noise_->Reset();
972 }
973
974 // Copy from |algorithm_buffer| to |sync_buffer_|.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +0000975 sync_buffer_->PushBack(*algorithm_buffer_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000976
977 // Extract data from |sync_buffer_| to |output|.
turaj@webrtc.org362a55e2013-09-20 16:25:28 +0000978 size_t num_output_samples_per_channel = output_size_samples_;
979 size_t num_output_samples = output_size_samples_ * sync_buffer_->Channels();
henrik.lundin6d8e0112016-03-04 10:34:21 -0800980 if (num_output_samples > AudioFrame::kMaxDataSizeSamples) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100981 RTC_LOG(LS_WARNING) << "Output array is too short. "
982 << AudioFrame::kMaxDataSizeSamples << " < "
983 << output_size_samples_ << " * "
984 << sync_buffer_->Channels();
henrik.lundin6d8e0112016-03-04 10:34:21 -0800985 num_output_samples = AudioFrame::kMaxDataSizeSamples;
986 num_output_samples_per_channel =
987 AudioFrame::kMaxDataSizeSamples / sync_buffer_->Channels();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000988 }
henrik.lundin6d8e0112016-03-04 10:34:21 -0800989 sync_buffer_->GetNextAudioInterleaved(num_output_samples_per_channel,
990 audio_frame);
991 audio_frame->sample_rate_hz_ = fs_hz_;
Henrik Lundin05f71fc2015-09-01 11:51:58 +0200992 if (sync_buffer_->FutureLength() < expand_->overlap_length()) {
993 // The sync buffer should always contain |overlap_length| samples, but now
994 // too many samples have been extracted. Reinstall the |overlap_length|
995 // lookahead by moving the index.
996 const size_t missing_lookahead_samples =
997 expand_->overlap_length() - sync_buffer_->FutureLength();
henrikg91d6ede2015-09-17 00:24:34 -0700998 RTC_DCHECK_GE(sync_buffer_->next_index(), missing_lookahead_samples);
Henrik Lundin05f71fc2015-09-01 11:51:58 +0200999 sync_buffer_->set_next_index(sync_buffer_->next_index() -
1000 missing_lookahead_samples);
1001 }
henrik.lundin6d8e0112016-03-04 10:34:21 -08001002 if (audio_frame->samples_per_channel_ != output_size_samples_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001003 RTC_LOG(LS_ERROR) << "audio_frame->samples_per_channel_ ("
1004 << audio_frame->samples_per_channel_
1005 << ") != output_size_samples_ (" << output_size_samples_
1006 << ")";
minyue@webrtc.orgdb1cefc2013-08-13 01:39:21 +00001007 // TODO(minyue): treatment of under-run, filling zeros
yujo36b1a5f2017-06-12 12:45:32 -07001008 audio_frame->Mute();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001009 return kSampleUnderrun;
1010 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001011
1012 // Should always have overlap samples left in the |sync_buffer_|.
henrikg91d6ede2015-09-17 00:24:34 -07001013 RTC_DCHECK_GE(sync_buffer_->FutureLength(), expand_->overlap_length());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001014
yujo36b1a5f2017-06-12 12:45:32 -07001015 // TODO(yujo): For muted frames, this can be a copy rather than an addition.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001016 if (play_dtmf) {
yujo36b1a5f2017-06-12 12:45:32 -07001017 return_value = DtmfOverdub(dtmf_event, sync_buffer_->Channels(),
1018 audio_frame->mutable_data());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001019 }
1020
1021 // Update the background noise parameters if last operation wrote data
1022 // straight from the decoder to the |sync_buffer_|. That is, none of the
1023 // operations that modify the signal can be followed by a parameter update.
1024 if ((last_mode_ == kModeNormal) ||
1025 (last_mode_ == kModeAccelerateFail) ||
1026 (last_mode_ == kModePreemptiveExpandFail) ||
1027 (last_mode_ == kModeRfc3389Cng) ||
1028 (last_mode_ == kModeCodecInternalCng)) {
1029 background_noise_->Update(*sync_buffer_, *vad_.get());
1030 }
1031
1032 if (operation == kDtmf) {
1033 // DTMF data was written the end of |sync_buffer_|.
1034 // Update index to end of DTMF data in |sync_buffer_|.
1035 sync_buffer_->set_dtmf_index(sync_buffer_->Size());
1036 }
1037
henrik.lundin@webrtc.orged865b52014-03-06 10:28:07 +00001038 if (last_mode_ != kModeExpand) {
1039 // If last operation was not expand, calculate the |playout_timestamp_| from
1040 // the |sync_buffer_|. However, do not update the |playout_timestamp_| if it
1041 // would be moved "backwards".
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001042 uint32_t temp_timestamp = sync_buffer_->end_timestamp() -
turaj@webrtc.org362a55e2013-09-20 16:25:28 +00001043 static_cast<uint32_t>(sync_buffer_->FutureLength());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001044 if (static_cast<int32_t>(temp_timestamp - playout_timestamp_) > 0) {
1045 playout_timestamp_ = temp_timestamp;
1046 }
1047 } else {
1048 // Use dead reckoning to estimate the |playout_timestamp_|.
Peter Kastingb7e50542015-06-11 12:55:50 -07001049 playout_timestamp_ += static_cast<uint32_t>(output_size_samples_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001050 }
henrik.lundin15c51e32016-04-06 08:38:56 -07001051 // Set the timestamp in the audio frame to zero before the first packet has
1052 // been inserted. Otherwise, subtract the frame size in samples to get the
1053 // timestamp of the first sample in the frame (playout_timestamp_ is the
1054 // last + 1).
1055 audio_frame->timestamp_ =
1056 first_packet_
1057 ? 0
1058 : timestamp_scaler_->ToExternal(playout_timestamp_) -
1059 static_cast<uint32_t>(audio_frame->samples_per_channel_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001060
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001061 if (!(last_mode_ == kModeRfc3389Cng ||
1062 last_mode_ == kModeCodecInternalCng ||
1063 last_mode_ == kModeExpand)) {
1064 generated_noise_stopwatch_.reset();
1065 }
1066
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001067 if (decode_return_value) return decode_return_value;
1068 return return_value;
1069}
1070
1071int NetEqImpl::GetDecision(Operations* operation,
1072 PacketList* packet_list,
1073 DtmfEvent* dtmf_event,
1074 bool* play_dtmf) {
1075 // Initialize output variables.
1076 *play_dtmf = false;
1077 *operation = kUndefined;
1078
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001079 assert(sync_buffer_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001080 uint32_t end_timestamp = sync_buffer_->end_timestamp();
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +00001081 if (!new_codec_) {
1082 const uint32_t five_seconds_samples = 5 * fs_hz_;
minyue-webrtcfae474c2017-07-05 11:17:40 +02001083 packet_buffer_->DiscardOldPackets(end_timestamp, five_seconds_samples,
1084 &stats_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +00001085 }
ossu7a377612016-10-18 04:06:13 -07001086 const Packet* packet = packet_buffer_->PeekNextPacket();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001087
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001088 RTC_DCHECK(!generated_noise_stopwatch_ ||
1089 generated_noise_stopwatch_->ElapsedTicks() >= 1);
1090 uint64_t generated_noise_samples =
1091 generated_noise_stopwatch_
1092 ? (generated_noise_stopwatch_->ElapsedTicks() - 1) *
1093 output_size_samples_ +
1094 decision_logic_->noise_fast_forward()
1095 : 0;
1096
henrik.lundin@webrtc.orgca8cb952014-03-12 10:26:52 +00001097 if (decision_logic_->CngRfc3389On() || last_mode_ == kModeRfc3389Cng) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001098 // Because of timestamp peculiarities, we have to "manually" disallow using
1099 // a CNG packet with the same timestamp as the one that was last played.
1100 // This can happen when using redundancy and will cause the timing to shift.
ossu7a377612016-10-18 04:06:13 -07001101 while (packet && decoder_database_->IsComfortNoise(packet->payload_type) &&
1102 (end_timestamp >= packet->timestamp ||
1103 end_timestamp + generated_noise_samples > packet->timestamp)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001104 // Don't use this packet, discard it.
minyue-webrtcfae474c2017-07-05 11:17:40 +02001105 if (packet_buffer_->DiscardNextPacket(&stats_) != PacketBuffer::kOK) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001106 assert(false); // Must be ok by design.
1107 }
1108 // Check buffer again.
1109 if (!new_codec_) {
minyue-webrtcfae474c2017-07-05 11:17:40 +02001110 packet_buffer_->DiscardOldPackets(end_timestamp, 5 * fs_hz_, &stats_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001111 }
ossu7a377612016-10-18 04:06:13 -07001112 packet = packet_buffer_->PeekNextPacket();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001113 }
1114 }
1115
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001116 assert(expand_.get());
turaj@webrtc.org362a55e2013-09-20 16:25:28 +00001117 const int samples_left = static_cast<int>(sync_buffer_->FutureLength() -
1118 expand_->overlap_length());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001119 if (last_mode_ == kModeAccelerateSuccess ||
1120 last_mode_ == kModeAccelerateLowEnergy ||
1121 last_mode_ == kModePreemptiveExpandSuccess ||
1122 last_mode_ == kModePreemptiveExpandLowEnergy) {
1123 // Subtract (samples_left + output_size_samples_) from sampleMemory.
Peter Kastingdce40cf2015-08-24 14:52:23 -07001124 decision_logic_->AddSampleMemory(
kwibergd3edd772017-03-01 18:52:48 -08001125 -(samples_left + rtc::dchecked_cast<int>(output_size_samples_)));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001126 }
1127
1128 // Check if it is time to play a DTMF event.
Peter Kastingb7e50542015-06-11 12:55:50 -07001129 if (dtmf_buffer_->GetEvent(
1130 static_cast<uint32_t>(
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001131 end_timestamp + generated_noise_samples),
Peter Kastingb7e50542015-06-11 12:55:50 -07001132 dtmf_event)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001133 *play_dtmf = true;
1134 }
1135
1136 // Get instruction.
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001137 assert(sync_buffer_.get());
1138 assert(expand_.get());
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001139 generated_noise_samples =
1140 generated_noise_stopwatch_
1141 ? generated_noise_stopwatch_->ElapsedTicks() * output_size_samples_ +
1142 decision_logic_->noise_fast_forward()
1143 : 0;
1144 *operation = decision_logic_->GetDecision(
ossu7a377612016-10-18 04:06:13 -07001145 *sync_buffer_, *expand_, decoder_frame_length_, packet, last_mode_,
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001146 *play_dtmf, generated_noise_samples, &reset_decoder_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001147
1148 // Check if we already have enough samples in the |sync_buffer_|. If so,
1149 // change decision to normal, unless the decision was merge, accelerate, or
1150 // preemptive expand.
kwibergd3edd772017-03-01 18:52:48 -08001151 if (samples_left >= rtc::dchecked_cast<int>(output_size_samples_) &&
1152 *operation != kMerge && *operation != kAccelerate &&
1153 *operation != kFastAccelerate && *operation != kPreemptiveExpand) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001154 *operation = kNormal;
1155 return 0;
1156 }
1157
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00001158 decision_logic_->ExpandDecision(*operation);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001159
1160 // Check conditions for reset.
1161 if (new_codec_ || *operation == kUndefined) {
1162 // The only valid reason to get kUndefined is that new_codec_ is set.
1163 assert(new_codec_);
ossu7a377612016-10-18 04:06:13 -07001164 if (*play_dtmf && !packet) {
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001165 timestamp_ = dtmf_event->timestamp;
1166 } else {
ossu7a377612016-10-18 04:06:13 -07001167 if (!packet) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001168 RTC_LOG(LS_ERROR) << "Packet missing where it shouldn't.";
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001169 return -1;
1170 }
ossu7a377612016-10-18 04:06:13 -07001171 timestamp_ = packet->timestamp;
ossu108ecec2016-07-08 08:45:18 -07001172 if (*operation == kRfc3389CngNoPacket &&
ossu7a377612016-10-18 04:06:13 -07001173 decoder_database_->IsComfortNoise(packet->payload_type)) {
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001174 // Change decision to CNG packet, since we do have a CNG packet, but it
1175 // was considered too early to use. Now, use it anyway.
1176 *operation = kRfc3389Cng;
1177 } else if (*operation != kRfc3389Cng) {
1178 *operation = kNormal;
1179 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001180 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001181 // Adjust |sync_buffer_| timestamp before setting |end_timestamp| to the
1182 // new value.
1183 sync_buffer_->IncreaseEndTimestamp(timestamp_ - end_timestamp);
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001184 end_timestamp = timestamp_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001185 new_codec_ = false;
1186 decision_logic_->SoftReset();
1187 buffer_level_filter_->Reset();
1188 delay_manager_->Reset();
1189 stats_.ResetMcu();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001190 }
1191
Peter Kastingdce40cf2015-08-24 14:52:23 -07001192 size_t required_samples = output_size_samples_;
1193 const size_t samples_10_ms = static_cast<size_t>(80 * fs_mult_);
1194 const size_t samples_20_ms = 2 * samples_10_ms;
1195 const size_t samples_30_ms = 3 * samples_10_ms;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001196
1197 switch (*operation) {
1198 case kExpand: {
1199 timestamp_ = end_timestamp;
1200 return 0;
1201 }
1202 case kRfc3389CngNoPacket:
1203 case kCodecInternalCng: {
1204 return 0;
1205 }
1206 case kDtmf: {
1207 // TODO(hlundin): Write test for this.
1208 // Update timestamp.
1209 timestamp_ = end_timestamp;
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001210 const uint64_t generated_noise_samples =
1211 generated_noise_stopwatch_
1212 ? generated_noise_stopwatch_->ElapsedTicks() *
1213 output_size_samples_ +
1214 decision_logic_->noise_fast_forward()
1215 : 0;
1216 if (generated_noise_samples > 0 && last_mode_ != kModeDtmf) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001217 // Make a jump in timestamp due to the recently played comfort noise.
Peter Kastingb7e50542015-06-11 12:55:50 -07001218 uint32_t timestamp_jump =
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001219 static_cast<uint32_t>(generated_noise_samples);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001220 sync_buffer_->IncreaseEndTimestamp(timestamp_jump);
1221 timestamp_ += timestamp_jump;
1222 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001223 return 0;
1224 }
Henrik Lundincf808d22015-05-27 14:33:29 +02001225 case kAccelerate:
1226 case kFastAccelerate: {
1227 // In order to do an accelerate we need at least 30 ms of audio data.
Peter Kastingdce40cf2015-08-24 14:52:23 -07001228 if (samples_left >= static_cast<int>(samples_30_ms)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001229 // Already have enough data, so we do not need to extract any more.
1230 decision_logic_->set_sample_memory(samples_left);
1231 decision_logic_->set_prev_time_scale(true);
1232 return 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -07001233 } else if (samples_left >= static_cast<int>(samples_10_ms) &&
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001234 decoder_frame_length_ >= samples_30_ms) {
1235 // Avoid decoding more data as it might overflow the playout buffer.
1236 *operation = kNormal;
1237 return 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -07001238 } else if (samples_left < static_cast<int>(samples_20_ms) &&
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001239 decoder_frame_length_ < samples_30_ms) {
1240 // Build up decoded data by decoding at least 20 ms of audio data. Do
1241 // not perform accelerate yet, but wait until we only need to do one
1242 // decoding.
1243 required_samples = 2 * output_size_samples_;
1244 *operation = kNormal;
1245 }
1246 // If none of the above is true, we have one of two possible situations:
1247 // (1) 20 ms <= samples_left < 30 ms and decoder_frame_length_ < 30 ms; or
1248 // (2) samples_left < 10 ms and decoder_frame_length_ >= 30 ms.
1249 // In either case, we move on with the accelerate decision, and decode one
1250 // frame now.
1251 break;
1252 }
1253 case kPreemptiveExpand: {
1254 // In order to do a preemptive expand we need at least 30 ms of decoded
1255 // audio data.
Peter Kastingdce40cf2015-08-24 14:52:23 -07001256 if ((samples_left >= static_cast<int>(samples_30_ms)) ||
1257 (samples_left >= static_cast<int>(samples_10_ms) &&
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001258 decoder_frame_length_ >= samples_30_ms)) {
1259 // Already have enough data, so we do not need to extract any more.
1260 // Or, avoid decoding more data as it might overflow the playout buffer.
1261 // Still try preemptive expand, though.
1262 decision_logic_->set_sample_memory(samples_left);
1263 decision_logic_->set_prev_time_scale(true);
1264 return 0;
1265 }
Peter Kastingdce40cf2015-08-24 14:52:23 -07001266 if (samples_left < static_cast<int>(samples_20_ms) &&
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001267 decoder_frame_length_ < samples_30_ms) {
1268 // Build up decoded data by decoding at least 20 ms of audio data.
1269 // Still try to perform preemptive expand.
1270 required_samples = 2 * output_size_samples_;
1271 }
1272 // Move on with the preemptive expand decision.
1273 break;
1274 }
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00001275 case kMerge: {
1276 required_samples =
1277 std::max(merge_->RequiredFutureSamples(), required_samples);
1278 break;
1279 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001280 default: {
1281 // Do nothing.
1282 }
1283 }
1284
1285 // Get packets from buffer.
1286 int extracted_samples = 0;
ossu7a377612016-10-18 04:06:13 -07001287 if (packet && *operation != kAlternativePlc &&
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001288 *operation != kAlternativePlcIncreaseTimestamp &&
1289 *operation != kAudioRepetition &&
1290 *operation != kAudioRepetitionIncreaseTimestamp) {
ossu7a377612016-10-18 04:06:13 -07001291 sync_buffer_->IncreaseEndTimestamp(packet->timestamp - end_timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001292 if (decision_logic_->CngOff()) {
1293 // Adjustment of timestamp only corresponds to an actual packet loss
1294 // if comfort noise is not played. If comfort noise was just played,
1295 // this adjustment of timestamp is only done to get back in sync with the
1296 // stream timestamp; no loss to report.
ossu7a377612016-10-18 04:06:13 -07001297 stats_.LostSamples(packet->timestamp - end_timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001298 }
1299
1300 if (*operation != kRfc3389Cng) {
1301 // We are about to decode and use a non-CNG packet.
1302 decision_logic_->SetCngOff();
1303 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001304
1305 extracted_samples = ExtractPackets(required_samples, packet_list);
1306 if (extracted_samples < 0) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001307 return kPacketBufferCorruption;
1308 }
1309 }
1310
Henrik Lundincf808d22015-05-27 14:33:29 +02001311 if (*operation == kAccelerate || *operation == kFastAccelerate ||
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001312 *operation == kPreemptiveExpand) {
1313 decision_logic_->set_sample_memory(samples_left + extracted_samples);
1314 decision_logic_->set_prev_time_scale(true);
1315 }
1316
Henrik Lundincf808d22015-05-27 14:33:29 +02001317 if (*operation == kAccelerate || *operation == kFastAccelerate) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001318 // Check that we have enough data (30ms) to do accelerate.
Peter Kastingdce40cf2015-08-24 14:52:23 -07001319 if (extracted_samples + samples_left < static_cast<int>(samples_30_ms)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001320 // TODO(hlundin): Write test for this.
1321 // Not enough, do normal operation instead.
1322 *operation = kNormal;
1323 }
1324 }
1325
1326 timestamp_ = end_timestamp;
1327 return 0;
1328}
1329
1330int NetEqImpl::Decode(PacketList* packet_list, Operations* operation,
1331 int* decoded_length,
1332 AudioDecoder::SpeechType* speech_type) {
1333 *speech_type = AudioDecoder::kSpeech;
minyuel6d92bf52015-09-23 15:20:39 +02001334
1335 // When packet_list is empty, we may be in kCodecInternalCng mode, and for
1336 // that we use current active decoder.
1337 AudioDecoder* decoder = decoder_database_->GetActiveDecoder();
1338
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001339 if (!packet_list->empty()) {
ossua73f6c92016-10-24 08:25:28 -07001340 const Packet& packet = packet_list->front();
1341 uint8_t payload_type = packet.payload_type;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001342 if (!decoder_database_->IsComfortNoise(payload_type)) {
1343 decoder = decoder_database_->GetDecoder(payload_type);
1344 assert(decoder);
1345 if (!decoder) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001346 RTC_LOG(LS_WARNING)
1347 << "Unknown payload type " << static_cast<int>(payload_type);
ossua73f6c92016-10-24 08:25:28 -07001348 packet_list->clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001349 return kDecoderNotFound;
1350 }
1351 bool decoder_changed;
1352 decoder_database_->SetActiveDecoder(payload_type, &decoder_changed);
1353 if (decoder_changed) {
1354 // We have a new decoder. Re-init some values.
1355 const DecoderDatabase::DecoderInfo* decoder_info = decoder_database_
1356 ->GetDecoderInfo(payload_type);
1357 assert(decoder_info);
1358 if (!decoder_info) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001359 RTC_LOG(LS_WARNING)
1360 << "Unknown payload type " << static_cast<int>(payload_type);
ossua73f6c92016-10-24 08:25:28 -07001361 packet_list->clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001362 return kDecoderNotFound;
1363 }
tina.legrand@webrtc.orgba5a6c32014-03-23 09:58:48 +00001364 // If sampling rate or number of channels has changed, we need to make
1365 // a reset.
kwibergc0f2dcf2016-05-31 06:28:03 -07001366 if (decoder_info->SampleRateHz() != fs_hz_ ||
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +00001367 decoder->Channels() != algorithm_buffer_->Channels()) {
tina.legrand@webrtc.orgba5a6c32014-03-23 09:58:48 +00001368 // TODO(tlegrand): Add unittest to cover this event.
kwibergc0f2dcf2016-05-31 06:28:03 -07001369 SetSampleRateAndChannels(decoder_info->SampleRateHz(),
1370 decoder->Channels());
turaj@webrtc.orga6101d72013-10-01 22:01:09 +00001371 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001372 sync_buffer_->set_end_timestamp(timestamp_);
1373 playout_timestamp_ = timestamp_;
1374 }
1375 }
1376 }
1377
1378 if (reset_decoder_) {
1379 // TODO(hlundin): Write test for this.
Karl Wiberg43766482015-08-27 15:22:11 +02001380 if (decoder)
1381 decoder->Reset();
1382
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001383 // Reset comfort noise decoder.
ossu97ba30e2016-04-25 07:55:58 -07001384 ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
Karl Wiberg43766482015-08-27 15:22:11 +02001385 if (cng_decoder)
1386 cng_decoder->Reset();
1387
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001388 reset_decoder_ = false;
1389 }
1390
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001391 *decoded_length = 0;
1392 // Update codec-internal PLC state.
1393 if ((*operation == kMerge) && decoder && decoder->HasDecodePlc()) {
1394 decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]);
1395 }
1396
minyuel6d92bf52015-09-23 15:20:39 +02001397 int return_value;
1398 if (*operation == kCodecInternalCng) {
1399 RTC_DCHECK(packet_list->empty());
1400 return_value = DecodeCng(decoder, decoded_length, speech_type);
1401 } else {
1402 return_value = DecodeLoop(packet_list, *operation, decoder,
1403 decoded_length, speech_type);
1404 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001405
1406 if (*decoded_length < 0) {
1407 // Error returned from the decoder.
1408 *decoded_length = 0;
Peter Kastingb7e50542015-06-11 12:55:50 -07001409 sync_buffer_->IncreaseEndTimestamp(
1410 static_cast<uint32_t>(decoder_frame_length_));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001411 int error_code = 0;
1412 if (decoder)
1413 error_code = decoder->ErrorCode();
1414 if (error_code != 0) {
1415 // Got some error code from the decoder.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001416 return_value = kDecoderErrorCode;
Mirko Bonadei675513b2017-11-09 11:09:25 +01001417 RTC_LOG(LS_WARNING) << "Decoder returned error code: " << error_code;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001418 } else {
1419 // Decoder does not implement error codes. Return generic error.
1420 return_value = kOtherDecoderError;
Mirko Bonadei675513b2017-11-09 11:09:25 +01001421 RTC_LOG(LS_WARNING) << "Decoder error (no error code)";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001422 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001423 *operation = kExpand; // Do expansion to get data instead.
1424 }
1425 if (*speech_type != AudioDecoder::kComfortNoise) {
1426 // Don't increment timestamp if codec returned CNG speech type
1427 // since in this case, the we will increment the CNGplayedTS counter.
1428 // Increase with number of samples per channel.
1429 assert(*decoded_length == 0 ||
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +00001430 (decoder && decoder->Channels() == sync_buffer_->Channels()));
turaj@webrtc.org362a55e2013-09-20 16:25:28 +00001431 sync_buffer_->IncreaseEndTimestamp(
1432 *decoded_length / static_cast<int>(sync_buffer_->Channels()));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001433 }
1434 return return_value;
1435}
1436
minyuel6d92bf52015-09-23 15:20:39 +02001437int NetEqImpl::DecodeCng(AudioDecoder* decoder, int* decoded_length,
1438 AudioDecoder::SpeechType* speech_type) {
1439 if (!decoder) {
1440 // This happens when active decoder is not defined.
1441 *decoded_length = -1;
1442 return 0;
1443 }
1444
kwibergd3edd772017-03-01 18:52:48 -08001445 while (*decoded_length < rtc::dchecked_cast<int>(output_size_samples_)) {
minyuel6d92bf52015-09-23 15:20:39 +02001446 const int length = decoder->Decode(
1447 nullptr, 0, fs_hz_,
1448 (decoded_buffer_length_ - *decoded_length) * sizeof(int16_t),
1449 &decoded_buffer_[*decoded_length], speech_type);
1450 if (length > 0) {
1451 *decoded_length += length;
minyuel6d92bf52015-09-23 15:20:39 +02001452 } else {
1453 // Error.
Mirko Bonadei675513b2017-11-09 11:09:25 +01001454 RTC_LOG(LS_WARNING) << "Failed to decode CNG";
minyuel6d92bf52015-09-23 15:20:39 +02001455 *decoded_length = -1;
1456 break;
1457 }
1458 if (*decoded_length > static_cast<int>(decoded_buffer_length_)) {
1459 // Guard against overflow.
Mirko Bonadei675513b2017-11-09 11:09:25 +01001460 RTC_LOG(LS_WARNING) << "Decoded too much CNG.";
minyuel6d92bf52015-09-23 15:20:39 +02001461 return kDecodedTooMuch;
1462 }
1463 }
1464 return 0;
1465}
1466
1467int NetEqImpl::DecodeLoop(PacketList* packet_list, const Operations& operation,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001468 AudioDecoder* decoder, int* decoded_length,
1469 AudioDecoder::SpeechType* speech_type) {
henrik.lundin114c1b32017-04-26 07:47:32 -07001470 RTC_DCHECK(last_decoded_timestamps_.empty());
1471
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001472 // Do decoding.
ossua73f6c92016-10-24 08:25:28 -07001473 while (
1474 !packet_list->empty() &&
1475 !decoder_database_->IsComfortNoise(packet_list->front().payload_type)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001476 assert(decoder); // At this point, we must have a decoder object.
1477 // The number of channels in the |sync_buffer_| should be the same as the
1478 // number decoder channels.
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +00001479 assert(sync_buffer_->Channels() == decoder->Channels());
1480 assert(decoded_buffer_length_ >= kMaxFrameSize * decoder->Channels());
minyuel6d92bf52015-09-23 15:20:39 +02001481 assert(operation == kNormal || operation == kAccelerate ||
1482 operation == kFastAccelerate || operation == kMerge ||
1483 operation == kPreemptiveExpand);
ossua73f6c92016-10-24 08:25:28 -07001484
1485 auto opt_result = packet_list->front().frame->Decode(
ossu61a208b2016-09-20 01:38:00 -07001486 rtc::ArrayView<int16_t>(&decoded_buffer_[*decoded_length],
1487 decoded_buffer_length_ - *decoded_length));
henrik.lundin114c1b32017-04-26 07:47:32 -07001488 last_decoded_timestamps_.push_back(packet_list->front().timestamp);
ossua73f6c92016-10-24 08:25:28 -07001489 packet_list->pop_front();
ossu61a208b2016-09-20 01:38:00 -07001490 if (opt_result) {
1491 const auto& result = *opt_result;
1492 *speech_type = result.speech_type;
1493 if (result.num_decoded_samples > 0) {
kwibergd3edd772017-03-01 18:52:48 -08001494 *decoded_length += rtc::dchecked_cast<int>(result.num_decoded_samples);
ossu61a208b2016-09-20 01:38:00 -07001495 // Update |decoder_frame_length_| with number of samples per channel.
1496 decoder_frame_length_ =
1497 result.num_decoded_samples / decoder->Channels();
1498 }
1499 } else {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001500 // Error.
ossu61a208b2016-09-20 01:38:00 -07001501 // TODO(ossu): What to put here?
Mirko Bonadei675513b2017-11-09 11:09:25 +01001502 RTC_LOG(LS_WARNING) << "Decode error";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001503 *decoded_length = -1;
ossua73f6c92016-10-24 08:25:28 -07001504 packet_list->clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001505 break;
1506 }
kwibergd3edd772017-03-01 18:52:48 -08001507 if (*decoded_length > rtc::dchecked_cast<int>(decoded_buffer_length_)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001508 // Guard against overflow.
Mirko Bonadei675513b2017-11-09 11:09:25 +01001509 RTC_LOG(LS_WARNING) << "Decoded too much.";
ossua73f6c92016-10-24 08:25:28 -07001510 packet_list->clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001511 return kDecodedTooMuch;
1512 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001513 } // End of decode loop.
1514
turaj@webrtc.org58cd3162013-10-31 15:15:55 +00001515 // If the list is not empty at this point, either a decoding error terminated
1516 // the while-loop, or list must hold exactly one CNG packet.
ossua73f6c92016-10-24 08:25:28 -07001517 assert(
1518 packet_list->empty() || *decoded_length < 0 ||
1519 (packet_list->size() == 1 &&
1520 decoder_database_->IsComfortNoise(packet_list->front().payload_type)));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001521 return 0;
1522}
1523
1524void NetEqImpl::DoNormal(const int16_t* decoded_buffer, size_t decoded_length,
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001525 AudioDecoder::SpeechType speech_type, bool play_dtmf) {
henrik.lundin@webrtc.org40d3fc62013-09-18 12:19:50 +00001526 assert(normal_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001527 assert(mute_factor_array_.get());
henrik.lundin@webrtc.org40d3fc62013-09-18 12:19:50 +00001528 normal_->Process(decoded_buffer, decoded_length, last_mode_,
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001529 mute_factor_array_.get(), algorithm_buffer_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001530 if (decoded_length != 0) {
1531 last_mode_ = kModeNormal;
1532 }
1533
1534 // If last packet was decoded as an inband CNG, set mode to CNG instead.
1535 if ((speech_type == AudioDecoder::kComfortNoise)
1536 || ((last_mode_ == kModeCodecInternalCng)
1537 && (decoded_length == 0))) {
1538 // TODO(hlundin): Remove second part of || statement above.
1539 last_mode_ = kModeCodecInternalCng;
1540 }
1541
1542 if (!play_dtmf) {
1543 dtmf_tone_generator_->Reset();
1544 }
1545}
1546
1547void NetEqImpl::DoMerge(int16_t* decoded_buffer, size_t decoded_length,
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001548 AudioDecoder::SpeechType speech_type, bool play_dtmf) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001549 assert(mute_factor_array_.get());
henrik.lundin@webrtc.org40d3fc62013-09-18 12:19:50 +00001550 assert(merge_.get());
Peter Kastingdce40cf2015-08-24 14:52:23 -07001551 size_t new_length = merge_->Process(decoded_buffer, decoded_length,
1552 mute_factor_array_.get(),
1553 algorithm_buffer_.get());
henrik.lundin2979f552017-05-05 05:04:16 -07001554 // Correction can be negative.
1555 int expand_length_correction =
1556 rtc::dchecked_cast<int>(new_length) -
1557 rtc::dchecked_cast<int>(decoded_length / algorithm_buffer_->Channels());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001558
1559 // Update in-call and post-call statistics.
1560 if (expand_->MuteFactor(0) == 0) {
1561 // Expand generates only noise.
henrik.lundin2979f552017-05-05 05:04:16 -07001562 stats_.ExpandedNoiseSamplesCorrection(expand_length_correction);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001563 } else {
1564 // Expansion generates more than only noise.
henrik.lundin2979f552017-05-05 05:04:16 -07001565 stats_.ExpandedVoiceSamplesCorrection(expand_length_correction);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001566 }
1567
1568 last_mode_ = kModeMerge;
1569 // If last packet was decoded as an inband CNG, set mode to CNG instead.
1570 if (speech_type == AudioDecoder::kComfortNoise) {
1571 last_mode_ = kModeCodecInternalCng;
1572 }
1573 expand_->Reset();
1574 if (!play_dtmf) {
1575 dtmf_tone_generator_->Reset();
1576 }
1577}
1578
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001579int NetEqImpl::DoExpand(bool play_dtmf) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001580 while ((sync_buffer_->FutureLength() - expand_->overlap_length()) <
Peter Kastingdce40cf2015-08-24 14:52:23 -07001581 output_size_samples_) {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001582 algorithm_buffer_->Clear();
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001583 int return_value = expand_->Process(algorithm_buffer_.get());
Peter Kastingdce40cf2015-08-24 14:52:23 -07001584 size_t length = algorithm_buffer_->Size();
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +02001585 bool is_new_concealment_event = (last_mode_ != kModeExpand);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001586
1587 // Update in-call and post-call statistics.
1588 if (expand_->MuteFactor(0) == 0) {
1589 // Expand operation generates only noise.
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +02001590 stats_.ExpandedNoiseSamples(length, is_new_concealment_event);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001591 } else {
1592 // Expand operation generates more than only noise.
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +02001593 stats_.ExpandedVoiceSamples(length, is_new_concealment_event);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001594 }
1595
1596 last_mode_ = kModeExpand;
1597
1598 if (return_value < 0) {
1599 return return_value;
1600 }
1601
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001602 sync_buffer_->PushBack(*algorithm_buffer_);
1603 algorithm_buffer_->Clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001604 }
1605 if (!play_dtmf) {
1606 dtmf_tone_generator_->Reset();
1607 }
henrik.lundinb1fb72b2016-05-03 08:18:47 -07001608
1609 if (!generated_noise_stopwatch_) {
1610 // Start a new stopwatch since we may be covering for a lost CNG packet.
1611 generated_noise_stopwatch_ = tick_timer_->GetNewStopwatch();
1612 }
1613
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001614 return 0;
1615}
1616
Henrik Lundincf808d22015-05-27 14:33:29 +02001617int NetEqImpl::DoAccelerate(int16_t* decoded_buffer,
1618 size_t decoded_length,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001619 AudioDecoder::SpeechType speech_type,
Henrik Lundincf808d22015-05-27 14:33:29 +02001620 bool play_dtmf,
1621 bool fast_accelerate) {
Peter Kastingdce40cf2015-08-24 14:52:23 -07001622 const size_t required_samples =
1623 static_cast<size_t>(240 * fs_mult_); // Must have 30 ms.
turaj@webrtc.org362a55e2013-09-20 16:25:28 +00001624 size_t borrowed_samples_per_channel = 0;
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001625 size_t num_channels = algorithm_buffer_->Channels();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001626 size_t decoded_length_per_channel = decoded_length / num_channels;
1627 if (decoded_length_per_channel < required_samples) {
1628 // Must move data from the |sync_buffer_| in order to get 30 ms.
turaj@webrtc.org362a55e2013-09-20 16:25:28 +00001629 borrowed_samples_per_channel = static_cast<int>(required_samples -
1630 decoded_length_per_channel);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001631 memmove(&decoded_buffer[borrowed_samples_per_channel * num_channels],
1632 decoded_buffer,
1633 sizeof(int16_t) * decoded_length);
1634 sync_buffer_->ReadInterleavedFromEnd(borrowed_samples_per_channel,
1635 decoded_buffer);
1636 decoded_length = required_samples * num_channels;
1637 }
1638
Peter Kastingdce40cf2015-08-24 14:52:23 -07001639 size_t samples_removed;
Henrik Lundincf808d22015-05-27 14:33:29 +02001640 Accelerate::ReturnCodes return_code =
1641 accelerate_->Process(decoded_buffer, decoded_length, fast_accelerate,
1642 algorithm_buffer_.get(), &samples_removed);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001643 stats_.AcceleratedSamples(samples_removed);
1644 switch (return_code) {
1645 case Accelerate::kSuccess:
1646 last_mode_ = kModeAccelerateSuccess;
1647 break;
1648 case Accelerate::kSuccessLowEnergy:
1649 last_mode_ = kModeAccelerateLowEnergy;
1650 break;
1651 case Accelerate::kNoStretch:
1652 last_mode_ = kModeAccelerateFail;
1653 break;
1654 case Accelerate::kError:
1655 // TODO(hlundin): Map to kModeError instead?
1656 last_mode_ = kModeAccelerateFail;
1657 return kAccelerateError;
1658 }
1659
1660 if (borrowed_samples_per_channel > 0) {
1661 // Copy borrowed samples back to the |sync_buffer_|.
turaj@webrtc.org362a55e2013-09-20 16:25:28 +00001662 size_t length = algorithm_buffer_->Size();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001663 if (length < borrowed_samples_per_channel) {
1664 // This destroys the beginning of the buffer, but will not cause any
1665 // problems.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001666 sync_buffer_->ReplaceAtIndex(*algorithm_buffer_,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001667 sync_buffer_->Size() -
1668 borrowed_samples_per_channel);
1669 sync_buffer_->PushFrontZeros(borrowed_samples_per_channel - length);
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001670 algorithm_buffer_->PopFront(length);
1671 assert(algorithm_buffer_->Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001672 } else {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001673 sync_buffer_->ReplaceAtIndex(*algorithm_buffer_,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001674 borrowed_samples_per_channel,
1675 sync_buffer_->Size() -
1676 borrowed_samples_per_channel);
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001677 algorithm_buffer_->PopFront(borrowed_samples_per_channel);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001678 }
1679 }
1680
1681 // If last packet was decoded as an inband CNG, set mode to CNG instead.
1682 if (speech_type == AudioDecoder::kComfortNoise) {
1683 last_mode_ = kModeCodecInternalCng;
1684 }
1685 if (!play_dtmf) {
1686 dtmf_tone_generator_->Reset();
1687 }
1688 expand_->Reset();
1689 return 0;
1690}
1691
1692int NetEqImpl::DoPreemptiveExpand(int16_t* decoded_buffer,
1693 size_t decoded_length,
1694 AudioDecoder::SpeechType speech_type,
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001695 bool play_dtmf) {
Peter Kastingdce40cf2015-08-24 14:52:23 -07001696 const size_t required_samples =
1697 static_cast<size_t>(240 * fs_mult_); // Must have 30 ms.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001698 size_t num_channels = algorithm_buffer_->Channels();
Peter Kastingdce40cf2015-08-24 14:52:23 -07001699 size_t borrowed_samples_per_channel = 0;
1700 size_t old_borrowed_samples_per_channel = 0;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001701 size_t decoded_length_per_channel = decoded_length / num_channels;
1702 if (decoded_length_per_channel < required_samples) {
1703 // Must move data from the |sync_buffer_| in order to get 30 ms.
Peter Kastingdce40cf2015-08-24 14:52:23 -07001704 borrowed_samples_per_channel =
1705 required_samples - decoded_length_per_channel;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001706 // Calculate how many of these were already played out.
Peter Kastingf045e4d2015-06-10 21:15:38 -07001707 old_borrowed_samples_per_channel =
Peter Kastingdce40cf2015-08-24 14:52:23 -07001708 (borrowed_samples_per_channel > sync_buffer_->FutureLength()) ?
1709 (borrowed_samples_per_channel - sync_buffer_->FutureLength()) : 0;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001710 memmove(&decoded_buffer[borrowed_samples_per_channel * num_channels],
1711 decoded_buffer,
1712 sizeof(int16_t) * decoded_length);
1713 sync_buffer_->ReadInterleavedFromEnd(borrowed_samples_per_channel,
1714 decoded_buffer);
1715 decoded_length = required_samples * num_channels;
1716 }
1717
Peter Kastingdce40cf2015-08-24 14:52:23 -07001718 size_t samples_added;
henrik.lundin@webrtc.org40d3fc62013-09-18 12:19:50 +00001719 PreemptiveExpand::ReturnCodes return_code = preemptive_expand_->Process(
Peter Kastingdce40cf2015-08-24 14:52:23 -07001720 decoded_buffer, decoded_length,
turaj@webrtc.org362a55e2013-09-20 16:25:28 +00001721 old_borrowed_samples_per_channel,
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001722 algorithm_buffer_.get(), &samples_added);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001723 stats_.PreemptiveExpandedSamples(samples_added);
1724 switch (return_code) {
1725 case PreemptiveExpand::kSuccess:
1726 last_mode_ = kModePreemptiveExpandSuccess;
1727 break;
1728 case PreemptiveExpand::kSuccessLowEnergy:
1729 last_mode_ = kModePreemptiveExpandLowEnergy;
1730 break;
1731 case PreemptiveExpand::kNoStretch:
1732 last_mode_ = kModePreemptiveExpandFail;
1733 break;
1734 case PreemptiveExpand::kError:
1735 // TODO(hlundin): Map to kModeError instead?
1736 last_mode_ = kModePreemptiveExpandFail;
1737 return kPreemptiveExpandError;
1738 }
1739
1740 if (borrowed_samples_per_channel > 0) {
1741 // Copy borrowed samples back to the |sync_buffer_|.
1742 sync_buffer_->ReplaceAtIndex(
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001743 *algorithm_buffer_, borrowed_samples_per_channel,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001744 sync_buffer_->Size() - borrowed_samples_per_channel);
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001745 algorithm_buffer_->PopFront(borrowed_samples_per_channel);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001746 }
1747
1748 // If last packet was decoded as an inband CNG, set mode to CNG instead.
1749 if (speech_type == AudioDecoder::kComfortNoise) {
1750 last_mode_ = kModeCodecInternalCng;
1751 }
1752 if (!play_dtmf) {
1753 dtmf_tone_generator_->Reset();
1754 }
1755 expand_->Reset();
1756 return 0;
1757}
1758
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001759int NetEqImpl::DoRfc3389Cng(PacketList* packet_list, bool play_dtmf) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001760 if (!packet_list->empty()) {
1761 // Must have exactly one SID frame at this point.
1762 assert(packet_list->size() == 1);
ossua73f6c92016-10-24 08:25:28 -07001763 const Packet& packet = packet_list->front();
1764 if (!decoder_database_->IsComfortNoise(packet.payload_type)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001765 RTC_LOG(LS_ERROR) << "Trying to decode non-CNG payload as CNG.";
henrik.lundin@webrtc.org73deaad2013-01-31 13:32:51 +00001766 return kOtherError;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001767 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001768 if (comfort_noise_->UpdateParameters(packet) ==
1769 ComfortNoise::kInternalError) {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001770 algorithm_buffer_->Zeros(output_size_samples_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001771 return -comfort_noise_->internal_error_code();
1772 }
1773 }
1774 int cn_return = comfort_noise_->Generate(output_size_samples_,
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001775 algorithm_buffer_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001776 expand_->Reset();
1777 last_mode_ = kModeRfc3389Cng;
1778 if (!play_dtmf) {
1779 dtmf_tone_generator_->Reset();
1780 }
1781 if (cn_return == ComfortNoise::kInternalError) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001782 RTC_LOG(LS_WARNING) << "Comfort noise generator returned error code: "
1783 << comfort_noise_->internal_error_code();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001784 return kComfortNoiseErrorCode;
1785 } else if (cn_return == ComfortNoise::kUnknownPayloadType) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001786 return kUnknownRtpPayloadType;
1787 }
1788 return 0;
1789}
1790
minyuel6d92bf52015-09-23 15:20:39 +02001791void NetEqImpl::DoCodecInternalCng(const int16_t* decoded_buffer,
1792 size_t decoded_length) {
1793 RTC_DCHECK(normal_.get());
1794 RTC_DCHECK(mute_factor_array_.get());
1795 normal_->Process(decoded_buffer, decoded_length, last_mode_,
1796 mute_factor_array_.get(), algorithm_buffer_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001797 last_mode_ = kModeCodecInternalCng;
1798 expand_->Reset();
1799}
1800
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001801int NetEqImpl::DoDtmf(const DtmfEvent& dtmf_event, bool* play_dtmf) {
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001802 // This block of the code and the block further down, handling |dtmf_switch|
1803 // are commented out. Otherwise playing out-of-band DTMF would fail in VoE
1804 // test, DtmfTest.ManualSuccessfullySendsOutOfBandTelephoneEvents. This is
1805 // equivalent to |dtmf_switch| always be false.
1806 //
1807 // See http://webrtc-codereview.appspot.com/1195004/ for discussion
1808 // On this issue. This change might cause some glitches at the point of
1809 // switch from audio to DTMF. Issue 1545 is filed to track this.
1810 //
1811 // bool dtmf_switch = false;
1812 // if ((last_mode_ != kModeDtmf) && dtmf_tone_generator_->initialized()) {
1813 // // Special case; see below.
1814 // // We must catch this before calling Generate, since |initialized| is
1815 // // modified in that call.
1816 // dtmf_switch = true;
1817 // }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001818
1819 int dtmf_return_value = 0;
1820 if (!dtmf_tone_generator_->initialized()) {
1821 // Initialize if not already done.
1822 dtmf_return_value = dtmf_tone_generator_->Init(fs_hz_, dtmf_event.event_no,
1823 dtmf_event.volume);
1824 }
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001825
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001826 if (dtmf_return_value == 0) {
1827 // Generate DTMF signal.
1828 dtmf_return_value = dtmf_tone_generator_->Generate(output_size_samples_,
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00001829 algorithm_buffer_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001830 }
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001831
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001832 if (dtmf_return_value < 0) {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001833 algorithm_buffer_->Zeros(output_size_samples_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001834 return dtmf_return_value;
1835 }
1836
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001837 // if (dtmf_switch) {
1838 // // This is the special case where the previous operation was DTMF
1839 // // overdub, but the current instruction is "regular" DTMF. We must make
1840 // // sure that the DTMF does not have any discontinuities. The first DTMF
1841 // // sample that we generate now must be played out immediately, therefore
1842 // // it must be copied to the speech buffer.
1843 // // TODO(hlundin): This code seems incorrect. (Legacy.) Write test and
1844 // // verify correct operation.
1845 // assert(false);
1846 // // Must generate enough data to replace all of the |sync_buffer_|
1847 // // "future".
1848 // int required_length = sync_buffer_->FutureLength();
1849 // assert(dtmf_tone_generator_->initialized());
1850 // dtmf_return_value = dtmf_tone_generator_->Generate(required_length,
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001851 // algorithm_buffer_);
1852 // assert((size_t) required_length == algorithm_buffer_->Size());
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001853 // if (dtmf_return_value < 0) {
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001854 // algorithm_buffer_->Zeros(output_size_samples_);
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001855 // return dtmf_return_value;
1856 // }
1857 //
1858 // // Overwrite the "future" part of the speech buffer with the new DTMF
1859 // // data.
1860 // // TODO(hlundin): It seems that this overwriting has gone lost.
1861 // // Not adapted for multi-channel yet.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001862 // assert(algorithm_buffer_->Channels() == 1);
1863 // if (algorithm_buffer_->Channels() != 1) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001864 // RTC_LOG(LS_WARNING) << "DTMF not supported for more than one channel";
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001865 // return kStereoNotSupported;
1866 // }
1867 // // Shuffle the remaining data to the beginning of algorithm buffer.
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001868 // algorithm_buffer_->PopFront(sync_buffer_->FutureLength());
turaj@webrtc.org4d06db52013-03-27 18:31:42 +00001869 // }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001870
Peter Kastingb7e50542015-06-11 12:55:50 -07001871 sync_buffer_->IncreaseEndTimestamp(
1872 static_cast<uint32_t>(output_size_samples_));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001873 expand_->Reset();
1874 last_mode_ = kModeDtmf;
1875
1876 // Set to false because the DTMF is already in the algorithm buffer.
1877 *play_dtmf = false;
1878 return 0;
1879}
1880
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001881void NetEqImpl::DoAlternativePlc(bool increase_timestamp) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001882 AudioDecoder* decoder = decoder_database_->GetActiveDecoder();
Peter Kastingdce40cf2015-08-24 14:52:23 -07001883 size_t length;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001884 if (decoder && decoder->HasDecodePlc()) {
1885 // Use the decoder's packet-loss concealment.
1886 // TODO(hlundin): Will probably need a longer buffer for multi-channel.
1887 int16_t decoded_buffer[kMaxFrameSize];
1888 length = decoder->DecodePlc(1, decoded_buffer);
Peter Kastingdce40cf2015-08-24 14:52:23 -07001889 if (length > 0)
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001890 algorithm_buffer_->PushBackInterleaved(decoded_buffer, length);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001891 } else {
1892 // Do simple zero-stuffing.
1893 length = output_size_samples_;
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00001894 algorithm_buffer_->Zeros(length);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001895 // By not advancing the timestamp, NetEq inserts samples.
1896 stats_.AddZeros(length);
1897 }
1898 if (increase_timestamp) {
Peter Kastingb7e50542015-06-11 12:55:50 -07001899 sync_buffer_->IncreaseEndTimestamp(static_cast<uint32_t>(length));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001900 }
1901 expand_->Reset();
1902}
1903
1904int NetEqImpl::DtmfOverdub(const DtmfEvent& dtmf_event, size_t num_channels,
1905 int16_t* output) const {
1906 size_t out_index = 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -07001907 size_t overdub_length = output_size_samples_; // Default value.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001908
1909 if (sync_buffer_->dtmf_index() > sync_buffer_->next_index()) {
1910 // Special operation for transition from "DTMF only" to "DTMF overdub".
1911 out_index = std::min(
1912 sync_buffer_->dtmf_index() - sync_buffer_->next_index(),
Peter Kastingdce40cf2015-08-24 14:52:23 -07001913 output_size_samples_);
1914 overdub_length = output_size_samples_ - out_index;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001915 }
1916
henrik.lundin@webrtc.orgfd11bbf2013-09-30 20:38:44 +00001917 AudioMultiVector dtmf_output(num_channels);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001918 int dtmf_return_value = 0;
1919 if (!dtmf_tone_generator_->initialized()) {
1920 dtmf_return_value = dtmf_tone_generator_->Init(fs_hz_, dtmf_event.event_no,
1921 dtmf_event.volume);
1922 }
1923 if (dtmf_return_value == 0) {
1924 dtmf_return_value = dtmf_tone_generator_->Generate(overdub_length,
1925 &dtmf_output);
Peter Kastingdce40cf2015-08-24 14:52:23 -07001926 assert(overdub_length == dtmf_output.Size());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001927 }
1928 dtmf_output.ReadInterleaved(overdub_length, &output[out_index]);
1929 return dtmf_return_value < 0 ? dtmf_return_value : 0;
1930}
1931
Peter Kastingdce40cf2015-08-24 14:52:23 -07001932int NetEqImpl::ExtractPackets(size_t required_samples,
1933 PacketList* packet_list) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001934 bool first_packet = true;
1935 uint8_t prev_payload_type = 0;
1936 uint32_t prev_timestamp = 0;
1937 uint16_t prev_sequence_number = 0;
1938 bool next_packet_available = false;
1939
ossu7a377612016-10-18 04:06:13 -07001940 const Packet* next_packet = packet_buffer_->PeekNextPacket();
1941 RTC_DCHECK(next_packet);
1942 if (!next_packet) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001943 RTC_LOG(LS_ERROR) << "Packet buffer unexpectedly empty.";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001944 return -1;
1945 }
ossu7a377612016-10-18 04:06:13 -07001946 uint32_t first_timestamp = next_packet->timestamp;
ossu61a208b2016-09-20 01:38:00 -07001947 size_t extracted_samples = 0;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001948
1949 // Packet extraction loop.
1950 do {
ossu7a377612016-10-18 04:06:13 -07001951 timestamp_ = next_packet->timestamp;
ossua73f6c92016-10-24 08:25:28 -07001952 rtc::Optional<Packet> packet = packet_buffer_->GetNextPacket();
ossu7a377612016-10-18 04:06:13 -07001953 // |next_packet| may be invalid after the |packet_buffer_| operation.
ossua73f6c92016-10-24 08:25:28 -07001954 next_packet = nullptr;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001955 if (!packet) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001956 RTC_LOG(LS_ERROR) << "Should always be able to extract a packet here";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001957 assert(false); // Should always be able to extract a packet here.
1958 return -1;
1959 }
Gustaf Ullbergb0a02072017-10-02 12:00:34 +02001960 const uint64_t waiting_time_ms = packet->waiting_time->ElapsedMs();
1961 stats_.StoreWaitingTime(waiting_time_ms);
ossu61a208b2016-09-20 01:38:00 -07001962 RTC_DCHECK(!packet->empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001963
1964 if (first_packet) {
1965 first_packet = false;
henrik.lundin48ed9302015-10-29 05:36:24 -07001966 if (nack_enabled_) {
1967 RTC_DCHECK(nack_);
1968 // TODO(henrik.lundin): Should we update this for all decoded packets?
ossu7a377612016-10-18 04:06:13 -07001969 nack_->UpdateLastDecodedPacket(packet->sequence_number,
1970 packet->timestamp);
henrik.lundin48ed9302015-10-29 05:36:24 -07001971 }
ossu7a377612016-10-18 04:06:13 -07001972 prev_sequence_number = packet->sequence_number;
1973 prev_timestamp = packet->timestamp;
1974 prev_payload_type = packet->payload_type;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001975 }
1976
ossucafb4972017-01-02 07:00:50 -08001977 const bool has_cng_packet =
1978 decoder_database_->IsComfortNoise(packet->payload_type);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001979 // Store number of extracted samples.
ossu61a208b2016-09-20 01:38:00 -07001980 size_t packet_duration = 0;
1981 if (packet->frame) {
1982 packet_duration = packet->frame->Duration();
ossua70695a2016-09-22 02:06:28 -07001983 // TODO(ossu): Is this the correct way to track Opus FEC packets?
1984 if (packet->priority.codec_level > 0) {
kwibergd3edd772017-03-01 18:52:48 -08001985 stats_.SecondaryDecodedSamples(
1986 rtc::dchecked_cast<int>(packet_duration));
minyue@webrtc.orgb28bfa72014-03-21 12:07:40 +00001987 }
ossucafb4972017-01-02 07:00:50 -08001988 } else if (!has_cng_packet) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001989 RTC_LOG(LS_WARNING) << "Unknown payload type "
1990 << static_cast<int>(packet->payload_type);
ossu61a208b2016-09-20 01:38:00 -07001991 RTC_NOTREACHED();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001992 }
ossu61a208b2016-09-20 01:38:00 -07001993
1994 if (packet_duration == 0) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001995 // Decoder did not return a packet duration. Assume that the packet
1996 // contains the same number of samples as the previous one.
ossu61a208b2016-09-20 01:38:00 -07001997 packet_duration = decoder_frame_length_;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001998 }
ossu7a377612016-10-18 04:06:13 -07001999 extracted_samples = packet->timestamp - first_timestamp + packet_duration;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002000
Gustaf Ullbergb0a02072017-10-02 12:00:34 +02002001 stats_.JitterBufferDelay(extracted_samples, waiting_time_ms);
2002
ossua73f6c92016-10-24 08:25:28 -07002003 packet_list->push_back(std::move(*packet)); // Store packet in list.
Oskar Sundbom12ab00b2017-11-16 15:31:38 +01002004 packet = rtc::nullopt; // Ensure it's never used after the move.
ossua73f6c92016-10-24 08:25:28 -07002005
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002006 // Check what packet is available next.
ossu7a377612016-10-18 04:06:13 -07002007 next_packet = packet_buffer_->PeekNextPacket();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002008 next_packet_available = false;
ossucafb4972017-01-02 07:00:50 -08002009 if (next_packet && prev_payload_type == next_packet->payload_type &&
2010 !has_cng_packet) {
ossu7a377612016-10-18 04:06:13 -07002011 int16_t seq_no_diff = next_packet->sequence_number - prev_sequence_number;
2012 size_t ts_diff = next_packet->timestamp - prev_timestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002013 if (seq_no_diff == 1 ||
2014 (seq_no_diff == 0 && ts_diff == decoder_frame_length_)) {
2015 // The next sequence number is available, or the next part of a packet
2016 // that was split into pieces upon insertion.
2017 next_packet_available = true;
2018 }
ossu7a377612016-10-18 04:06:13 -07002019 prev_sequence_number = next_packet->sequence_number;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002020 }
ossu61a208b2016-09-20 01:38:00 -07002021 } while (extracted_samples < required_samples && next_packet_available);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002022
henrik.lundin@webrtc.org61217152014-09-22 08:30:07 +00002023 if (extracted_samples > 0) {
2024 // Delete old packets only when we are going to decode something. Otherwise,
2025 // we could end up in the situation where we never decode anything, since
2026 // all incoming packets are considered too old but the buffer will also
2027 // never be flooded and flushed.
minyue-webrtcfae474c2017-07-05 11:17:40 +02002028 packet_buffer_->DiscardAllOldPackets(timestamp_, &stats_);
henrik.lundin@webrtc.org61217152014-09-22 08:30:07 +00002029 }
2030
kwibergd3edd772017-03-01 18:52:48 -08002031 return rtc::dchecked_cast<int>(extracted_samples);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002032}
2033
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002034void NetEqImpl::UpdatePlcComponents(int fs_hz, size_t channels) {
2035 // Delete objects and create new ones.
2036 expand_.reset(expand_factory_->Create(background_noise_.get(),
2037 sync_buffer_.get(), &random_vector_,
Henrik Lundinbef77e22015-08-18 14:58:09 +02002038 &stats_, fs_hz, channels));
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002039 merge_.reset(new Merge(fs_hz, channels, expand_.get(), sync_buffer_.get()));
2040}
2041
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002042void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01002043 RTC_LOG(LS_VERBOSE) << "SetSampleRateAndChannels " << fs_hz << " "
2044 << channels;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002045 // TODO(hlundin): Change to an enumerator and skip assert.
2046 assert(fs_hz == 8000 || fs_hz == 16000 || fs_hz == 32000 || fs_hz == 48000);
2047 assert(channels > 0);
2048
2049 fs_hz_ = fs_hz;
2050 fs_mult_ = fs_hz / 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -07002051 output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002052 decoder_frame_length_ = 3 * output_size_samples_; // Initialize to 30ms.
2053
2054 last_mode_ = kModeNormal;
2055
2056 // Create a new array of mute factors and set all to 1.
2057 mute_factor_array_.reset(new int16_t[channels]);
2058 for (size_t i = 0; i < channels; ++i) {
2059 mute_factor_array_[i] = 16384; // 1.0 in Q14.
2060 }
2061
ossu97ba30e2016-04-25 07:55:58 -07002062 ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
Karl Wiberg43766482015-08-27 15:22:11 +02002063 if (cng_decoder)
2064 cng_decoder->Reset();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002065
2066 // Reinit post-decode VAD with new sample rate.
2067 assert(vad_.get()); // Cannot be NULL here.
2068 vad_->Init();
2069
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00002070 // Delete algorithm buffer and create a new one.
henrik.lundin@webrtc.orgfd11bbf2013-09-30 20:38:44 +00002071 algorithm_buffer_.reset(new AudioMultiVector(channels));
henrik.lundin@webrtc.orgc487c6a2013-09-02 07:59:30 +00002072
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002073 // Delete sync buffer and create a new one.
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00002074 sync_buffer_.reset(new SyncBuffer(channels, kSyncBufferSize * fs_mult_));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002075
henrik.lundin@webrtc.orgea257842014-08-07 12:27:37 +00002076 // Delete BackgroundNoise object and create a new one.
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00002077 background_noise_.reset(new BackgroundNoise(channels));
henrik.lundin@webrtc.orgea257842014-08-07 12:27:37 +00002078 background_noise_->set_mode(background_noise_mode_);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002079
2080 // Reset random vector.
2081 random_vector_.Reset();
2082
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002083 UpdatePlcComponents(fs_hz, channels);
2084
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002085 // Move index so that we create a small set of future samples (all 0).
2086 sync_buffer_->set_next_index(sync_buffer_->next_index() -
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002087 expand_->overlap_length());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002088
henrik.lundin@webrtc.org40d3fc62013-09-18 12:19:50 +00002089 normal_.reset(new Normal(fs_hz, decoder_database_.get(), *background_noise_,
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00002090 expand_.get()));
henrik.lundin@webrtc.orgd9faa462014-01-14 10:18:45 +00002091 accelerate_.reset(
2092 accelerate_factory_->Create(fs_hz, channels, *background_noise_));
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002093 preemptive_expand_.reset(preemptive_expand_factory_->Create(
Peter Kastingdce40cf2015-08-24 14:52:23 -07002094 fs_hz, channels, *background_noise_, expand_->overlap_length()));
henrik.lundin@webrtc.org40d3fc62013-09-18 12:19:50 +00002095
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002096 // Delete ComfortNoise object and create a new one.
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00002097 comfort_noise_.reset(new ComfortNoise(fs_hz, decoder_database_.get(),
2098 sync_buffer_.get()));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002099
2100 // Verify that |decoded_buffer_| is long enough.
2101 if (decoded_buffer_length_ < kMaxFrameSize * channels) {
2102 // Reallocate to larger size.
2103 decoded_buffer_length_ = kMaxFrameSize * channels;
2104 decoded_buffer_.reset(new int16_t[decoded_buffer_length_]);
2105 }
2106
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002107 // Create DecisionLogic if it is not created yet, then communicate new sample
2108 // rate and output size to DecisionLogic object.
2109 if (!decision_logic_.get()) {
henrik.lundin@webrtc.org7cbc4f92014-10-07 06:37:39 +00002110 CreateDecisionLogic();
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002111 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002112 decision_logic_->SetSampleRate(fs_hz_, output_size_samples_);
2113}
2114
henrik.lundin55480f52016-03-08 02:37:57 -08002115NetEqImpl::OutputType NetEqImpl::LastOutputType() {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002116 assert(vad_.get());
henrik.lundin@webrtc.org0d5da252013-09-18 21:12:38 +00002117 assert(expand_.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002118 if (last_mode_ == kModeCodecInternalCng || last_mode_ == kModeRfc3389Cng) {
henrik.lundin55480f52016-03-08 02:37:57 -08002119 return OutputType::kCNG;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002120 } else if (last_mode_ == kModeExpand && expand_->MuteFactor(0) == 0) {
2121 // Expand mode has faded down to background noise only (very long expand).
henrik.lundin55480f52016-03-08 02:37:57 -08002122 return OutputType::kPLCCNG;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002123 } else if (last_mode_ == kModeExpand) {
henrik.lundin55480f52016-03-08 02:37:57 -08002124 return OutputType::kPLC;
wu@webrtc.org24301a62013-12-13 19:17:43 +00002125 } else if (vad_->running() && !vad_->active_speech()) {
henrik.lundin55480f52016-03-08 02:37:57 -08002126 return OutputType::kVadPassive;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002127 } else {
henrik.lundin55480f52016-03-08 02:37:57 -08002128 return OutputType::kNormalSpeech;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002129 }
2130}
2131
henrik.lundin@webrtc.org7cbc4f92014-10-07 06:37:39 +00002132void NetEqImpl::CreateDecisionLogic() {
Henrik Lundin47b17dc2016-05-10 10:20:59 +02002133 decision_logic_.reset(DecisionLogic::Create(
2134 fs_hz_, output_size_samples_, playout_mode_, decoder_database_.get(),
2135 *packet_buffer_.get(), delay_manager_.get(), buffer_level_filter_.get(),
2136 tick_timer_.get()));
turaj@webrtc.org8d1cdaa2014-04-11 18:47:55 +00002137}
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00002138} // namespace webrtc