summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/webrtc/modules/audio_coding/main/source/acm_neteq.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/webrtc/modules/audio_coding/main/source/acm_neteq.cc')
-rw-r--r--chromium/third_party/webrtc/modules/audio_coding/main/source/acm_neteq.cc1151
1 files changed, 0 insertions, 1151 deletions
diff --git a/chromium/third_party/webrtc/modules/audio_coding/main/source/acm_neteq.cc b/chromium/third_party/webrtc/modules/audio_coding/main/source/acm_neteq.cc
deleted file mode 100644
index 154cc54d004..00000000000
--- a/chromium/third_party/webrtc/modules/audio_coding/main/source/acm_neteq.cc
+++ /dev/null
@@ -1,1151 +0,0 @@
-/*
- * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/modules/audio_coding/main/source/acm_neteq.h"
-
-#include <stdlib.h> // malloc
-
-#include <algorithm> // sort
-#include <vector>
-
-#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
-#include "webrtc/common_types.h"
-#include "webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h"
-#include "webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_internal.h"
-#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
-#include "webrtc/system_wrappers/interface/trace.h"
-#include "webrtc/system_wrappers/interface/trace_event.h"
-
-namespace webrtc {
-
-namespace acm1 {
-
-#define RTP_HEADER_SIZE 12
-#define NETEQ_INIT_FREQ 8000
-#define NETEQ_INIT_FREQ_KHZ (NETEQ_INIT_FREQ/1000)
-#define NETEQ_ERR_MSG_LEN_BYTE (WEBRTC_NETEQ_MAX_ERROR_NAME + 1)
-
-ACMNetEQ::ACMNetEQ()
- : id_(0),
- current_samp_freq_khz_(NETEQ_INIT_FREQ_KHZ),
- avt_playout_(false),
- playout_mode_(voice),
- neteq_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
- vad_status_(false),
- vad_mode_(VADNormal),
- decode_lock_(RWLockWrapper::CreateRWLock()),
- num_slaves_(0),
- received_stereo_(false),
- master_slave_info_(NULL),
- previous_audio_activity_(AudioFrame::kVadUnknown),
- callback_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
- min_of_max_num_packets_(0),
- min_of_buffer_size_bytes_(0),
- per_packet_overhead_bytes_(0),
- av_sync_(false),
- minimum_delay_ms_(0),
- maximum_delay_ms_(0) {
- for (int n = 0; n < MAX_NUM_SLAVE_NETEQ + 1; n++) {
- is_initialized_[n] = false;
- ptr_vadinst_[n] = NULL;
- inst_[n] = NULL;
- inst_mem_[n] = NULL;
- neteq_packet_buffer_[n] = NULL;
- }
-}
-
-ACMNetEQ::~ACMNetEQ() {
- {
- CriticalSectionScoped lock(neteq_crit_sect_);
- RemoveNetEQSafe(0); // Master.
- RemoveSlavesSafe();
- }
- if (neteq_crit_sect_ != NULL) {
- delete neteq_crit_sect_;
- }
-
- if (decode_lock_ != NULL) {
- delete decode_lock_;
- }
-
- if (callback_crit_sect_ != NULL) {
- delete callback_crit_sect_;
- }
-}
-
-int32_t ACMNetEQ::Init() {
- CriticalSectionScoped lock(neteq_crit_sect_);
-
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (InitByIdxSafe(idx) < 0) {
- return -1;
- }
- // delete VAD instance and start fresh if required.
- if (ptr_vadinst_[idx] != NULL) {
- WebRtcVad_Free(ptr_vadinst_[idx]);
- ptr_vadinst_[idx] = NULL;
- }
- if (vad_status_) {
- // Has to enable VAD
- if (EnableVADByIdxSafe(idx) < 0) {
- // Failed to enable VAD.
- // Delete VAD instance, if it is created
- if (ptr_vadinst_[idx] != NULL) {
- WebRtcVad_Free(ptr_vadinst_[idx]);
- ptr_vadinst_[idx] = NULL;
- }
- // We are at initialization of NetEq, if failed to
- // enable VAD, we delete the NetEq instance.
- if (inst_mem_[idx] != NULL) {
- free(inst_mem_[idx]);
- inst_mem_[idx] = NULL;
- inst_[idx] = NULL;
- }
- is_initialized_[idx] = false;
- return -1;
- }
- }
- is_initialized_[idx] = true;
- }
- if (EnableVAD() == -1) {
- return -1;
- }
- return 0;
-}
-
-int16_t ACMNetEQ::InitByIdxSafe(const int16_t idx) {
- int memory_size_bytes;
- if (WebRtcNetEQ_AssignSize(&memory_size_bytes) != 0) {
- LogError("AssignSize", idx);
- return -1;
- }
-
- if (inst_mem_[idx] != NULL) {
- free(inst_mem_[idx]);
- inst_mem_[idx] = NULL;
- inst_[idx] = NULL;
- }
- inst_mem_[idx] = malloc(memory_size_bytes);
- if (inst_mem_[idx] == NULL) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "InitByIdxSafe: NetEq Initialization error: could not "
- "allocate memory for NetEq");
- is_initialized_[idx] = false;
- return -1;
- }
- if (WebRtcNetEQ_Assign(&inst_[idx], inst_mem_[idx]) != 0) {
- if (inst_mem_[idx] != NULL) {
- free(inst_mem_[idx]);
- inst_mem_[idx] = NULL;
- inst_[idx] = NULL;
- }
- LogError("Assign", idx);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "InitByIdxSafe: NetEq Initialization error: could not Assign");
- is_initialized_[idx] = false;
- return -1;
- }
- if (WebRtcNetEQ_Init(inst_[idx], NETEQ_INIT_FREQ) != 0) {
- if (inst_mem_[idx] != NULL) {
- free(inst_mem_[idx]);
- inst_mem_[idx] = NULL;
- inst_[idx] = NULL;
- }
- LogError("Init", idx);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "InitByIdxSafe: NetEq Initialization error: could not "
- "initialize NetEq");
- is_initialized_[idx] = false;
- return -1;
- }
- is_initialized_[idx] = true;
- return 0;
-}
-
-int16_t ACMNetEQ::EnableVADByIdxSafe(const int16_t idx) {
- if (ptr_vadinst_[idx] == NULL) {
- if (WebRtcVad_Create(&ptr_vadinst_[idx]) < 0) {
- ptr_vadinst_[idx] = NULL;
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "EnableVADByIdxSafe: NetEq Initialization error: could not "
- "create VAD");
- return -1;
- }
- }
-
- if (WebRtcNetEQ_SetVADInstance(
- inst_[idx], ptr_vadinst_[idx],
- (WebRtcNetEQ_VADInitFunction) WebRtcVad_Init,
- (WebRtcNetEQ_VADSetmodeFunction) WebRtcVad_set_mode,
- (WebRtcNetEQ_VADFunction) WebRtcVad_Process) < 0) {
- LogError("setVADinstance", idx);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "EnableVADByIdxSafe: NetEq Initialization error: could not "
- "set VAD instance");
- return -1;
- }
-
- if (WebRtcNetEQ_SetVADMode(inst_[idx], vad_mode_) < 0) {
- LogError("setVADmode", idx);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "EnableVADByIdxSafe: NetEq Initialization error: could not "
- "set VAD mode");
- return -1;
- }
- return 0;
-}
-
-int32_t ACMNetEQ::AllocatePacketBuffer(
- const WebRtcNetEQDecoder* used_codecs,
- int16_t num_codecs) {
- // Due to WebRtcNetEQ_GetRecommendedBufferSize
- // the following has to be int otherwise we will have compiler error
- // if not casted
-
- CriticalSectionScoped lock(neteq_crit_sect_);
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (AllocatePacketBufferByIdxSafe(used_codecs, num_codecs, idx) < 0) {
- return -1;
- }
- }
- return 0;
-}
-
-int16_t ACMNetEQ::AllocatePacketBufferByIdxSafe(
- const WebRtcNetEQDecoder* used_codecs,
- int16_t num_codecs,
- const int16_t idx) {
- int max_num_packets;
- int buffer_size_in_bytes;
- int per_packet_overhead_bytes;
-
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AllocatePacketBufferByIdxSafe: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_GetRecommendedBufferSize(inst_[idx], used_codecs,
- num_codecs,
- kTCPXLargeJitter,
- &max_num_packets,
- &buffer_size_in_bytes,
- &per_packet_overhead_bytes) != 0) {
- LogError("GetRecommendedBufferSize", idx);
- return -1;
- }
- if (idx == 0) {
- min_of_buffer_size_bytes_ = buffer_size_in_bytes;
- min_of_max_num_packets_ = max_num_packets;
- per_packet_overhead_bytes_ = per_packet_overhead_bytes;
- } else {
- min_of_buffer_size_bytes_ = std::min(min_of_buffer_size_bytes_,
- buffer_size_in_bytes);
- min_of_max_num_packets_ = std::min(min_of_max_num_packets_,
- max_num_packets);
- }
- if (neteq_packet_buffer_[idx] != NULL) {
- free(neteq_packet_buffer_[idx]);
- neteq_packet_buffer_[idx] = NULL;
- }
-
- neteq_packet_buffer_[idx] = (int16_t *) malloc(buffer_size_in_bytes);
- if (neteq_packet_buffer_[idx] == NULL) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AllocatePacketBufferByIdxSafe: NetEq Initialization error: "
- "could not allocate memory for NetEq Packet Buffer");
- return -1;
- }
- if (WebRtcNetEQ_AssignBuffer(inst_[idx], max_num_packets,
- neteq_packet_buffer_[idx],
- buffer_size_in_bytes) != 0) {
- if (neteq_packet_buffer_[idx] != NULL) {
- free(neteq_packet_buffer_[idx]);
- neteq_packet_buffer_[idx] = NULL;
- }
- LogError("AssignBuffer", idx);
- return -1;
- }
- return 0;
-}
-
-int32_t ACMNetEQ::SetAVTPlayout(const bool enable) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (avt_playout_ != enable) {
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "SetAVTPlayout: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_SetAVTPlayout(inst_[idx], (enable) ? 1 : 0) < 0) {
- LogError("SetAVTPlayout", idx);
- return -1;
- }
- }
- }
- avt_playout_ = enable;
- return 0;
-}
-
-bool ACMNetEQ::avt_playout() const {
- CriticalSectionScoped lock(neteq_crit_sect_);
- return avt_playout_;
-}
-
-int32_t ACMNetEQ::CurrentSampFreqHz() const {
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (!is_initialized_[0]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "CurrentSampFreqHz: NetEq is not initialized.");
- return -1;
- }
- return (int32_t)(1000 * current_samp_freq_khz_);
-}
-
-int32_t ACMNetEQ::SetPlayoutMode(const AudioPlayoutMode mode) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (playout_mode_ == mode)
- return 0;
-
- enum WebRtcNetEQPlayoutMode playout_mode = kPlayoutOff;
- enum WebRtcNetEQBGNMode background_noise_mode = kBGNOn;
- switch (mode) {
- case voice:
- playout_mode = kPlayoutOn;
- background_noise_mode = kBGNOn;
- break;
- case fax:
- playout_mode = kPlayoutFax;
- WebRtcNetEQ_GetBGNMode(inst_[0], &background_noise_mode); // No change.
- break;
- case streaming:
- playout_mode = kPlayoutStreaming;
- background_noise_mode = kBGNOff;
- break;
- case off:
- playout_mode = kPlayoutOff;
- background_noise_mode = kBGNOff;
- break;
- }
-
- int err = 0;
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "SetPlayoutMode: NetEq is not initialized.");
- return -1;
- }
-
- if (WebRtcNetEQ_SetPlayoutMode(inst_[idx], playout_mode) < 0) {
- LogError("SetPlayoutMode", idx);
- err = -1;
- }
-
- if (WebRtcNetEQ_SetBGNMode(inst_[idx], kBGNOff) < 0) {
- LogError("SetPlayoutMode::SetBGNMode", idx);
- err = -1;
- }
- }
- if (err == 0)
- playout_mode_ = mode;
- return err;
-}
-
-AudioPlayoutMode ACMNetEQ::playout_mode() const {
- CriticalSectionScoped lock(neteq_crit_sect_);
- return playout_mode_;
-}
-
-int32_t ACMNetEQ::NetworkStatistics(
- ACMNetworkStatistics* statistics) const {
- WebRtcNetEQ_NetworkStatistics stats;
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (!is_initialized_[0]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "NetworkStatistics: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_GetNetworkStatistics(inst_[0], &stats) == 0) {
- statistics->currentAccelerateRate = stats.currentAccelerateRate;
- statistics->currentBufferSize = stats.currentBufferSize;
- statistics->jitterPeaksFound = (stats.jitterPeaksFound > 0);
- statistics->currentDiscardRate = stats.currentDiscardRate;
- statistics->currentExpandRate = stats.currentExpandRate;
- statistics->currentPacketLossRate = stats.currentPacketLossRate;
- statistics->currentPreemptiveRate = stats.currentPreemptiveRate;
- statistics->preferredBufferSize = stats.preferredBufferSize;
- statistics->clockDriftPPM = stats.clockDriftPPM;
- statistics->addedSamples = stats.addedSamples;
- } else {
- LogError("getNetworkStatistics", 0);
- return -1;
- }
- const int kArrayLen = 100;
- int waiting_times[kArrayLen];
- int waiting_times_len = WebRtcNetEQ_GetRawFrameWaitingTimes(inst_[0],
- kArrayLen,
- waiting_times);
- if (waiting_times_len > 0) {
- std::vector<int> waiting_times_vec(waiting_times,
- waiting_times + waiting_times_len);
- std::sort(waiting_times_vec.begin(), waiting_times_vec.end());
- size_t size = waiting_times_vec.size();
- assert(size == static_cast<size_t>(waiting_times_len));
- if (size % 2 == 0) {
- statistics->medianWaitingTimeMs = (waiting_times_vec[size / 2 - 1] +
- waiting_times_vec[size / 2]) / 2;
- } else {
- statistics->medianWaitingTimeMs = waiting_times_vec[size / 2];
- }
- statistics->minWaitingTimeMs = waiting_times_vec.front();
- statistics->maxWaitingTimeMs = waiting_times_vec.back();
- double sum = 0;
- for (size_t i = 0; i < size; ++i) {
- sum += waiting_times_vec[i];
- }
- statistics->meanWaitingTimeMs = static_cast<int>(sum / size);
- } else if (waiting_times_len == 0) {
- statistics->meanWaitingTimeMs = -1;
- statistics->medianWaitingTimeMs = -1;
- statistics->minWaitingTimeMs = -1;
- statistics->maxWaitingTimeMs = -1;
- } else {
- LogError("getRawFrameWaitingTimes", 0);
- return -1;
- }
- return 0;
-}
-
-// Should only be called in AV-sync mode.
-int ACMNetEQ::RecIn(const WebRtcRTPHeader& rtp_info,
- uint32_t receive_timestamp) {
- assert(av_sync_);
-
- // Translate to NetEq structure.
- WebRtcNetEQ_RTPInfo neteq_rtpinfo;
- neteq_rtpinfo.payloadType = rtp_info.header.payloadType;
- neteq_rtpinfo.sequenceNumber = rtp_info.header.sequenceNumber;
- neteq_rtpinfo.timeStamp = rtp_info.header.timestamp;
- neteq_rtpinfo.SSRC = rtp_info.header.ssrc;
- neteq_rtpinfo.markerBit = rtp_info.header.markerBit;
-
- CriticalSectionScoped lock(neteq_crit_sect_);
-
- // Master should be initialized.
- assert(is_initialized_[0]);
-
- // Push into Master.
- int status = WebRtcNetEQ_RecInSyncRTP(inst_[0], &neteq_rtpinfo,
- receive_timestamp);
- if (status < 0) {
- LogError("RecInSyncRTP", 0);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecIn (sync): NetEq, error in pushing in Master");
- return -1;
- }
-
- // If the received stream is stereo, insert a sync payload into slave.
- if (rtp_info.type.Audio.channel == 2) {
- // Slave should be initialized.
- assert(is_initialized_[1]);
-
- // PUSH into Slave
- status = WebRtcNetEQ_RecInSyncRTP(inst_[1], &neteq_rtpinfo,
- receive_timestamp);
- if (status < 0) {
- LogError("RecInRTPStruct", 1);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecIn (sync): NetEq, error in pushing in Slave");
- return -1;
- }
- }
- return status;
-}
-
-int32_t ACMNetEQ::RecIn(const uint8_t* incoming_payload,
- const int32_t length_payload,
- const WebRtcRTPHeader& rtp_info,
- uint32_t receive_timestamp) {
- int16_t payload_length = static_cast<int16_t>(length_payload);
-
- // Translate to NetEq structure.
- WebRtcNetEQ_RTPInfo neteq_rtpinfo;
- neteq_rtpinfo.payloadType = rtp_info.header.payloadType;
- neteq_rtpinfo.sequenceNumber = rtp_info.header.sequenceNumber;
- neteq_rtpinfo.timeStamp = rtp_info.header.timestamp;
- neteq_rtpinfo.SSRC = rtp_info.header.ssrc;
- neteq_rtpinfo.markerBit = rtp_info.header.markerBit;
-
- CriticalSectionScoped lock(neteq_crit_sect_);
-
- int status;
- // In case of stereo payload, first half of the data should be pushed into
- // master, and the second half into slave.
- if (rtp_info.type.Audio.channel == 2) {
- payload_length = payload_length / 2;
- }
-
- // Check that master is initialized.
- if (!is_initialized_[0]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecIn: NetEq is not initialized.");
- return -1;
- }
- // Push into Master.
- status = WebRtcNetEQ_RecInRTPStruct(inst_[0], &neteq_rtpinfo,
- incoming_payload, payload_length,
- receive_timestamp);
- if (status < 0) {
- LogError("RecInRTPStruct", 0);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecIn: NetEq, error in pushing in Master");
- return -1;
- }
-
- // If the received stream is stereo, insert second half of paket into slave.
- if (rtp_info.type.Audio.channel == 2) {
- if (!is_initialized_[1]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecIn: NetEq is not initialized.");
- return -1;
- }
- // Push into Slave.
- status = WebRtcNetEQ_RecInRTPStruct(inst_[1], &neteq_rtpinfo,
- &incoming_payload[payload_length],
- payload_length, receive_timestamp);
- if (status < 0) {
- LogError("RecInRTPStruct", 1);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecIn: NetEq, error in pushing in Slave");
- return -1;
- }
- }
-
- return 0;
-}
-
-int32_t ACMNetEQ::RecOut(AudioFrame& audio_frame) {
- enum WebRtcNetEQOutputType type;
- int16_t payload_len_sample;
- enum WebRtcNetEQOutputType type_master;
- enum WebRtcNetEQOutputType type_slave;
-
- int16_t payload_len_sample_slave;
-
- CriticalSectionScoped lockNetEq(neteq_crit_sect_);
-
- if (!received_stereo_) {
- if (!is_initialized_[0]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecOut: NetEq is not initialized.");
- return -1;
- }
- {
- WriteLockScoped lockCodec(*decode_lock_);
- if (WebRtcNetEQ_RecOut(inst_[0], &(audio_frame.data_[0]),
- &payload_len_sample) != 0) {
- LogError("RecOut", 0);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecOut: NetEq, error in pulling out for mono case");
- // Check for errors that can be recovered from:
- // RECOUT_ERROR_SAMPLEUNDERRUN = 2003
- int error_code = WebRtcNetEQ_GetErrorCode(inst_[0]);
- if (error_code != 2003) {
- // Cannot recover; return an error
- return -1;
- }
- }
- }
- WebRtcNetEQ_GetSpeechOutputType(inst_[0], &type);
- audio_frame.num_channels_ = 1;
- } else {
- if (!is_initialized_[0] || !is_initialized_[1]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecOut: NetEq is not initialized.");
- return -1;
- }
- int16_t payload_master[480];
- int16_t payload_slave[480];
- {
- WriteLockScoped lockCodec(*decode_lock_);
- if (WebRtcNetEQ_RecOutMasterSlave(inst_[0], payload_master,
- &payload_len_sample, master_slave_info_,
- 1) != 0) {
- LogError("RecOutMasterSlave", 0);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecOut: NetEq, error in pulling out for master");
-
- // Check for errors that can be recovered from:
- // RECOUT_ERROR_SAMPLEUNDERRUN = 2003
- int error_code = WebRtcNetEQ_GetErrorCode(inst_[0]);
- if (error_code != 2003) {
- // Cannot recover; return an error
- return -1;
- }
- }
- if (WebRtcNetEQ_RecOutMasterSlave(inst_[1], payload_slave,
- &payload_len_sample_slave,
- master_slave_info_, 0) != 0) {
- LogError("RecOutMasterSlave", 1);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RecOut: NetEq, error in pulling out for slave");
-
- // Check for errors that can be recovered from:
- // RECOUT_ERROR_SAMPLEUNDERRUN = 2003
- int error_code = WebRtcNetEQ_GetErrorCode(inst_[1]);
- if (error_code != 2003) {
- // Cannot recover; return an error
- return -1;
- }
- }
- }
-
- if (payload_len_sample != payload_len_sample_slave) {
- WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_,
- "RecOut: mismatch between the lenght of the decoded audio "
- "by Master (%d samples) and Slave (%d samples).",
- payload_len_sample, payload_len_sample_slave);
- if (payload_len_sample > payload_len_sample_slave) {
- memset(&payload_slave[payload_len_sample_slave], 0,
- (payload_len_sample - payload_len_sample_slave) *
- sizeof(int16_t));
- }
- }
-
- for (int16_t n = 0; n < payload_len_sample; n++) {
- audio_frame.data_[n << 1] = payload_master[n];
- audio_frame.data_[(n << 1) + 1] = payload_slave[n];
- }
- audio_frame.num_channels_ = 2;
-
- WebRtcNetEQ_GetSpeechOutputType(inst_[0], &type_master);
- WebRtcNetEQ_GetSpeechOutputType(inst_[1], &type_slave);
- if ((type_master == kOutputNormal) || (type_slave == kOutputNormal)) {
- type = kOutputNormal;
- } else {
- type = type_master;
- }
- }
-
- audio_frame.samples_per_channel_ =
- static_cast<uint16_t>(payload_len_sample);
- // NetEq always returns 10 ms of audio.
- current_samp_freq_khz_ =
- static_cast<float>(audio_frame.samples_per_channel_) / 10.0f;
- audio_frame.sample_rate_hz_ = audio_frame.samples_per_channel_ * 100;
- if (vad_status_) {
- if (type == kOutputVADPassive) {
- audio_frame.vad_activity_ = AudioFrame::kVadPassive;
- audio_frame.speech_type_ = AudioFrame::kNormalSpeech;
- } else if (type == kOutputNormal) {
- audio_frame.vad_activity_ = AudioFrame::kVadActive;
- audio_frame.speech_type_ = AudioFrame::kNormalSpeech;
- } else if (type == kOutputPLC) {
- audio_frame.vad_activity_ = previous_audio_activity_;
- audio_frame.speech_type_ = AudioFrame::kPLC;
- } else if (type == kOutputCNG) {
- audio_frame.vad_activity_ = AudioFrame::kVadPassive;
- audio_frame.speech_type_ = AudioFrame::kCNG;
- } else {
- audio_frame.vad_activity_ = AudioFrame::kVadPassive;
- audio_frame.speech_type_ = AudioFrame::kPLCCNG;
- }
- } else {
- // Always return kVadUnknown when receive VAD is inactive
- audio_frame.vad_activity_ = AudioFrame::kVadUnknown;
- if (type == kOutputNormal) {
- audio_frame.speech_type_ = AudioFrame::kNormalSpeech;
- } else if (type == kOutputPLC) {
- audio_frame.speech_type_ = AudioFrame::kPLC;
- } else if (type == kOutputPLCtoCNG) {
- audio_frame.speech_type_ = AudioFrame::kPLCCNG;
- } else if (type == kOutputCNG) {
- audio_frame.speech_type_ = AudioFrame::kCNG;
- } else {
- // type is kOutputVADPassive which
- // we don't expect to get if vad_status_ is false
- WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_,
- "RecOut: NetEq returned kVadPassive while vad_status_ is "
- "false.");
- audio_frame.vad_activity_ = AudioFrame::kVadUnknown;
- audio_frame.speech_type_ = AudioFrame::kNormalSpeech;
- }
- }
- previous_audio_activity_ = audio_frame.vad_activity_;
-
- WebRtcNetEQ_ProcessingActivity processing_stats;
- WebRtcNetEQ_GetProcessingActivity(inst_[0], &processing_stats);
- WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, id_,
- "ACM::RecOut accelerate_bgn=%d accelerate_normal=%d"
- " expand_bgn=%d expand_normal=%d"
- " preemptive_bgn=%d preemptive_normal=%d"
- " merge_bgn=%d merge_normal=%d",
- processing_stats.accelerate_bgn_samples,
- processing_stats.accelerate_normal_samples,
- processing_stats.expand_bgn_sampels,
- processing_stats.expand_normal_samples,
- processing_stats.preemptive_expand_bgn_samples,
- processing_stats.preemptive_expand_normal_samples,
- processing_stats.merge_expand_bgn_samples,
- processing_stats.merge_expand_normal_samples);
- return 0;
-}
-
-// When ACMGenericCodec has set the codec specific parameters in codec_def
-// it calls AddCodec() to add the new codec to the NetEQ database.
-int32_t ACMNetEQ::AddCodec(WebRtcNetEQ_CodecDef* codec_def,
- bool to_master) {
- if (codec_def == NULL) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "ACMNetEQ::AddCodec: error, codec_def is NULL");
- return -1;
- }
- CriticalSectionScoped lock(neteq_crit_sect_);
-
- int16_t idx;
- if (to_master) {
- idx = 0;
- } else {
- idx = 1;
- }
-
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "ACMNetEQ::AddCodec: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_CodecDbAdd(inst_[idx], codec_def) < 0) {
- LogError("CodecDB_Add", idx);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "ACMNetEQ::AddCodec: NetEq, error in adding codec");
- return -1;
- } else {
- return 0;
- }
-}
-
-// Creates a Word16 RTP packet out of a Word8 payload and an rtp info struct.
-// Must be byte order safe.
-void ACMNetEQ::RTPPack(int16_t* rtp_packet, const int8_t* payload,
- const int32_t payload_length_bytes,
- const WebRtcRTPHeader& rtp_info) {
- int32_t idx = 0;
- WEBRTC_SPL_SET_BYTE(rtp_packet, (int8_t) 0x80, idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet, rtp_info.header.payloadType, idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet,
- WEBRTC_SPL_GET_BYTE(&(rtp_info.header.sequenceNumber), 1),
- idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet,
- WEBRTC_SPL_GET_BYTE(&(rtp_info.header.sequenceNumber), 0),
- idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet,
- WEBRTC_SPL_GET_BYTE(&(rtp_info.header.timestamp), 3),
- idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet,
- WEBRTC_SPL_GET_BYTE(&(rtp_info.header.timestamp), 2),
- idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet,
- WEBRTC_SPL_GET_BYTE(&(rtp_info.header.timestamp), 1),
- idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet,
- WEBRTC_SPL_GET_BYTE(&(rtp_info.header.timestamp), 0),
- idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet,
- WEBRTC_SPL_GET_BYTE(&(rtp_info.header.ssrc), 3), idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet, WEBRTC_SPL_GET_BYTE(&(rtp_info.header.ssrc),
- 2), idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet, WEBRTC_SPL_GET_BYTE(&(rtp_info.header.ssrc),
- 1), idx);
- idx++;
- WEBRTC_SPL_SET_BYTE(rtp_packet, WEBRTC_SPL_GET_BYTE(&(rtp_info.header.ssrc),
- 0), idx);
- idx++;
- for (int16_t i = 0; i < payload_length_bytes; i++) {
- WEBRTC_SPL_SET_BYTE(rtp_packet, payload[i], idx);
- idx++;
- }
- if (payload_length_bytes & 1) {
- // Our 16 bits buffer is one byte too large, set that
- // last byte to zero.
- WEBRTC_SPL_SET_BYTE(rtp_packet, 0x0, idx);
- }
-}
-
-int16_t ACMNetEQ::EnableVAD() {
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (vad_status_) {
- return 0;
- }
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "SetVADStatus: NetEq is not initialized.");
- return -1;
- }
- // VAD was off and we have to turn it on
- if (EnableVADByIdxSafe(idx) < 0) {
- return -1;
- }
-
- // Set previous VAD status to PASSIVE
- previous_audio_activity_ = AudioFrame::kVadPassive;
- }
- vad_status_ = true;
- return 0;
-}
-
-ACMVADMode ACMNetEQ::vad_mode() const {
- CriticalSectionScoped lock(neteq_crit_sect_);
- return vad_mode_;
-}
-
-int16_t ACMNetEQ::SetVADMode(const ACMVADMode mode) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- if ((mode < VADNormal) || (mode > VADVeryAggr)) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "SetVADMode: NetEq error: could not set VAD mode, mode is not "
- "supported");
- return -1;
- } else {
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "SetVADMode: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_SetVADMode(inst_[idx], mode) < 0) {
- LogError("SetVADmode", idx);
- return -1;
- }
- }
- vad_mode_ = mode;
- return 0;
- }
-}
-
-int32_t ACMNetEQ::FlushBuffers() {
- CriticalSectionScoped lock(neteq_crit_sect_);
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "FlushBuffers: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_FlushBuffers(inst_[idx]) < 0) {
- LogError("FlushBuffers", idx);
- return -1;
- }
- }
- return 0;
-}
-
-int16_t ACMNetEQ::RemoveCodec(WebRtcNetEQDecoder codec_idx,
- bool is_stereo) {
- // sanity check
- if ((codec_idx <= kDecoderReservedStart) ||
- (codec_idx >= kDecoderReservedEnd)) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RemoveCodec: NetEq error: could not Remove Codec, codec "
- "index out of range");
- return -1;
- }
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (!is_initialized_[0]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "RemoveCodec: NetEq is not initialized.");
- return -1;
- }
-
- if (WebRtcNetEQ_CodecDbRemove(inst_[0], codec_idx) < 0) {
- LogError("CodecDB_Remove", 0);
- return -1;
- }
-
- if (is_stereo) {
- if (WebRtcNetEQ_CodecDbRemove(inst_[1], codec_idx) < 0) {
- LogError("CodecDB_Remove", 1);
- return -1;
- }
- }
-
- return 0;
-}
-
-int16_t ACMNetEQ::SetBackgroundNoiseMode(
- const ACMBackgroundNoiseMode mode) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- for (int16_t idx = 0; idx < num_slaves_ + 1; idx++) {
- if (!is_initialized_[idx]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "SetBackgroundNoiseMode: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_SetBGNMode(inst_[idx], (WebRtcNetEQBGNMode) mode) < 0) {
- LogError("SetBGNMode", idx);
- return -1;
- }
- }
- return 0;
-}
-
-int16_t ACMNetEQ::BackgroundNoiseMode(ACMBackgroundNoiseMode& mode) {
- WebRtcNetEQBGNMode my_mode;
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (!is_initialized_[0]) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "BackgroundNoiseMode: NetEq is not initialized.");
- return -1;
- }
- if (WebRtcNetEQ_GetBGNMode(inst_[0], &my_mode) < 0) {
- LogError("WebRtcNetEQ_GetBGNMode", 0);
- return -1;
- } else {
- mode = (ACMBackgroundNoiseMode) my_mode;
- }
- return 0;
-}
-
-void ACMNetEQ::set_id(int32_t id) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- id_ = id;
-}
-
-void ACMNetEQ::LogError(const char* neteq_func_name,
- const int16_t idx) const {
- char error_name[NETEQ_ERR_MSG_LEN_BYTE];
- char my_func_name[50];
- int neteq_error_code = WebRtcNetEQ_GetErrorCode(inst_[idx]);
- WebRtcNetEQ_GetErrorName(neteq_error_code, error_name,
- NETEQ_ERR_MSG_LEN_BYTE - 1);
- strncpy(my_func_name, neteq_func_name, 49);
- error_name[NETEQ_ERR_MSG_LEN_BYTE - 1] = '\0';
- my_func_name[49] = '\0';
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "NetEq-%d Error in function %s, error-code: %d, error-string: "
- " %s", idx, my_func_name, neteq_error_code, error_name);
-}
-
-int32_t ACMNetEQ::PlayoutTimestamp(uint32_t& timestamp) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (WebRtcNetEQ_GetSpeechTimeStamp(inst_[0], &timestamp) < 0) {
- LogError("GetSpeechTimeStamp", 0);
- return -1;
- } else {
- return 0;
- }
-}
-
-void ACMNetEQ::RemoveSlaves() {
- CriticalSectionScoped lock(neteq_crit_sect_);
- RemoveSlavesSafe();
-}
-
-void ACMNetEQ::RemoveSlavesSafe() {
- for (int i = 1; i < num_slaves_ + 1; i++) {
- RemoveNetEQSafe(i);
- }
-
- if (master_slave_info_ != NULL) {
- free(master_slave_info_);
- master_slave_info_ = NULL;
- }
- num_slaves_ = 0;
-}
-
-void ACMNetEQ::RemoveNetEQSafe(int index) {
- if (inst_mem_[index] != NULL) {
- free(inst_mem_[index]);
- inst_mem_[index] = NULL;
- inst_[index] = NULL;
- }
- if (neteq_packet_buffer_[index] != NULL) {
- free(neteq_packet_buffer_[index]);
- neteq_packet_buffer_[index] = NULL;
- }
- if (ptr_vadinst_[index] != NULL) {
- WebRtcVad_Free(ptr_vadinst_[index]);
- ptr_vadinst_[index] = NULL;
- }
-}
-
-int16_t ACMNetEQ::AddSlave(const WebRtcNetEQDecoder* used_codecs,
- int16_t num_codecs) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- const int16_t slave_idx = 1;
- if (num_slaves_ < 1) {
- // initialize the receiver, this also sets up VAD.
- if (InitByIdxSafe(slave_idx) < 0) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AddSlave: AddSlave Failed, Could not Initialize");
- return -1;
- }
-
- // Allocate buffer.
- if (AllocatePacketBufferByIdxSafe(used_codecs, num_codecs,
- slave_idx) < 0) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AddSlave: AddSlave Failed, Could not Allocate Packet "
- "Buffer");
- return -1;
- }
-
- if (master_slave_info_ != NULL) {
- free(master_slave_info_);
- master_slave_info_ = NULL;
- }
- int ms_info_size = WebRtcNetEQ_GetMasterSlaveInfoSize();
- master_slave_info_ = malloc(ms_info_size);
-
- if (master_slave_info_ == NULL) {
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AddSlave: AddSlave Failed, Could not Allocate memory for "
- "Master-Slave Info");
- return -1;
- }
-
- // We accept this as initialized NetEQ, the rest is to synchronize
- // Slave with Master.
- num_slaves_ = 1;
- is_initialized_[slave_idx] = true;
-
- // Set AVT
- if (WebRtcNetEQ_SetAVTPlayout(inst_[slave_idx],
- (avt_playout_) ? 1 : 0) < 0) {
- LogError("SetAVTPlayout", slave_idx);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AddSlave: AddSlave Failed, Could not set AVT playout.");
- return -1;
- }
-
- // Set Background Noise
- WebRtcNetEQBGNMode current_mode;
- if (WebRtcNetEQ_GetBGNMode(inst_[0], &current_mode) < 0) {
- LogError("GetBGNMode", 0);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AAddSlave: AddSlave Failed, Could not Get BGN form "
- "Master.");
- return -1;
- }
-
- if (WebRtcNetEQ_SetBGNMode(inst_[slave_idx],
- (WebRtcNetEQBGNMode) current_mode) < 0) {
- LogError("SetBGNMode", slave_idx);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AddSlave: AddSlave Failed, Could not set BGN mode.");
- return -1;
- }
-
- enum WebRtcNetEQPlayoutMode playout_mode = kPlayoutOff;
- switch (playout_mode_) {
- case voice:
- playout_mode = kPlayoutOn;
- break;
- case fax:
- playout_mode = kPlayoutFax;
- break;
- case streaming:
- playout_mode = kPlayoutStreaming;
- break;
- case off:
- playout_mode = kPlayoutOff;
- break;
- }
- if (WebRtcNetEQ_SetPlayoutMode(inst_[slave_idx], playout_mode) < 0) {
- LogError("SetPlayoutMode", 1);
- WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
- "AddSlave: AddSlave Failed, Could not Set Playout Mode.");
- return -1;
- }
-
- // Set AV-sync for the slave.
- WebRtcNetEQ_EnableAVSync(inst_[slave_idx], av_sync_ ? 1 : 0);
-
- // Set minimum delay.
- if (minimum_delay_ms_ > 0)
- WebRtcNetEQ_SetMinimumDelay(inst_[slave_idx], minimum_delay_ms_);
-
- // Set maximum delay.
- if (maximum_delay_ms_ > 0)
- WebRtcNetEQ_SetMaximumDelay(inst_[slave_idx], maximum_delay_ms_);
- }
-
- return 0;
-}
-
-void ACMNetEQ::set_received_stereo(bool received_stereo) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- received_stereo_ = received_stereo;
-}
-
-uint8_t ACMNetEQ::num_slaves() {
- CriticalSectionScoped lock(neteq_crit_sect_);
- return num_slaves_;
-}
-
-void ACMNetEQ::EnableAVSync(bool enable) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- av_sync_ = enable;
- for (int i = 0; i < num_slaves_ + 1; ++i) {
- assert(is_initialized_[i]);
- WebRtcNetEQ_EnableAVSync(inst_[i], enable ? 1 : 0);
- }
-}
-
-int ACMNetEQ::SetMinimumDelay(int minimum_delay_ms) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- for (int i = 0; i < num_slaves_ + 1; ++i) {
- assert(is_initialized_[i]);
- if (WebRtcNetEQ_SetMinimumDelay(inst_[i], minimum_delay_ms) < 0)
- return -1;
- }
- minimum_delay_ms_ = minimum_delay_ms;
- return 0;
-}
-
-int ACMNetEQ::SetMaximumDelay(int maximum_delay_ms) {
- CriticalSectionScoped lock(neteq_crit_sect_);
- for (int i = 0; i < num_slaves_ + 1; ++i) {
- assert(is_initialized_[i]);
- if (WebRtcNetEQ_SetMaximumDelay(inst_[i], maximum_delay_ms) < 0)
- return -1;
- }
- maximum_delay_ms_ = maximum_delay_ms;
- return 0;
-}
-
-int ACMNetEQ::LeastRequiredDelayMs() const {
- CriticalSectionScoped lock(neteq_crit_sect_);
- assert(is_initialized_[0]);
-
- // Sufficient to query the master.
- return WebRtcNetEQ_GetRequiredDelayMs(inst_[0]);
-}
-
-bool ACMNetEQ::DecodedRtpInfo(int* sequence_number, uint32_t* timestamp) const {
- CriticalSectionScoped lock(neteq_crit_sect_);
- if (WebRtcNetEQ_DecodedRtpInfo(inst_[0], sequence_number, timestamp) < 0)
- return false;
- return true;
-}
-
-} // namespace acm1
-
-} // namespace webrtc