diff options
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.cc | 1151 |
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], ×tamp) < 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], ¤t_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 |