blob: d6752038da86e09ac7a741277a16ac005a2ef722 [file] [log] [blame]
turaj@webrtc.org7959e162013-09-12 18:30:26 +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/include/audio_coding_module.h"
turaj@webrtc.org7959e162013-09-12 18:30:26 +000012
Jonathan Yu36344a02017-07-30 01:55:34 -070013#include <algorithm>
14
Niels Möller2edab4c2018-10-22 09:48:08 +020015#include "absl/strings/match.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/audio_coding/acm2/acm_receiver.h"
17#include "modules/audio_coding/acm2/acm_resampler.h"
18#include "modules/audio_coding/acm2/codec_manager.h"
19#include "modules/audio_coding/acm2/rent_a_codec.h"
Fredrik Solenbergbbf21a32018-04-12 22:44:09 +020020#include "modules/include/module_common_types.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/checks.h"
22#include "rtc_base/logging.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010023#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "system_wrappers/include/metrics.h"
turaj@webrtc.org7959e162013-09-12 18:30:26 +000025
26namespace webrtc {
27
kwibergc13ded52016-06-17 06:00:45 -070028namespace {
29
30struct EncoderFactory {
31 AudioEncoder* external_speech_encoder = nullptr;
32 acm2::CodecManager codec_manager;
33 acm2::RentACodec rent_a_codec;
34};
35
36class AudioCodingModuleImpl final : public AudioCodingModule {
37 public:
38 explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config);
39 ~AudioCodingModuleImpl() override;
40
41 /////////////////////////////////////////
42 // Sender
43 //
44
45 // Can be called multiple times for Codec, CNG, RED.
46 int RegisterSendCodec(const CodecInst& send_codec) override;
47
48 void RegisterExternalSendCodec(
49 AudioEncoder* external_speech_encoder) override;
50
kwiberg24c7c122016-09-28 11:57:10 -070051 void ModifyEncoder(rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)>
52 modifier) override;
kwibergc13ded52016-06-17 06:00:45 -070053
54 // Get current send codec.
Danil Chapovalovb6021232018-06-19 13:26:36 +020055 absl::optional<CodecInst> SendCodec() const override;
kwibergc13ded52016-06-17 06:00:45 -070056
kwibergc13ded52016-06-17 06:00:45 -070057 // Sets the bitrate to the specified value in bits/sec. In case the codec does
58 // not support the requested value it will choose an appropriate value
59 // instead.
60 void SetBitRate(int bitrate_bps) override;
61
62 // Register a transport callback which will be
63 // called to deliver the encoded buffers.
64 int RegisterTransportCallback(AudioPacketizationCallback* transport) override;
65
66 // Add 10 ms of raw (PCM) audio data to the encoder.
67 int Add10MsData(const AudioFrame& audio_frame) override;
68
69 /////////////////////////////////////////
70 // (RED) Redundant Coding
71 //
72
73 // Configure RED status i.e. on/off.
74 int SetREDStatus(bool enable_red) override;
75
76 // Get RED status.
77 bool REDStatus() const override;
78
79 /////////////////////////////////////////
80 // (FEC) Forward Error Correction (codec internal)
81 //
82
83 // Configure FEC status i.e. on/off.
84 int SetCodecFEC(bool enabled_codec_fec) override;
85
86 // Get FEC status.
87 bool CodecFEC() const override;
88
89 // Set target packet loss rate
90 int SetPacketLossRate(int loss_rate) override;
91
92 /////////////////////////////////////////
93 // (VAD) Voice Activity Detection
94 // and
95 // (CNG) Comfort Noise Generation
96 //
97
98 int SetVAD(bool enable_dtx = true,
99 bool enable_vad = false,
100 ACMVADMode mode = VADNormal) override;
101
102 int VAD(bool* dtx_enabled,
103 bool* vad_enabled,
104 ACMVADMode* mode) const override;
105
106 int RegisterVADCallback(ACMVADCallback* vad_callback) override;
107
108 /////////////////////////////////////////
109 // Receiver
110 //
111
112 // Initialize receiver, resets codec database etc.
113 int InitializeReceiver() override;
114
115 // Get current receive frequency.
116 int ReceiveFrequency() const override;
117
118 // Get current playout frequency.
119 int PlayoutFrequency() const override;
120
kwiberg1c07c702017-03-27 07:15:49 -0700121 void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
122
kwiberg5adaf732016-10-04 09:33:27 -0700123 bool RegisterReceiveCodec(int rtp_payload_type,
124 const SdpAudioFormat& audio_format) override;
125
kwibergc13ded52016-06-17 06:00:45 -0700126 int RegisterReceiveCodec(const CodecInst& receive_codec) override;
127 int RegisterReceiveCodec(
128 const CodecInst& receive_codec,
kwiberg24c7c122016-09-28 11:57:10 -0700129 rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory) override;
kwibergc13ded52016-06-17 06:00:45 -0700130
131 int RegisterExternalReceiveCodec(int rtp_payload_type,
132 AudioDecoder* external_decoder,
133 int sample_rate_hz,
134 int num_channels,
135 const std::string& name) override;
136
137 // Get current received codec.
138 int ReceiveCodec(CodecInst* current_codec) const override;
139
Danil Chapovalovb6021232018-06-19 13:26:36 +0200140 absl::optional<SdpAudioFormat> ReceiveFormat() const override;
ossue280cde2016-10-12 11:04:10 -0700141
kwibergc13ded52016-06-17 06:00:45 -0700142 // Incoming packet from network parsed and ready for decode.
143 int IncomingPacket(const uint8_t* incoming_payload,
144 const size_t payload_length,
145 const WebRtcRTPHeader& rtp_info) override;
146
kwibergc13ded52016-06-17 06:00:45 -0700147 // Minimum playout delay.
148 int SetMinimumPlayoutDelay(int time_ms) override;
149
150 // Maximum playout delay.
151 int SetMaximumPlayoutDelay(int time_ms) override;
152
Danil Chapovalovb6021232018-06-19 13:26:36 +0200153 absl::optional<uint32_t> PlayoutTimestamp() override;
kwibergc13ded52016-06-17 06:00:45 -0700154
henrik.lundinb3f1c5d2016-08-22 15:39:53 -0700155 int FilteredCurrentDelayMs() const override;
156
Henrik Lundinabbff892017-11-29 09:14:04 +0100157 int TargetDelayMs() const override;
158
kwibergc13ded52016-06-17 06:00:45 -0700159 // Get 10 milliseconds of raw audio data to play out, and
160 // automatic resample to the requested frequency if > 0.
161 int PlayoutData10Ms(int desired_freq_hz,
162 AudioFrame* audio_frame,
163 bool* muted) override;
kwibergc13ded52016-06-17 06:00:45 -0700164
165 /////////////////////////////////////////
166 // Statistics
167 //
168
169 int GetNetworkStatistics(NetworkStatistics* statistics) override;
170
kwibergc13ded52016-06-17 06:00:45 -0700171 // If current send codec is Opus, informs it about the maximum playback rate
172 // the receiver will render.
173 int SetOpusMaxPlaybackRate(int frequency_hz) override;
174
175 int EnableOpusDtx() override;
176
177 int DisableOpusDtx() override;
178
179 int UnregisterReceiveCodec(uint8_t payload_type) override;
180
181 int EnableNack(size_t max_nack_list_size) override;
182
183 void DisableNack() override;
184
185 std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const override;
186
187 void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const override;
188
ivoce1198e02017-09-08 08:13:19 -0700189 ANAStats GetANAStats() const override;
190
kwibergc13ded52016-06-17 06:00:45 -0700191 private:
192 struct InputData {
193 uint32_t input_timestamp;
194 const int16_t* audio;
195 size_t length_per_channel;
196 size_t audio_channel;
197 // If a re-mix is required (up or down), this buffer will store a re-mixed
198 // version of the input.
199 int16_t buffer[WEBRTC_10MS_PCM_AUDIO];
200 };
201
202 // This member class writes values to the named UMA histogram, but only if
203 // the value has changed since the last time (and always for the first call).
204 class ChangeLogger {
205 public:
206 explicit ChangeLogger(const std::string& histogram_name)
207 : histogram_name_(histogram_name) {}
208 // Logs the new value if it is different from the last logged value, or if
209 // this is the first call.
210 void MaybeLog(int value);
211
212 private:
213 int last_value_ = 0;
214 int first_time_ = true;
215 const std::string histogram_name_;
216 };
217
218 int RegisterReceiveCodecUnlocked(
219 const CodecInst& codec,
kwiberg24c7c122016-09-28 11:57:10 -0700220 rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory)
danilchap56359be2017-09-07 07:53:45 -0700221 RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700222
223 int Add10MsDataInternal(const AudioFrame& audio_frame, InputData* input_data)
danilchap56359be2017-09-07 07:53:45 -0700224 RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700225 int Encode(const InputData& input_data)
danilchap56359be2017-09-07 07:53:45 -0700226 RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700227
danilchap56359be2017-09-07 07:53:45 -0700228 int InitializeReceiverSafe() RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700229
230 bool HaveValidEncoder(const char* caller_name) const
danilchap56359be2017-09-07 07:53:45 -0700231 RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700232
233 // Preprocessing of input audio, including resampling and down-mixing if
234 // required, before pushing audio into encoder's buffer.
235 //
236 // in_frame: input audio-frame
237 // ptr_out: pointer to output audio_frame. If no preprocessing is required
238 // |ptr_out| will be pointing to |in_frame|, otherwise pointing to
239 // |preprocess_frame_|.
240 //
241 // Return value:
242 // -1: if encountering an error.
243 // 0: otherwise.
244 int PreprocessToAddData(const AudioFrame& in_frame,
245 const AudioFrame** ptr_out)
danilchap56359be2017-09-07 07:53:45 -0700246 RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700247
248 // Change required states after starting to receive the codec corresponding
249 // to |index|.
250 int UpdateUponReceivingCodec(int index);
251
252 rtc::CriticalSection acm_crit_sect_;
danilchap56359be2017-09-07 07:53:45 -0700253 rtc::Buffer encode_buffer_ RTC_GUARDED_BY(acm_crit_sect_);
danilchap56359be2017-09-07 07:53:45 -0700254 uint32_t expected_codec_ts_ RTC_GUARDED_BY(acm_crit_sect_);
255 uint32_t expected_in_ts_ RTC_GUARDED_BY(acm_crit_sect_);
256 acm2::ACMResampler resampler_ RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700257 acm2::AcmReceiver receiver_; // AcmReceiver has it's own internal lock.
danilchap56359be2017-09-07 07:53:45 -0700258 ChangeLogger bitrate_logger_ RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700259
danilchap56359be2017-09-07 07:53:45 -0700260 std::unique_ptr<EncoderFactory> encoder_factory_
261 RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700262
263 // Current encoder stack, either obtained from
264 // encoder_factory_->rent_a_codec.RentEncoderStack or provided by a call to
265 // RegisterEncoder.
danilchap56359be2017-09-07 07:53:45 -0700266 std::unique_ptr<AudioEncoder> encoder_stack_ RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700267
danilchap56359be2017-09-07 07:53:45 -0700268 std::unique_ptr<AudioDecoder> isac_decoder_16k_
269 RTC_GUARDED_BY(acm_crit_sect_);
270 std::unique_ptr<AudioDecoder> isac_decoder_32k_
271 RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700272
273 // This is to keep track of CN instances where we can send DTMFs.
danilchap56359be2017-09-07 07:53:45 -0700274 uint8_t previous_pltype_ RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700275
danilchap56359be2017-09-07 07:53:45 -0700276 bool receiver_initialized_ RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700277
danilchap56359be2017-09-07 07:53:45 -0700278 AudioFrame preprocess_frame_ RTC_GUARDED_BY(acm_crit_sect_);
279 bool first_10ms_data_ RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700280
danilchap56359be2017-09-07 07:53:45 -0700281 bool first_frame_ RTC_GUARDED_BY(acm_crit_sect_);
282 uint32_t last_timestamp_ RTC_GUARDED_BY(acm_crit_sect_);
283 uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(acm_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700284
285 rtc::CriticalSection callback_crit_sect_;
286 AudioPacketizationCallback* packetization_callback_
danilchap56359be2017-09-07 07:53:45 -0700287 RTC_GUARDED_BY(callback_crit_sect_);
288 ACMVADCallback* vad_callback_ RTC_GUARDED_BY(callback_crit_sect_);
kwibergc13ded52016-06-17 06:00:45 -0700289
290 int codec_histogram_bins_log_[static_cast<size_t>(
291 AudioEncoder::CodecType::kMaxLoggedAudioCodecTypes)];
292 int number_of_consecutive_empty_packets_;
293};
294
295// Adds a codec usage sample to the histogram.
296void UpdateCodecTypeHistogram(size_t codec_type) {
297 RTC_HISTOGRAM_ENUMERATION(
298 "WebRTC.Audio.Encoder.CodecType", static_cast<int>(codec_type),
299 static_cast<int>(
300 webrtc::AudioEncoder::CodecType::kMaxLoggedAudioCodecTypes));
301}
302
kwibergc13ded52016-06-17 06:00:45 -0700303// Stereo-to-mono can be used as in-place.
304int DownMix(const AudioFrame& frame,
305 size_t length_out_buff,
306 int16_t* out_buff) {
yujo36b1a5f2017-06-12 12:45:32 -0700307 RTC_DCHECK_EQ(frame.num_channels_, 2);
308 RTC_DCHECK_GE(length_out_buff, frame.samples_per_channel_);
309
310 if (!frame.muted()) {
311 const int16_t* frame_data = frame.data();
312 for (size_t n = 0; n < frame.samples_per_channel_; ++n) {
Yves Gerey665174f2018-06-19 15:03:05 +0200313 out_buff[n] =
314 static_cast<int16_t>((static_cast<int32_t>(frame_data[2 * n]) +
315 static_cast<int32_t>(frame_data[2 * n + 1])) >>
316 1);
yujo36b1a5f2017-06-12 12:45:32 -0700317 }
318 } else {
Jonathan Yu36344a02017-07-30 01:55:34 -0700319 std::fill(out_buff, out_buff + frame.samples_per_channel_, 0);
kwibergc13ded52016-06-17 06:00:45 -0700320 }
kwibergc13ded52016-06-17 06:00:45 -0700321 return 0;
322}
323
324// Mono-to-stereo can be used as in-place.
325int UpMix(const AudioFrame& frame, size_t length_out_buff, int16_t* out_buff) {
yujo36b1a5f2017-06-12 12:45:32 -0700326 RTC_DCHECK_EQ(frame.num_channels_, 1);
327 RTC_DCHECK_GE(length_out_buff, 2 * frame.samples_per_channel_);
328
329 if (!frame.muted()) {
330 const int16_t* frame_data = frame.data();
331 for (size_t n = frame.samples_per_channel_; n != 0; --n) {
332 size_t i = n - 1;
333 int16_t sample = frame_data[i];
334 out_buff[2 * i + 1] = sample;
335 out_buff[2 * i] = sample;
336 }
337 } else {
Jonathan Yu36344a02017-07-30 01:55:34 -0700338 std::fill(out_buff, out_buff + frame.samples_per_channel_ * 2, 0);
kwibergc13ded52016-06-17 06:00:45 -0700339 }
340 return 0;
341}
342
343void ConvertEncodedInfoToFragmentationHeader(
344 const AudioEncoder::EncodedInfo& info,
345 RTPFragmentationHeader* frag) {
346 if (info.redundant.empty()) {
347 frag->fragmentationVectorSize = 0;
348 return;
349 }
350
351 frag->VerifyAndAllocateFragmentationHeader(
352 static_cast<uint16_t>(info.redundant.size()));
353 frag->fragmentationVectorSize = static_cast<uint16_t>(info.redundant.size());
354 size_t offset = 0;
355 for (size_t i = 0; i < info.redundant.size(); ++i) {
356 frag->fragmentationOffset[i] = offset;
357 offset += info.redundant[i].encoded_bytes;
358 frag->fragmentationLength[i] = info.redundant[i].encoded_bytes;
kwibergd3edd772017-03-01 18:52:48 -0800359 frag->fragmentationTimeDiff[i] = rtc::dchecked_cast<uint16_t>(
kwibergc13ded52016-06-17 06:00:45 -0700360 info.encoded_timestamp - info.redundant[i].encoded_timestamp);
361 frag->fragmentationPlType[i] = info.redundant[i].payload_type;
362 }
363}
364
365// Wraps a raw AudioEncoder pointer. The idea is that you can put one of these
366// in a unique_ptr, to protect the contained raw pointer from being deleted
367// when the unique_ptr expires. (This is of course a bad idea in general, but
368// backwards compatibility.)
369class RawAudioEncoderWrapper final : public AudioEncoder {
370 public:
371 RawAudioEncoderWrapper(AudioEncoder* enc) : enc_(enc) {}
372 int SampleRateHz() const override { return enc_->SampleRateHz(); }
373 size_t NumChannels() const override { return enc_->NumChannels(); }
374 int RtpTimestampRateHz() const override { return enc_->RtpTimestampRateHz(); }
375 size_t Num10MsFramesInNextPacket() const override {
376 return enc_->Num10MsFramesInNextPacket();
377 }
378 size_t Max10MsFramesInAPacket() const override {
379 return enc_->Max10MsFramesInAPacket();
380 }
381 int GetTargetBitrate() const override { return enc_->GetTargetBitrate(); }
382 EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
383 rtc::ArrayView<const int16_t> audio,
384 rtc::Buffer* encoded) override {
385 return enc_->Encode(rtp_timestamp, audio, encoded);
386 }
387 void Reset() override { return enc_->Reset(); }
388 bool SetFec(bool enable) override { return enc_->SetFec(enable); }
389 bool SetDtx(bool enable) override { return enc_->SetDtx(enable); }
390 bool SetApplication(Application application) override {
391 return enc_->SetApplication(application);
392 }
393 void SetMaxPlaybackRate(int frequency_hz) override {
394 return enc_->SetMaxPlaybackRate(frequency_hz);
395 }
kwibergc13ded52016-06-17 06:00:45 -0700396
397 private:
398 AudioEncoder* enc_;
399};
400
401// Return false on error.
402bool CreateSpeechEncoderIfNecessary(EncoderFactory* ef) {
403 auto* sp = ef->codec_manager.GetStackParams();
404 if (sp->speech_encoder) {
405 // Do nothing; we already have a speech encoder.
406 } else if (ef->codec_manager.GetCodecInst()) {
407 RTC_DCHECK(!ef->external_speech_encoder);
408 // We have no speech encoder, but we have a specification for making one.
409 std::unique_ptr<AudioEncoder> enc =
410 ef->rent_a_codec.RentEncoder(*ef->codec_manager.GetCodecInst());
411 if (!enc)
412 return false; // Encoder spec was bad.
413 sp->speech_encoder = std::move(enc);
414 } else if (ef->external_speech_encoder) {
415 RTC_DCHECK(!ef->codec_manager.GetCodecInst());
416 // We have an external speech encoder.
417 sp->speech_encoder = std::unique_ptr<AudioEncoder>(
418 new RawAudioEncoderWrapper(ef->external_speech_encoder));
419 }
420 return true;
421}
422
423void AudioCodingModuleImpl::ChangeLogger::MaybeLog(int value) {
424 if (value != last_value_ || first_time_) {
425 first_time_ = false;
426 last_value_ = value;
427 RTC_HISTOGRAM_COUNTS_SPARSE_100(histogram_name_, value);
428 }
429}
430
431AudioCodingModuleImpl::AudioCodingModuleImpl(
432 const AudioCodingModule::Config& config)
solenbergc7b4a452017-09-28 07:37:11 -0700433 : expected_codec_ts_(0xD87F3F9F),
kwibergc13ded52016-06-17 06:00:45 -0700434 expected_in_ts_(0xD87F3F9F),
435 receiver_(config),
436 bitrate_logger_("WebRTC.Audio.TargetBitrateInKbps"),
437 encoder_factory_(new EncoderFactory),
438 encoder_stack_(nullptr),
439 previous_pltype_(255),
440 receiver_initialized_(false),
441 first_10ms_data_(false),
442 first_frame_(true),
443 packetization_callback_(NULL),
444 vad_callback_(NULL),
445 codec_histogram_bins_log_(),
446 number_of_consecutive_empty_packets_(0) {
447 if (InitializeReceiverSafe() < 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100448 RTC_LOG(LS_ERROR) << "Cannot initialize receiver";
kwibergc13ded52016-06-17 06:00:45 -0700449 }
Mirko Bonadei675513b2017-11-09 11:09:25 +0100450 RTC_LOG(LS_INFO) << "Created";
kwibergc13ded52016-06-17 06:00:45 -0700451}
452
453AudioCodingModuleImpl::~AudioCodingModuleImpl() = default;
454
455int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) {
456 AudioEncoder::EncodedInfo encoded_info;
457 uint8_t previous_pltype;
458
459 // Check if there is an encoder before.
460 if (!HaveValidEncoder("Process"))
461 return -1;
462
Yves Gerey665174f2018-06-19 15:03:05 +0200463 if (!first_frame_) {
deadbeeffcada902016-08-24 12:45:13 -0700464 RTC_DCHECK(IsNewerTimestamp(input_data.input_timestamp, last_timestamp_))
ossu63fb95a2016-07-06 09:34:22 -0700465 << "Time should not move backwards";
466 }
467
kwibergc13ded52016-06-17 06:00:45 -0700468 // Scale the timestamp to the codec's RTP timestamp rate.
469 uint32_t rtp_timestamp =
470 first_frame_ ? input_data.input_timestamp
471 : last_rtp_timestamp_ +
472 rtc::CheckedDivExact(
473 input_data.input_timestamp - last_timestamp_,
474 static_cast<uint32_t>(rtc::CheckedDivExact(
475 encoder_stack_->SampleRateHz(),
476 encoder_stack_->RtpTimestampRateHz())));
477 last_timestamp_ = input_data.input_timestamp;
478 last_rtp_timestamp_ = rtp_timestamp;
479 first_frame_ = false;
480
481 // Clear the buffer before reuse - encoded data will get appended.
482 encode_buffer_.Clear();
483 encoded_info = encoder_stack_->Encode(
Yves Gerey665174f2018-06-19 15:03:05 +0200484 rtp_timestamp,
485 rtc::ArrayView<const int16_t>(
486 input_data.audio,
487 input_data.audio_channel * input_data.length_per_channel),
kwibergc13ded52016-06-17 06:00:45 -0700488 &encode_buffer_);
489
490 bitrate_logger_.MaybeLog(encoder_stack_->GetTargetBitrate() / 1000);
491 if (encode_buffer_.size() == 0 && !encoded_info.send_even_if_empty) {
492 // Not enough data.
493 return 0;
494 }
495 previous_pltype = previous_pltype_; // Read it while we have the critsect.
496
497 // Log codec type to histogram once every 500 packets.
498 if (encoded_info.encoded_bytes == 0) {
499 ++number_of_consecutive_empty_packets_;
500 } else {
501 size_t codec_type = static_cast<size_t>(encoded_info.encoder_type);
502 codec_histogram_bins_log_[codec_type] +=
503 number_of_consecutive_empty_packets_ + 1;
504 number_of_consecutive_empty_packets_ = 0;
505 if (codec_histogram_bins_log_[codec_type] >= 500) {
506 codec_histogram_bins_log_[codec_type] -= 500;
507 UpdateCodecTypeHistogram(codec_type);
508 }
509 }
510
511 RTPFragmentationHeader my_fragmentation;
512 ConvertEncodedInfoToFragmentationHeader(encoded_info, &my_fragmentation);
513 FrameType frame_type;
514 if (encode_buffer_.size() == 0 && encoded_info.send_even_if_empty) {
515 frame_type = kEmptyFrame;
516 encoded_info.payload_type = previous_pltype;
517 } else {
kwibergaf476c72016-11-28 15:21:39 -0800518 RTC_DCHECK_GT(encode_buffer_.size(), 0);
kwibergc13ded52016-06-17 06:00:45 -0700519 frame_type = encoded_info.speech ? kAudioFrameSpeech : kAudioFrameCN;
520 }
521
522 {
523 rtc::CritScope lock(&callback_crit_sect_);
524 if (packetization_callback_) {
525 packetization_callback_->SendData(
526 frame_type, encoded_info.payload_type, encoded_info.encoded_timestamp,
527 encode_buffer_.data(), encode_buffer_.size(),
528 my_fragmentation.fragmentationVectorSize > 0 ? &my_fragmentation
529 : nullptr);
530 }
531
532 if (vad_callback_) {
533 // Callback with VAD decision.
534 vad_callback_->InFrameType(frame_type);
535 }
536 }
537 previous_pltype_ = encoded_info.payload_type;
538 return static_cast<int32_t>(encode_buffer_.size());
539}
540
541/////////////////////////////////////////
542// Sender
543//
544
545// Can be called multiple times for Codec, CNG, RED.
546int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) {
547 rtc::CritScope lock(&acm_crit_sect_);
548 if (!encoder_factory_->codec_manager.RegisterEncoder(send_codec)) {
549 return -1;
550 }
551 if (encoder_factory_->codec_manager.GetCodecInst()) {
552 encoder_factory_->external_speech_encoder = nullptr;
553 }
554 if (!CreateSpeechEncoderIfNecessary(encoder_factory_.get())) {
555 return -1;
556 }
557 auto* sp = encoder_factory_->codec_manager.GetStackParams();
558 if (sp->speech_encoder)
559 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
560 return 0;
561}
562
563void AudioCodingModuleImpl::RegisterExternalSendCodec(
564 AudioEncoder* external_speech_encoder) {
565 rtc::CritScope lock(&acm_crit_sect_);
566 encoder_factory_->codec_manager.UnsetCodecInst();
567 encoder_factory_->external_speech_encoder = external_speech_encoder;
568 RTC_CHECK(CreateSpeechEncoderIfNecessary(encoder_factory_.get()));
569 auto* sp = encoder_factory_->codec_manager.GetStackParams();
570 RTC_CHECK(sp->speech_encoder);
571 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
572}
573
574void AudioCodingModuleImpl::ModifyEncoder(
kwiberg24c7c122016-09-28 11:57:10 -0700575 rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier) {
kwibergc13ded52016-06-17 06:00:45 -0700576 rtc::CritScope lock(&acm_crit_sect_);
577
578 // Wipe the encoder factory, so that everything that relies on it will fail.
579 // We don't want the complexity of supporting swapping back and forth.
580 if (encoder_factory_) {
581 encoder_factory_.reset();
582 RTC_CHECK(!encoder_stack_); // Ensure we hadn't started using the factory.
583 }
584
585 modifier(&encoder_stack_);
586}
587
588// Get current send codec.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200589absl::optional<CodecInst> AudioCodingModuleImpl::SendCodec() const {
kwibergc13ded52016-06-17 06:00:45 -0700590 rtc::CritScope lock(&acm_crit_sect_);
591 if (encoder_factory_) {
592 auto* ci = encoder_factory_->codec_manager.GetCodecInst();
593 if (ci) {
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100594 return *ci;
kwibergc13ded52016-06-17 06:00:45 -0700595 }
596 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
597 const std::unique_ptr<AudioEncoder>& enc =
598 encoder_factory_->codec_manager.GetStackParams()->speech_encoder;
599 if (enc) {
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100600 return acm2::CodecManager::ForgeCodecInst(enc.get());
kwibergc13ded52016-06-17 06:00:45 -0700601 }
Danil Chapovalovb6021232018-06-19 13:26:36 +0200602 return absl::nullopt;
kwibergc13ded52016-06-17 06:00:45 -0700603 } else {
604 return encoder_stack_
Danil Chapovalovb6021232018-06-19 13:26:36 +0200605 ? absl::optional<CodecInst>(
kwibergc13ded52016-06-17 06:00:45 -0700606 acm2::CodecManager::ForgeCodecInst(encoder_stack_.get()))
Danil Chapovalovb6021232018-06-19 13:26:36 +0200607 : absl::nullopt;
kwibergc13ded52016-06-17 06:00:45 -0700608 }
609}
610
kwibergc13ded52016-06-17 06:00:45 -0700611void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) {
612 rtc::CritScope lock(&acm_crit_sect_);
613 if (encoder_stack_) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200614 encoder_stack_->OnReceivedUplinkBandwidth(bitrate_bps, absl::nullopt);
kwibergc13ded52016-06-17 06:00:45 -0700615 }
616}
617
618// Register a transport callback which will be called to deliver
619// the encoded buffers.
620int AudioCodingModuleImpl::RegisterTransportCallback(
621 AudioPacketizationCallback* transport) {
622 rtc::CritScope lock(&callback_crit_sect_);
623 packetization_callback_ = transport;
624 return 0;
625}
626
627// Add 10MS of raw (PCM) audio data to the encoder.
628int AudioCodingModuleImpl::Add10MsData(const AudioFrame& audio_frame) {
629 InputData input_data;
630 rtc::CritScope lock(&acm_crit_sect_);
631 int r = Add10MsDataInternal(audio_frame, &input_data);
632 return r < 0 ? r : Encode(input_data);
633}
634
635int AudioCodingModuleImpl::Add10MsDataInternal(const AudioFrame& audio_frame,
636 InputData* input_data) {
637 if (audio_frame.samples_per_channel_ == 0) {
638 assert(false);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100639 RTC_LOG(LS_ERROR) << "Cannot Add 10 ms audio, payload length is zero";
kwibergc13ded52016-06-17 06:00:45 -0700640 return -1;
641 }
642
643 if (audio_frame.sample_rate_hz_ > 48000) {
644 assert(false);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100645 RTC_LOG(LS_ERROR) << "Cannot Add 10 ms audio, input frequency not valid";
kwibergc13ded52016-06-17 06:00:45 -0700646 return -1;
647 }
648
649 // If the length and frequency matches. We currently just support raw PCM.
650 if (static_cast<size_t>(audio_frame.sample_rate_hz_ / 100) !=
651 audio_frame.samples_per_channel_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100652 RTC_LOG(LS_ERROR)
Alex Loiko300ec8c2017-05-30 17:23:28 +0200653 << "Cannot Add 10 ms audio, input frequency and length doesn't match";
kwibergc13ded52016-06-17 06:00:45 -0700654 return -1;
655 }
656
657 if (audio_frame.num_channels_ != 1 && audio_frame.num_channels_ != 2) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100658 RTC_LOG(LS_ERROR) << "Cannot Add 10 ms audio, invalid number of channels.";
kwibergc13ded52016-06-17 06:00:45 -0700659 return -1;
660 }
661
662 // Do we have a codec registered?
663 if (!HaveValidEncoder("Add10MsData")) {
664 return -1;
665 }
666
667 const AudioFrame* ptr_frame;
668 // Perform a resampling, also down-mix if it is required and can be
669 // performed before resampling (a down mix prior to resampling will take
670 // place if both primary and secondary encoders are mono and input is in
671 // stereo).
672 if (PreprocessToAddData(audio_frame, &ptr_frame) < 0) {
673 return -1;
674 }
675
676 // Check whether we need an up-mix or down-mix?
677 const size_t current_num_channels = encoder_stack_->NumChannels();
678 const bool same_num_channels =
679 ptr_frame->num_channels_ == current_num_channels;
680
681 if (!same_num_channels) {
682 if (ptr_frame->num_channels_ == 1) {
683 if (UpMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0)
684 return -1;
685 } else {
686 if (DownMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0)
687 return -1;
688 }
689 }
690
691 // When adding data to encoders this pointer is pointing to an audio buffer
692 // with correct number of channels.
yujo36b1a5f2017-06-12 12:45:32 -0700693 const int16_t* ptr_audio = ptr_frame->data();
kwibergc13ded52016-06-17 06:00:45 -0700694
695 // For pushing data to primary, point the |ptr_audio| to correct buffer.
696 if (!same_num_channels)
697 ptr_audio = input_data->buffer;
698
yujo36b1a5f2017-06-12 12:45:32 -0700699 // TODO(yujo): Skip encode of muted frames.
kwibergc13ded52016-06-17 06:00:45 -0700700 input_data->input_timestamp = ptr_frame->timestamp_;
701 input_data->audio = ptr_audio;
702 input_data->length_per_channel = ptr_frame->samples_per_channel_;
703 input_data->audio_channel = current_num_channels;
704
705 return 0;
706}
707
708// Perform a resampling and down-mix if required. We down-mix only if
709// encoder is mono and input is stereo. In case of dual-streaming, both
710// encoders has to be mono for down-mix to take place.
711// |*ptr_out| will point to the pre-processed audio-frame. If no pre-processing
712// is required, |*ptr_out| points to |in_frame|.
yujo36b1a5f2017-06-12 12:45:32 -0700713// TODO(yujo): Make this more efficient for muted frames.
kwibergc13ded52016-06-17 06:00:45 -0700714int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame,
715 const AudioFrame** ptr_out) {
716 const bool resample =
717 in_frame.sample_rate_hz_ != encoder_stack_->SampleRateHz();
718
719 // This variable is true if primary codec and secondary codec (if exists)
720 // are both mono and input is stereo.
721 // TODO(henrik.lundin): This condition should probably be
722 // in_frame.num_channels_ > encoder_stack_->NumChannels()
723 const bool down_mix =
724 in_frame.num_channels_ == 2 && encoder_stack_->NumChannels() == 1;
725
726 if (!first_10ms_data_) {
727 expected_in_ts_ = in_frame.timestamp_;
728 expected_codec_ts_ = in_frame.timestamp_;
729 first_10ms_data_ = true;
730 } else if (in_frame.timestamp_ != expected_in_ts_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100731 RTC_LOG(LS_WARNING) << "Unexpected input timestamp: " << in_frame.timestamp_
732 << ", expected: " << expected_in_ts_;
kwibergc13ded52016-06-17 06:00:45 -0700733 expected_codec_ts_ +=
734 (in_frame.timestamp_ - expected_in_ts_) *
735 static_cast<uint32_t>(
736 static_cast<double>(encoder_stack_->SampleRateHz()) /
737 static_cast<double>(in_frame.sample_rate_hz_));
738 expected_in_ts_ = in_frame.timestamp_;
739 }
740
kwibergc13ded52016-06-17 06:00:45 -0700741 if (!down_mix && !resample) {
742 // No pre-processing is required.
ossu63fb95a2016-07-06 09:34:22 -0700743 if (expected_in_ts_ == expected_codec_ts_) {
744 // If we've never resampled, we can use the input frame as-is
745 *ptr_out = &in_frame;
746 } else {
747 // Otherwise we'll need to alter the timestamp. Since in_frame is const,
748 // we'll have to make a copy of it.
749 preprocess_frame_.CopyFrom(in_frame);
750 preprocess_frame_.timestamp_ = expected_codec_ts_;
751 *ptr_out = &preprocess_frame_;
752 }
753
kwibergc13ded52016-06-17 06:00:45 -0700754 expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_);
755 expected_codec_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_);
kwibergc13ded52016-06-17 06:00:45 -0700756 return 0;
757 }
758
759 *ptr_out = &preprocess_frame_;
760 preprocess_frame_.num_channels_ = in_frame.num_channels_;
761 int16_t audio[WEBRTC_10MS_PCM_AUDIO];
yujo36b1a5f2017-06-12 12:45:32 -0700762 const int16_t* src_ptr_audio = in_frame.data();
kwibergc13ded52016-06-17 06:00:45 -0700763 if (down_mix) {
764 // If a resampling is required the output of a down-mix is written into a
765 // local buffer, otherwise, it will be written to the output frame.
Yves Gerey665174f2018-06-19 15:03:05 +0200766 int16_t* dest_ptr_audio =
767 resample ? audio : preprocess_frame_.mutable_data();
kwibergc13ded52016-06-17 06:00:45 -0700768 if (DownMix(in_frame, WEBRTC_10MS_PCM_AUDIO, dest_ptr_audio) < 0)
769 return -1;
770 preprocess_frame_.num_channels_ = 1;
771 // Set the input of the resampler is the down-mixed signal.
772 src_ptr_audio = audio;
773 }
774
775 preprocess_frame_.timestamp_ = expected_codec_ts_;
776 preprocess_frame_.samples_per_channel_ = in_frame.samples_per_channel_;
777 preprocess_frame_.sample_rate_hz_ = in_frame.sample_rate_hz_;
778 // If it is required, we have to do a resampling.
779 if (resample) {
780 // The result of the resampler is written to output frame.
yujo36b1a5f2017-06-12 12:45:32 -0700781 int16_t* dest_ptr_audio = preprocess_frame_.mutable_data();
kwibergc13ded52016-06-17 06:00:45 -0700782
783 int samples_per_channel = resampler_.Resample10Msec(
784 src_ptr_audio, in_frame.sample_rate_hz_, encoder_stack_->SampleRateHz(),
785 preprocess_frame_.num_channels_, AudioFrame::kMaxDataSizeSamples,
786 dest_ptr_audio);
787
788 if (samples_per_channel < 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100789 RTC_LOG(LS_ERROR) << "Cannot add 10 ms audio, resampling failed";
kwibergc13ded52016-06-17 06:00:45 -0700790 return -1;
791 }
792 preprocess_frame_.samples_per_channel_ =
793 static_cast<size_t>(samples_per_channel);
794 preprocess_frame_.sample_rate_hz_ = encoder_stack_->SampleRateHz();
795 }
796
797 expected_codec_ts_ +=
798 static_cast<uint32_t>(preprocess_frame_.samples_per_channel_);
799 expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_);
800
801 return 0;
802}
803
804/////////////////////////////////////////
805// (RED) Redundant Coding
806//
807
808bool AudioCodingModuleImpl::REDStatus() const {
809 rtc::CritScope lock(&acm_crit_sect_);
810 return encoder_factory_->codec_manager.GetStackParams()->use_red;
811}
812
813// Configure RED status i.e on/off.
814int AudioCodingModuleImpl::SetREDStatus(bool enable_red) {
815#ifdef WEBRTC_CODEC_RED
816 rtc::CritScope lock(&acm_crit_sect_);
817 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
818 if (!encoder_factory_->codec_manager.SetCopyRed(enable_red)) {
819 return -1;
820 }
821 auto* sp = encoder_factory_->codec_manager.GetStackParams();
822 if (sp->speech_encoder)
823 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
824 return 0;
825#else
Mirko Bonadei675513b2017-11-09 11:09:25 +0100826 RTC_LOG(LS_WARNING) << " WEBRTC_CODEC_RED is undefined";
kwibergc13ded52016-06-17 06:00:45 -0700827 return -1;
828#endif
829}
830
831/////////////////////////////////////////
832// (FEC) Forward Error Correction (codec internal)
833//
834
835bool AudioCodingModuleImpl::CodecFEC() const {
836 rtc::CritScope lock(&acm_crit_sect_);
837 return encoder_factory_->codec_manager.GetStackParams()->use_codec_fec;
838}
839
840int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) {
841 rtc::CritScope lock(&acm_crit_sect_);
842 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
843 if (!encoder_factory_->codec_manager.SetCodecFEC(enable_codec_fec)) {
844 return -1;
845 }
846 auto* sp = encoder_factory_->codec_manager.GetStackParams();
847 if (sp->speech_encoder)
848 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
849 if (enable_codec_fec) {
850 return sp->use_codec_fec ? 0 : -1;
851 } else {
852 RTC_DCHECK(!sp->use_codec_fec);
853 return 0;
854 }
855}
856
857int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) {
858 rtc::CritScope lock(&acm_crit_sect_);
859 if (HaveValidEncoder("SetPacketLossRate")) {
minyue4b9a2cb2016-11-30 06:49:59 -0800860 encoder_stack_->OnReceivedUplinkPacketLossFraction(loss_rate / 100.0);
kwibergc13ded52016-06-17 06:00:45 -0700861 }
862 return 0;
863}
864
865/////////////////////////////////////////
866// (VAD) Voice Activity Detection
867//
868int AudioCodingModuleImpl::SetVAD(bool enable_dtx,
869 bool enable_vad,
870 ACMVADMode mode) {
871 // Note: |enable_vad| is not used; VAD is enabled based on the DTX setting.
872 RTC_DCHECK_EQ(enable_dtx, enable_vad);
873 rtc::CritScope lock(&acm_crit_sect_);
874 CreateSpeechEncoderIfNecessary(encoder_factory_.get());
875 if (!encoder_factory_->codec_manager.SetVAD(enable_dtx, mode)) {
876 return -1;
877 }
878 auto* sp = encoder_factory_->codec_manager.GetStackParams();
879 if (sp->speech_encoder)
880 encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
881 return 0;
882}
883
884// Get VAD/DTX settings.
Yves Gerey665174f2018-06-19 15:03:05 +0200885int AudioCodingModuleImpl::VAD(bool* dtx_enabled,
886 bool* vad_enabled,
kwibergc13ded52016-06-17 06:00:45 -0700887 ACMVADMode* mode) const {
888 rtc::CritScope lock(&acm_crit_sect_);
889 const auto* sp = encoder_factory_->codec_manager.GetStackParams();
890 *dtx_enabled = *vad_enabled = sp->use_cng;
891 *mode = sp->vad_mode;
892 return 0;
893}
894
895/////////////////////////////////////////
896// Receiver
897//
898
899int AudioCodingModuleImpl::InitializeReceiver() {
900 rtc::CritScope lock(&acm_crit_sect_);
901 return InitializeReceiverSafe();
902}
903
904// Initialize receiver, resets codec database etc.
905int AudioCodingModuleImpl::InitializeReceiverSafe() {
906 // If the receiver is already initialized then we want to destroy any
907 // existing decoders. After a call to this function, we should have a clean
908 // start-up.
kwiberg6b19b562016-09-20 04:02:25 -0700909 if (receiver_initialized_)
910 receiver_.RemoveAllCodecs();
kwibergc13ded52016-06-17 06:00:45 -0700911 receiver_.ResetInitialDelay();
912 receiver_.SetMinimumDelay(0);
913 receiver_.SetMaximumDelay(0);
914 receiver_.FlushBuffers();
915
kwibergc13ded52016-06-17 06:00:45 -0700916 receiver_initialized_ = true;
917 return 0;
918}
919
920// Get current receive frequency.
921int AudioCodingModuleImpl::ReceiveFrequency() const {
922 const auto last_packet_sample_rate = receiver_.last_packet_sample_rate_hz();
923 return last_packet_sample_rate ? *last_packet_sample_rate
924 : receiver_.last_output_sample_rate_hz();
925}
926
927// Get current playout frequency.
928int AudioCodingModuleImpl::PlayoutFrequency() const {
kwibergc13ded52016-06-17 06:00:45 -0700929 return receiver_.last_output_sample_rate_hz();
930}
931
kwiberg1c07c702017-03-27 07:15:49 -0700932void AudioCodingModuleImpl::SetReceiveCodecs(
933 const std::map<int, SdpAudioFormat>& codecs) {
934 rtc::CritScope lock(&acm_crit_sect_);
935 receiver_.SetCodecs(codecs);
936}
937
kwiberg5adaf732016-10-04 09:33:27 -0700938bool AudioCodingModuleImpl::RegisterReceiveCodec(
939 int rtp_payload_type,
940 const SdpAudioFormat& audio_format) {
941 rtc::CritScope lock(&acm_crit_sect_);
942 RTC_DCHECK(receiver_initialized_);
943
944 if (!acm2::RentACodec::IsPayloadTypeValid(rtp_payload_type)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100945 RTC_LOG_F(LS_ERROR) << "Invalid payload-type " << rtp_payload_type
946 << " for decoder.";
kwiberg5adaf732016-10-04 09:33:27 -0700947 return false;
948 }
949
950 return receiver_.AddCodec(rtp_payload_type, audio_format);
951}
952
kwibergc13ded52016-06-17 06:00:45 -0700953int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) {
954 rtc::CritScope lock(&acm_crit_sect_);
955 auto* ef = encoder_factory_.get();
956 return RegisterReceiveCodecUnlocked(
957 codec, [&] { return ef->rent_a_codec.RentIsacDecoder(codec.plfreq); });
958}
959
960int AudioCodingModuleImpl::RegisterReceiveCodec(
961 const CodecInst& codec,
kwiberg24c7c122016-09-28 11:57:10 -0700962 rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory) {
kwibergc13ded52016-06-17 06:00:45 -0700963 rtc::CritScope lock(&acm_crit_sect_);
964 return RegisterReceiveCodecUnlocked(codec, isac_factory);
965}
966
967int AudioCodingModuleImpl::RegisterReceiveCodecUnlocked(
968 const CodecInst& codec,
kwiberg24c7c122016-09-28 11:57:10 -0700969 rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory) {
kwibergc13ded52016-06-17 06:00:45 -0700970 RTC_DCHECK(receiver_initialized_);
971 if (codec.channels > 2) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100972 RTC_LOG_F(LS_ERROR) << "Unsupported number of channels: " << codec.channels;
kwibergc13ded52016-06-17 06:00:45 -0700973 return -1;
974 }
975
976 auto codec_id = acm2::RentACodec::CodecIdByParams(codec.plname, codec.plfreq,
977 codec.channels);
978 if (!codec_id) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100979 RTC_LOG_F(LS_ERROR)
980 << "Wrong codec params to be registered as receive codec";
kwibergc13ded52016-06-17 06:00:45 -0700981 return -1;
982 }
983 auto codec_index = acm2::RentACodec::CodecIndexFromId(*codec_id);
984 RTC_CHECK(codec_index) << "Invalid codec ID: " << static_cast<int>(*codec_id);
985
986 // Check if the payload-type is valid.
987 if (!acm2::RentACodec::IsPayloadTypeValid(codec.pltype)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100988 RTC_LOG_F(LS_ERROR) << "Invalid payload type " << codec.pltype << " for "
989 << codec.plname;
kwibergc13ded52016-06-17 06:00:45 -0700990 return -1;
991 }
992
993 AudioDecoder* isac_decoder = nullptr;
Niels Möller2edab4c2018-10-22 09:48:08 +0200994 if (absl::EqualsIgnoreCase(codec.plname, "isac")) {
kwibergc13ded52016-06-17 06:00:45 -0700995 std::unique_ptr<AudioDecoder>& saved_isac_decoder =
996 codec.plfreq == 16000 ? isac_decoder_16k_ : isac_decoder_32k_;
997 if (!saved_isac_decoder) {
998 saved_isac_decoder = isac_factory();
999 }
1000 isac_decoder = saved_isac_decoder.get();
1001 }
1002 return receiver_.AddCodec(*codec_index, codec.pltype, codec.channels,
1003 codec.plfreq, isac_decoder, codec.plname);
1004}
1005
1006int AudioCodingModuleImpl::RegisterExternalReceiveCodec(
1007 int rtp_payload_type,
1008 AudioDecoder* external_decoder,
1009 int sample_rate_hz,
1010 int num_channels,
1011 const std::string& name) {
1012 rtc::CritScope lock(&acm_crit_sect_);
1013 RTC_DCHECK(receiver_initialized_);
1014 if (num_channels > 2 || num_channels < 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001015 RTC_LOG_F(LS_ERROR) << "Unsupported number of channels: " << num_channels;
kwibergc13ded52016-06-17 06:00:45 -07001016 return -1;
1017 }
1018
1019 // Check if the payload-type is valid.
1020 if (!acm2::RentACodec::IsPayloadTypeValid(rtp_payload_type)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001021 RTC_LOG_F(LS_ERROR) << "Invalid payload-type " << rtp_payload_type
1022 << " for external decoder.";
kwibergc13ded52016-06-17 06:00:45 -07001023 return -1;
1024 }
1025
1026 return receiver_.AddCodec(-1 /* external */, rtp_payload_type, num_channels,
1027 sample_rate_hz, external_decoder, name);
1028}
1029
1030// Get current received codec.
1031int AudioCodingModuleImpl::ReceiveCodec(CodecInst* current_codec) const {
1032 rtc::CritScope lock(&acm_crit_sect_);
1033 return receiver_.LastAudioCodec(current_codec);
1034}
1035
Danil Chapovalovb6021232018-06-19 13:26:36 +02001036absl::optional<SdpAudioFormat> AudioCodingModuleImpl::ReceiveFormat() const {
ossue280cde2016-10-12 11:04:10 -07001037 rtc::CritScope lock(&acm_crit_sect_);
1038 return receiver_.LastAudioFormat();
1039}
1040
kwibergc13ded52016-06-17 06:00:45 -07001041// Incoming packet from network parsed and ready for decode.
1042int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
1043 const size_t payload_length,
1044 const WebRtcRTPHeader& rtp_header) {
henrik.lundinb8c55b12017-05-10 07:38:01 -07001045 RTC_DCHECK_EQ(payload_length == 0, incoming_payload == nullptr);
kwibergc13ded52016-06-17 06:00:45 -07001046 return receiver_.InsertPacket(
1047 rtp_header,
1048 rtc::ArrayView<const uint8_t>(incoming_payload, payload_length));
1049}
1050
1051// Minimum playout delay (Used for lip-sync).
1052int AudioCodingModuleImpl::SetMinimumPlayoutDelay(int time_ms) {
1053 if ((time_ms < 0) || (time_ms > 10000)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001054 RTC_LOG(LS_ERROR) << "Delay must be in the range of 0-10000 milliseconds.";
kwibergc13ded52016-06-17 06:00:45 -07001055 return -1;
1056 }
1057 return receiver_.SetMinimumDelay(time_ms);
1058}
1059
1060int AudioCodingModuleImpl::SetMaximumPlayoutDelay(int time_ms) {
1061 if ((time_ms < 0) || (time_ms > 10000)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001062 RTC_LOG(LS_ERROR) << "Delay must be in the range of 0-10000 milliseconds.";
kwibergc13ded52016-06-17 06:00:45 -07001063 return -1;
1064 }
1065 return receiver_.SetMaximumDelay(time_ms);
1066}
1067
1068// Get 10 milliseconds of raw audio data to play out.
1069// Automatic resample to the requested frequency.
1070int AudioCodingModuleImpl::PlayoutData10Ms(int desired_freq_hz,
1071 AudioFrame* audio_frame,
1072 bool* muted) {
1073 // GetAudio always returns 10 ms, at the requested sample rate.
1074 if (receiver_.GetAudio(desired_freq_hz, audio_frame, muted) != 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001075 RTC_LOG(LS_ERROR) << "PlayoutData failed, RecOut Failed";
kwibergc13ded52016-06-17 06:00:45 -07001076 return -1;
1077 }
kwibergc13ded52016-06-17 06:00:45 -07001078 return 0;
1079}
1080
kwibergc13ded52016-06-17 06:00:45 -07001081/////////////////////////////////////////
1082// Statistics
1083//
1084
1085// TODO(turajs) change the return value to void. Also change the corresponding
1086// NetEq function.
1087int AudioCodingModuleImpl::GetNetworkStatistics(NetworkStatistics* statistics) {
1088 receiver_.GetNetworkStatistics(statistics);
1089 return 0;
1090}
1091
1092int AudioCodingModuleImpl::RegisterVADCallback(ACMVADCallback* vad_callback) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001093 RTC_LOG(LS_VERBOSE) << "RegisterVADCallback()";
kwibergc13ded52016-06-17 06:00:45 -07001094 rtc::CritScope lock(&callback_crit_sect_);
1095 vad_callback_ = vad_callback;
1096 return 0;
1097}
1098
kwibergc13ded52016-06-17 06:00:45 -07001099// Informs Opus encoder of the maximum playback rate the receiver will render.
1100int AudioCodingModuleImpl::SetOpusMaxPlaybackRate(int frequency_hz) {
1101 rtc::CritScope lock(&acm_crit_sect_);
1102 if (!HaveValidEncoder("SetOpusMaxPlaybackRate")) {
1103 return -1;
1104 }
1105 encoder_stack_->SetMaxPlaybackRate(frequency_hz);
1106 return 0;
1107}
1108
1109int AudioCodingModuleImpl::EnableOpusDtx() {
1110 rtc::CritScope lock(&acm_crit_sect_);
1111 if (!HaveValidEncoder("EnableOpusDtx")) {
1112 return -1;
1113 }
1114 return encoder_stack_->SetDtx(true) ? 0 : -1;
1115}
1116
1117int AudioCodingModuleImpl::DisableOpusDtx() {
1118 rtc::CritScope lock(&acm_crit_sect_);
1119 if (!HaveValidEncoder("DisableOpusDtx")) {
1120 return -1;
1121 }
1122 return encoder_stack_->SetDtx(false) ? 0 : -1;
1123}
1124
Danil Chapovalovb6021232018-06-19 13:26:36 +02001125absl::optional<uint32_t> AudioCodingModuleImpl::PlayoutTimestamp() {
kwibergc13ded52016-06-17 06:00:45 -07001126 return receiver_.GetPlayoutTimestamp();
1127}
1128
henrik.lundinb3f1c5d2016-08-22 15:39:53 -07001129int AudioCodingModuleImpl::FilteredCurrentDelayMs() const {
1130 return receiver_.FilteredCurrentDelayMs();
1131}
1132
Henrik Lundinabbff892017-11-29 09:14:04 +01001133int AudioCodingModuleImpl::TargetDelayMs() const {
1134 return receiver_.TargetDelayMs();
1135}
1136
kwibergc13ded52016-06-17 06:00:45 -07001137bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const {
1138 if (!encoder_stack_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001139 RTC_LOG(LS_ERROR) << caller_name << " failed: No send codec is registered.";
kwibergc13ded52016-06-17 06:00:45 -07001140 return false;
1141 }
1142 return true;
1143}
1144
1145int AudioCodingModuleImpl::UnregisterReceiveCodec(uint8_t payload_type) {
1146 return receiver_.RemoveCodec(payload_type);
1147}
1148
1149int AudioCodingModuleImpl::EnableNack(size_t max_nack_list_size) {
1150 return receiver_.EnableNack(max_nack_list_size);
1151}
1152
1153void AudioCodingModuleImpl::DisableNack() {
1154 receiver_.DisableNack();
1155}
1156
1157std::vector<uint16_t> AudioCodingModuleImpl::GetNackList(
1158 int64_t round_trip_time_ms) const {
1159 return receiver_.GetNackList(round_trip_time_ms);
1160}
1161
kwibergc13ded52016-06-17 06:00:45 -07001162void AudioCodingModuleImpl::GetDecodingCallStatistics(
Yves Gerey665174f2018-06-19 15:03:05 +02001163 AudioDecodingCallStats* call_stats) const {
kwibergc13ded52016-06-17 06:00:45 -07001164 receiver_.GetDecodingCallStatistics(call_stats);
1165}
1166
ivoce1198e02017-09-08 08:13:19 -07001167ANAStats AudioCodingModuleImpl::GetANAStats() const {
1168 rtc::CritScope lock(&acm_crit_sect_);
1169 if (encoder_stack_)
1170 return encoder_stack_->GetANAStats();
1171 // If no encoder is set, return default stats.
1172 return ANAStats();
1173}
1174
kwibergc13ded52016-06-17 06:00:45 -07001175} // namespace
1176
Karl Wiberg5817d3d2018-04-06 10:06:42 +02001177AudioCodingModule::Config::Config(
1178 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
1179 : neteq_config(),
1180 clock(Clock::GetRealTimeClock()),
1181 decoder_factory(decoder_factory) {
kwiberg36a43882016-08-29 05:33:32 -07001182 // Post-decode VAD is disabled by default in NetEq, however, Audio
1183 // Conference Mixer relies on VAD decisions and fails without them.
1184 neteq_config.enable_post_decode_vad = true;
1185}
1186
1187AudioCodingModule::Config::Config(const Config&) = default;
1188AudioCodingModule::Config::~Config() = default;
1189
Henrik Lundin64dad832015-05-11 12:44:23 +02001190AudioCodingModule* AudioCodingModule::Create(const Config& config) {
kwibergc13ded52016-06-17 06:00:45 -07001191 return new AudioCodingModuleImpl(config);
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001192}
1193
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001194int AudioCodingModule::NumberOfCodecs() {
kwibergfce4a942015-10-27 11:40:24 -07001195 return static_cast<int>(acm2::RentACodec::NumberOfCodecs());
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001196}
1197
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001198int AudioCodingModule::Codec(int list_id, CodecInst* codec) {
kwibergfce4a942015-10-27 11:40:24 -07001199 auto codec_id = acm2::RentACodec::CodecIdFromIndex(list_id);
1200 if (!codec_id)
1201 return -1;
1202 auto ci = acm2::RentACodec::CodecInstById(*codec_id);
1203 if (!ci)
1204 return -1;
1205 *codec = *ci;
1206 return 0;
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001207}
1208
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001209int AudioCodingModule::Codec(const char* payload_name,
1210 CodecInst* codec,
1211 int sampling_freq_hz,
Peter Kasting69558702016-01-12 16:26:35 -08001212 size_t channels) {
Danil Chapovalovb6021232018-06-19 13:26:36 +02001213 absl::optional<CodecInst> ci = acm2::RentACodec::CodecInstByParams(
turaj@webrtc.org6d5d2482013-10-06 04:47:28 +00001214 payload_name, sampling_freq_hz, channels);
kwibergfce4a942015-10-27 11:40:24 -07001215 if (ci) {
1216 *codec = *ci;
1217 return 0;
1218 } else {
1219 // We couldn't find a matching codec, so set the parameters to unacceptable
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001220 // values and return.
1221 codec->plname[0] = '\0';
1222 codec->pltype = -1;
1223 codec->pacsize = 0;
1224 codec->rate = 0;
1225 codec->plfreq = 0;
1226 return -1;
1227 }
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001228}
1229
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001230int AudioCodingModule::Codec(const char* payload_name,
1231 int sampling_freq_hz,
Peter Kasting69558702016-01-12 16:26:35 -08001232 size_t channels) {
Danil Chapovalovb6021232018-06-19 13:26:36 +02001233 absl::optional<acm2::RentACodec::CodecId> ci =
Karl Wibergbe579832015-11-10 22:34:18 +01001234 acm2::RentACodec::CodecIdByParams(payload_name, sampling_freq_hz,
1235 channels);
kwibergfce4a942015-10-27 11:40:24 -07001236 if (!ci)
1237 return -1;
Danil Chapovalovb6021232018-06-19 13:26:36 +02001238 absl::optional<int> i = acm2::RentACodec::CodecIndexFromId(*ci);
kwibergfce4a942015-10-27 11:40:24 -07001239 return i ? *i : -1;
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001240}
1241
turaj@webrtc.org7959e162013-09-12 18:30:26 +00001242} // namespace webrtc