diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index 25f44c1c66..d5f10bfdf8 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -116,8 +116,7 @@ class TransportSequenceNumberProxy : public TransportSequenceNumberAllocator { class RtpPacketSenderProxy : public RtpPacketSender { public: - RtpPacketSenderProxy() : rtp_packet_sender_(nullptr) { - } + RtpPacketSenderProxy() : rtp_packet_sender_(nullptr) {} void SetPacketSender(RtpPacketSender* rtp_packet_sender) { RTC_DCHECK(thread_checker_.CalledOnValidThread()); @@ -230,8 +229,9 @@ class VoERtcpObserver : public RtcpBandwidthObserver { } int weighted_fraction_lost = 0; if (total_number_of_packets > 0) { - weighted_fraction_lost = (fraction_lost_aggregate + - total_number_of_packets / 2) / total_number_of_packets; + weighted_fraction_lost = + (fraction_lost_aggregate + total_number_of_packets / 2) / + total_number_of_packets; } owner_->OnIncomingFractionLoss(weighted_fraction_lost); } @@ -242,169 +242,146 @@ class VoERtcpObserver : public RtcpBandwidthObserver { std::map extended_max_sequence_number_; }; -int32_t -Channel::SendData(FrameType frameType, - uint8_t payloadType, - uint32_t timeStamp, - const uint8_t* payloadData, - size_t payloadSize, - const RTPFragmentationHeader* fragmentation) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u," - " payloadSize=%" PRIuS ", fragmentation=0x%x)", - frameType, payloadType, timeStamp, - payloadSize, fragmentation); +int32_t Channel::SendData(FrameType frameType, + uint8_t payloadType, + uint32_t timeStamp, + const uint8_t* payloadData, + size_t payloadSize, + const RTPFragmentationHeader* fragmentation) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u," + " payloadSize=%" PRIuS ", fragmentation=0x%x)", + frameType, payloadType, timeStamp, payloadSize, fragmentation); - if (_includeAudioLevelIndication) - { - // Store current audio level in the RTP/RTCP module. - // The level will be used in combination with voice-activity state - // (frameType) to add an RTP header extension - _rtpRtcpModule->SetAudioLevel(rms_level_.RMS()); - } + if (_includeAudioLevelIndication) { + // Store current audio level in the RTP/RTCP module. + // The level will be used in combination with voice-activity state + // (frameType) to add an RTP header extension + _rtpRtcpModule->SetAudioLevel(rms_level_.RMS()); + } - // Push data from ACM to RTP/RTCP-module to deliver audio frame for - // packetization. - // This call will trigger Transport::SendPacket() from the RTP/RTCP module. - if (_rtpRtcpModule->SendOutgoingData((FrameType&)frameType, - payloadType, - timeStamp, - // Leaving the time when this frame was - // received from the capture device as - // undefined for voice for now. - -1, - payloadData, - payloadSize, - fragmentation) == -1) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, - "Channel::SendData() failed to send data to RTP/RTCP module"); - return -1; - } + // Push data from ACM to RTP/RTCP-module to deliver audio frame for + // packetization. + // This call will trigger Transport::SendPacket() from the RTP/RTCP module. + if (_rtpRtcpModule->SendOutgoingData( + (FrameType&)frameType, payloadType, timeStamp, + // Leaving the time when this frame was + // received from the capture device as + // undefined for voice for now. + -1, payloadData, payloadSize, fragmentation) == -1) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, + "Channel::SendData() failed to send data to RTP/RTCP module"); + return -1; + } - _lastLocalTimeStamp = timeStamp; - _lastPayloadType = payloadType; + _lastLocalTimeStamp = timeStamp; + _lastPayloadType = payloadType; - return 0; + return 0; } -int32_t -Channel::InFrameType(FrameType frame_type) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::InFrameType(frame_type=%d)", frame_type); +int32_t Channel::InFrameType(FrameType frame_type) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::InFrameType(frame_type=%d)", frame_type); - rtc::CritScope cs(&_callbackCritSect); - _sendFrameType = (frame_type == kAudioFrameSpeech); - return 0; + rtc::CritScope cs(&_callbackCritSect); + _sendFrameType = (frame_type == kAudioFrameSpeech); + return 0; } -int32_t -Channel::OnRxVadDetected(int vadDecision) -{ - rtc::CritScope cs(&_callbackCritSect); - if (_rxVadObserverPtr) - { - _rxVadObserverPtr->OnRxVad(_channelId, vadDecision); - } +int32_t Channel::OnRxVadDetected(int vadDecision) { + rtc::CritScope cs(&_callbackCritSect); + if (_rxVadObserverPtr) { + _rxVadObserverPtr->OnRxVad(_channelId, vadDecision); + } - return 0; + return 0; } bool Channel::SendRtp(const uint8_t* data, size_t len, const PacketOptions& options) { - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SendPacket(channel=%d, len=%" PRIuS ")", len); + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendPacket(channel=%d, len=%" PRIuS ")", len); - rtc::CritScope cs(&_callbackCritSect); + rtc::CritScope cs(&_callbackCritSect); - if (_transportPtr == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SendPacket() failed to send RTP packet due to" - " invalid transport object"); - return false; - } + if (_transportPtr == NULL) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendPacket() failed to send RTP packet due to" + " invalid transport object"); + return false; + } - uint8_t* bufferToSendPtr = (uint8_t*)data; - size_t bufferLength = len; + uint8_t* bufferToSendPtr = (uint8_t*)data; + size_t bufferLength = len; - if (!_transportPtr->SendRtp(bufferToSendPtr, bufferLength, options)) { - std::string transport_name = - _externalTransport ? "external transport" : "WebRtc sockets"; - WEBRTC_TRACE(kTraceError, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::SendPacket() RTP transmission using %s failed", - transport_name.c_str()); - return false; - } - return true; + if (!_transportPtr->SendRtp(bufferToSendPtr, bufferLength, options)) { + std::string transport_name = + _externalTransport ? "external transport" : "WebRtc sockets"; + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendPacket() RTP transmission using %s failed", + transport_name.c_str()); + return false; + } + return true; } -bool -Channel::SendRtcp(const uint8_t *data, size_t len) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SendRtcp(len=%" PRIuS ")", len); +bool Channel::SendRtcp(const uint8_t* data, size_t len) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendRtcp(len=%" PRIuS ")", len); - rtc::CritScope cs(&_callbackCritSect); - if (_transportPtr == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::SendRtcp() failed to send RTCP packet" - " due to invalid transport object"); - return false; - } + rtc::CritScope cs(&_callbackCritSect); + if (_transportPtr == NULL) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendRtcp() failed to send RTCP packet" + " due to invalid transport object"); + return false; + } - uint8_t* bufferToSendPtr = (uint8_t*)data; - size_t bufferLength = len; + uint8_t* bufferToSendPtr = (uint8_t*)data; + size_t bufferLength = len; - int n = _transportPtr->SendRtcp(bufferToSendPtr, bufferLength); - if (n < 0) { - std::string transport_name = - _externalTransport ? "external transport" : "WebRtc sockets"; - WEBRTC_TRACE(kTraceInfo, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::SendRtcp() transmission using %s failed", - transport_name.c_str()); - return false; - } - return true; + int n = _transportPtr->SendRtcp(bufferToSendPtr, bufferLength); + if (n < 0) { + std::string transport_name = + _externalTransport ? "external transport" : "WebRtc sockets"; + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendRtcp() transmission using %s failed", + transport_name.c_str()); + return false; + } + return true; } void Channel::OnPlayTelephoneEvent(uint8_t event, uint16_t lengthMs, uint8_t volume) { - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::OnPlayTelephoneEvent(event=%u, lengthMs=%u," - " volume=%u)", event, lengthMs, volume); + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::OnPlayTelephoneEvent(event=%u, lengthMs=%u," + " volume=%u)", + event, lengthMs, volume); - if (!_playOutbandDtmfEvent || (event > 15)) - { - // Ignore callback since feedback is disabled or event is not a - // Dtmf tone event. - return; - } + if (!_playOutbandDtmfEvent || (event > 15)) { + // Ignore callback since feedback is disabled or event is not a + // Dtmf tone event. + return; + } - assert(_outputMixerPtr != NULL); + assert(_outputMixerPtr != NULL); - // Start playing out the Dtmf tone (if playout is enabled). - // Reduce length of tone with 80ms to the reduce risk of echo. - _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); + // Start playing out the Dtmf tone (if playout is enabled). + // Reduce length of tone with 80ms to the reduce risk of echo. + _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); } -void -Channel::OnIncomingSSRCChanged(uint32_t ssrc) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::OnIncomingSSRCChanged(SSRC=%d)", ssrc); +void Channel::OnIncomingSSRCChanged(uint32_t ssrc) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::OnIncomingSSRCChanged(SSRC=%d)", ssrc); - // Update ssrc so that NTP for AV sync can be updated. - _rtpRtcpModule->SetRemoteSSRC(ssrc); + // Update ssrc so that NTP for AV sync can be updated. + _rtpRtcpModule->SetRemoteSSRC(ssrc); } void Channel::OnIncomingCSRCChanged(uint32_t CSRC, bool added) { @@ -419,88 +396,80 @@ int32_t Channel::OnInitializeDecoder( int frequency, size_t channels, uint32_t rate) { - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::OnInitializeDecoder(payloadType=%d, " - "payloadName=%s, frequency=%u, channels=%" PRIuS ", rate=%u)", - payloadType, payloadName, frequency, channels, rate); + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::OnInitializeDecoder(payloadType=%d, " + "payloadName=%s, frequency=%u, channels=%" PRIuS ", rate=%u)", + payloadType, payloadName, frequency, channels, rate); - CodecInst receiveCodec = {0}; - CodecInst dummyCodec = {0}; + CodecInst receiveCodec = {0}; + CodecInst dummyCodec = {0}; - receiveCodec.pltype = payloadType; - receiveCodec.plfreq = frequency; - receiveCodec.channels = channels; - receiveCodec.rate = rate; - strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); + receiveCodec.pltype = payloadType; + receiveCodec.plfreq = frequency; + receiveCodec.channels = channels; + receiveCodec.rate = rate; + strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); - audio_coding_->Codec(payloadName, &dummyCodec, frequency, channels); - receiveCodec.pacsize = dummyCodec.pacsize; + audio_coding_->Codec(payloadName, &dummyCodec, frequency, channels); + receiveCodec.pacsize = dummyCodec.pacsize; - // Register the new codec to the ACM - if (audio_coding_->RegisterReceiveCodec(receiveCodec) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::OnInitializeDecoder() invalid codec (" - "pt=%d, name=%s) received - 1", payloadType, payloadName); - _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR); - return -1; - } + // Register the new codec to the ACM + if (audio_coding_->RegisterReceiveCodec(receiveCodec) == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::OnInitializeDecoder() invalid codec (" + "pt=%d, name=%s) received - 1", + payloadType, payloadName); + _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR); + return -1; + } - return 0; + return 0; } -int32_t -Channel::OnReceivedPayloadData(const uint8_t* payloadData, - size_t payloadSize, - const WebRtcRTPHeader* rtpHeader) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::OnReceivedPayloadData(payloadSize=%" PRIuS "," - " payloadType=%u, audioChannel=%" PRIuS ")", - payloadSize, - rtpHeader->header.payloadType, - rtpHeader->type.Audio.channel); +int32_t Channel::OnReceivedPayloadData(const uint8_t* payloadData, + size_t payloadSize, + const WebRtcRTPHeader* rtpHeader) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::OnReceivedPayloadData(payloadSize=%" PRIuS + "," + " payloadType=%u, audioChannel=%" PRIuS ")", + payloadSize, rtpHeader->header.payloadType, + rtpHeader->type.Audio.channel); - if (!channel_state_.Get().playing) - { - // Avoid inserting into NetEQ when we are not playing. Count the - // packet as discarded. - WEBRTC_TRACE(kTraceStream, kTraceVoice, - VoEId(_instanceId, _channelId), - "received packet is discarded since playing is not" - " activated"); - _numberOfDiscardedPackets++; - return 0; - } - - // Push the incoming payload (parsed and ready for decoding) into the ACM - if (audio_coding_->IncomingPacket(payloadData, - payloadSize, - *rtpHeader) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, - "Channel::OnReceivedPayloadData() unable to push data to the ACM"); - return -1; - } - - // Update the packet delay. - UpdatePacketDelay(rtpHeader->header.timestamp, - rtpHeader->header.sequenceNumber); - - int64_t round_trip_time = 0; - _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time, - NULL, NULL, NULL); - - std::vector nack_list = audio_coding_->GetNackList( - round_trip_time); - if (!nack_list.empty()) { - // Can't use nack_list.data() since it's not supported by all - // compilers. - ResendPackets(&(nack_list[0]), static_cast(nack_list.size())); - } + if (!channel_state_.Get().playing) { + // Avoid inserting into NetEQ when we are not playing. Count the + // packet as discarded. + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "received packet is discarded since playing is not" + " activated"); + _numberOfDiscardedPackets++; return 0; + } + + // Push the incoming payload (parsed and ready for decoding) into the ACM + if (audio_coding_->IncomingPacket(payloadData, payloadSize, *rtpHeader) != + 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, + "Channel::OnReceivedPayloadData() unable to push data to the ACM"); + return -1; + } + + // Update the packet delay. + UpdatePacketDelay(rtpHeader->header.timestamp, + rtpHeader->header.sequenceNumber); + + int64_t round_trip_time = 0; + _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time, NULL, NULL, + NULL); + + std::vector nack_list = audio_coding_->GetNackList(round_trip_time); + if (!nack_list.empty()) { + // Can't use nack_list.data() since it's not supported by all + // compilers. + ResendPackets(&(nack_list[0]), static_cast(nack_list.size())); + } + return 0; } bool Channel::OnRecoveredPacket(const uint8_t* rtp_packet, @@ -518,201 +487,182 @@ bool Channel::OnRecoveredPacket(const uint8_t* rtp_packet, return ReceivePacket(rtp_packet, rtp_packet_length, header, false); } -int32_t Channel::GetAudioFrame(int32_t id, AudioFrame* audioFrame) -{ - if (event_log_) { - unsigned int ssrc; - RTC_CHECK_EQ(GetLocalSSRC(ssrc), 0); - event_log_->LogAudioPlayout(ssrc); +int32_t Channel::GetAudioFrame(int32_t id, AudioFrame* audioFrame) { + if (event_log_) { + unsigned int ssrc; + RTC_CHECK_EQ(GetLocalSSRC(ssrc), 0); + event_log_->LogAudioPlayout(ssrc); + } + // Get 10ms raw PCM data from the ACM (mixer limits output frequency) + if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_, audioFrame) == + -1) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); + // In all likelihood, the audio in this frame is garbage. We return an + // error so that the audio mixer module doesn't add it to the mix. As + // a result, it won't be played out and the actions skipped here are + // irrelevant. + return -1; + } + + if (_RxVadDetection) { + UpdateRxVadDetection(*audioFrame); + } + + // Convert module ID to internal VoE channel ID + audioFrame->id_ = VoEChannelId(audioFrame->id_); + // Store speech type for dead-or-alive detection + _outputSpeechType = audioFrame->speech_type_; + + ChannelState::State state = channel_state_.Get(); + + if (state.rx_apm_is_enabled) { + int err = rx_audioproc_->ProcessStream(audioFrame); + if (err) { + LOG(LS_ERROR) << "ProcessStream() error: " << err; + assert(false); } - // Get 10ms raw PCM data from the ACM (mixer limits output frequency) - if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_, - audioFrame) == -1) + } + + { + // Pass the audio buffers to an optional sink callback, before applying + // scaling/panning, as that applies to the mix operation. + // External recipients of the audio (e.g. via AudioTrack), will do their + // own mixing/dynamic processing. + rtc::CritScope cs(&_callbackCritSect); + if (audio_sink_) { + AudioSinkInterface::Data data( + &audioFrame->data_[0], audioFrame->samples_per_channel_, + audioFrame->sample_rate_hz_, audioFrame->num_channels_, + audioFrame->timestamp_); + audio_sink_->OnData(data); + } + } + + float output_gain = 1.0f; + float left_pan = 1.0f; + float right_pan = 1.0f; + { + rtc::CritScope cs(&volume_settings_critsect_); + output_gain = _outputGain; + left_pan = _panLeft; + right_pan = _panRight; + } + + // Output volume scaling + if (output_gain < 0.99f || output_gain > 1.01f) { + AudioFrameOperations::ScaleWithSat(output_gain, *audioFrame); + } + + // Scale left and/or right channel(s) if stereo and master balance is + // active + + if (left_pan != 1.0f || right_pan != 1.0f) { + if (audioFrame->num_channels_ == 1) { + // Emulate stereo mode since panning is active. + // The mono signal is copied to both left and right channels here. + AudioFrameOperations::MonoToStereo(audioFrame); + } + // For true stereo mode (when we are receiving a stereo signal), no + // action is needed. + + // Do the panning operation (the audio frame contains stereo at this + // stage) + AudioFrameOperations::Scale(left_pan, right_pan, *audioFrame); + } + + // Mix decoded PCM output with file if file mixing is enabled + if (state.output_file_playing) { + MixAudioWithFile(*audioFrame, audioFrame->sample_rate_hz_); + } + + // External media + if (_outputExternalMedia) { + rtc::CritScope cs(&_callbackCritSect); + const bool isStereo = (audioFrame->num_channels_ == 2); + if (_outputExternalMediaCallbackPtr) { + _outputExternalMediaCallbackPtr->Process( + _channelId, kPlaybackPerChannel, (int16_t*)audioFrame->data_, + audioFrame->samples_per_channel_, audioFrame->sample_rate_hz_, + isStereo); + } + } + + // Record playout if enabled + { + rtc::CritScope cs(&_fileCritSect); + + if (_outputFileRecording && _outputFileRecorderPtr) { + _outputFileRecorderPtr->RecordAudioToFile(*audioFrame); + } + } + + // Measure audio level (0-9) + _outputAudioLevel.ComputeLevel(*audioFrame); + + if (capture_start_rtp_time_stamp_ < 0 && audioFrame->timestamp_ != 0) { + // The first frame with a valid rtp timestamp. + capture_start_rtp_time_stamp_ = audioFrame->timestamp_; + } + + if (capture_start_rtp_time_stamp_ >= 0) { + // audioFrame.timestamp_ should be valid from now on. + + // Compute elapsed time. + int64_t unwrap_timestamp = + rtp_ts_wraparound_handler_->Unwrap(audioFrame->timestamp_); + audioFrame->elapsed_time_ms_ = + (unwrap_timestamp - capture_start_rtp_time_stamp_) / + (GetPlayoutFrequency() / 1000); + { - WEBRTC_TRACE(kTraceError, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); - // In all likelihood, the audio in this frame is garbage. We return an - // error so that the audio mixer module doesn't add it to the mix. As - // a result, it won't be played out and the actions skipped here are - // irrelevant. - return -1; - } - - if (_RxVadDetection) - { - UpdateRxVadDetection(*audioFrame); - } - - // Convert module ID to internal VoE channel ID - audioFrame->id_ = VoEChannelId(audioFrame->id_); - // Store speech type for dead-or-alive detection - _outputSpeechType = audioFrame->speech_type_; - - ChannelState::State state = channel_state_.Get(); - - if (state.rx_apm_is_enabled) { - int err = rx_audioproc_->ProcessStream(audioFrame); - if (err) { - LOG(LS_ERROR) << "ProcessStream() error: " << err; - assert(false); + rtc::CritScope lock(&ts_stats_lock_); + // Compute ntp time. + audioFrame->ntp_time_ms_ = + ntp_estimator_.Estimate(audioFrame->timestamp_); + // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received. + if (audioFrame->ntp_time_ms_ > 0) { + // Compute |capture_start_ntp_time_ms_| so that + // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_| + capture_start_ntp_time_ms_ = + audioFrame->ntp_time_ms_ - audioFrame->elapsed_time_ms_; } } + } - { - // Pass the audio buffers to an optional sink callback, before applying - // scaling/panning, as that applies to the mix operation. - // External recipients of the audio (e.g. via AudioTrack), will do their - // own mixing/dynamic processing. - rtc::CritScope cs(&_callbackCritSect); - if (audio_sink_) { - AudioSinkInterface::Data data( - &audioFrame->data_[0], - audioFrame->samples_per_channel_, audioFrame->sample_rate_hz_, - audioFrame->num_channels_, audioFrame->timestamp_); - audio_sink_->OnData(data); - } - } - - float output_gain = 1.0f; - float left_pan = 1.0f; - float right_pan = 1.0f; - { - rtc::CritScope cs(&volume_settings_critsect_); - output_gain = _outputGain; - left_pan = _panLeft; - right_pan= _panRight; - } - - // Output volume scaling - if (output_gain < 0.99f || output_gain > 1.01f) - { - AudioFrameOperations::ScaleWithSat(output_gain, *audioFrame); - } - - // Scale left and/or right channel(s) if stereo and master balance is - // active - - if (left_pan != 1.0f || right_pan != 1.0f) - { - if (audioFrame->num_channels_ == 1) - { - // Emulate stereo mode since panning is active. - // The mono signal is copied to both left and right channels here. - AudioFrameOperations::MonoToStereo(audioFrame); - } - // For true stereo mode (when we are receiving a stereo signal), no - // action is needed. - - // Do the panning operation (the audio frame contains stereo at this - // stage) - AudioFrameOperations::Scale(left_pan, right_pan, *audioFrame); - } - - // Mix decoded PCM output with file if file mixing is enabled - if (state.output_file_playing) - { - MixAudioWithFile(*audioFrame, audioFrame->sample_rate_hz_); - } - - // External media - if (_outputExternalMedia) - { - rtc::CritScope cs(&_callbackCritSect); - const bool isStereo = (audioFrame->num_channels_ == 2); - if (_outputExternalMediaCallbackPtr) - { - _outputExternalMediaCallbackPtr->Process( - _channelId, kPlaybackPerChannel, (int16_t*)audioFrame->data_, - audioFrame->samples_per_channel_, audioFrame->sample_rate_hz_, - isStereo); - } - } - - // Record playout if enabled - { - rtc::CritScope cs(&_fileCritSect); - - if (_outputFileRecording && _outputFileRecorderPtr) - { - _outputFileRecorderPtr->RecordAudioToFile(*audioFrame); - } - } - - // Measure audio level (0-9) - _outputAudioLevel.ComputeLevel(*audioFrame); - - if (capture_start_rtp_time_stamp_ < 0 && audioFrame->timestamp_ != 0) { - // The first frame with a valid rtp timestamp. - capture_start_rtp_time_stamp_ = audioFrame->timestamp_; - } - - if (capture_start_rtp_time_stamp_ >= 0) { - // audioFrame.timestamp_ should be valid from now on. - - // Compute elapsed time. - int64_t unwrap_timestamp = - rtp_ts_wraparound_handler_->Unwrap(audioFrame->timestamp_); - audioFrame->elapsed_time_ms_ = - (unwrap_timestamp - capture_start_rtp_time_stamp_) / - (GetPlayoutFrequency() / 1000); - - { - rtc::CritScope lock(&ts_stats_lock_); - // Compute ntp time. - audioFrame->ntp_time_ms_ = ntp_estimator_.Estimate( - audioFrame->timestamp_); - // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received. - if (audioFrame->ntp_time_ms_ > 0) { - // Compute |capture_start_ntp_time_ms_| so that - // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_| - capture_start_ntp_time_ms_ = - audioFrame->ntp_time_ms_ - audioFrame->elapsed_time_ms_; - } - } - } - - return 0; + return 0; } -int32_t -Channel::NeededFrequency(int32_t id) const -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::NeededFrequency(id=%d)", id); +int32_t Channel::NeededFrequency(int32_t id) const { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::NeededFrequency(id=%d)", id); - int highestNeeded = 0; + int highestNeeded = 0; - // Determine highest needed receive frequency - int32_t receiveFrequency = audio_coding_->ReceiveFrequency(); + // Determine highest needed receive frequency + int32_t receiveFrequency = audio_coding_->ReceiveFrequency(); - // Return the bigger of playout and receive frequency in the ACM. - if (audio_coding_->PlayoutFrequency() > receiveFrequency) - { - highestNeeded = audio_coding_->PlayoutFrequency(); - } - else - { - highestNeeded = receiveFrequency; + // Return the bigger of playout and receive frequency in the ACM. + if (audio_coding_->PlayoutFrequency() > receiveFrequency) { + highestNeeded = audio_coding_->PlayoutFrequency(); + } else { + highestNeeded = receiveFrequency; + } + + // Special case, if we're playing a file on the playout side + // we take that frequency into consideration as well + // This is not needed on sending side, since the codec will + // limit the spectrum anyway. + if (channel_state_.Get().output_file_playing) { + rtc::CritScope cs(&_fileCritSect); + if (_outputFilePlayerPtr) { + if (_outputFilePlayerPtr->Frequency() > highestNeeded) { + highestNeeded = _outputFilePlayerPtr->Frequency(); + } } + } - // Special case, if we're playing a file on the playout side - // we take that frequency into consideration as well - // This is not needed on sending side, since the codec will - // limit the spectrum anyway. - if (channel_state_.Get().output_file_playing) - { - rtc::CritScope cs(&_fileCritSect); - if (_outputFilePlayerPtr) - { - if(_outputFilePlayerPtr->Frequency()>highestNeeded) - { - highestNeeded=_outputFilePlayerPtr->Frequency(); - } - } - } - - return(highestNeeded); + return (highestNeeded); } int32_t Channel::CreateChannel(Channel*& channel, @@ -720,81 +670,65 @@ int32_t Channel::CreateChannel(Channel*& channel, uint32_t instanceId, RtcEventLog* const event_log, const Config& config) { - WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId), - "Channel::CreateChannel(channelId=%d, instanceId=%d)", - channelId, instanceId); + WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), + "Channel::CreateChannel(channelId=%d, instanceId=%d)", channelId, + instanceId); - channel = new Channel(channelId, instanceId, event_log, config); - if (channel == NULL) - { - WEBRTC_TRACE(kTraceMemory, kTraceVoice, - VoEId(instanceId,channelId), - "Channel::CreateChannel() unable to allocate memory for" - " channel"); - return -1; - } - return 0; + channel = new Channel(channelId, instanceId, event_log, config); + if (channel == NULL) { + WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId), + "Channel::CreateChannel() unable to allocate memory for" + " channel"); + return -1; + } + return 0; } -void -Channel::PlayNotification(int32_t id, uint32_t durationMs) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::PlayNotification(id=%d, durationMs=%d)", - id, durationMs); +void Channel::PlayNotification(int32_t id, uint32_t durationMs) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::PlayNotification(id=%d, durationMs=%d)", id, + durationMs); - // Not implement yet + // Not implement yet } -void -Channel::RecordNotification(int32_t id, uint32_t durationMs) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::RecordNotification(id=%d, durationMs=%d)", - id, durationMs); +void Channel::RecordNotification(int32_t id, uint32_t durationMs) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RecordNotification(id=%d, durationMs=%d)", id, + durationMs); - // Not implement yet + // Not implement yet } -void -Channel::PlayFileEnded(int32_t id) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::PlayFileEnded(id=%d)", id); +void Channel::PlayFileEnded(int32_t id) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::PlayFileEnded(id=%d)", id); - if (id == _inputFilePlayerId) - { - channel_state_.SetInputFilePlaying(false); - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::PlayFileEnded() => input file player module is" - " shutdown"); - } - else if (id == _outputFilePlayerId) - { - channel_state_.SetOutputFilePlaying(false); - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::PlayFileEnded() => output file player module is" - " shutdown"); - } -} - -void -Channel::RecordFileEnded(int32_t id) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::RecordFileEnded(id=%d)", id); - - assert(id == _outputFileRecorderId); - - rtc::CritScope cs(&_fileCritSect); - - _outputFileRecording = false; - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::RecordFileEnded() => output file recorder module is" + if (id == _inputFilePlayerId) { + channel_state_.SetInputFilePlaying(false); + WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::PlayFileEnded() => input file player module is" " shutdown"); + } else if (id == _outputFilePlayerId) { + channel_state_.SetOutputFilePlaying(false); + WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::PlayFileEnded() => output file player module is" + " shutdown"); + } +} + +void Channel::RecordFileEnded(int32_t id) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RecordFileEnded(id=%d)", id); + + assert(id == _outputFileRecorderId); + + rtc::CritScope cs(&_fileCritSect); + + _outputFileRecording = false; + WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RecordFileEnded() => output file recorder module is" + " shutdown"); } Channel::Channel(int32_t channelId, @@ -885,291 +819,251 @@ Channel::Channel(int32_t channelId, pacing_enabled_ ? new TransportSequenceNumberProxy() : nullptr), rtp_packet_sender_proxy_(pacing_enabled_ ? new RtpPacketSenderProxy() : nullptr) { - WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::Channel() - ctor"); - AudioCodingModule::Config acm_config; - acm_config.id = VoEModuleId(instanceId, channelId); - if (config.Get().enabled) { - // Clamping the buffer capacity at 20 packets. While going lower will - // probably work, it makes little sense. - acm_config.neteq_config.max_packets_in_buffer = - std::max(20, config.Get().capacity); - } - acm_config.neteq_config.enable_fast_accelerate = - config.Get().enabled; - audio_coding_.reset(AudioCodingModule::Create(acm_config)); + WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Channel() - ctor"); + AudioCodingModule::Config acm_config; + acm_config.id = VoEModuleId(instanceId, channelId); + if (config.Get().enabled) { + // Clamping the buffer capacity at 20 packets. While going lower will + // probably work, it makes little sense. + acm_config.neteq_config.max_packets_in_buffer = + std::max(20, config.Get().capacity); + } + acm_config.neteq_config.enable_fast_accelerate = + config.Get().enabled; + audio_coding_.reset(AudioCodingModule::Create(acm_config)); - _inbandDtmfQueue.ResetDtmf(); - _inbandDtmfGenerator.Init(); - _outputAudioLevel.Clear(); + _inbandDtmfQueue.ResetDtmf(); + _inbandDtmfGenerator.Init(); + _outputAudioLevel.Clear(); - RtpRtcp::Configuration configuration; - configuration.audio = true; - configuration.outgoing_transport = this; - configuration.audio_messages = this; - configuration.receive_statistics = rtp_receive_statistics_.get(); - configuration.bandwidth_callback = rtcp_observer_.get(); - configuration.paced_sender = rtp_packet_sender_proxy_.get(); - configuration.transport_sequence_number_allocator = - seq_num_allocator_proxy_.get(); - configuration.transport_feedback_callback = feedback_observer_proxy_.get(); - configuration.event_log = event_log; + RtpRtcp::Configuration configuration; + configuration.audio = true; + configuration.outgoing_transport = this; + configuration.audio_messages = this; + configuration.receive_statistics = rtp_receive_statistics_.get(); + configuration.bandwidth_callback = rtcp_observer_.get(); + configuration.paced_sender = rtp_packet_sender_proxy_.get(); + configuration.transport_sequence_number_allocator = + seq_num_allocator_proxy_.get(); + configuration.transport_feedback_callback = feedback_observer_proxy_.get(); + configuration.event_log = event_log; - _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); + _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); - statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); - rtp_receive_statistics_->RegisterRtcpStatisticsCallback( - statistics_proxy_.get()); + statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); + rtp_receive_statistics_->RegisterRtcpStatisticsCallback( + statistics_proxy_.get()); - Config audioproc_config; - audioproc_config.Set(new ExperimentalAgc(false)); - rx_audioproc_.reset(AudioProcessing::Create(audioproc_config)); + Config audioproc_config; + audioproc_config.Set(new ExperimentalAgc(false)); + rx_audioproc_.reset(AudioProcessing::Create(audioproc_config)); } -Channel::~Channel() -{ - rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL); - WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::~Channel() - dtor"); +Channel::~Channel() { + rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL); + WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::~Channel() - dtor"); - if (_outputExternalMedia) - { - DeRegisterExternalMediaProcessing(kPlaybackPerChannel); - } - if (channel_state_.Get().input_external_media) - { - DeRegisterExternalMediaProcessing(kRecordingPerChannel); - } - StopSend(); - StopPlayout(); + if (_outputExternalMedia) { + DeRegisterExternalMediaProcessing(kPlaybackPerChannel); + } + if (channel_state_.Get().input_external_media) { + DeRegisterExternalMediaProcessing(kRecordingPerChannel); + } + StopSend(); + StopPlayout(); - { - rtc::CritScope cs(&_fileCritSect); - if (_inputFilePlayerPtr) - { - _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); - _inputFilePlayerPtr->StopPlayingFile(); - FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); - _inputFilePlayerPtr = NULL; - } - if (_outputFilePlayerPtr) - { - _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); - _outputFilePlayerPtr->StopPlayingFile(); - FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); - _outputFilePlayerPtr = NULL; - } - if (_outputFileRecorderPtr) - { - _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); - _outputFileRecorderPtr->StopRecording(); - FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); - _outputFileRecorderPtr = NULL; - } + { + rtc::CritScope cs(&_fileCritSect); + if (_inputFilePlayerPtr) { + _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); + _inputFilePlayerPtr->StopPlayingFile(); + FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); + _inputFilePlayerPtr = NULL; } + if (_outputFilePlayerPtr) { + _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); + _outputFilePlayerPtr->StopPlayingFile(); + FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); + _outputFilePlayerPtr = NULL; + } + if (_outputFileRecorderPtr) { + _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); + _outputFileRecorderPtr->StopRecording(); + FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); + _outputFileRecorderPtr = NULL; + } + } - // The order to safely shutdown modules in a channel is: - // 1. De-register callbacks in modules - // 2. De-register modules in process thread - // 3. Destroy modules - if (audio_coding_->RegisterTransportCallback(NULL) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId,_channelId), - "~Channel() failed to de-register transport callback" - " (Audio coding module)"); - } - if (audio_coding_->RegisterVADCallback(NULL) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId,_channelId), - "~Channel() failed to de-register VAD callback" - " (Audio coding module)"); - } - // De-register modules in process thread - _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); + // The order to safely shutdown modules in a channel is: + // 1. De-register callbacks in modules + // 2. De-register modules in process thread + // 3. Destroy modules + if (audio_coding_->RegisterTransportCallback(NULL) == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "~Channel() failed to de-register transport callback" + " (Audio coding module)"); + } + if (audio_coding_->RegisterVADCallback(NULL) == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "~Channel() failed to de-register VAD callback" + " (Audio coding module)"); + } + // De-register modules in process thread + _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); - // End of modules shutdown + // End of modules shutdown } -int32_t -Channel::Init() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::Init()"); +int32_t Channel::Init() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Init()"); - channel_state_.Reset(); + channel_state_.Reset(); - // --- Initial sanity + // --- Initial sanity - if ((_engineStatisticsPtr == NULL) || - (_moduleProcessThreadPtr == NULL)) - { - WEBRTC_TRACE(kTraceError, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::Init() must call SetEngineInformation() first"); - return -1; + if ((_engineStatisticsPtr == NULL) || (_moduleProcessThreadPtr == NULL)) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Init() must call SetEngineInformation() first"); + return -1; + } + + // --- Add modules to process thread (for periodic schedulation) + + _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()); + + // --- ACM initialization + + if (audio_coding_->InitializeReceiver() == -1) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceError, + "Channel::Init() unable to initialize the ACM - 1"); + return -1; + } + + // --- RTP/RTCP module initialization + + // Ensure that RTCP is enabled by default for the created channel. + // Note that, the module will keep generating RTCP until it is explicitly + // disabled by the user. + // After StopListen (when no sockets exists), RTCP packets will no longer + // be transmitted since the Transport object will then be invalid. + telephone_event_handler_->SetTelephoneEventForwardToDecoder(true); + // RTCP is enabled by default. + _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound); + // --- Register all permanent callbacks + const bool fail = (audio_coding_->RegisterTransportCallback(this) == -1) || + (audio_coding_->RegisterVADCallback(this) == -1); + + if (fail) { + _engineStatisticsPtr->SetLastError( + VE_CANNOT_INIT_CHANNEL, kTraceError, + "Channel::Init() callbacks not registered"); + return -1; + } + + // --- Register all supported codecs to the receiving side of the + // RTP/RTCP module + + CodecInst codec; + const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); + + for (int idx = 0; idx < nSupportedCodecs; idx++) { + // Open up the RTP/RTCP receiver for all supported codecs + if ((audio_coding_->Codec(idx, &codec) == -1) || + (rtp_receiver_->RegisterReceivePayload( + codec.plname, codec.pltype, codec.plfreq, codec.channels, + (codec.rate < 0) ? 0 : codec.rate) == -1)) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Init() unable to register %s " + "(%d/%d/%" PRIuS "/%d) to RTP/RTCP receiver", + codec.plname, codec.pltype, codec.plfreq, codec.channels, + codec.rate); + } else { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Init() %s (%d/%d/%" PRIuS + "/%d) has been " + "added to the RTP/RTCP receiver", + codec.plname, codec.pltype, codec.plfreq, codec.channels, + codec.rate); } - // --- Add modules to process thread (for periodic schedulation) - - _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()); - - // --- ACM initialization - - if (audio_coding_->InitializeReceiver() == -1) { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "Channel::Init() unable to initialize the ACM - 1"); - return -1; + // Ensure that PCMU is used as default codec on the sending side + if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) { + SetSendCodec(codec); } - // --- RTP/RTCP module initialization - - // Ensure that RTCP is enabled by default for the created channel. - // Note that, the module will keep generating RTCP until it is explicitly - // disabled by the user. - // After StopListen (when no sockets exists), RTCP packets will no longer - // be transmitted since the Transport object will then be invalid. - telephone_event_handler_->SetTelephoneEventForwardToDecoder(true); - // RTCP is enabled by default. - _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound); - // --- Register all permanent callbacks - const bool fail = - (audio_coding_->RegisterTransportCallback(this) == -1) || - (audio_coding_->RegisterVADCallback(this) == -1); - - if (fail) - { - _engineStatisticsPtr->SetLastError( - VE_CANNOT_INIT_CHANNEL, kTraceError, - "Channel::Init() callbacks not registered"); - return -1; + // Register default PT for outband 'telephone-event' + if (!STR_CASE_CMP(codec.plname, "telephone-event")) { + if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) || + (audio_coding_->RegisterReceiveCodec(codec) == -1)) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Init() failed to register outband " + "'telephone-event' (%d/%d) correctly", + codec.pltype, codec.plfreq); + } } - // --- Register all supported codecs to the receiving side of the - // RTP/RTCP module - - CodecInst codec; - const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); - - for (int idx = 0; idx < nSupportedCodecs; idx++) - { - // Open up the RTP/RTCP receiver for all supported codecs - if ((audio_coding_->Codec(idx, &codec) == -1) || - (rtp_receiver_->RegisterReceivePayload( - codec.plname, - codec.pltype, - codec.plfreq, - codec.channels, - (codec.rate < 0) ? 0 : codec.rate) == -1)) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::Init() unable to register %s " - "(%d/%d/%" PRIuS "/%d) to RTP/RTCP receiver", - codec.plname, codec.pltype, codec.plfreq, - codec.channels, codec.rate); - } - else - { - WEBRTC_TRACE(kTraceInfo, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::Init() %s (%d/%d/%" PRIuS "/%d) has been " - "added to the RTP/RTCP receiver", - codec.plname, codec.pltype, codec.plfreq, - codec.channels, codec.rate); - } - - // Ensure that PCMU is used as default codec on the sending side - if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) - { - SetSendCodec(codec); - } - - // Register default PT for outband 'telephone-event' - if (!STR_CASE_CMP(codec.plname, "telephone-event")) - { - if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) || - (audio_coding_->RegisterReceiveCodec(codec) == -1)) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::Init() failed to register outband " - "'telephone-event' (%d/%d) correctly", - codec.pltype, codec.plfreq); - } - } - - if (!STR_CASE_CMP(codec.plname, "CN")) - { - if ((audio_coding_->RegisterSendCodec(codec) == -1) || - (audio_coding_->RegisterReceiveCodec(codec) == -1) || - (_rtpRtcpModule->RegisterSendPayload(codec) == -1)) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::Init() failed to register CN (%d/%d) " - "correctly - 1", - codec.pltype, codec.plfreq); - } - } + if (!STR_CASE_CMP(codec.plname, "CN")) { + if ((audio_coding_->RegisterSendCodec(codec) == -1) || + (audio_coding_->RegisterReceiveCodec(codec) == -1) || + (_rtpRtcpModule->RegisterSendPayload(codec) == -1)) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Init() failed to register CN (%d/%d) " + "correctly - 1", + codec.pltype, codec.plfreq); + } + } #ifdef WEBRTC_CODEC_RED - // Register RED to the receiving side of the ACM. - // We will not receive an OnInitializeDecoder() callback for RED. - if (!STR_CASE_CMP(codec.plname, "RED")) - { - if (audio_coding_->RegisterReceiveCodec(codec) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId,_channelId), - "Channel::Init() failed to register RED (%d/%d) " - "correctly", - codec.pltype, codec.plfreq); - } - } + // Register RED to the receiving side of the ACM. + // We will not receive an OnInitializeDecoder() callback for RED. + if (!STR_CASE_CMP(codec.plname, "RED")) { + if (audio_coding_->RegisterReceiveCodec(codec) == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Init() failed to register RED (%d/%d) " + "correctly", + codec.pltype, codec.plfreq); + } + } #endif - } + } - if (rx_audioproc_->noise_suppression()->set_level(kDefaultNsMode) != 0) { - LOG(LS_ERROR) << "noise_suppression()->set_level(kDefaultNsMode) failed."; - return -1; - } - if (rx_audioproc_->gain_control()->set_mode(kDefaultRxAgcMode) != 0) { - LOG(LS_ERROR) << "gain_control()->set_mode(kDefaultRxAgcMode) failed."; - return -1; - } + if (rx_audioproc_->noise_suppression()->set_level(kDefaultNsMode) != 0) { + LOG(LS_ERROR) << "noise_suppression()->set_level(kDefaultNsMode) failed."; + return -1; + } + if (rx_audioproc_->gain_control()->set_mode(kDefaultRxAgcMode) != 0) { + LOG(LS_ERROR) << "gain_control()->set_mode(kDefaultRxAgcMode) failed."; + return -1; + } - return 0; + return 0; } -int32_t -Channel::SetEngineInformation(Statistics& engineStatistics, - OutputMixer& outputMixer, - voe::TransmitMixer& transmitMixer, - ProcessThread& moduleProcessThread, - AudioDeviceModule& audioDeviceModule, - VoiceEngineObserver* voiceEngineObserver, - rtc::CriticalSection* callbackCritSect) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetEngineInformation()"); - _engineStatisticsPtr = &engineStatistics; - _outputMixerPtr = &outputMixer; - _transmitMixerPtr = &transmitMixer, - _moduleProcessThreadPtr = &moduleProcessThread; - _audioDeviceModulePtr = &audioDeviceModule; - _voiceEngineObserverPtr = voiceEngineObserver; - _callbackCritSectPtr = callbackCritSect; - return 0; +int32_t Channel::SetEngineInformation(Statistics& engineStatistics, + OutputMixer& outputMixer, + voe::TransmitMixer& transmitMixer, + ProcessThread& moduleProcessThread, + AudioDeviceModule& audioDeviceModule, + VoiceEngineObserver* voiceEngineObserver, + rtc::CriticalSection* callbackCritSect) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetEngineInformation()"); + _engineStatisticsPtr = &engineStatistics; + _outputMixerPtr = &outputMixer; + _transmitMixerPtr = &transmitMixer, + _moduleProcessThreadPtr = &moduleProcessThread; + _audioDeviceModulePtr = &audioDeviceModule; + _voiceEngineObserverPtr = voiceEngineObserver; + _callbackCritSectPtr = callbackCritSect; + return 0; } -int32_t -Channel::UpdateLocalTimeStamp() -{ - - _timeStamp += static_cast(_audioFrame.samples_per_channel_); - return 0; +int32_t Channel::UpdateLocalTimeStamp() { + _timeStamp += static_cast(_audioFrame.samples_per_channel_); + return 0; } void Channel::SetSink(rtc::scoped_ptr sink) { @@ -1177,188 +1071,158 @@ void Channel::SetSink(rtc::scoped_ptr sink) { audio_sink_ = std::move(sink); } -int32_t -Channel::StartPlayout() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartPlayout()"); - if (channel_state_.Get().playing) - { - return 0; - } - - if (!_externalMixing) { - // Add participant as candidates for mixing. - if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, - "StartPlayout() failed to add participant to mixer"); - return -1; - } - } - - channel_state_.SetPlaying(true); - if (RegisterFilePlayingToMixer() != 0) - return -1; - +int32_t Channel::StartPlayout() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartPlayout()"); + if (channel_state_.Get().playing) { return 0; + } + + if (!_externalMixing) { + // Add participant as candidates for mixing. + if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, + "StartPlayout() failed to add participant to mixer"); + return -1; + } + } + + channel_state_.SetPlaying(true); + if (RegisterFilePlayingToMixer() != 0) + return -1; + + return 0; } -int32_t -Channel::StopPlayout() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StopPlayout()"); - if (!channel_state_.Get().playing) - { - return 0; - } - - if (!_externalMixing) { - // Remove participant as candidates for mixing - if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, - "StopPlayout() failed to remove participant from mixer"); - return -1; - } - } - - channel_state_.SetPlaying(false); - _outputAudioLevel.Clear(); - +int32_t Channel::StopPlayout() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StopPlayout()"); + if (!channel_state_.Get().playing) { return 0; + } + + if (!_externalMixing) { + // Remove participant as candidates for mixing + if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, + "StopPlayout() failed to remove participant from mixer"); + return -1; + } + } + + channel_state_.SetPlaying(false); + _outputAudioLevel.Clear(); + + return 0; } -int32_t -Channel::StartSend() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartSend()"); - // Resume the previous sequence number which was reset by StopSend(). - // This needs to be done before |sending| is set to true. - if (send_sequence_number_) - SetInitSequenceNumber(send_sequence_number_); - - if (channel_state_.Get().sending) - { - return 0; - } - channel_state_.SetSending(true); - - if (_rtpRtcpModule->SetSendingStatus(true) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "StartSend() RTP/RTCP failed to start sending"); - rtc::CritScope cs(&_callbackCritSect); - channel_state_.SetSending(false); - return -1; - } +int32_t Channel::StartSend() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartSend()"); + // Resume the previous sequence number which was reset by StopSend(). + // This needs to be done before |sending| is set to true. + if (send_sequence_number_) + SetInitSequenceNumber(send_sequence_number_); + if (channel_state_.Get().sending) { return 0; -} + } + channel_state_.SetSending(true); -int32_t -Channel::StopSend() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StopSend()"); - if (!channel_state_.Get().sending) - { - return 0; - } + if (_rtpRtcpModule->SetSendingStatus(true) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "StartSend() RTP/RTCP failed to start sending"); + rtc::CritScope cs(&_callbackCritSect); channel_state_.SetSending(false); + return -1; + } - // Store the sequence number to be able to pick up the same sequence for - // the next StartSend(). This is needed for restarting device, otherwise - // it might cause libSRTP to complain about packets being replayed. - // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring - // CL is landed. See issue - // https://code.google.com/p/webrtc/issues/detail?id=2111 . - send_sequence_number_ = _rtpRtcpModule->SequenceNumber(); - - // Reset sending SSRC and sequence number and triggers direct transmission - // of RTCP BYE - if (_rtpRtcpModule->SetSendingStatus(false) == -1) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, - "StartSend() RTP/RTCP failed to stop sending"); - } - - return 0; + return 0; } -int32_t -Channel::StartReceiving() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartReceiving()"); - if (channel_state_.Get().receiving) - { - return 0; - } - channel_state_.SetReceiving(true); - _numberOfDiscardedPackets = 0; +int32_t Channel::StopSend() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StopSend()"); + if (!channel_state_.Get().sending) { return 0; + } + channel_state_.SetSending(false); + + // Store the sequence number to be able to pick up the same sequence for + // the next StartSend(). This is needed for restarting device, otherwise + // it might cause libSRTP to complain about packets being replayed. + // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring + // CL is landed. See issue + // https://code.google.com/p/webrtc/issues/detail?id=2111 . + send_sequence_number_ = _rtpRtcpModule->SequenceNumber(); + + // Reset sending SSRC and sequence number and triggers direct transmission + // of RTCP BYE + if (_rtpRtcpModule->SetSendingStatus(false) == -1) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, + "StartSend() RTP/RTCP failed to stop sending"); + } + + return 0; } -int32_t -Channel::StopReceiving() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StopReceiving()"); - if (!channel_state_.Get().receiving) - { - return 0; - } - - channel_state_.SetReceiving(false); +int32_t Channel::StartReceiving() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartReceiving()"); + if (channel_state_.Get().receiving) { return 0; + } + channel_state_.SetReceiving(true); + _numberOfDiscardedPackets = 0; + return 0; } -int32_t -Channel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::RegisterVoiceEngineObserver()"); - rtc::CritScope cs(&_callbackCritSect); - - if (_voiceEngineObserverPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceError, - "RegisterVoiceEngineObserver() observer already enabled"); - return -1; - } - _voiceEngineObserverPtr = &observer; +int32_t Channel::StopReceiving() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StopReceiving()"); + if (!channel_state_.Get().receiving) { return 0; + } + + channel_state_.SetReceiving(false); + return 0; } -int32_t -Channel::DeRegisterVoiceEngineObserver() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::DeRegisterVoiceEngineObserver()"); - rtc::CritScope cs(&_callbackCritSect); +int32_t Channel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RegisterVoiceEngineObserver()"); + rtc::CritScope cs(&_callbackCritSect); - if (!_voiceEngineObserverPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceWarning, - "DeRegisterVoiceEngineObserver() observer already disabled"); - return 0; - } - _voiceEngineObserverPtr = NULL; - return 0; + if (_voiceEngineObserverPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceError, + "RegisterVoiceEngineObserver() observer already enabled"); + return -1; + } + _voiceEngineObserverPtr = &observer; + return 0; } -int32_t -Channel::GetSendCodec(CodecInst& codec) -{ +int32_t Channel::DeRegisterVoiceEngineObserver() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::DeRegisterVoiceEngineObserver()"); + rtc::CritScope cs(&_callbackCritSect); + + if (!_voiceEngineObserverPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceWarning, + "DeRegisterVoiceEngineObserver() observer already disabled"); + return 0; + } + _voiceEngineObserverPtr = NULL; + return 0; +} + +int32_t Channel::GetSendCodec(CodecInst& codec) { auto send_codec = audio_coding_->SendCodec(); if (send_codec) { codec = *send_codec; @@ -1367,46 +1231,37 @@ Channel::GetSendCodec(CodecInst& codec) return -1; } -int32_t -Channel::GetRecCodec(CodecInst& codec) -{ - return (audio_coding_->ReceiveCodec(&codec)); +int32_t Channel::GetRecCodec(CodecInst& codec) { + return (audio_coding_->ReceiveCodec(&codec)); } -int32_t -Channel::SetSendCodec(const CodecInst& codec) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetSendCodec()"); +int32_t Channel::SetSendCodec(const CodecInst& codec) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetSendCodec()"); - if (audio_coding_->RegisterSendCodec(codec) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), - "SetSendCodec() failed to register codec to ACM"); - return -1; + if (audio_coding_->RegisterSendCodec(codec) != 0) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "SetSendCodec() failed to register codec to ACM"); + return -1; + } + + if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { + _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); + if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "SetSendCodec() failed to register codec to" + " RTP/RTCP module"); + return -1; } + } - if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) - { - _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); - if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) - { - WEBRTC_TRACE( - kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), - "SetSendCodec() failed to register codec to" - " RTP/RTCP module"); - return -1; - } - } + if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "SetSendCodec() failed to set audio packet size"); + return -1; + } - if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), - "SetSendCodec() failed to set audio packet size"); - return -1; - } - - return 0; + return 0; } void Channel::SetBitRate(int bitrate_bps) { @@ -1420,203 +1275,168 @@ void Channel::OnIncomingFractionLoss(int fraction_lost) { uint8_t average_fraction_loss = network_predictor_->GetLossRate(); // Normalizes rate to 0 - 100. - if (audio_coding_->SetPacketLossRate( - 100 * average_fraction_loss / 255) != 0) { + if (audio_coding_->SetPacketLossRate(100 * average_fraction_loss / 255) != + 0) { assert(false); // This should not happen. } } -int32_t -Channel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetVADStatus(mode=%d)", mode); - assert(!(disableDTX && enableVAD)); // disableDTX mode is deprecated. - // To disable VAD, DTX must be disabled too - disableDTX = ((enableVAD == false) ? true : disableDTX); - if (audio_coding_->SetVAD(!disableDTX, enableVAD, mode) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "SetVADStatus() failed to set VAD"); - return -1; - } - return 0; +int32_t Channel::SetVADStatus(bool enableVAD, + ACMVADMode mode, + bool disableDTX) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetVADStatus(mode=%d)", mode); + assert(!(disableDTX && enableVAD)); // disableDTX mode is deprecated. + // To disable VAD, DTX must be disabled too + disableDTX = ((enableVAD == false) ? true : disableDTX); + if (audio_coding_->SetVAD(!disableDTX, enableVAD, mode) != 0) { + _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR, + kTraceError, + "SetVADStatus() failed to set VAD"); + return -1; + } + return 0; } -int32_t -Channel::GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX) -{ - if (audio_coding_->VAD(&disabledDTX, &enabledVAD, &mode) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "GetVADStatus() failed to get VAD status"); - return -1; - } - disabledDTX = !disabledDTX; - return 0; +int32_t Channel::GetVADStatus(bool& enabledVAD, + ACMVADMode& mode, + bool& disabledDTX) { + if (audio_coding_->VAD(&disabledDTX, &enabledVAD, &mode) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceError, + "GetVADStatus() failed to get VAD status"); + return -1; + } + disabledDTX = !disabledDTX; + return 0; } -int32_t -Channel::SetRecPayloadType(const CodecInst& codec) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetRecPayloadType()"); +int32_t Channel::SetRecPayloadType(const CodecInst& codec) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetRecPayloadType()"); - if (channel_state_.Get().playing) - { - _engineStatisticsPtr->SetLastError( - VE_ALREADY_PLAYING, kTraceError, - "SetRecPayloadType() unable to set PT while playing"); - return -1; + if (channel_state_.Get().playing) { + _engineStatisticsPtr->SetLastError( + VE_ALREADY_PLAYING, kTraceError, + "SetRecPayloadType() unable to set PT while playing"); + return -1; + } + if (channel_state_.Get().receiving) { + _engineStatisticsPtr->SetLastError( + VE_ALREADY_LISTENING, kTraceError, + "SetRecPayloadType() unable to set PT while listening"); + return -1; + } + + if (codec.pltype == -1) { + // De-register the selected codec (RTP/RTCP module and ACM) + + int8_t pltype(-1); + CodecInst rxCodec = codec; + + // Get payload type for the given codec + rtp_payload_registry_->ReceivePayloadType( + rxCodec.plname, rxCodec.plfreq, rxCodec.channels, + (rxCodec.rate < 0) ? 0 : rxCodec.rate, &pltype); + rxCodec.pltype = pltype; + + if (rtp_receiver_->DeRegisterReceivePayload(pltype) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "SetRecPayloadType() RTP/RTCP-module deregistration " + "failed"); + return -1; } - if (channel_state_.Get().receiving) - { - _engineStatisticsPtr->SetLastError( - VE_ALREADY_LISTENING, kTraceError, - "SetRecPayloadType() unable to set PT while listening"); - return -1; - } - - if (codec.pltype == -1) - { - // De-register the selected codec (RTP/RTCP module and ACM) - - int8_t pltype(-1); - CodecInst rxCodec = codec; - - // Get payload type for the given codec - rtp_payload_registry_->ReceivePayloadType( - rxCodec.plname, - rxCodec.plfreq, - rxCodec.channels, - (rxCodec.rate < 0) ? 0 : rxCodec.rate, - &pltype); - rxCodec.pltype = pltype; - - if (rtp_receiver_->DeRegisterReceivePayload(pltype) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, - kTraceError, - "SetRecPayloadType() RTP/RTCP-module deregistration " - "failed"); - return -1; - } - if (audio_coding_->UnregisterReceiveCodec(rxCodec.pltype) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "SetRecPayloadType() ACM deregistration failed - 1"); - return -1; - } - return 0; + if (audio_coding_->UnregisterReceiveCodec(rxCodec.pltype) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceError, + "SetRecPayloadType() ACM deregistration failed - 1"); + return -1; } + return 0; + } + if (rtp_receiver_->RegisterReceivePayload( + codec.plname, codec.pltype, codec.plfreq, codec.channels, + (codec.rate < 0) ? 0 : codec.rate) != 0) { + // First attempt to register failed => de-register and try again + rtp_receiver_->DeRegisterReceivePayload(codec.pltype); if (rtp_receiver_->RegisterReceivePayload( - codec.plname, - codec.pltype, - codec.plfreq, - codec.channels, - (codec.rate < 0) ? 0 : codec.rate) != 0) - { - // First attempt to register failed => de-register and try again - rtp_receiver_->DeRegisterReceivePayload(codec.pltype); - if (rtp_receiver_->RegisterReceivePayload( - codec.plname, - codec.pltype, - codec.plfreq, - codec.channels, - (codec.rate < 0) ? 0 : codec.rate) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "SetRecPayloadType() RTP/RTCP-module registration failed"); - return -1; - } + codec.plname, codec.pltype, codec.plfreq, codec.channels, + (codec.rate < 0) ? 0 : codec.rate) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "SetRecPayloadType() RTP/RTCP-module registration failed"); + return -1; } - if (audio_coding_->RegisterReceiveCodec(codec) != 0) - { - audio_coding_->UnregisterReceiveCodec(codec.pltype); - if (audio_coding_->RegisterReceiveCodec(codec) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "SetRecPayloadType() ACM registration failed - 1"); - return -1; - } + } + if (audio_coding_->RegisterReceiveCodec(codec) != 0) { + audio_coding_->UnregisterReceiveCodec(codec.pltype); + if (audio_coding_->RegisterReceiveCodec(codec) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceError, + "SetRecPayloadType() ACM registration failed - 1"); + return -1; } - return 0; + } + return 0; } -int32_t -Channel::GetRecPayloadType(CodecInst& codec) -{ - int8_t payloadType(-1); - if (rtp_payload_registry_->ReceivePayloadType( - codec.plname, - codec.plfreq, - codec.channels, - (codec.rate < 0) ? 0 : codec.rate, - &payloadType) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, - "GetRecPayloadType() failed to retrieve RX payload type"); - return -1; - } - codec.pltype = payloadType; - return 0; +int32_t Channel::GetRecPayloadType(CodecInst& codec) { + int8_t payloadType(-1); + if (rtp_payload_registry_->ReceivePayloadType( + codec.plname, codec.plfreq, codec.channels, + (codec.rate < 0) ? 0 : codec.rate, &payloadType) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, + "GetRecPayloadType() failed to retrieve RX payload type"); + return -1; + } + codec.pltype = payloadType; + return 0; } -int32_t -Channel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetSendCNPayloadType()"); +int32_t Channel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetSendCNPayloadType()"); - CodecInst codec; - int32_t samplingFreqHz(-1); - const size_t kMono = 1; - if (frequency == kFreq32000Hz) - samplingFreqHz = 32000; - else if (frequency == kFreq16000Hz) - samplingFreqHz = 16000; + CodecInst codec; + int32_t samplingFreqHz(-1); + const size_t kMono = 1; + if (frequency == kFreq32000Hz) + samplingFreqHz = 32000; + else if (frequency == kFreq16000Hz) + samplingFreqHz = 16000; - if (audio_coding_->Codec("CN", &codec, samplingFreqHz, kMono) == -1) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "SetSendCNPayloadType() failed to retrieve default CN codec " - "settings"); - return -1; + if (audio_coding_->Codec("CN", &codec, samplingFreqHz, kMono) == -1) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceError, + "SetSendCNPayloadType() failed to retrieve default CN codec " + "settings"); + return -1; + } + + // Modify the payload type (must be set to dynamic range) + codec.pltype = type; + + if (audio_coding_->RegisterSendCodec(codec) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceError, + "SetSendCNPayloadType() failed to register CN to ACM"); + return -1; + } + + if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { + _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); + if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "SetSendCNPayloadType() failed to register CN to RTP/RTCP " + "module"); + return -1; } - - // Modify the payload type (must be set to dynamic range) - codec.pltype = type; - - if (audio_coding_->RegisterSendCodec(codec) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "SetSendCNPayloadType() failed to register CN to ACM"); - return -1; - } - - if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) - { - _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); - if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "SetSendCNPayloadType() failed to register CN to RTP/RTCP " - "module"); - return -1; - } - } - return 0; + } + return 0; } int Channel::SetOpusMaxPlaybackRate(int frequency_hz) { @@ -1638,58 +1458,54 @@ int Channel::SetOpusDtx(bool enable_dtx) { int ret = enable_dtx ? audio_coding_->EnableOpusDtx() : audio_coding_->DisableOpusDtx(); if (ret != 0) { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, "SetOpusDtx() failed"); + _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR, + kTraceError, "SetOpusDtx() failed"); return -1; } return 0; } -int32_t Channel::RegisterExternalTransport(Transport& transport) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), +int32_t Channel::RegisterExternalTransport(Transport& transport) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::RegisterExternalTransport()"); - rtc::CritScope cs(&_callbackCritSect); + rtc::CritScope cs(&_callbackCritSect); - if (_externalTransport) - { - _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, - kTraceError, - "RegisterExternalTransport() external transport already enabled"); - return -1; - } - _externalTransport = true; - _transportPtr = &transport; - return 0; + if (_externalTransport) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceError, + "RegisterExternalTransport() external transport already enabled"); + return -1; + } + _externalTransport = true; + _transportPtr = &transport; + return 0; } -int32_t -Channel::DeRegisterExternalTransport() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::DeRegisterExternalTransport()"); +int32_t Channel::DeRegisterExternalTransport() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::DeRegisterExternalTransport()"); - rtc::CritScope cs(&_callbackCritSect); + rtc::CritScope cs(&_callbackCritSect); - if (!_transportPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceWarning, - "DeRegisterExternalTransport() external transport already " - "disabled"); - return 0; - } - _externalTransport = false; - _transportPtr = NULL; - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "DeRegisterExternalTransport() all transport is disabled"); + if (!_transportPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceWarning, + "DeRegisterExternalTransport() external transport already " + "disabled"); return 0; + } + _externalTransport = false; + _transportPtr = NULL; + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "DeRegisterExternalTransport() all transport is disabled"); + return 0; } -int32_t Channel::ReceivedRTPPacket(const int8_t* data, size_t length, +int32_t Channel::ReceivedRTPPacket(const int8_t* data, + size_t length, const PacketTime& packet_time) { - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::ReceivedRTPPacket()"); // Store playout timestamp for the received RTP packet @@ -1707,8 +1523,8 @@ int32_t Channel::ReceivedRTPPacket(const int8_t* data, size_t length, if (header.payload_type_frequency < 0) return -1; bool in_order = IsPacketInOrder(header); - rtp_receive_statistics_->IncomingPacket(header, length, - IsPacketRetransmitted(header, in_order)); + rtp_receive_statistics_->IncomingPacket( + header, length, IsPacketRetransmitted(header, in_order)); rtp_payload_registry_->SetIncomingPayloadType(header); return ReceivePacket(received_packet, length, header, in_order) ? 0 : -1; @@ -1782,12 +1598,11 @@ bool Channel::IsPacketRetransmitted(const RTPHeader& header, // Check if this is a retransmission. int64_t min_rtt = 0; _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); - return !in_order && - statistician->IsRetransmitOfOldPacket(header, min_rtt); + return !in_order && statistician->IsRetransmitOfOldPacket(header, min_rtt); } int32_t Channel::ReceivedRTCPPacket(const int8_t* data, size_t length) { - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::ReceivedRTCPPacket()"); // Store playout timestamp for the received RTCP packet UpdatePlayoutTimestamp(true); @@ -1807,8 +1622,9 @@ int32_t Channel::ReceivedRTCPPacket(const int8_t* data, size_t length) { uint32_t ntp_secs = 0; uint32_t ntp_frac = 0; uint32_t rtp_timestamp = 0; - if (0 != _rtpRtcpModule->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL, - &rtp_timestamp)) { + if (0 != + _rtpRtcpModule->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL, + &rtp_timestamp)) { // Waiting for RTCP. return 0; } @@ -1826,70 +1642,61 @@ int Channel::StartPlayingFileLocally(const char* fileName, int startPosition, float volumeScaling, int stopPosition, - const CodecInst* codecInst) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d," - " format=%d, volumeScaling=%5.3f, startPosition=%d, " - "stopPosition=%d)", fileName, loop, format, volumeScaling, - startPosition, stopPosition); + const CodecInst* codecInst) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d," + " format=%d, volumeScaling=%5.3f, startPosition=%d, " + "stopPosition=%d)", + fileName, loop, format, volumeScaling, startPosition, + stopPosition); - if (channel_state_.Get().output_file_playing) - { - _engineStatisticsPtr->SetLastError( - VE_ALREADY_PLAYING, kTraceError, - "StartPlayingFileLocally() is already playing"); - return -1; + if (channel_state_.Get().output_file_playing) { + _engineStatisticsPtr->SetLastError( + VE_ALREADY_PLAYING, kTraceError, + "StartPlayingFileLocally() is already playing"); + return -1; + } + + { + rtc::CritScope cs(&_fileCritSect); + + if (_outputFilePlayerPtr) { + _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); + FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); + _outputFilePlayerPtr = NULL; } - { - rtc::CritScope cs(&_fileCritSect); + _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( + _outputFilePlayerId, (const FileFormats)format); - if (_outputFilePlayerPtr) - { - _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); - FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); - _outputFilePlayerPtr = NULL; - } - - _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( - _outputFilePlayerId, (const FileFormats)format); - - if (_outputFilePlayerPtr == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "StartPlayingFileLocally() filePlayer format is not correct"); - return -1; - } - - const uint32_t notificationTime(0); - - if (_outputFilePlayerPtr->StartPlayingFile( - fileName, - loop, - startPosition, - volumeScaling, - notificationTime, - stopPosition, - (const CodecInst*)codecInst) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_BAD_FILE, kTraceError, - "StartPlayingFile() failed to start file playout"); - _outputFilePlayerPtr->StopPlayingFile(); - FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); - _outputFilePlayerPtr = NULL; - return -1; - } - _outputFilePlayerPtr->RegisterModuleFileCallback(this); - channel_state_.SetOutputFilePlaying(true); + if (_outputFilePlayerPtr == NULL) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "StartPlayingFileLocally() filePlayer format is not correct"); + return -1; } - if (RegisterFilePlayingToMixer() != 0) - return -1; + const uint32_t notificationTime(0); - return 0; + if (_outputFilePlayerPtr->StartPlayingFile( + fileName, loop, startPosition, volumeScaling, notificationTime, + stopPosition, (const CodecInst*)codecInst) != 0) { + _engineStatisticsPtr->SetLastError( + VE_BAD_FILE, kTraceError, + "StartPlayingFile() failed to start file playout"); + _outputFilePlayerPtr->StopPlayingFile(); + FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); + _outputFilePlayerPtr = NULL; + return -1; + } + _outputFilePlayerPtr->RegisterModuleFileCallback(this); + channel_state_.SetOutputFilePlaying(true); + } + + if (RegisterFilePlayingToMixer() != 0) + return -1; + + return 0; } int Channel::StartPlayingFileLocally(InStream* stream, @@ -1897,153 +1704,136 @@ int Channel::StartPlayingFileLocally(InStream* stream, int startPosition, float volumeScaling, int stopPosition, - const CodecInst* codecInst) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartPlayingFileLocally(format=%d," - " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", - format, volumeScaling, startPosition, stopPosition); + const CodecInst* codecInst) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartPlayingFileLocally(format=%d," + " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", + format, volumeScaling, startPosition, stopPosition); - if(stream == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_BAD_FILE, kTraceError, - "StartPlayingFileLocally() NULL as input stream"); - return -1; + if (stream == NULL) { + _engineStatisticsPtr->SetLastError( + VE_BAD_FILE, kTraceError, + "StartPlayingFileLocally() NULL as input stream"); + return -1; + } + + if (channel_state_.Get().output_file_playing) { + _engineStatisticsPtr->SetLastError( + VE_ALREADY_PLAYING, kTraceError, + "StartPlayingFileLocally() is already playing"); + return -1; + } + + { + rtc::CritScope cs(&_fileCritSect); + + // Destroy the old instance + if (_outputFilePlayerPtr) { + _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); + FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); + _outputFilePlayerPtr = NULL; } + // Create the instance + _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( + _outputFilePlayerId, (const FileFormats)format); - if (channel_state_.Get().output_file_playing) - { - _engineStatisticsPtr->SetLastError( - VE_ALREADY_PLAYING, kTraceError, - "StartPlayingFileLocally() is already playing"); - return -1; + if (_outputFilePlayerPtr == NULL) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "StartPlayingFileLocally() filePlayer format isnot correct"); + return -1; } - { - rtc::CritScope cs(&_fileCritSect); + const uint32_t notificationTime(0); - // Destroy the old instance - if (_outputFilePlayerPtr) - { - _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); - FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); - _outputFilePlayerPtr = NULL; - } - - // Create the instance - _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( - _outputFilePlayerId, - (const FileFormats)format); - - if (_outputFilePlayerPtr == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "StartPlayingFileLocally() filePlayer format isnot correct"); - return -1; - } - - const uint32_t notificationTime(0); - - if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition, - volumeScaling, - notificationTime, - stopPosition, codecInst) != 0) - { - _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, - "StartPlayingFile() failed to " - "start file playout"); - _outputFilePlayerPtr->StopPlayingFile(); - FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); - _outputFilePlayerPtr = NULL; - return -1; - } - _outputFilePlayerPtr->RegisterModuleFileCallback(this); - channel_state_.SetOutputFilePlaying(true); + if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition, + volumeScaling, notificationTime, + stopPosition, codecInst) != 0) { + _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, + "StartPlayingFile() failed to " + "start file playout"); + _outputFilePlayerPtr->StopPlayingFile(); + FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); + _outputFilePlayerPtr = NULL; + return -1; } + _outputFilePlayerPtr->RegisterModuleFileCallback(this); + channel_state_.SetOutputFilePlaying(true); + } - if (RegisterFilePlayingToMixer() != 0) - return -1; + if (RegisterFilePlayingToMixer() != 0) + return -1; - return 0; + return 0; } -int Channel::StopPlayingFileLocally() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StopPlayingFileLocally()"); - - if (!channel_state_.Get().output_file_playing) - { - return 0; - } - - { - rtc::CritScope cs(&_fileCritSect); - - if (_outputFilePlayerPtr->StopPlayingFile() != 0) - { - _engineStatisticsPtr->SetLastError( - VE_STOP_RECORDING_FAILED, kTraceError, - "StopPlayingFile() could not stop playing"); - return -1; - } - _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); - FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); - _outputFilePlayerPtr = NULL; - channel_state_.SetOutputFilePlaying(false); - } - // _fileCritSect cannot be taken while calling - // SetAnonymousMixibilityStatus. Refer to comments in - // StartPlayingFileLocally(const char* ...) for more details. - if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, - "StopPlayingFile() failed to stop participant from playing as" - "file in the mixer"); - return -1; - } +int Channel::StopPlayingFileLocally() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StopPlayingFileLocally()"); + if (!channel_state_.Get().output_file_playing) { return 0; + } + + { + rtc::CritScope cs(&_fileCritSect); + + if (_outputFilePlayerPtr->StopPlayingFile() != 0) { + _engineStatisticsPtr->SetLastError( + VE_STOP_RECORDING_FAILED, kTraceError, + "StopPlayingFile() could not stop playing"); + return -1; + } + _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); + FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); + _outputFilePlayerPtr = NULL; + channel_state_.SetOutputFilePlaying(false); + } + // _fileCritSect cannot be taken while calling + // SetAnonymousMixibilityStatus. Refer to comments in + // StartPlayingFileLocally(const char* ...) for more details. + if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, + "StopPlayingFile() failed to stop participant from playing as" + "file in the mixer"); + return -1; + } + + return 0; } -int Channel::IsPlayingFileLocally() const -{ - return channel_state_.Get().output_file_playing; +int Channel::IsPlayingFileLocally() const { + return channel_state_.Get().output_file_playing; } -int Channel::RegisterFilePlayingToMixer() -{ - // Return success for not registering for file playing to mixer if: - // 1. playing file before playout is started on that channel. - // 2. starting playout without file playing on that channel. - if (!channel_state_.Get().playing || - !channel_state_.Get().output_file_playing) - { - return 0; - } - - // |_fileCritSect| cannot be taken while calling - // SetAnonymousMixabilityStatus() since as soon as the participant is added - // frames can be pulled by the mixer. Since the frames are generated from - // the file, _fileCritSect will be taken. This would result in a deadlock. - if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) - { - channel_state_.SetOutputFilePlaying(false); - rtc::CritScope cs(&_fileCritSect); - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, - "StartPlayingFile() failed to add participant as file to mixer"); - _outputFilePlayerPtr->StopPlayingFile(); - FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); - _outputFilePlayerPtr = NULL; - return -1; - } - +int Channel::RegisterFilePlayingToMixer() { + // Return success for not registering for file playing to mixer if: + // 1. playing file before playout is started on that channel. + // 2. starting playout without file playing on that channel. + if (!channel_state_.Get().playing || + !channel_state_.Get().output_file_playing) { return 0; + } + + // |_fileCritSect| cannot be taken while calling + // SetAnonymousMixabilityStatus() since as soon as the participant is added + // frames can be pulled by the mixer. Since the frames are generated from + // the file, _fileCritSect will be taken. This would result in a deadlock. + if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) { + channel_state_.SetOutputFilePlaying(false); + rtc::CritScope cs(&_fileCritSect); + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, + "StartPlayingFile() failed to add participant as file to mixer"); + _outputFilePlayerPtr->StopPlayingFile(); + FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); + _outputFilePlayerPtr = NULL; + return -1; + } + + return 0; } int Channel::StartPlayingFileAsMicrophone(const char* fileName, @@ -2052,67 +1842,58 @@ int Channel::StartPlayingFileAsMicrophone(const char* fileName, int startPosition, float volumeScaling, int stopPosition, - const CodecInst* codecInst) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, " - "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, " - "stopPosition=%d)", fileName, loop, format, volumeScaling, - startPosition, stopPosition); + const CodecInst* codecInst) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, " + "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, " + "stopPosition=%d)", + fileName, loop, format, volumeScaling, startPosition, + stopPosition); - rtc::CritScope cs(&_fileCritSect); - - if (channel_state_.Get().input_file_playing) - { - _engineStatisticsPtr->SetLastError( - VE_ALREADY_PLAYING, kTraceWarning, - "StartPlayingFileAsMicrophone() filePlayer is playing"); - return 0; - } - - // Destroy the old instance - if (_inputFilePlayerPtr) - { - _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); - FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); - _inputFilePlayerPtr = NULL; - } - - // Create the instance - _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( - _inputFilePlayerId, (const FileFormats)format); - - if (_inputFilePlayerPtr == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); - return -1; - } - - const uint32_t notificationTime(0); - - if (_inputFilePlayerPtr->StartPlayingFile( - fileName, - loop, - startPosition, - volumeScaling, - notificationTime, - stopPosition, - (const CodecInst*)codecInst) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_BAD_FILE, kTraceError, - "StartPlayingFile() failed to start file playout"); - _inputFilePlayerPtr->StopPlayingFile(); - FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); - _inputFilePlayerPtr = NULL; - return -1; - } - _inputFilePlayerPtr->RegisterModuleFileCallback(this); - channel_state_.SetInputFilePlaying(true); + rtc::CritScope cs(&_fileCritSect); + if (channel_state_.Get().input_file_playing) { + _engineStatisticsPtr->SetLastError( + VE_ALREADY_PLAYING, kTraceWarning, + "StartPlayingFileAsMicrophone() filePlayer is playing"); return 0; + } + + // Destroy the old instance + if (_inputFilePlayerPtr) { + _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); + FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); + _inputFilePlayerPtr = NULL; + } + + // Create the instance + _inputFilePlayerPtr = FilePlayer::CreateFilePlayer(_inputFilePlayerId, + (const FileFormats)format); + + if (_inputFilePlayerPtr == NULL) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); + return -1; + } + + const uint32_t notificationTime(0); + + if (_inputFilePlayerPtr->StartPlayingFile( + fileName, loop, startPosition, volumeScaling, notificationTime, + stopPosition, (const CodecInst*)codecInst) != 0) { + _engineStatisticsPtr->SetLastError( + VE_BAD_FILE, kTraceError, + "StartPlayingFile() failed to start file playout"); + _inputFilePlayerPtr->StopPlayingFile(); + FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); + _inputFilePlayerPtr = NULL; + return -1; + } + _inputFilePlayerPtr->RegisterModuleFileCallback(this); + channel_state_.SetInputFilePlaying(true); + + return 0; } int Channel::StartPlayingFileAsMicrophone(InStream* stream, @@ -2120,758 +1901,640 @@ int Channel::StartPlayingFileAsMicrophone(InStream* stream, int startPosition, float volumeScaling, int stopPosition, - const CodecInst* codecInst) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartPlayingFileAsMicrophone(format=%d, " - "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", - format, volumeScaling, startPosition, stopPosition); + const CodecInst* codecInst) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartPlayingFileAsMicrophone(format=%d, " + "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", + format, volumeScaling, startPosition, stopPosition); - if(stream == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_BAD_FILE, kTraceError, - "StartPlayingFileAsMicrophone NULL as input stream"); - return -1; - } + if (stream == NULL) { + _engineStatisticsPtr->SetLastError( + VE_BAD_FILE, kTraceError, + "StartPlayingFileAsMicrophone NULL as input stream"); + return -1; + } - rtc::CritScope cs(&_fileCritSect); - - if (channel_state_.Get().input_file_playing) - { - _engineStatisticsPtr->SetLastError( - VE_ALREADY_PLAYING, kTraceWarning, - "StartPlayingFileAsMicrophone() is playing"); - return 0; - } - - // Destroy the old instance - if (_inputFilePlayerPtr) - { - _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); - FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); - _inputFilePlayerPtr = NULL; - } - - // Create the instance - _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( - _inputFilePlayerId, (const FileFormats)format); - - if (_inputFilePlayerPtr == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "StartPlayingInputFile() filePlayer format isnot correct"); - return -1; - } - - const uint32_t notificationTime(0); - - if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition, - volumeScaling, notificationTime, - stopPosition, codecInst) != 0) - { - _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, - "StartPlayingFile() failed to start " - "file playout"); - _inputFilePlayerPtr->StopPlayingFile(); - FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); - _inputFilePlayerPtr = NULL; - return -1; - } - - _inputFilePlayerPtr->RegisterModuleFileCallback(this); - channel_state_.SetInputFilePlaying(true); + rtc::CritScope cs(&_fileCritSect); + if (channel_state_.Get().input_file_playing) { + _engineStatisticsPtr->SetLastError( + VE_ALREADY_PLAYING, kTraceWarning, + "StartPlayingFileAsMicrophone() is playing"); return 0; -} + } -int Channel::StopPlayingFileAsMicrophone() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StopPlayingFileAsMicrophone()"); - - rtc::CritScope cs(&_fileCritSect); - - if (!channel_state_.Get().input_file_playing) - { - return 0; - } - - if (_inputFilePlayerPtr->StopPlayingFile() != 0) - { - _engineStatisticsPtr->SetLastError( - VE_STOP_RECORDING_FAILED, kTraceError, - "StopPlayingFile() could not stop playing"); - return -1; - } + // Destroy the old instance + if (_inputFilePlayerPtr) { _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); _inputFilePlayerPtr = NULL; - channel_state_.SetInputFilePlaying(false); + } - return 0; + // Create the instance + _inputFilePlayerPtr = FilePlayer::CreateFilePlayer(_inputFilePlayerId, + (const FileFormats)format); + + if (_inputFilePlayerPtr == NULL) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "StartPlayingInputFile() filePlayer format isnot correct"); + return -1; + } + + const uint32_t notificationTime(0); + + if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition, + volumeScaling, notificationTime, + stopPosition, codecInst) != 0) { + _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, + "StartPlayingFile() failed to start " + "file playout"); + _inputFilePlayerPtr->StopPlayingFile(); + FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); + _inputFilePlayerPtr = NULL; + return -1; + } + + _inputFilePlayerPtr->RegisterModuleFileCallback(this); + channel_state_.SetInputFilePlaying(true); + + return 0; } -int Channel::IsPlayingFileAsMicrophone() const -{ - return channel_state_.Get().input_file_playing; +int Channel::StopPlayingFileAsMicrophone() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StopPlayingFileAsMicrophone()"); + + rtc::CritScope cs(&_fileCritSect); + + if (!channel_state_.Get().input_file_playing) { + return 0; + } + + if (_inputFilePlayerPtr->StopPlayingFile() != 0) { + _engineStatisticsPtr->SetLastError( + VE_STOP_RECORDING_FAILED, kTraceError, + "StopPlayingFile() could not stop playing"); + return -1; + } + _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); + FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); + _inputFilePlayerPtr = NULL; + channel_state_.SetInputFilePlaying(false); + + return 0; +} + +int Channel::IsPlayingFileAsMicrophone() const { + return channel_state_.Get().input_file_playing; } int Channel::StartRecordingPlayout(const char* fileName, - const CodecInst* codecInst) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartRecordingPlayout(fileName=%s)", fileName); - - if (_outputFileRecording) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), - "StartRecordingPlayout() is already recording"); - return 0; - } - - FileFormats format; - const uint32_t notificationTime(0); // Not supported in VoE - CodecInst dummyCodec={100,"L16",16000,320,1,320000}; - - if ((codecInst != NULL) && - ((codecInst->channels < 1) || (codecInst->channels > 2))) - { - _engineStatisticsPtr->SetLastError( - VE_BAD_ARGUMENT, kTraceError, - "StartRecordingPlayout() invalid compression"); - return(-1); - } - if(codecInst == NULL) - { - format = kFileFormatPcm16kHzFile; - codecInst=&dummyCodec; - } - else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || - (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || - (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) - { - format = kFileFormatWavFile; - } - else - { - format = kFileFormatCompressedFile; - } - - rtc::CritScope cs(&_fileCritSect); - - // Destroy the old instance - if (_outputFileRecorderPtr) - { - _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); - FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); - _outputFileRecorderPtr = NULL; - } - - _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( - _outputFileRecorderId, (const FileFormats)format); - if (_outputFileRecorderPtr == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "StartRecordingPlayout() fileRecorder format isnot correct"); - return -1; - } - - if (_outputFileRecorderPtr->StartRecordingAudioFile( - fileName, (const CodecInst&)*codecInst, notificationTime) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_BAD_FILE, kTraceError, - "StartRecordingAudioFile() failed to start file recording"); - _outputFileRecorderPtr->StopRecording(); - FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); - _outputFileRecorderPtr = NULL; - return -1; - } - _outputFileRecorderPtr->RegisterModuleFileCallback(this); - _outputFileRecording = true; + const CodecInst* codecInst) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartRecordingPlayout(fileName=%s)", fileName); + if (_outputFileRecording) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), + "StartRecordingPlayout() is already recording"); return 0; -} + } -int Channel::StartRecordingPlayout(OutStream* stream, - const CodecInst* codecInst) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::StartRecordingPlayout()"); + FileFormats format; + const uint32_t notificationTime(0); // Not supported in VoE + CodecInst dummyCodec = {100, "L16", 16000, 320, 1, 320000}; - if (_outputFileRecording) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), - "StartRecordingPlayout() is already recording"); - return 0; - } + if ((codecInst != NULL) && + ((codecInst->channels < 1) || (codecInst->channels > 2))) { + _engineStatisticsPtr->SetLastError( + VE_BAD_ARGUMENT, kTraceError, + "StartRecordingPlayout() invalid compression"); + return (-1); + } + if (codecInst == NULL) { + format = kFileFormatPcm16kHzFile; + codecInst = &dummyCodec; + } else if ((STR_CASE_CMP(codecInst->plname, "L16") == 0) || + (STR_CASE_CMP(codecInst->plname, "PCMU") == 0) || + (STR_CASE_CMP(codecInst->plname, "PCMA") == 0)) { + format = kFileFormatWavFile; + } else { + format = kFileFormatCompressedFile; + } - FileFormats format; - const uint32_t notificationTime(0); // Not supported in VoE - CodecInst dummyCodec={100,"L16",16000,320,1,320000}; + rtc::CritScope cs(&_fileCritSect); - if (codecInst != NULL && codecInst->channels != 1) - { - _engineStatisticsPtr->SetLastError( - VE_BAD_ARGUMENT, kTraceError, - "StartRecordingPlayout() invalid compression"); - return(-1); - } - if(codecInst == NULL) - { - format = kFileFormatPcm16kHzFile; - codecInst=&dummyCodec; - } - else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || - (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || - (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) - { - format = kFileFormatWavFile; - } - else - { - format = kFileFormatCompressedFile; - } - - rtc::CritScope cs(&_fileCritSect); - - // Destroy the old instance - if (_outputFileRecorderPtr) - { - _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); - FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); - _outputFileRecorderPtr = NULL; - } - - _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( - _outputFileRecorderId, (const FileFormats)format); - if (_outputFileRecorderPtr == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "StartRecordingPlayout() fileRecorder format isnot correct"); - return -1; - } - - if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst, - notificationTime) != 0) - { - _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, - "StartRecordingPlayout() failed to " - "start file recording"); - _outputFileRecorderPtr->StopRecording(); - FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); - _outputFileRecorderPtr = NULL; - return -1; - } - - _outputFileRecorderPtr->RegisterModuleFileCallback(this); - _outputFileRecording = true; - - return 0; -} - -int Channel::StopRecordingPlayout() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), - "Channel::StopRecordingPlayout()"); - - if (!_outputFileRecording) - { - WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), - "StopRecordingPlayout() isnot recording"); - return -1; - } - - - rtc::CritScope cs(&_fileCritSect); - - if (_outputFileRecorderPtr->StopRecording() != 0) - { - _engineStatisticsPtr->SetLastError( - VE_STOP_RECORDING_FAILED, kTraceError, - "StopRecording() could not stop recording"); - return(-1); - } + // Destroy the old instance + if (_outputFileRecorderPtr) { _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); _outputFileRecorderPtr = NULL; - _outputFileRecording = false; + } + _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( + _outputFileRecorderId, (const FileFormats)format); + if (_outputFileRecorderPtr == NULL) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "StartRecordingPlayout() fileRecorder format isnot correct"); + return -1; + } + + if (_outputFileRecorderPtr->StartRecordingAudioFile( + fileName, (const CodecInst&)*codecInst, notificationTime) != 0) { + _engineStatisticsPtr->SetLastError( + VE_BAD_FILE, kTraceError, + "StartRecordingAudioFile() failed to start file recording"); + _outputFileRecorderPtr->StopRecording(); + FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); + _outputFileRecorderPtr = NULL; + return -1; + } + _outputFileRecorderPtr->RegisterModuleFileCallback(this); + _outputFileRecording = true; + + return 0; +} + +int Channel::StartRecordingPlayout(OutStream* stream, + const CodecInst* codecInst) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::StartRecordingPlayout()"); + + if (_outputFileRecording) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), + "StartRecordingPlayout() is already recording"); return 0; + } + + FileFormats format; + const uint32_t notificationTime(0); // Not supported in VoE + CodecInst dummyCodec = {100, "L16", 16000, 320, 1, 320000}; + + if (codecInst != NULL && codecInst->channels != 1) { + _engineStatisticsPtr->SetLastError( + VE_BAD_ARGUMENT, kTraceError, + "StartRecordingPlayout() invalid compression"); + return (-1); + } + if (codecInst == NULL) { + format = kFileFormatPcm16kHzFile; + codecInst = &dummyCodec; + } else if ((STR_CASE_CMP(codecInst->plname, "L16") == 0) || + (STR_CASE_CMP(codecInst->plname, "PCMU") == 0) || + (STR_CASE_CMP(codecInst->plname, "PCMA") == 0)) { + format = kFileFormatWavFile; + } else { + format = kFileFormatCompressedFile; + } + + rtc::CritScope cs(&_fileCritSect); + + // Destroy the old instance + if (_outputFileRecorderPtr) { + _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); + FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); + _outputFileRecorderPtr = NULL; + } + + _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( + _outputFileRecorderId, (const FileFormats)format); + if (_outputFileRecorderPtr == NULL) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "StartRecordingPlayout() fileRecorder format isnot correct"); + return -1; + } + + if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst, + notificationTime) != 0) { + _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, + "StartRecordingPlayout() failed to " + "start file recording"); + _outputFileRecorderPtr->StopRecording(); + FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); + _outputFileRecorderPtr = NULL; + return -1; + } + + _outputFileRecorderPtr->RegisterModuleFileCallback(this); + _outputFileRecording = true; + + return 0; } -void -Channel::SetMixWithMicStatus(bool mix) -{ - rtc::CritScope cs(&_fileCritSect); - _mixFileWithMicrophone=mix; +int Channel::StopRecordingPlayout() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), + "Channel::StopRecordingPlayout()"); + + if (!_outputFileRecording) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1), + "StopRecordingPlayout() isnot recording"); + return -1; + } + + rtc::CritScope cs(&_fileCritSect); + + if (_outputFileRecorderPtr->StopRecording() != 0) { + _engineStatisticsPtr->SetLastError( + VE_STOP_RECORDING_FAILED, kTraceError, + "StopRecording() could not stop recording"); + return (-1); + } + _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); + FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); + _outputFileRecorderPtr = NULL; + _outputFileRecording = false; + + return 0; } -int -Channel::GetSpeechOutputLevel(uint32_t& level) const -{ - int8_t currentLevel = _outputAudioLevel.Level(); - level = static_cast (currentLevel); - return 0; +void Channel::SetMixWithMicStatus(bool mix) { + rtc::CritScope cs(&_fileCritSect); + _mixFileWithMicrophone = mix; } -int -Channel::GetSpeechOutputLevelFullRange(uint32_t& level) const -{ - int16_t currentLevel = _outputAudioLevel.LevelFullRange(); - level = static_cast (currentLevel); - return 0; +int Channel::GetSpeechOutputLevel(uint32_t& level) const { + int8_t currentLevel = _outputAudioLevel.Level(); + level = static_cast(currentLevel); + return 0; } -int -Channel::SetMute(bool enable) -{ - rtc::CritScope cs(&volume_settings_critsect_); - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), +int Channel::GetSpeechOutputLevelFullRange(uint32_t& level) const { + int16_t currentLevel = _outputAudioLevel.LevelFullRange(); + level = static_cast(currentLevel); + return 0; +} + +int Channel::SetMute(bool enable) { + rtc::CritScope cs(&volume_settings_critsect_); + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::SetMute(enable=%d)", enable); - _mute = enable; - return 0; + _mute = enable; + return 0; } -bool -Channel::Mute() const -{ - rtc::CritScope cs(&volume_settings_critsect_); - return _mute; +bool Channel::Mute() const { + rtc::CritScope cs(&volume_settings_critsect_); + return _mute; } -int -Channel::SetOutputVolumePan(float left, float right) -{ - rtc::CritScope cs(&volume_settings_critsect_); - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), +int Channel::SetOutputVolumePan(float left, float right) { + rtc::CritScope cs(&volume_settings_critsect_); + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::SetOutputVolumePan()"); - _panLeft = left; - _panRight = right; - return 0; + _panLeft = left; + _panRight = right; + return 0; } -int -Channel::GetOutputVolumePan(float& left, float& right) const -{ - rtc::CritScope cs(&volume_settings_critsect_); - left = _panLeft; - right = _panRight; - return 0; +int Channel::GetOutputVolumePan(float& left, float& right) const { + rtc::CritScope cs(&volume_settings_critsect_); + left = _panLeft; + right = _panRight; + return 0; } -int -Channel::SetChannelOutputVolumeScaling(float scaling) -{ - rtc::CritScope cs(&volume_settings_critsect_); - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), +int Channel::SetChannelOutputVolumeScaling(float scaling) { + rtc::CritScope cs(&volume_settings_critsect_); + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::SetChannelOutputVolumeScaling()"); - _outputGain = scaling; - return 0; + _outputGain = scaling; + return 0; } -int -Channel::GetChannelOutputVolumeScaling(float& scaling) const -{ - rtc::CritScope cs(&volume_settings_critsect_); - scaling = _outputGain; - return 0; +int Channel::GetChannelOutputVolumeScaling(float& scaling) const { + rtc::CritScope cs(&volume_settings_critsect_); + scaling = _outputGain; + return 0; } int Channel::SendTelephoneEventOutband(unsigned char eventCode, - int lengthMs, int attenuationDb, - bool playDtmfEvent) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + int lengthMs, + int attenuationDb, + bool playDtmfEvent) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)", playDtmfEvent); - if (!Sending()) { - return -1; - } + if (!Sending()) { + return -1; + } - _playOutbandDtmfEvent = playDtmfEvent; + _playOutbandDtmfEvent = playDtmfEvent; - if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, - attenuationDb) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_SEND_DTMF_FAILED, - kTraceWarning, - "SendTelephoneEventOutband() failed to send event"); - return -1; - } - return 0; + if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, + attenuationDb) != 0) { + _engineStatisticsPtr->SetLastError( + VE_SEND_DTMF_FAILED, kTraceWarning, + "SendTelephoneEventOutband() failed to send event"); + return -1; + } + return 0; } int Channel::SendTelephoneEventInband(unsigned char eventCode, - int lengthMs, - int attenuationDb, - bool playDtmfEvent) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + int lengthMs, + int attenuationDb, + bool playDtmfEvent) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", playDtmfEvent); - _playInbandDtmfEvent = playDtmfEvent; - _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); + _playInbandDtmfEvent = playDtmfEvent; + _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); - return 0; + return 0; } -int -Channel::SetSendTelephoneEventPayloadType(unsigned char type) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), +int Channel::SetSendTelephoneEventPayloadType(unsigned char type) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::SetSendTelephoneEventPayloadType()"); - if (type > 127) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "SetSendTelephoneEventPayloadType() invalid type"); - return -1; + if (type > 127) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "SetSendTelephoneEventPayloadType() invalid type"); + return -1; + } + CodecInst codec = {}; + codec.plfreq = 8000; + codec.pltype = type; + memcpy(codec.plname, "telephone-event", 16); + if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { + _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); + if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "SetSendTelephoneEventPayloadType() failed to register send" + "payload type"); + return -1; } - CodecInst codec = {}; - codec.plfreq = 8000; - codec.pltype = type; - memcpy(codec.plname, "telephone-event", 16); - if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) - { - _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); - if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "SetSendTelephoneEventPayloadType() failed to register send" - "payload type"); - return -1; - } - } - _sendTelephoneEventPayloadType = type; - return 0; + } + _sendTelephoneEventPayloadType = type; + return 0; } -int -Channel::GetSendTelephoneEventPayloadType(unsigned char& type) -{ - type = _sendTelephoneEventPayloadType; - return 0; +int Channel::GetSendTelephoneEventPayloadType(unsigned char& type) { + type = _sendTelephoneEventPayloadType; + return 0; } -int -Channel::UpdateRxVadDetection(AudioFrame& audioFrame) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::UpdateRxVadDetection()"); +int Channel::UpdateRxVadDetection(AudioFrame& audioFrame) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::UpdateRxVadDetection()"); - int vadDecision = 1; + int vadDecision = 1; - vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive)? 1 : 0; + vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive) ? 1 : 0; - if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) - { - OnRxVadDetected(vadDecision); - _oldVadDecision = vadDecision; - } + if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) { + OnRxVadDetected(vadDecision); + _oldVadDecision = vadDecision; + } - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::UpdateRxVadDetection() => vadDecision=%d", - vadDecision); - return 0; + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::UpdateRxVadDetection() => vadDecision=%d", + vadDecision); + return 0; } -int -Channel::RegisterRxVadObserver(VoERxVadCallback &observer) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::RegisterRxVadObserver()"); - rtc::CritScope cs(&_callbackCritSect); +int Channel::RegisterRxVadObserver(VoERxVadCallback& observer) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RegisterRxVadObserver()"); + rtc::CritScope cs(&_callbackCritSect); - if (_rxVadObserverPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceError, - "RegisterRxVadObserver() observer already enabled"); - return -1; - } - _rxVadObserverPtr = &observer; - _RxVadDetection = true; - return 0; + if (_rxVadObserverPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceError, + "RegisterRxVadObserver() observer already enabled"); + return -1; + } + _rxVadObserverPtr = &observer; + _RxVadDetection = true; + return 0; } -int -Channel::DeRegisterRxVadObserver() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::DeRegisterRxVadObserver()"); - rtc::CritScope cs(&_callbackCritSect); +int Channel::DeRegisterRxVadObserver() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::DeRegisterRxVadObserver()"); + rtc::CritScope cs(&_callbackCritSect); - if (!_rxVadObserverPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceWarning, - "DeRegisterRxVadObserver() observer already disabled"); - return 0; - } - _rxVadObserverPtr = NULL; - _RxVadDetection = false; + if (!_rxVadObserverPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceWarning, + "DeRegisterRxVadObserver() observer already disabled"); return 0; + } + _rxVadObserverPtr = NULL; + _RxVadDetection = false; + return 0; } -int -Channel::VoiceActivityIndicator(int &activity) -{ - activity = _sendFrameType; - return 0; +int Channel::VoiceActivityIndicator(int& activity) { + activity = _sendFrameType; + return 0; } #ifdef WEBRTC_VOICE_ENGINE_AGC -int -Channel::SetRxAgcStatus(bool enable, AgcModes mode) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetRxAgcStatus(enable=%d, mode=%d)", - (int)enable, (int)mode); +int Channel::SetRxAgcStatus(bool enable, AgcModes mode) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetRxAgcStatus(enable=%d, mode=%d)", (int)enable, + (int)mode); - GainControl::Mode agcMode = kDefaultRxAgcMode; - switch (mode) - { - case kAgcDefault: - break; - case kAgcUnchanged: - agcMode = rx_audioproc_->gain_control()->mode(); - break; - case kAgcFixedDigital: - agcMode = GainControl::kFixedDigital; - break; - case kAgcAdaptiveDigital: - agcMode =GainControl::kAdaptiveDigital; - break; - default: - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "SetRxAgcStatus() invalid Agc mode"); - return -1; - } + GainControl::Mode agcMode = kDefaultRxAgcMode; + switch (mode) { + case kAgcDefault: + break; + case kAgcUnchanged: + agcMode = rx_audioproc_->gain_control()->mode(); + break; + case kAgcFixedDigital: + agcMode = GainControl::kFixedDigital; + break; + case kAgcAdaptiveDigital: + agcMode = GainControl::kAdaptiveDigital; + break; + default: + _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, + "SetRxAgcStatus() invalid Agc mode"); + return -1; + } - if (rx_audioproc_->gain_control()->set_mode(agcMode) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "SetRxAgcStatus() failed to set Agc mode"); - return -1; - } - if (rx_audioproc_->gain_control()->Enable(enable) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "SetRxAgcStatus() failed to set Agc state"); - return -1; - } + if (rx_audioproc_->gain_control()->set_mode(agcMode) != 0) { + _engineStatisticsPtr->SetLastError( + VE_APM_ERROR, kTraceError, "SetRxAgcStatus() failed to set Agc mode"); + return -1; + } + if (rx_audioproc_->gain_control()->Enable(enable) != 0) { + _engineStatisticsPtr->SetLastError( + VE_APM_ERROR, kTraceError, "SetRxAgcStatus() failed to set Agc state"); + return -1; + } - _rxAgcIsEnabled = enable; - channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); + _rxAgcIsEnabled = enable; + channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); - return 0; + return 0; } -int -Channel::GetRxAgcStatus(bool& enabled, AgcModes& mode) -{ - bool enable = rx_audioproc_->gain_control()->is_enabled(); - GainControl::Mode agcMode = - rx_audioproc_->gain_control()->mode(); +int Channel::GetRxAgcStatus(bool& enabled, AgcModes& mode) { + bool enable = rx_audioproc_->gain_control()->is_enabled(); + GainControl::Mode agcMode = rx_audioproc_->gain_control()->mode(); - enabled = enable; + enabled = enable; - switch (agcMode) - { - case GainControl::kFixedDigital: - mode = kAgcFixedDigital; - break; - case GainControl::kAdaptiveDigital: - mode = kAgcAdaptiveDigital; - break; - default: - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "GetRxAgcStatus() invalid Agc mode"); - return -1; - } + switch (agcMode) { + case GainControl::kFixedDigital: + mode = kAgcFixedDigital; + break; + case GainControl::kAdaptiveDigital: + mode = kAgcAdaptiveDigital; + break; + default: + _engineStatisticsPtr->SetLastError(VE_APM_ERROR, kTraceError, + "GetRxAgcStatus() invalid Agc mode"); + return -1; + } - return 0; + return 0; } -int -Channel::SetRxAgcConfig(AgcConfig config) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetRxAgcConfig()"); +int Channel::SetRxAgcConfig(AgcConfig config) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetRxAgcConfig()"); - if (rx_audioproc_->gain_control()->set_target_level_dbfs( - config.targetLeveldBOv) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "SetRxAgcConfig() failed to set target peak |level|" - "(or envelope) of the Agc"); - return -1; - } - if (rx_audioproc_->gain_control()->set_compression_gain_db( - config.digitalCompressionGaindB) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "SetRxAgcConfig() failed to set the range in |gain| the" - " digital compression stage may apply"); - return -1; - } - if (rx_audioproc_->gain_control()->enable_limiter( - config.limiterEnable) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "SetRxAgcConfig() failed to set hard limiter to the signal"); - return -1; - } + if (rx_audioproc_->gain_control()->set_target_level_dbfs( + config.targetLeveldBOv) != 0) { + _engineStatisticsPtr->SetLastError( + VE_APM_ERROR, kTraceError, + "SetRxAgcConfig() failed to set target peak |level|" + "(or envelope) of the Agc"); + return -1; + } + if (rx_audioproc_->gain_control()->set_compression_gain_db( + config.digitalCompressionGaindB) != 0) { + _engineStatisticsPtr->SetLastError( + VE_APM_ERROR, kTraceError, + "SetRxAgcConfig() failed to set the range in |gain| the" + " digital compression stage may apply"); + return -1; + } + if (rx_audioproc_->gain_control()->enable_limiter(config.limiterEnable) != + 0) { + _engineStatisticsPtr->SetLastError( + VE_APM_ERROR, kTraceError, + "SetRxAgcConfig() failed to set hard limiter to the signal"); + return -1; + } - return 0; + return 0; } -int -Channel::GetRxAgcConfig(AgcConfig& config) -{ - config.targetLeveldBOv = - rx_audioproc_->gain_control()->target_level_dbfs(); - config.digitalCompressionGaindB = - rx_audioproc_->gain_control()->compression_gain_db(); - config.limiterEnable = - rx_audioproc_->gain_control()->is_limiter_enabled(); +int Channel::GetRxAgcConfig(AgcConfig& config) { + config.targetLeveldBOv = rx_audioproc_->gain_control()->target_level_dbfs(); + config.digitalCompressionGaindB = + rx_audioproc_->gain_control()->compression_gain_db(); + config.limiterEnable = rx_audioproc_->gain_control()->is_limiter_enabled(); - return 0; + return 0; } -#endif // #ifdef WEBRTC_VOICE_ENGINE_AGC +#endif // #ifdef WEBRTC_VOICE_ENGINE_AGC #ifdef WEBRTC_VOICE_ENGINE_NR -int -Channel::SetRxNsStatus(bool enable, NsModes mode) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetRxNsStatus(enable=%d, mode=%d)", - (int)enable, (int)mode); +int Channel::SetRxNsStatus(bool enable, NsModes mode) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetRxNsStatus(enable=%d, mode=%d)", (int)enable, + (int)mode); - NoiseSuppression::Level nsLevel = kDefaultNsMode; - switch (mode) - { + NoiseSuppression::Level nsLevel = kDefaultNsMode; + switch (mode) { + case kNsDefault: + break; + case kNsUnchanged: + nsLevel = rx_audioproc_->noise_suppression()->level(); + break; + case kNsConference: + nsLevel = NoiseSuppression::kHigh; + break; + case kNsLowSuppression: + nsLevel = NoiseSuppression::kLow; + break; + case kNsModerateSuppression: + nsLevel = NoiseSuppression::kModerate; + break; + case kNsHighSuppression: + nsLevel = NoiseSuppression::kHigh; + break; + case kNsVeryHighSuppression: + nsLevel = NoiseSuppression::kVeryHigh; + break; + } - case kNsDefault: - break; - case kNsUnchanged: - nsLevel = rx_audioproc_->noise_suppression()->level(); - break; - case kNsConference: - nsLevel = NoiseSuppression::kHigh; - break; - case kNsLowSuppression: - nsLevel = NoiseSuppression::kLow; - break; - case kNsModerateSuppression: - nsLevel = NoiseSuppression::kModerate; - break; - case kNsHighSuppression: - nsLevel = NoiseSuppression::kHigh; - break; - case kNsVeryHighSuppression: - nsLevel = NoiseSuppression::kVeryHigh; - break; - } + if (rx_audioproc_->noise_suppression()->set_level(nsLevel) != 0) { + _engineStatisticsPtr->SetLastError( + VE_APM_ERROR, kTraceError, "SetRxNsStatus() failed to set NS level"); + return -1; + } + if (rx_audioproc_->noise_suppression()->Enable(enable) != 0) { + _engineStatisticsPtr->SetLastError( + VE_APM_ERROR, kTraceError, "SetRxNsStatus() failed to set NS state"); + return -1; + } - if (rx_audioproc_->noise_suppression()->set_level(nsLevel) - != 0) - { - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "SetRxNsStatus() failed to set NS level"); - return -1; - } - if (rx_audioproc_->noise_suppression()->Enable(enable) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_APM_ERROR, kTraceError, - "SetRxNsStatus() failed to set NS state"); - return -1; - } + _rxNsIsEnabled = enable; + channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); - _rxNsIsEnabled = enable; - channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); - - return 0; + return 0; } -int -Channel::GetRxNsStatus(bool& enabled, NsModes& mode) -{ - bool enable = - rx_audioproc_->noise_suppression()->is_enabled(); - NoiseSuppression::Level ncLevel = - rx_audioproc_->noise_suppression()->level(); +int Channel::GetRxNsStatus(bool& enabled, NsModes& mode) { + bool enable = rx_audioproc_->noise_suppression()->is_enabled(); + NoiseSuppression::Level ncLevel = rx_audioproc_->noise_suppression()->level(); - enabled = enable; + enabled = enable; - switch (ncLevel) - { - case NoiseSuppression::kLow: - mode = kNsLowSuppression; - break; - case NoiseSuppression::kModerate: - mode = kNsModerateSuppression; - break; - case NoiseSuppression::kHigh: - mode = kNsHighSuppression; - break; - case NoiseSuppression::kVeryHigh: - mode = kNsVeryHighSuppression; - break; - } + switch (ncLevel) { + case NoiseSuppression::kLow: + mode = kNsLowSuppression; + break; + case NoiseSuppression::kModerate: + mode = kNsModerateSuppression; + break; + case NoiseSuppression::kHigh: + mode = kNsHighSuppression; + break; + case NoiseSuppression::kVeryHigh: + mode = kNsVeryHighSuppression; + break; + } - return 0; + return 0; } -#endif // #ifdef WEBRTC_VOICE_ENGINE_NR +#endif // #ifdef WEBRTC_VOICE_ENGINE_NR -int -Channel::SetLocalSSRC(unsigned int ssrc) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), - "Channel::SetLocalSSRC()"); - if (channel_state_.Get().sending) - { - _engineStatisticsPtr->SetLastError( - VE_ALREADY_SENDING, kTraceError, - "SetLocalSSRC() already sending"); - return -1; - } - _rtpRtcpModule->SetSSRC(ssrc); - return 0; +int Channel::SetLocalSSRC(unsigned int ssrc) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetLocalSSRC()"); + if (channel_state_.Get().sending) { + _engineStatisticsPtr->SetLastError(VE_ALREADY_SENDING, kTraceError, + "SetLocalSSRC() already sending"); + return -1; + } + _rtpRtcpModule->SetSSRC(ssrc); + return 0; } -int -Channel::GetLocalSSRC(unsigned int& ssrc) -{ - ssrc = _rtpRtcpModule->SSRC(); - return 0; +int Channel::GetLocalSSRC(unsigned int& ssrc) { + ssrc = _rtpRtcpModule->SSRC(); + return 0; } -int -Channel::GetRemoteSSRC(unsigned int& ssrc) -{ - ssrc = rtp_receiver_->SSRC(); - return 0; +int Channel::GetRemoteSSRC(unsigned int& ssrc) { + ssrc = rtp_receiver_->SSRC(); + return 0; } int Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) { @@ -2881,10 +2544,10 @@ int Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) { int Channel::SetReceiveAudioLevelIndicationStatus(bool enable, unsigned char id) { - rtp_header_parser_->DeregisterRtpHeaderExtension( - kRtpExtensionAudioLevel); - if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension( - kRtpExtensionAudioLevel, id)) { + rtp_header_parser_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel); + if (enable && + !rtp_header_parser_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel, + id)) { return -1; } return 0; @@ -2897,8 +2560,9 @@ int Channel::SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id) { int Channel::SetReceiveAbsoluteSenderTimeStatus(bool enable, unsigned char id) { rtp_header_parser_->DeregisterRtpHeaderExtension( kRtpExtensionAbsoluteSendTime); - if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime, id)) { + if (enable && + !rtp_header_parser_->RegisterRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime, id)) { return -1; } return 0; @@ -2950,218 +2614,193 @@ void Channel::SetRTCPStatus(bool enable) { _rtpRtcpModule->SetRTCPStatus(enable ? RtcpMode::kCompound : RtcpMode::kOff); } -int -Channel::GetRTCPStatus(bool& enabled) -{ +int Channel::GetRTCPStatus(bool& enabled) { RtcpMode method = _rtpRtcpModule->RTCP(); enabled = (method != RtcpMode::kOff); - return 0; + return 0; } -int -Channel::SetRTCP_CNAME(const char cName[256]) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), - "Channel::SetRTCP_CNAME()"); - if (_rtpRtcpModule->SetCNAME(cName) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "SetRTCP_CNAME() failed to set RTCP CNAME"); - return -1; - } - return 0; +int Channel::SetRTCP_CNAME(const char cName[256]) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetRTCP_CNAME()"); + if (_rtpRtcpModule->SetCNAME(cName) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "SetRTCP_CNAME() failed to set RTCP CNAME"); + return -1; + } + return 0; } -int -Channel::GetRemoteRTCP_CNAME(char cName[256]) -{ - if (cName == NULL) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "GetRemoteRTCP_CNAME() invalid CNAME input buffer"); - return -1; - } - char cname[RTCP_CNAME_SIZE]; - const uint32_t remoteSSRC = rtp_receiver_->SSRC(); - if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_CANNOT_RETRIEVE_CNAME, kTraceError, - "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME"); - return -1; - } - strcpy(cName, cname); - return 0; +int Channel::GetRemoteRTCP_CNAME(char cName[256]) { + if (cName == NULL) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "GetRemoteRTCP_CNAME() invalid CNAME input buffer"); + return -1; + } + char cname[RTCP_CNAME_SIZE]; + const uint32_t remoteSSRC = rtp_receiver_->SSRC(); + if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) { + _engineStatisticsPtr->SetLastError( + VE_CANNOT_RETRIEVE_CNAME, kTraceError, + "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME"); + return -1; + } + strcpy(cName, cname); + return 0; } -int -Channel::GetRemoteRTCPData( - unsigned int& NTPHigh, - unsigned int& NTPLow, - unsigned int& timestamp, - unsigned int& playoutTimestamp, - unsigned int* jitter, - unsigned short* fractionLost) -{ - // --- Information from sender info in received Sender Reports +int Channel::GetRemoteRTCPData(unsigned int& NTPHigh, + unsigned int& NTPLow, + unsigned int& timestamp, + unsigned int& playoutTimestamp, + unsigned int* jitter, + unsigned short* fractionLost) { + // --- Information from sender info in received Sender Reports - RTCPSenderInfo senderInfo; - if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "GetRemoteRTCPData() failed to retrieve sender info for remote " - "side"); - return -1; + RTCPSenderInfo senderInfo; + if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "GetRemoteRTCPData() failed to retrieve sender info for remote " + "side"); + return -1; + } + + // We only utilize 12 out of 20 bytes in the sender info (ignores packet + // and octet count) + NTPHigh = senderInfo.NTPseconds; + NTPLow = senderInfo.NTPfraction; + timestamp = senderInfo.RTPtimeStamp; + + // --- Locally derived information + + // This value is updated on each incoming RTCP packet (0 when no packet + // has been received) + playoutTimestamp = playout_timestamp_rtcp_; + + if (NULL != jitter || NULL != fractionLost) { + // Get all RTCP receiver report blocks that have been received on this + // channel. If we receive RTP packets from a remote source we know the + // remote SSRC and use the report block from him. + // Otherwise use the first report block. + std::vector remote_stats; + if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || + remote_stats.empty()) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "GetRemoteRTCPData() failed to measure statistics due" + " to lack of received RTP and/or RTCP packets"); + return -1; } - // We only utilize 12 out of 20 bytes in the sender info (ignores packet - // and octet count) - NTPHigh = senderInfo.NTPseconds; - NTPLow = senderInfo.NTPfraction; - timestamp = senderInfo.RTPtimeStamp; - - // --- Locally derived information - - // This value is updated on each incoming RTCP packet (0 when no packet - // has been received) - playoutTimestamp = playout_timestamp_rtcp_; - - if (NULL != jitter || NULL != fractionLost) - { - // Get all RTCP receiver report blocks that have been received on this - // channel. If we receive RTP packets from a remote source we know the - // remote SSRC and use the report block from him. - // Otherwise use the first report block. - std::vector remote_stats; - if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || - remote_stats.empty()) { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "GetRemoteRTCPData() failed to measure statistics due" - " to lack of received RTP and/or RTCP packets"); - return -1; - } - - uint32_t remoteSSRC = rtp_receiver_->SSRC(); - std::vector::const_iterator it = remote_stats.begin(); - for (; it != remote_stats.end(); ++it) { - if (it->remoteSSRC == remoteSSRC) - break; - } - - if (it == remote_stats.end()) { - // If we have not received any RTCP packets from this SSRC it probably - // means that we have not received any RTP packets. - // Use the first received report block instead. - it = remote_stats.begin(); - remoteSSRC = it->remoteSSRC; - } - - if (jitter) { - *jitter = it->jitter; - } - - if (fractionLost) { - *fractionLost = it->fractionLost; - } + uint32_t remoteSSRC = rtp_receiver_->SSRC(); + std::vector::const_iterator it = remote_stats.begin(); + for (; it != remote_stats.end(); ++it) { + if (it->remoteSSRC == remoteSSRC) + break; } - return 0; + + if (it == remote_stats.end()) { + // If we have not received any RTCP packets from this SSRC it probably + // means that we have not received any RTP packets. + // Use the first received report block instead. + it = remote_stats.begin(); + remoteSSRC = it->remoteSSRC; + } + + if (jitter) { + *jitter = it->jitter; + } + + if (fractionLost) { + *fractionLost = it->fractionLost; + } + } + return 0; } -int -Channel::SendApplicationDefinedRTCPPacket(unsigned char subType, - unsigned int name, - const char* data, - unsigned short dataLengthInBytes) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), - "Channel::SendApplicationDefinedRTCPPacket()"); - if (!channel_state_.Get().sending) - { - _engineStatisticsPtr->SetLastError( - VE_NOT_SENDING, kTraceError, - "SendApplicationDefinedRTCPPacket() not sending"); - return -1; - } - if (NULL == data) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "SendApplicationDefinedRTCPPacket() invalid data value"); - return -1; - } - if (dataLengthInBytes % 4 != 0) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "SendApplicationDefinedRTCPPacket() invalid length value"); - return -1; - } - RtcpMode status = _rtpRtcpModule->RTCP(); - if (status == RtcpMode::kOff) { - _engineStatisticsPtr->SetLastError( - VE_RTCP_ERROR, kTraceError, - "SendApplicationDefinedRTCPPacket() RTCP is disabled"); - return -1; - } +int Channel::SendApplicationDefinedRTCPPacket( + unsigned char subType, + unsigned int name, + const char* data, + unsigned short dataLengthInBytes) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SendApplicationDefinedRTCPPacket()"); + if (!channel_state_.Get().sending) { + _engineStatisticsPtr->SetLastError( + VE_NOT_SENDING, kTraceError, + "SendApplicationDefinedRTCPPacket() not sending"); + return -1; + } + if (NULL == data) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "SendApplicationDefinedRTCPPacket() invalid data value"); + return -1; + } + if (dataLengthInBytes % 4 != 0) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "SendApplicationDefinedRTCPPacket() invalid length value"); + return -1; + } + RtcpMode status = _rtpRtcpModule->RTCP(); + if (status == RtcpMode::kOff) { + _engineStatisticsPtr->SetLastError( + VE_RTCP_ERROR, kTraceError, + "SendApplicationDefinedRTCPPacket() RTCP is disabled"); + return -1; + } - // Create and schedule the RTCP APP packet for transmission - if (_rtpRtcpModule->SetRTCPApplicationSpecificData( - subType, - name, - (const unsigned char*) data, - dataLengthInBytes) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_SEND_ERROR, kTraceError, - "SendApplicationDefinedRTCPPacket() failed to send RTCP packet"); - return -1; - } - return 0; + // Create and schedule the RTCP APP packet for transmission + if (_rtpRtcpModule->SetRTCPApplicationSpecificData( + subType, name, (const unsigned char*)data, dataLengthInBytes) != 0) { + _engineStatisticsPtr->SetLastError( + VE_SEND_ERROR, kTraceError, + "SendApplicationDefinedRTCPPacket() failed to send RTCP packet"); + return -1; + } + return 0; } -int -Channel::GetRTPStatistics( - unsigned int& averageJitterMs, - unsigned int& maxJitterMs, - unsigned int& discardedPackets) -{ - // The jitter statistics is updated for each received RTP packet and is - // based on received packets. - if (_rtpRtcpModule->RTCP() == RtcpMode::kOff) { - // If RTCP is off, there is no timed thread in the RTCP module regularly - // generating new stats, trigger the update manually here instead. - StreamStatistician* statistician = - rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); - if (statistician) { - // Don't use returned statistics, use data from proxy instead so that - // max jitter can be fetched atomically. - RtcpStatistics s; - statistician->GetStatistics(&s, true); - } +int Channel::GetRTPStatistics(unsigned int& averageJitterMs, + unsigned int& maxJitterMs, + unsigned int& discardedPackets) { + // The jitter statistics is updated for each received RTP packet and is + // based on received packets. + if (_rtpRtcpModule->RTCP() == RtcpMode::kOff) { + // If RTCP is off, there is no timed thread in the RTCP module regularly + // generating new stats, trigger the update manually here instead. + StreamStatistician* statistician = + rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); + if (statistician) { + // Don't use returned statistics, use data from proxy instead so that + // max jitter can be fetched atomically. + RtcpStatistics s; + statistician->GetStatistics(&s, true); } + } - ChannelStatistics stats = statistics_proxy_->GetStats(); - const int32_t playoutFrequency = audio_coding_->PlayoutFrequency(); - if (playoutFrequency > 0) { - // Scale RTP statistics given the current playout frequency - maxJitterMs = stats.max_jitter / (playoutFrequency / 1000); - averageJitterMs = stats.rtcp.jitter / (playoutFrequency / 1000); - } + ChannelStatistics stats = statistics_proxy_->GetStats(); + const int32_t playoutFrequency = audio_coding_->PlayoutFrequency(); + if (playoutFrequency > 0) { + // Scale RTP statistics given the current playout frequency + maxJitterMs = stats.max_jitter / (playoutFrequency / 1000); + averageJitterMs = stats.rtcp.jitter / (playoutFrequency / 1000); + } - discardedPackets = _numberOfDiscardedPackets; + discardedPackets = _numberOfDiscardedPackets; - return 0; + return 0; } int Channel::GetRemoteRTCPReportBlocks( std::vector* report_blocks) { if (report_blocks == NULL) { - _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, - "GetRemoteRTCPReportBlock()s invalid report_blocks."); + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "GetRemoteRTCPReportBlock()s invalid report_blocks."); return -1; } @@ -3192,64 +2831,59 @@ int Channel::GetRemoteRTCPReportBlocks( return 0; } -int -Channel::GetRTPStatistics(CallStatistics& stats) -{ - // --- RtcpStatistics +int Channel::GetRTPStatistics(CallStatistics& stats) { + // --- RtcpStatistics - // The jitter statistics is updated for each received RTP packet and is - // based on received packets. - RtcpStatistics statistics; - StreamStatistician* statistician = - rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); - if (!statistician || - !statistician->GetStatistics( - &statistics, _rtpRtcpModule->RTCP() == RtcpMode::kOff)) { - _engineStatisticsPtr->SetLastError( - VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, - "GetRTPStatistics() failed to read RTP statistics from the " - "RTP/RTCP module"); - } + // The jitter statistics is updated for each received RTP packet and is + // based on received packets. + RtcpStatistics statistics; + StreamStatistician* statistician = + rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); + if (!statistician || + !statistician->GetStatistics(&statistics, + _rtpRtcpModule->RTCP() == RtcpMode::kOff)) { + _engineStatisticsPtr->SetLastError( + VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, + "GetRTPStatistics() failed to read RTP statistics from the " + "RTP/RTCP module"); + } - stats.fractionLost = statistics.fraction_lost; - stats.cumulativeLost = statistics.cumulative_lost; - stats.extendedMax = statistics.extended_max_sequence_number; - stats.jitterSamples = statistics.jitter; + stats.fractionLost = statistics.fraction_lost; + stats.cumulativeLost = statistics.cumulative_lost; + stats.extendedMax = statistics.extended_max_sequence_number; + stats.jitterSamples = statistics.jitter; - // --- RTT - stats.rttMs = GetRTT(true); + // --- RTT + stats.rttMs = GetRTT(true); - // --- Data counters + // --- Data counters - size_t bytesSent(0); - uint32_t packetsSent(0); - size_t bytesReceived(0); - uint32_t packetsReceived(0); + size_t bytesSent(0); + uint32_t packetsSent(0); + size_t bytesReceived(0); + uint32_t packetsReceived(0); - if (statistician) { - statistician->GetDataCounters(&bytesReceived, &packetsReceived); - } + if (statistician) { + statistician->GetDataCounters(&bytesReceived, &packetsReceived); + } - if (_rtpRtcpModule->DataCountersRTP(&bytesSent, - &packetsSent) != 0) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "GetRTPStatistics() failed to retrieve RTP datacounters =>" - " output will not be complete"); - } + if (_rtpRtcpModule->DataCountersRTP(&bytesSent, &packetsSent) != 0) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "GetRTPStatistics() failed to retrieve RTP datacounters =>" + " output will not be complete"); + } - stats.bytesSent = bytesSent; - stats.packetsSent = packetsSent; - stats.bytesReceived = bytesReceived; - stats.packetsReceived = packetsReceived; + stats.bytesSent = bytesSent; + stats.packetsSent = packetsSent; + stats.bytesReceived = bytesReceived; + stats.packetsReceived = packetsReceived; - // --- Timestamps - { - rtc::CritScope lock(&ts_stats_lock_); - stats.capture_start_ntp_time_ms_ = capture_start_ntp_time_ms_; - } - return 0; + // --- Timestamps + { + rtc::CritScope lock(&ts_stats_lock_); + stats.capture_start_ntp_time_ms_ = capture_start_ntp_time_ms_; + } + return 0; } int Channel::SetREDStatus(bool enable, int redPayloadtype) { @@ -3281,24 +2915,21 @@ int Channel::SetREDStatus(bool enable, int redPayloadtype) { return 0; } -int -Channel::GetREDStatus(bool& enabled, int& redPayloadtype) -{ - enabled = audio_coding_->REDStatus(); - if (enabled) - { - int8_t payloadType = 0; - if (_rtpRtcpModule->SendREDPayloadType(&payloadType) != 0) { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "GetREDStatus() failed to retrieve RED PT from RTP/RTCP " - "module"); - return -1; - } - redPayloadtype = payloadType; - return 0; +int Channel::GetREDStatus(bool& enabled, int& redPayloadtype) { + enabled = audio_coding_->REDStatus(); + if (enabled) { + int8_t payloadType = 0; + if (_rtpRtcpModule->SendREDPayloadType(&payloadType) != 0) { + _engineStatisticsPtr->SetLastError( + VE_RTP_RTCP_MODULE_ERROR, kTraceError, + "GetREDStatus() failed to retrieve RED PT from RTP/RTCP " + "module"); + return -1; } + redPayloadtype = payloadType; return 0; + } + return 0; } int Channel::SetCodecFECStatus(bool enable) { @@ -3337,14 +2968,12 @@ int Channel::ResendPackets(const uint16_t* sequence_numbers, int length) { return _rtpRtcpModule->SendNACK(sequence_numbers, length); } -uint32_t -Channel::Demultiplex(const AudioFrame& audioFrame) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::Demultiplex()"); - _audioFrame.CopyFrom(audioFrame); - _audioFrame.id_ = _channelId; - return 0; +uint32_t Channel::Demultiplex(const AudioFrame& audioFrame) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::Demultiplex()"); + _audioFrame.CopyFrom(audioFrame); + _audioFrame.id_ = _channelId; + return 0; } void Channel::Demultiplex(const int16_t* audio_data, @@ -3362,92 +2991,79 @@ void Channel::Demultiplex(const int16_t* audio_data, sample_rate, &input_resampler_, &_audioFrame); } -uint32_t -Channel::PrepareEncodeAndSend(int mixingFrequency) -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::PrepareEncodeAndSend()"); +uint32_t Channel::PrepareEncodeAndSend(int mixingFrequency) { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::PrepareEncodeAndSend()"); - if (_audioFrame.samples_per_channel_ == 0) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::PrepareEncodeAndSend() invalid audio frame"); - return 0xFFFFFFFF; + if (_audioFrame.samples_per_channel_ == 0) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::PrepareEncodeAndSend() invalid audio frame"); + return 0xFFFFFFFF; + } + + if (channel_state_.Get().input_file_playing) { + MixOrReplaceAudioWithFile(mixingFrequency); + } + + bool is_muted = Mute(); // Cache locally as Mute() takes a lock. + if (is_muted) { + AudioFrameOperations::Mute(_audioFrame); + } + + if (channel_state_.Get().input_external_media) { + rtc::CritScope cs(&_callbackCritSect); + const bool isStereo = (_audioFrame.num_channels_ == 2); + if (_inputExternalMediaCallbackPtr) { + _inputExternalMediaCallbackPtr->Process( + _channelId, kRecordingPerChannel, (int16_t*)_audioFrame.data_, + _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_, + isStereo); } + } - if (channel_state_.Get().input_file_playing) - { - MixOrReplaceAudioWithFile(mixingFrequency); - } + InsertInbandDtmfTone(); - bool is_muted = Mute(); // Cache locally as Mute() takes a lock. + if (_includeAudioLevelIndication) { + size_t length = + _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; if (is_muted) { - AudioFrameOperations::Mute(_audioFrame); + rms_level_.ProcessMuted(length); + } else { + rms_level_.Process(_audioFrame.data_, length); } + } - if (channel_state_.Get().input_external_media) - { - rtc::CritScope cs(&_callbackCritSect); - const bool isStereo = (_audioFrame.num_channels_ == 2); - if (_inputExternalMediaCallbackPtr) - { - _inputExternalMediaCallbackPtr->Process( - _channelId, - kRecordingPerChannel, - (int16_t*)_audioFrame.data_, - _audioFrame.samples_per_channel_, - _audioFrame.sample_rate_hz_, - isStereo); - } - } - - InsertInbandDtmfTone(); - - if (_includeAudioLevelIndication) { - size_t length = - _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; - if (is_muted) { - rms_level_.ProcessMuted(length); - } else { - rms_level_.Process(_audioFrame.data_, length); - } - } - - return 0; + return 0; } -uint32_t -Channel::EncodeAndSend() -{ - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::EncodeAndSend()"); +uint32_t Channel::EncodeAndSend() { + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::EncodeAndSend()"); - assert(_audioFrame.num_channels_ <= 2); - if (_audioFrame.samples_per_channel_ == 0) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::EncodeAndSend() invalid audio frame"); - return 0xFFFFFFFF; - } + assert(_audioFrame.num_channels_ <= 2); + if (_audioFrame.samples_per_channel_ == 0) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::EncodeAndSend() invalid audio frame"); + return 0xFFFFFFFF; + } - _audioFrame.id_ = _channelId; + _audioFrame.id_ = _channelId; - // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz. + // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz. - // The ACM resamples internally. - _audioFrame.timestamp_ = _timeStamp; - // This call will trigger AudioPacketizationCallback::SendData if encoding - // is done and payload is ready for packetization and transmission. - // Otherwise, it will return without invoking the callback. - if (audio_coding_->Add10MsData((AudioFrame&)_audioFrame) < 0) - { - WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::EncodeAndSend() ACM encoding failed"); - return 0xFFFFFFFF; - } + // The ACM resamples internally. + _audioFrame.timestamp_ = _timeStamp; + // This call will trigger AudioPacketizationCallback::SendData if encoding + // is done and payload is ready for packetization and transmission. + // Otherwise, it will return without invoking the callback. + if (audio_coding_->Add10MsData((AudioFrame&)_audioFrame) < 0) { + WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::EncodeAndSend() ACM encoding failed"); + return 0xFFFFFFFF; + } - _timeStamp += static_cast(_audioFrame.samples_per_channel_); - return 0; + _timeStamp += static_cast(_audioFrame.samples_per_channel_); + return 0; } void Channel::DisassociateSendChannel(int channel_id) { @@ -3461,103 +3077,87 @@ void Channel::DisassociateSendChannel(int channel_id) { } } -int Channel::RegisterExternalMediaProcessing( - ProcessingTypes type, - VoEMediaProcess& processObject) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::RegisterExternalMediaProcessing()"); +int Channel::RegisterExternalMediaProcessing(ProcessingTypes type, + VoEMediaProcess& processObject) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RegisterExternalMediaProcessing()"); - rtc::CritScope cs(&_callbackCritSect); + rtc::CritScope cs(&_callbackCritSect); - if (kPlaybackPerChannel == type) - { - if (_outputExternalMediaCallbackPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceError, - "Channel::RegisterExternalMediaProcessing() " - "output external media already enabled"); - return -1; - } - _outputExternalMediaCallbackPtr = &processObject; - _outputExternalMedia = true; + if (kPlaybackPerChannel == type) { + if (_outputExternalMediaCallbackPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceError, + "Channel::RegisterExternalMediaProcessing() " + "output external media already enabled"); + return -1; } - else if (kRecordingPerChannel == type) - { - if (_inputExternalMediaCallbackPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceError, - "Channel::RegisterExternalMediaProcessing() " - "output external media already enabled"); - return -1; - } - _inputExternalMediaCallbackPtr = &processObject; - channel_state_.SetInputExternalMedia(true); + _outputExternalMediaCallbackPtr = &processObject; + _outputExternalMedia = true; + } else if (kRecordingPerChannel == type) { + if (_inputExternalMediaCallbackPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceError, + "Channel::RegisterExternalMediaProcessing() " + "output external media already enabled"); + return -1; } - return 0; + _inputExternalMediaCallbackPtr = &processObject; + channel_state_.SetInputExternalMedia(true); + } + return 0; } -int Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::DeRegisterExternalMediaProcessing()"); +int Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::DeRegisterExternalMediaProcessing()"); - rtc::CritScope cs(&_callbackCritSect); + rtc::CritScope cs(&_callbackCritSect); - if (kPlaybackPerChannel == type) - { - if (!_outputExternalMediaCallbackPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceWarning, - "Channel::DeRegisterExternalMediaProcessing() " - "output external media already disabled"); - return 0; - } - _outputExternalMedia = false; - _outputExternalMediaCallbackPtr = NULL; + if (kPlaybackPerChannel == type) { + if (!_outputExternalMediaCallbackPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceWarning, + "Channel::DeRegisterExternalMediaProcessing() " + "output external media already disabled"); + return 0; } - else if (kRecordingPerChannel == type) - { - if (!_inputExternalMediaCallbackPtr) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceWarning, - "Channel::DeRegisterExternalMediaProcessing() " - "input external media already disabled"); - return 0; - } - channel_state_.SetInputExternalMedia(false); - _inputExternalMediaCallbackPtr = NULL; + _outputExternalMedia = false; + _outputExternalMediaCallbackPtr = NULL; + } else if (kRecordingPerChannel == type) { + if (!_inputExternalMediaCallbackPtr) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceWarning, + "Channel::DeRegisterExternalMediaProcessing() " + "input external media already disabled"); + return 0; } + channel_state_.SetInputExternalMedia(false); + _inputExternalMediaCallbackPtr = NULL; + } - return 0; + return 0; } int Channel::SetExternalMixing(bool enabled) { - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetExternalMixing(enabled=%d)", enabled); + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetExternalMixing(enabled=%d)", enabled); - if (channel_state_.Get().playing) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_OPERATION, kTraceError, - "Channel::SetExternalMixing() " - "external mixing cannot be changed while playing."); - return -1; - } + if (channel_state_.Get().playing) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_OPERATION, kTraceError, + "Channel::SetExternalMixing() " + "external mixing cannot be changed while playing."); + return -1; + } - _externalMixing = enabled; + _externalMixing = enabled; - return 0; + return 0; } -int -Channel::GetNetworkStatistics(NetworkStatistics& stats) -{ - return audio_coding_->GetNetworkStatistics(&stats); +int Channel::GetNetworkStatistics(NetworkStatistics& stats) { + return audio_coding_->GetNetworkStatistics(&stats); } void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const { @@ -3570,8 +3170,8 @@ bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms, if (_average_jitter_buffer_delay_us == 0) { return false; } - *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 + - _recPacketDelayMs; + *jitter_buffer_delay_ms = + (_average_jitter_buffer_delay_us + 500) / 1000 + _recPacketDelayMs; *playout_buffer_delay_ms = playout_delay_ms_; return true; } @@ -3587,27 +3187,23 @@ int Channel::LeastRequiredDelayMs() const { return audio_coding_->LeastRequiredDelayMs(); } -int -Channel::SetMinimumPlayoutDelay(int delayMs) -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::SetMinimumPlayoutDelay()"); - if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) || - (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) - { - _engineStatisticsPtr->SetLastError( - VE_INVALID_ARGUMENT, kTraceError, - "SetMinimumPlayoutDelay() invalid min delay"); - return -1; - } - if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_AUDIO_CODING_MODULE_ERROR, kTraceError, - "SetMinimumPlayoutDelay() failed to set min playout delay"); - return -1; - } - return 0; +int Channel::SetMinimumPlayoutDelay(int delayMs) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::SetMinimumPlayoutDelay()"); + if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) || + (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) { + _engineStatisticsPtr->SetLastError( + VE_INVALID_ARGUMENT, kTraceError, + "SetMinimumPlayoutDelay() invalid min delay"); + return -1; + } + if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0) { + _engineStatisticsPtr->SetLastError( + VE_AUDIO_CODING_MODULE_ERROR, kTraceError, + "SetMinimumPlayoutDelay() failed to set min playout delay"); + return -1; + } + return 0; } int Channel::GetPlayoutTimestamp(unsigned int& timestamp) { @@ -3616,7 +3212,7 @@ int Channel::GetPlayoutTimestamp(unsigned int& timestamp) { rtc::CritScope lock(&video_sync_lock_); playout_timestamp_rtp = playout_timestamp_rtp_; } - if (playout_timestamp_rtp == 0) { + if (playout_timestamp_rtp == 0) { _engineStatisticsPtr->SetLastError( VE_CANNOT_RETRIEVE_VALUE, kTraceError, "GetPlayoutTimestamp() failed to retrieve timestamp"); @@ -3650,216 +3246,164 @@ int Channel::SetInitSequenceNumber(short sequenceNumber) { return 0; } -int -Channel::GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const -{ - *rtpRtcpModule = _rtpRtcpModule.get(); - *rtp_receiver = rtp_receiver_.get(); - return 0; +int Channel::GetRtpRtcp(RtpRtcp** rtpRtcpModule, + RtpReceiver** rtp_receiver) const { + *rtpRtcpModule = _rtpRtcpModule.get(); + *rtp_receiver = rtp_receiver_.get(); + return 0; } // TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use // a shared helper. -int32_t -Channel::MixOrReplaceAudioWithFile(int mixingFrequency) -{ +int32_t Channel::MixOrReplaceAudioWithFile(int mixingFrequency) { rtc::scoped_ptr fileBuffer(new int16_t[640]); - size_t fileSamples(0); + size_t fileSamples(0); - { - rtc::CritScope cs(&_fileCritSect); + { + rtc::CritScope cs(&_fileCritSect); - if (_inputFilePlayerPtr == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::MixOrReplaceAudioWithFile() fileplayer" - " doesnt exist"); - return -1; - } - - if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), - fileSamples, - mixingFrequency) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::MixOrReplaceAudioWithFile() file mixing " - "failed"); - return -1; - } - if (fileSamples == 0) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::MixOrReplaceAudioWithFile() file is ended"); - return 0; - } + if (_inputFilePlayerPtr == NULL) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::MixOrReplaceAudioWithFile() fileplayer" + " doesnt exist"); + return -1; } - assert(_audioFrame.samples_per_channel_ == fileSamples); - - if (_mixFileWithMicrophone) - { - // Currently file stream is always mono. - // TODO(xians): Change the code when FilePlayer supports real stereo. - MixWithSat(_audioFrame.data_, - _audioFrame.num_channels_, - fileBuffer.get(), - 1, - fileSamples); + if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), fileSamples, + mixingFrequency) == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::MixOrReplaceAudioWithFile() file mixing " + "failed"); + return -1; } - else - { - // Replace ACM audio with file. - // Currently file stream is always mono. - // TODO(xians): Change the code when FilePlayer supports real stereo. - _audioFrame.UpdateFrame(_channelId, - 0xFFFFFFFF, - fileBuffer.get(), - fileSamples, - mixingFrequency, - AudioFrame::kNormalSpeech, - AudioFrame::kVadUnknown, - 1); - + if (fileSamples == 0) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::MixOrReplaceAudioWithFile() file is ended"); + return 0; } - return 0; + } + + assert(_audioFrame.samples_per_channel_ == fileSamples); + + if (_mixFileWithMicrophone) { + // Currently file stream is always mono. + // TODO(xians): Change the code when FilePlayer supports real stereo. + MixWithSat(_audioFrame.data_, _audioFrame.num_channels_, fileBuffer.get(), + 1, fileSamples); + } else { + // Replace ACM audio with file. + // Currently file stream is always mono. + // TODO(xians): Change the code when FilePlayer supports real stereo. + _audioFrame.UpdateFrame( + _channelId, 0xFFFFFFFF, fileBuffer.get(), fileSamples, mixingFrequency, + AudioFrame::kNormalSpeech, AudioFrame::kVadUnknown, 1); + } + return 0; } -int32_t -Channel::MixAudioWithFile(AudioFrame& audioFrame, - int mixingFrequency) -{ - assert(mixingFrequency <= 48000); +int32_t Channel::MixAudioWithFile(AudioFrame& audioFrame, int mixingFrequency) { + assert(mixingFrequency <= 48000); - rtc::scoped_ptr fileBuffer(new int16_t[960]); - size_t fileSamples(0); + rtc::scoped_ptr fileBuffer(new int16_t[960]); + size_t fileSamples(0); - { - rtc::CritScope cs(&_fileCritSect); + { + rtc::CritScope cs(&_fileCritSect); - if (_outputFilePlayerPtr == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::MixAudioWithFile() file mixing failed"); - return -1; - } - - // We should get the frequency we ask for. - if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), - fileSamples, - mixingFrequency) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::MixAudioWithFile() file mixing failed"); - return -1; - } + if (_outputFilePlayerPtr == NULL) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::MixAudioWithFile() file mixing failed"); + return -1; } - if (audioFrame.samples_per_channel_ == fileSamples) - { - // Currently file stream is always mono. - // TODO(xians): Change the code when FilePlayer supports real stereo. - MixWithSat(audioFrame.data_, - audioFrame.num_channels_, - fileBuffer.get(), - 1, - fileSamples); - } - else - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS ") != " - "fileSamples(%" PRIuS ")", - audioFrame.samples_per_channel_, fileSamples); - return -1; + // We should get the frequency we ask for. + if (_outputFilePlayerPtr->Get10msAudioFromFile( + fileBuffer.get(), fileSamples, mixingFrequency) == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::MixAudioWithFile() file mixing failed"); + return -1; } + } - return 0; + if (audioFrame.samples_per_channel_ == fileSamples) { + // Currently file stream is always mono. + // TODO(xians): Change the code when FilePlayer supports real stereo. + MixWithSat(audioFrame.data_, audioFrame.num_channels_, fileBuffer.get(), 1, + fileSamples); + } else { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS + ") != " + "fileSamples(%" PRIuS ")", + audioFrame.samples_per_channel_, fileSamples); + return -1; + } + + return 0; } -int -Channel::InsertInbandDtmfTone() -{ - // Check if we should start a new tone. - if (_inbandDtmfQueue.PendingDtmf() && - !_inbandDtmfGenerator.IsAddingTone() && - _inbandDtmfGenerator.DelaySinceLastTone() > - kMinTelephoneEventSeparationMs) - { - int8_t eventCode(0); - uint16_t lengthMs(0); - uint8_t attenuationDb(0); +int Channel::InsertInbandDtmfTone() { + // Check if we should start a new tone. + if (_inbandDtmfQueue.PendingDtmf() && !_inbandDtmfGenerator.IsAddingTone() && + _inbandDtmfGenerator.DelaySinceLastTone() > + kMinTelephoneEventSeparationMs) { + int8_t eventCode(0); + uint16_t lengthMs(0); + uint8_t attenuationDb(0); - eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); - _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); - if (_playInbandDtmfEvent) - { - // Add tone to output mixer using a reduced length to minimize - // risk of echo. - _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, - attenuationDb); - } + eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); + _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); + if (_playInbandDtmfEvent) { + // Add tone to output mixer using a reduced length to minimize + // risk of echo. + _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, attenuationDb); + } + } + + if (_inbandDtmfGenerator.IsAddingTone()) { + uint16_t frequency(0); + _inbandDtmfGenerator.GetSampleRate(frequency); + + if (frequency != _audioFrame.sample_rate_hz_) { + // Update sample rate of Dtmf tone since the mixing frequency + // has changed. + _inbandDtmfGenerator.SetSampleRate( + (uint16_t)(_audioFrame.sample_rate_hz_)); + // Reset the tone to be added taking the new sample rate into + // account. + _inbandDtmfGenerator.ResetTone(); } - if (_inbandDtmfGenerator.IsAddingTone()) - { - uint16_t frequency(0); - _inbandDtmfGenerator.GetSampleRate(frequency); - - if (frequency != _audioFrame.sample_rate_hz_) - { - // Update sample rate of Dtmf tone since the mixing frequency - // has changed. - _inbandDtmfGenerator.SetSampleRate( - (uint16_t) (_audioFrame.sample_rate_hz_)); - // Reset the tone to be added taking the new sample rate into - // account. - _inbandDtmfGenerator.ResetTone(); - } - - int16_t toneBuffer[320]; - uint16_t toneSamples(0); - // Get 10ms tone segment and set time since last tone to zero - if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::EncodeAndSend() inserting Dtmf failed"); - return -1; - } - - // Replace mixed audio with DTMF tone. - for (size_t sample = 0; - sample < _audioFrame.samples_per_channel_; - sample++) - { - for (size_t channel = 0; - channel < _audioFrame.num_channels_; - channel++) - { - const size_t index = - sample * _audioFrame.num_channels_ + channel; - _audioFrame.data_[index] = toneBuffer[sample]; - } - } - - assert(_audioFrame.samples_per_channel_ == toneSamples); - } else - { - // Add 10ms to "delay-since-last-tone" counter - _inbandDtmfGenerator.UpdateDelaySinceLastTone(); + int16_t toneBuffer[320]; + uint16_t toneSamples(0); + // Get 10ms tone segment and set time since last tone to zero + if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::EncodeAndSend() inserting Dtmf failed"); + return -1; } - return 0; + + // Replace mixed audio with DTMF tone. + for (size_t sample = 0; sample < _audioFrame.samples_per_channel_; + sample++) { + for (size_t channel = 0; channel < _audioFrame.num_channels_; channel++) { + const size_t index = sample * _audioFrame.num_channels_ + channel; + _audioFrame.data_[index] = toneBuffer[sample]; + } + } + + assert(_audioFrame.samples_per_channel_ == toneSamples); + } else { + // Add 10ms to "delay-since-last-tone" counter + _inbandDtmfGenerator.UpdateDelaySinceLastTone(); + } + return 0; } void Channel::UpdatePlayoutTimestamp(bool rtcp) { uint32_t playout_timestamp = 0; - if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { + if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { // This can happen if this channel has not been received any RTP packet. In // this case, NetEq is not capable of computing playout timestamp. return; @@ -3867,7 +3411,7 @@ void Channel::UpdatePlayoutTimestamp(bool rtcp) { uint16_t delay_ms = 0; if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::UpdatePlayoutTimestamp() failed to read playout" " delay from the ADM"); _engineStatisticsPtr->SetLastError( @@ -3881,7 +3425,7 @@ void Channel::UpdatePlayoutTimestamp(bool rtcp) { // Remove the playout delay. playout_timestamp -= (delay_ms * (GetPlayoutFrequency() / 1000)); - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu", playout_timestamp); @@ -3899,7 +3443,7 @@ void Channel::UpdatePlayoutTimestamp(bool rtcp) { // Called for incoming RTP packets after successful RTP header parsing. void Channel::UpdatePacketDelay(uint32_t rtp_timestamp, uint16_t sequence_number) { - WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), + WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)", rtp_timestamp, sequence_number); @@ -3908,8 +3452,9 @@ void Channel::UpdatePacketDelay(uint32_t rtp_timestamp, // |jitter_buffer_playout_timestamp_| updated in UpdatePlayoutTimestamp for // every incoming packet. - uint32_t timestamp_diff_ms = (rtp_timestamp - - jitter_buffer_playout_timestamp_) / (rtp_receive_frequency / 1000); + uint32_t timestamp_diff_ms = + (rtp_timestamp - jitter_buffer_playout_timestamp_) / + (rtp_receive_frequency / 1000); if (!IsNewerTimestamp(rtp_timestamp, jitter_buffer_playout_timestamp_) || timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) { // If |jitter_buffer_playout_timestamp_| is newer than the incoming RTP @@ -3919,12 +3464,13 @@ void Channel::UpdatePacketDelay(uint32_t rtp_timestamp, timestamp_diff_ms = 0; } - uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) / - (rtp_receive_frequency / 1000); + uint16_t packet_delay_ms = + (rtp_timestamp - _previousTimestamp) / (rtp_receive_frequency / 1000); _previousTimestamp = rtp_timestamp; - if (timestamp_diff_ms == 0) return; + if (timestamp_diff_ms == 0) + return; { rtc::CritScope lock(&video_sync_lock_); @@ -3942,52 +3488,42 @@ void Channel::UpdatePacketDelay(uint32_t rtp_timestamp, // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces // risk of rounding error) and compensate for it in GetDelayEstimate() // later. - _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 + - 1000 * timestamp_diff_ms + 500) / 8; + _average_jitter_buffer_delay_us = + (_average_jitter_buffer_delay_us * 7 + 1000 * timestamp_diff_ms + 500) / + 8; } } -void -Channel::RegisterReceiveCodecsToRTPModule() -{ - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), - "Channel::RegisterReceiveCodecsToRTPModule()"); +void Channel::RegisterReceiveCodecsToRTPModule() { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RegisterReceiveCodecsToRTPModule()"); - CodecInst codec; - const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); + CodecInst codec; + const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); - for (int idx = 0; idx < nSupportedCodecs; idx++) - { - // Open up the RTP/RTCP receiver for all supported codecs - if ((audio_coding_->Codec(idx, &codec) == -1) || - (rtp_receiver_->RegisterReceivePayload( - codec.plname, - codec.pltype, - codec.plfreq, - codec.channels, - (codec.rate < 0) ? 0 : codec.rate) == -1)) - { - WEBRTC_TRACE(kTraceWarning, - kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::RegisterReceiveCodecsToRTPModule() unable" - " to register %s (%d/%d/%" PRIuS "/%d) to RTP/RTCP " - "receiver", - codec.plname, codec.pltype, codec.plfreq, - codec.channels, codec.rate); - } - else - { - WEBRTC_TRACE(kTraceInfo, - kTraceVoice, - VoEId(_instanceId, _channelId), - "Channel::RegisterReceiveCodecsToRTPModule() %s " - "(%d/%d/%" PRIuS "/%d) has been added to the RTP/RTCP " - "receiver", - codec.plname, codec.pltype, codec.plfreq, - codec.channels, codec.rate); - } + for (int idx = 0; idx < nSupportedCodecs; idx++) { + // Open up the RTP/RTCP receiver for all supported codecs + if ((audio_coding_->Codec(idx, &codec) == -1) || + (rtp_receiver_->RegisterReceivePayload( + codec.plname, codec.pltype, codec.plfreq, codec.channels, + (codec.rate < 0) ? 0 : codec.rate) == -1)) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RegisterReceiveCodecsToRTPModule() unable" + " to register %s (%d/%d/%" PRIuS + "/%d) to RTP/RTCP " + "receiver", + codec.plname, codec.pltype, codec.plfreq, codec.channels, + codec.rate); + } else { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "Channel::RegisterReceiveCodecsToRTPModule() %s " + "(%d/%d/%" PRIuS + "/%d) has been added to the RTP/RTCP " + "receiver", + codec.plname, codec.pltype, codec.plfreq, codec.channels, + codec.rate); } + } } // Assuming this method is called with valid payload type. @@ -4029,7 +3565,8 @@ int Channel::SetRedPayloadType(int red_payload_type) { return 0; } -int Channel::SetSendRtpHeaderExtension(bool enable, RTPExtensionType type, +int Channel::SetSendRtpHeaderExtension(bool enable, + RTPExtensionType type, unsigned char id) { int error = 0; _rtpRtcpModule->DeregisterSendRtpHeaderExtension(type); @@ -4100,10 +3637,10 @@ int64_t Channel::GetRTT(bool allow_associate_channel) const { } int64_t avg_rtt = 0; - int64_t max_rtt= 0; + int64_t max_rtt = 0; int64_t min_rtt = 0; - if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) - != 0) { + if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != + 0) { return 0; } return rtt; diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index 3a4383ffd1..14bfc2bba0 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -84,526 +84,515 @@ class VoERtcpObserver; // safe and also avoid TSan v2 warnings. class ChannelState { public: - struct State { - State() : rx_apm_is_enabled(false), - input_external_media(false), - output_file_playing(false), - input_file_playing(false), - playing(false), - sending(false), - receiving(false) {} + struct State { + State() + : rx_apm_is_enabled(false), + input_external_media(false), + output_file_playing(false), + input_file_playing(false), + playing(false), + sending(false), + receiving(false) {} - bool rx_apm_is_enabled; - bool input_external_media; - bool output_file_playing; - bool input_file_playing; - bool playing; - bool sending; - bool receiving; - }; + bool rx_apm_is_enabled; + bool input_external_media; + bool output_file_playing; + bool input_file_playing; + bool playing; + bool sending; + bool receiving; + }; - ChannelState() {} - virtual ~ChannelState() {} + ChannelState() {} + virtual ~ChannelState() {} - void Reset() { - rtc::CritScope lock(&lock_); - state_ = State(); - } + void Reset() { + rtc::CritScope lock(&lock_); + state_ = State(); + } - State Get() const { - rtc::CritScope lock(&lock_); - return state_; - } + State Get() const { + rtc::CritScope lock(&lock_); + return state_; + } - void SetRxApmIsEnabled(bool enable) { - rtc::CritScope lock(&lock_); - state_.rx_apm_is_enabled = enable; - } + void SetRxApmIsEnabled(bool enable) { + rtc::CritScope lock(&lock_); + state_.rx_apm_is_enabled = enable; + } - void SetInputExternalMedia(bool enable) { - rtc::CritScope lock(&lock_); - state_.input_external_media = enable; - } + void SetInputExternalMedia(bool enable) { + rtc::CritScope lock(&lock_); + state_.input_external_media = enable; + } - void SetOutputFilePlaying(bool enable) { - rtc::CritScope lock(&lock_); - state_.output_file_playing = enable; - } + void SetOutputFilePlaying(bool enable) { + rtc::CritScope lock(&lock_); + state_.output_file_playing = enable; + } - void SetInputFilePlaying(bool enable) { - rtc::CritScope lock(&lock_); - state_.input_file_playing = enable; - } + void SetInputFilePlaying(bool enable) { + rtc::CritScope lock(&lock_); + state_.input_file_playing = enable; + } - void SetPlaying(bool enable) { - rtc::CritScope lock(&lock_); - state_.playing = enable; - } + void SetPlaying(bool enable) { + rtc::CritScope lock(&lock_); + state_.playing = enable; + } - void SetSending(bool enable) { - rtc::CritScope lock(&lock_); - state_.sending = enable; - } + void SetSending(bool enable) { + rtc::CritScope lock(&lock_); + state_.sending = enable; + } - void SetReceiving(bool enable) { - rtc::CritScope lock(&lock_); - state_.receiving = enable; - } + void SetReceiving(bool enable) { + rtc::CritScope lock(&lock_); + state_.receiving = enable; + } -private: - mutable rtc::CriticalSection lock_; - State state_; + private: + mutable rtc::CriticalSection lock_; + State state_; }; -class Channel: - public RtpData, - public RtpFeedback, - public FileCallback, // receiving notification from file player & recorder - public Transport, - public RtpAudioFeedback, - public AudioPacketizationCallback, // receive encoded packets from the ACM - public ACMVADCallback, // receive voice activity from the ACM - public MixerParticipant // supplies output mixer with audio frames +class Channel + : public RtpData, + public RtpFeedback, + public FileCallback, // receiving notification from file player & + // recorder + public Transport, + public RtpAudioFeedback, + public AudioPacketizationCallback, // receive encoded packets from the + // ACM + public ACMVADCallback, // receive voice activity from the ACM + public MixerParticipant // supplies output mixer with audio frames { -public: - friend class VoERtcpObserver; + public: + friend class VoERtcpObserver; - enum {KNumSocketThreads = 1}; - enum {KNumberOfSocketBuffers = 8}; - virtual ~Channel(); - static int32_t CreateChannel(Channel*& channel, - int32_t channelId, - uint32_t instanceId, - RtcEventLog* const event_log, - const Config& config); - Channel(int32_t channelId, - uint32_t instanceId, - RtcEventLog* const event_log, - const Config& config); - int32_t Init(); - int32_t SetEngineInformation( - Statistics& engineStatistics, - OutputMixer& outputMixer, - TransmitMixer& transmitMixer, - ProcessThread& moduleProcessThread, - AudioDeviceModule& audioDeviceModule, - VoiceEngineObserver* voiceEngineObserver, - rtc::CriticalSection* callbackCritSect); - int32_t UpdateLocalTimeStamp(); + enum { KNumSocketThreads = 1 }; + enum { KNumberOfSocketBuffers = 8 }; + virtual ~Channel(); + static int32_t CreateChannel(Channel*& channel, + int32_t channelId, + uint32_t instanceId, + RtcEventLog* const event_log, + const Config& config); + Channel(int32_t channelId, + uint32_t instanceId, + RtcEventLog* const event_log, + const Config& config); + int32_t Init(); + int32_t SetEngineInformation(Statistics& engineStatistics, + OutputMixer& outputMixer, + TransmitMixer& transmitMixer, + ProcessThread& moduleProcessThread, + AudioDeviceModule& audioDeviceModule, + VoiceEngineObserver* voiceEngineObserver, + rtc::CriticalSection* callbackCritSect); + int32_t UpdateLocalTimeStamp(); - void SetSink(rtc::scoped_ptr sink); + void SetSink(rtc::scoped_ptr sink); - // API methods + // API methods - // VoEBase - int32_t StartPlayout(); - int32_t StopPlayout(); - int32_t StartSend(); - int32_t StopSend(); - int32_t StartReceiving(); - int32_t StopReceiving(); + // VoEBase + int32_t StartPlayout(); + int32_t StopPlayout(); + int32_t StartSend(); + int32_t StopSend(); + int32_t StartReceiving(); + int32_t StopReceiving(); - int32_t RegisterVoiceEngineObserver(VoiceEngineObserver& observer); - int32_t DeRegisterVoiceEngineObserver(); + int32_t RegisterVoiceEngineObserver(VoiceEngineObserver& observer); + int32_t DeRegisterVoiceEngineObserver(); - // VoECodec - int32_t GetSendCodec(CodecInst& codec); - int32_t GetRecCodec(CodecInst& codec); - int32_t SetSendCodec(const CodecInst& codec); - void SetBitRate(int bitrate_bps); - int32_t SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX); - int32_t GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX); - int32_t SetRecPayloadType(const CodecInst& codec); - int32_t GetRecPayloadType(CodecInst& codec); - int32_t SetSendCNPayloadType(int type, PayloadFrequencies frequency); - int SetOpusMaxPlaybackRate(int frequency_hz); - int SetOpusDtx(bool enable_dtx); + // VoECodec + int32_t GetSendCodec(CodecInst& codec); + int32_t GetRecCodec(CodecInst& codec); + int32_t SetSendCodec(const CodecInst& codec); + void SetBitRate(int bitrate_bps); + int32_t SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX); + int32_t GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX); + int32_t SetRecPayloadType(const CodecInst& codec); + int32_t GetRecPayloadType(CodecInst& codec); + int32_t SetSendCNPayloadType(int type, PayloadFrequencies frequency); + int SetOpusMaxPlaybackRate(int frequency_hz); + int SetOpusDtx(bool enable_dtx); - // VoENetwork - int32_t RegisterExternalTransport(Transport& transport); - int32_t DeRegisterExternalTransport(); - int32_t ReceivedRTPPacket(const int8_t* data, size_t length, - const PacketTime& packet_time); - int32_t ReceivedRTCPPacket(const int8_t* data, size_t length); + // VoENetwork + int32_t RegisterExternalTransport(Transport& transport); + int32_t DeRegisterExternalTransport(); + int32_t ReceivedRTPPacket(const int8_t* data, + size_t length, + const PacketTime& packet_time); + int32_t ReceivedRTCPPacket(const int8_t* data, size_t length); - // VoEFile - int StartPlayingFileLocally(const char* fileName, bool loop, - FileFormats format, - int startPosition, - float volumeScaling, - int stopPosition, - const CodecInst* codecInst); - int StartPlayingFileLocally(InStream* stream, FileFormats format, - int startPosition, - float volumeScaling, - int stopPosition, - const CodecInst* codecInst); - int StopPlayingFileLocally(); - int IsPlayingFileLocally() const; - int RegisterFilePlayingToMixer(); - int StartPlayingFileAsMicrophone(const char* fileName, bool loop, - FileFormats format, - int startPosition, - float volumeScaling, - int stopPosition, - const CodecInst* codecInst); - int StartPlayingFileAsMicrophone(InStream* stream, - FileFormats format, - int startPosition, - float volumeScaling, - int stopPosition, - const CodecInst* codecInst); - int StopPlayingFileAsMicrophone(); - int IsPlayingFileAsMicrophone() const; - int StartRecordingPlayout(const char* fileName, const CodecInst* codecInst); - int StartRecordingPlayout(OutStream* stream, const CodecInst* codecInst); - int StopRecordingPlayout(); + // VoEFile + int StartPlayingFileLocally(const char* fileName, + bool loop, + FileFormats format, + int startPosition, + float volumeScaling, + int stopPosition, + const CodecInst* codecInst); + int StartPlayingFileLocally(InStream* stream, + FileFormats format, + int startPosition, + float volumeScaling, + int stopPosition, + const CodecInst* codecInst); + int StopPlayingFileLocally(); + int IsPlayingFileLocally() const; + int RegisterFilePlayingToMixer(); + int StartPlayingFileAsMicrophone(const char* fileName, + bool loop, + FileFormats format, + int startPosition, + float volumeScaling, + int stopPosition, + const CodecInst* codecInst); + int StartPlayingFileAsMicrophone(InStream* stream, + FileFormats format, + int startPosition, + float volumeScaling, + int stopPosition, + const CodecInst* codecInst); + int StopPlayingFileAsMicrophone(); + int IsPlayingFileAsMicrophone() const; + int StartRecordingPlayout(const char* fileName, const CodecInst* codecInst); + int StartRecordingPlayout(OutStream* stream, const CodecInst* codecInst); + int StopRecordingPlayout(); - void SetMixWithMicStatus(bool mix); + void SetMixWithMicStatus(bool mix); - // VoEExternalMediaProcessing - int RegisterExternalMediaProcessing(ProcessingTypes type, - VoEMediaProcess& processObject); - int DeRegisterExternalMediaProcessing(ProcessingTypes type); - int SetExternalMixing(bool enabled); + // VoEExternalMediaProcessing + int RegisterExternalMediaProcessing(ProcessingTypes type, + VoEMediaProcess& processObject); + int DeRegisterExternalMediaProcessing(ProcessingTypes type); + int SetExternalMixing(bool enabled); - // VoEVolumeControl - int GetSpeechOutputLevel(uint32_t& level) const; - int GetSpeechOutputLevelFullRange(uint32_t& level) const; - int SetMute(bool enable); - bool Mute() const; - int SetOutputVolumePan(float left, float right); - int GetOutputVolumePan(float& left, float& right) const; - int SetChannelOutputVolumeScaling(float scaling); - int GetChannelOutputVolumeScaling(float& scaling) const; + // VoEVolumeControl + int GetSpeechOutputLevel(uint32_t& level) const; + int GetSpeechOutputLevelFullRange(uint32_t& level) const; + int SetMute(bool enable); + bool Mute() const; + int SetOutputVolumePan(float left, float right); + int GetOutputVolumePan(float& left, float& right) const; + int SetChannelOutputVolumeScaling(float scaling); + int GetChannelOutputVolumeScaling(float& scaling) const; - // VoENetEqStats - int GetNetworkStatistics(NetworkStatistics& stats); - void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const; + // VoENetEqStats + int GetNetworkStatistics(NetworkStatistics& stats); + void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const; - // VoEVideoSync - bool GetDelayEstimate(int* jitter_buffer_delay_ms, - int* playout_buffer_delay_ms) const; - uint32_t GetDelayEstimate() const; - int LeastRequiredDelayMs() const; - int SetMinimumPlayoutDelay(int delayMs); - int GetPlayoutTimestamp(unsigned int& timestamp); - int SetInitTimestamp(unsigned int timestamp); - int SetInitSequenceNumber(short sequenceNumber); + // VoEVideoSync + bool GetDelayEstimate(int* jitter_buffer_delay_ms, + int* playout_buffer_delay_ms) const; + uint32_t GetDelayEstimate() const; + int LeastRequiredDelayMs() const; + int SetMinimumPlayoutDelay(int delayMs); + int GetPlayoutTimestamp(unsigned int& timestamp); + int SetInitTimestamp(unsigned int timestamp); + int SetInitSequenceNumber(short sequenceNumber); - // VoEVideoSyncExtended - int GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const; + // VoEVideoSyncExtended + int GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const; - // VoEDtmf - int SendTelephoneEventOutband(unsigned char eventCode, int lengthMs, - int attenuationDb, bool playDtmfEvent); - int SendTelephoneEventInband(unsigned char eventCode, int lengthMs, - int attenuationDb, bool playDtmfEvent); - int SetSendTelephoneEventPayloadType(unsigned char type); - int GetSendTelephoneEventPayloadType(unsigned char& type); + // VoEDtmf + int SendTelephoneEventOutband(unsigned char eventCode, + int lengthMs, + int attenuationDb, + bool playDtmfEvent); + int SendTelephoneEventInband(unsigned char eventCode, + int lengthMs, + int attenuationDb, + bool playDtmfEvent); + int SetSendTelephoneEventPayloadType(unsigned char type); + int GetSendTelephoneEventPayloadType(unsigned char& type); - // VoEAudioProcessingImpl - int UpdateRxVadDetection(AudioFrame& audioFrame); - int RegisterRxVadObserver(VoERxVadCallback &observer); - int DeRegisterRxVadObserver(); - int VoiceActivityIndicator(int &activity); + // VoEAudioProcessingImpl + int UpdateRxVadDetection(AudioFrame& audioFrame); + int RegisterRxVadObserver(VoERxVadCallback& observer); + int DeRegisterRxVadObserver(); + int VoiceActivityIndicator(int& activity); #ifdef WEBRTC_VOICE_ENGINE_AGC - int SetRxAgcStatus(bool enable, AgcModes mode); - int GetRxAgcStatus(bool& enabled, AgcModes& mode); - int SetRxAgcConfig(AgcConfig config); - int GetRxAgcConfig(AgcConfig& config); + int SetRxAgcStatus(bool enable, AgcModes mode); + int GetRxAgcStatus(bool& enabled, AgcModes& mode); + int SetRxAgcConfig(AgcConfig config); + int GetRxAgcConfig(AgcConfig& config); #endif #ifdef WEBRTC_VOICE_ENGINE_NR - int SetRxNsStatus(bool enable, NsModes mode); - int GetRxNsStatus(bool& enabled, NsModes& mode); + int SetRxNsStatus(bool enable, NsModes mode); + int GetRxNsStatus(bool& enabled, NsModes& mode); #endif - // VoERTP_RTCP - int SetLocalSSRC(unsigned int ssrc); - int GetLocalSSRC(unsigned int& ssrc); - int GetRemoteSSRC(unsigned int& ssrc); - int SetSendAudioLevelIndicationStatus(bool enable, unsigned char id); - int SetReceiveAudioLevelIndicationStatus(bool enable, unsigned char id); - int SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id); - int SetReceiveAbsoluteSenderTimeStatus(bool enable, unsigned char id); - void EnableSendTransportSequenceNumber(int id); - void EnableReceiveTransportSequenceNumber(int id); + // VoERTP_RTCP + int SetLocalSSRC(unsigned int ssrc); + int GetLocalSSRC(unsigned int& ssrc); + int GetRemoteSSRC(unsigned int& ssrc); + int SetSendAudioLevelIndicationStatus(bool enable, unsigned char id); + int SetReceiveAudioLevelIndicationStatus(bool enable, unsigned char id); + int SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id); + int SetReceiveAbsoluteSenderTimeStatus(bool enable, unsigned char id); + void EnableSendTransportSequenceNumber(int id); + void EnableReceiveTransportSequenceNumber(int id); - void SetCongestionControlObjects( - RtpPacketSender* rtp_packet_sender, - TransportFeedbackObserver* transport_feedback_observer, - PacketRouter* packet_router); + void SetCongestionControlObjects( + RtpPacketSender* rtp_packet_sender, + TransportFeedbackObserver* transport_feedback_observer, + PacketRouter* packet_router); - void SetRTCPStatus(bool enable); - int GetRTCPStatus(bool& enabled); - int SetRTCP_CNAME(const char cName[256]); - int GetRemoteRTCP_CNAME(char cName[256]); - int GetRemoteRTCPData(unsigned int& NTPHigh, unsigned int& NTPLow, - unsigned int& timestamp, - unsigned int& playoutTimestamp, unsigned int* jitter, - unsigned short* fractionLost); - int SendApplicationDefinedRTCPPacket(unsigned char subType, - unsigned int name, const char* data, - unsigned short dataLengthInBytes); - int GetRTPStatistics(unsigned int& averageJitterMs, - unsigned int& maxJitterMs, - unsigned int& discardedPackets); - int GetRemoteRTCPReportBlocks(std::vector* report_blocks); - int GetRTPStatistics(CallStatistics& stats); - int SetREDStatus(bool enable, int redPayloadtype); - int GetREDStatus(bool& enabled, int& redPayloadtype); - int SetCodecFECStatus(bool enable); - bool GetCodecFECStatus(); - void SetNACKStatus(bool enable, int maxNumberOfPackets); + void SetRTCPStatus(bool enable); + int GetRTCPStatus(bool& enabled); + int SetRTCP_CNAME(const char cName[256]); + int GetRemoteRTCP_CNAME(char cName[256]); + int GetRemoteRTCPData(unsigned int& NTPHigh, + unsigned int& NTPLow, + unsigned int& timestamp, + unsigned int& playoutTimestamp, + unsigned int* jitter, + unsigned short* fractionLost); + int SendApplicationDefinedRTCPPacket(unsigned char subType, + unsigned int name, + const char* data, + unsigned short dataLengthInBytes); + int GetRTPStatistics(unsigned int& averageJitterMs, + unsigned int& maxJitterMs, + unsigned int& discardedPackets); + int GetRemoteRTCPReportBlocks(std::vector* report_blocks); + int GetRTPStatistics(CallStatistics& stats); + int SetREDStatus(bool enable, int redPayloadtype); + int GetREDStatus(bool& enabled, int& redPayloadtype); + int SetCodecFECStatus(bool enable); + bool GetCodecFECStatus(); + void SetNACKStatus(bool enable, int maxNumberOfPackets); - // From AudioPacketizationCallback in the ACM - int32_t SendData(FrameType frameType, - uint8_t payloadType, - uint32_t timeStamp, - const uint8_t* payloadData, - size_t payloadSize, - const RTPFragmentationHeader* fragmentation) override; + // From AudioPacketizationCallback in the ACM + int32_t SendData(FrameType frameType, + uint8_t payloadType, + uint32_t timeStamp, + const uint8_t* payloadData, + size_t payloadSize, + const RTPFragmentationHeader* fragmentation) override; - // From ACMVADCallback in the ACM - int32_t InFrameType(FrameType frame_type) override; + // From ACMVADCallback in the ACM + int32_t InFrameType(FrameType frame_type) override; - int32_t OnRxVadDetected(int vadDecision); + int32_t OnRxVadDetected(int vadDecision); - // From RtpData in the RTP/RTCP module - int32_t OnReceivedPayloadData(const uint8_t* payloadData, - size_t payloadSize, - const WebRtcRTPHeader* rtpHeader) override; - bool OnRecoveredPacket(const uint8_t* packet, - size_t packet_length) override; + // From RtpData in the RTP/RTCP module + int32_t OnReceivedPayloadData(const uint8_t* payloadData, + size_t payloadSize, + const WebRtcRTPHeader* rtpHeader) override; + bool OnRecoveredPacket(const uint8_t* packet, size_t packet_length) override; - // From RtpFeedback in the RTP/RTCP module - int32_t OnInitializeDecoder(int8_t payloadType, - const char payloadName[RTP_PAYLOAD_NAME_SIZE], - int frequency, - size_t channels, - uint32_t rate) override; - void OnIncomingSSRCChanged(uint32_t ssrc) override; - void OnIncomingCSRCChanged(uint32_t CSRC, bool added) override; + // From RtpFeedback in the RTP/RTCP module + int32_t OnInitializeDecoder(int8_t payloadType, + const char payloadName[RTP_PAYLOAD_NAME_SIZE], + int frequency, + size_t channels, + uint32_t rate) override; + void OnIncomingSSRCChanged(uint32_t ssrc) override; + void OnIncomingCSRCChanged(uint32_t CSRC, bool added) override; - // From RtpAudioFeedback in the RTP/RTCP module - void OnPlayTelephoneEvent(uint8_t event, - uint16_t lengthMs, - uint8_t volume) override; + // From RtpAudioFeedback in the RTP/RTCP module + void OnPlayTelephoneEvent(uint8_t event, + uint16_t lengthMs, + uint8_t volume) override; - // From Transport (called by the RTP/RTCP module) - bool SendRtp(const uint8_t* data, - size_t len, - const PacketOptions& packet_options) override; - bool SendRtcp(const uint8_t* data, size_t len) override; + // From Transport (called by the RTP/RTCP module) + bool SendRtp(const uint8_t* data, + size_t len, + const PacketOptions& packet_options) override; + bool SendRtcp(const uint8_t* data, size_t len) override; - // From MixerParticipant - int32_t GetAudioFrame(int32_t id, AudioFrame* audioFrame) override; - int32_t NeededFrequency(int32_t id) const override; + // From MixerParticipant + int32_t GetAudioFrame(int32_t id, AudioFrame* audioFrame) override; + int32_t NeededFrequency(int32_t id) const override; - // From FileCallback - void PlayNotification(int32_t id, uint32_t durationMs) override; - void RecordNotification(int32_t id, uint32_t durationMs) override; - void PlayFileEnded(int32_t id) override; - void RecordFileEnded(int32_t id) override; + // From FileCallback + void PlayNotification(int32_t id, uint32_t durationMs) override; + void RecordNotification(int32_t id, uint32_t durationMs) override; + void PlayFileEnded(int32_t id) override; + void RecordFileEnded(int32_t id) override; - uint32_t InstanceId() const - { - return _instanceId; - } - int32_t ChannelId() const - { - return _channelId; - } - bool Playing() const - { - return channel_state_.Get().playing; - } - bool Sending() const - { - return channel_state_.Get().sending; - } - bool Receiving() const - { - return channel_state_.Get().receiving; - } - bool ExternalTransport() const - { - rtc::CritScope cs(&_callbackCritSect); - return _externalTransport; - } - bool ExternalMixing() const - { - return _externalMixing; - } - RtpRtcp* RtpRtcpModulePtr() const - { - return _rtpRtcpModule.get(); - } - int8_t OutputEnergyLevel() const - { - return _outputAudioLevel.Level(); - } - uint32_t Demultiplex(const AudioFrame& audioFrame); - // Demultiplex the data to the channel's |_audioFrame|. The difference - // between this method and the overloaded method above is that |audio_data| - // does not go through transmit_mixer and APM. - void Demultiplex(const int16_t* audio_data, - int sample_rate, - size_t number_of_frames, - size_t number_of_channels); - uint32_t PrepareEncodeAndSend(int mixingFrequency); - uint32_t EncodeAndSend(); + uint32_t InstanceId() const { return _instanceId; } + int32_t ChannelId() const { return _channelId; } + bool Playing() const { return channel_state_.Get().playing; } + bool Sending() const { return channel_state_.Get().sending; } + bool Receiving() const { return channel_state_.Get().receiving; } + bool ExternalTransport() const { + rtc::CritScope cs(&_callbackCritSect); + return _externalTransport; + } + bool ExternalMixing() const { return _externalMixing; } + RtpRtcp* RtpRtcpModulePtr() const { return _rtpRtcpModule.get(); } + int8_t OutputEnergyLevel() const { return _outputAudioLevel.Level(); } + uint32_t Demultiplex(const AudioFrame& audioFrame); + // Demultiplex the data to the channel's |_audioFrame|. The difference + // between this method and the overloaded method above is that |audio_data| + // does not go through transmit_mixer and APM. + void Demultiplex(const int16_t* audio_data, + int sample_rate, + size_t number_of_frames, + size_t number_of_channels); + uint32_t PrepareEncodeAndSend(int mixingFrequency); + uint32_t EncodeAndSend(); - // Associate to a send channel. - // Used for obtaining RTT for a receive-only channel. - void set_associate_send_channel(const ChannelOwner& channel) { - assert(_channelId != channel.channel()->ChannelId()); - rtc::CritScope lock(&assoc_send_channel_lock_); - associate_send_channel_ = channel; - } + // Associate to a send channel. + // Used for obtaining RTT for a receive-only channel. + void set_associate_send_channel(const ChannelOwner& channel) { + assert(_channelId != channel.channel()->ChannelId()); + rtc::CritScope lock(&assoc_send_channel_lock_); + associate_send_channel_ = channel; + } - // Disassociate a send channel if it was associated. - void DisassociateSendChannel(int channel_id); + // Disassociate a send channel if it was associated. + void DisassociateSendChannel(int channel_id); -protected: - void OnIncomingFractionLoss(int fraction_lost); + protected: + void OnIncomingFractionLoss(int fraction_lost); -private: - bool ReceivePacket(const uint8_t* packet, size_t packet_length, - const RTPHeader& header, bool in_order); - bool HandleRtxPacket(const uint8_t* packet, - size_t packet_length, - const RTPHeader& header); - bool IsPacketInOrder(const RTPHeader& header) const; - bool IsPacketRetransmitted(const RTPHeader& header, bool in_order) const; - int ResendPackets(const uint16_t* sequence_numbers, int length); - int InsertInbandDtmfTone(); - int32_t MixOrReplaceAudioWithFile(int mixingFrequency); - int32_t MixAudioWithFile(AudioFrame& audioFrame, int mixingFrequency); - void UpdatePlayoutTimestamp(bool rtcp); - void UpdatePacketDelay(uint32_t timestamp, - uint16_t sequenceNumber); - void RegisterReceiveCodecsToRTPModule(); + private: + bool ReceivePacket(const uint8_t* packet, + size_t packet_length, + const RTPHeader& header, + bool in_order); + bool HandleRtxPacket(const uint8_t* packet, + size_t packet_length, + const RTPHeader& header); + bool IsPacketInOrder(const RTPHeader& header) const; + bool IsPacketRetransmitted(const RTPHeader& header, bool in_order) const; + int ResendPackets(const uint16_t* sequence_numbers, int length); + int InsertInbandDtmfTone(); + int32_t MixOrReplaceAudioWithFile(int mixingFrequency); + int32_t MixAudioWithFile(AudioFrame& audioFrame, int mixingFrequency); + void UpdatePlayoutTimestamp(bool rtcp); + void UpdatePacketDelay(uint32_t timestamp, uint16_t sequenceNumber); + void RegisterReceiveCodecsToRTPModule(); - int SetRedPayloadType(int red_payload_type); - int SetSendRtpHeaderExtension(bool enable, RTPExtensionType type, - unsigned char id); + int SetRedPayloadType(int red_payload_type); + int SetSendRtpHeaderExtension(bool enable, + RTPExtensionType type, + unsigned char id); - int32_t GetPlayoutFrequency(); - int64_t GetRTT(bool allow_associate_channel) const; + int32_t GetPlayoutFrequency(); + int64_t GetRTT(bool allow_associate_channel) const; - mutable rtc::CriticalSection _fileCritSect; - mutable rtc::CriticalSection _callbackCritSect; - mutable rtc::CriticalSection volume_settings_critsect_; - uint32_t _instanceId; - int32_t _channelId; + mutable rtc::CriticalSection _fileCritSect; + mutable rtc::CriticalSection _callbackCritSect; + mutable rtc::CriticalSection volume_settings_critsect_; + uint32_t _instanceId; + int32_t _channelId; - ChannelState channel_state_; + ChannelState channel_state_; - RtcEventLog* const event_log_; + RtcEventLog* const event_log_; - rtc::scoped_ptr rtp_header_parser_; - rtc::scoped_ptr rtp_payload_registry_; - rtc::scoped_ptr rtp_receive_statistics_; - rtc::scoped_ptr statistics_proxy_; - rtc::scoped_ptr rtp_receiver_; - TelephoneEventHandler* telephone_event_handler_; - rtc::scoped_ptr _rtpRtcpModule; - rtc::scoped_ptr audio_coding_; - rtc::scoped_ptr audio_sink_; - AudioLevel _outputAudioLevel; - bool _externalTransport; - AudioFrame _audioFrame; - // Downsamples to the codec rate if necessary. - PushResampler input_resampler_; - FilePlayer* _inputFilePlayerPtr; - FilePlayer* _outputFilePlayerPtr; - FileRecorder* _outputFileRecorderPtr; - int _inputFilePlayerId; - int _outputFilePlayerId; - int _outputFileRecorderId; - bool _outputFileRecording; - DtmfInbandQueue _inbandDtmfQueue; - DtmfInband _inbandDtmfGenerator; - bool _outputExternalMedia; - VoEMediaProcess* _inputExternalMediaCallbackPtr; - VoEMediaProcess* _outputExternalMediaCallbackPtr; - uint32_t _timeStamp; - uint8_t _sendTelephoneEventPayloadType; + rtc::scoped_ptr rtp_header_parser_; + rtc::scoped_ptr rtp_payload_registry_; + rtc::scoped_ptr rtp_receive_statistics_; + rtc::scoped_ptr statistics_proxy_; + rtc::scoped_ptr rtp_receiver_; + TelephoneEventHandler* telephone_event_handler_; + rtc::scoped_ptr _rtpRtcpModule; + rtc::scoped_ptr audio_coding_; + rtc::scoped_ptr audio_sink_; + AudioLevel _outputAudioLevel; + bool _externalTransport; + AudioFrame _audioFrame; + // Downsamples to the codec rate if necessary. + PushResampler input_resampler_; + FilePlayer* _inputFilePlayerPtr; + FilePlayer* _outputFilePlayerPtr; + FileRecorder* _outputFileRecorderPtr; + int _inputFilePlayerId; + int _outputFilePlayerId; + int _outputFileRecorderId; + bool _outputFileRecording; + DtmfInbandQueue _inbandDtmfQueue; + DtmfInband _inbandDtmfGenerator; + bool _outputExternalMedia; + VoEMediaProcess* _inputExternalMediaCallbackPtr; + VoEMediaProcess* _outputExternalMediaCallbackPtr; + uint32_t _timeStamp; + uint8_t _sendTelephoneEventPayloadType; - RemoteNtpTimeEstimator ntp_estimator_ GUARDED_BY(ts_stats_lock_); + RemoteNtpTimeEstimator ntp_estimator_ GUARDED_BY(ts_stats_lock_); - // Timestamp of the audio pulled from NetEq. - uint32_t jitter_buffer_playout_timestamp_; - uint32_t playout_timestamp_rtp_ GUARDED_BY(video_sync_lock_); - uint32_t playout_timestamp_rtcp_; - uint32_t playout_delay_ms_ GUARDED_BY(video_sync_lock_); - uint32_t _numberOfDiscardedPackets; - uint16_t send_sequence_number_; - uint8_t restored_packet_[kVoiceEngineMaxIpPacketSizeBytes]; + // Timestamp of the audio pulled from NetEq. + uint32_t jitter_buffer_playout_timestamp_; + uint32_t playout_timestamp_rtp_ GUARDED_BY(video_sync_lock_); + uint32_t playout_timestamp_rtcp_; + uint32_t playout_delay_ms_ GUARDED_BY(video_sync_lock_); + uint32_t _numberOfDiscardedPackets; + uint16_t send_sequence_number_; + uint8_t restored_packet_[kVoiceEngineMaxIpPacketSizeBytes]; - mutable rtc::CriticalSection ts_stats_lock_; + mutable rtc::CriticalSection ts_stats_lock_; - rtc::scoped_ptr rtp_ts_wraparound_handler_; - // The rtp timestamp of the first played out audio frame. - int64_t capture_start_rtp_time_stamp_; - // The capture ntp time (in local timebase) of the first played out audio - // frame. - int64_t capture_start_ntp_time_ms_ GUARDED_BY(ts_stats_lock_); + rtc::scoped_ptr rtp_ts_wraparound_handler_; + // The rtp timestamp of the first played out audio frame. + int64_t capture_start_rtp_time_stamp_; + // The capture ntp time (in local timebase) of the first played out audio + // frame. + int64_t capture_start_ntp_time_ms_ GUARDED_BY(ts_stats_lock_); - // uses - Statistics* _engineStatisticsPtr; - OutputMixer* _outputMixerPtr; - TransmitMixer* _transmitMixerPtr; - ProcessThread* _moduleProcessThreadPtr; - AudioDeviceModule* _audioDeviceModulePtr; - VoiceEngineObserver* _voiceEngineObserverPtr; // owned by base - rtc::CriticalSection* _callbackCritSectPtr; // owned by base - Transport* _transportPtr; // WebRtc socket or external transport - RMSLevel rms_level_; - rtc::scoped_ptr rx_audioproc_; // far end AudioProcessing - VoERxVadCallback* _rxVadObserverPtr; - int32_t _oldVadDecision; - int32_t _sendFrameType; // Send data is voice, 1-voice, 0-otherwise - // VoEBase - bool _externalMixing; - bool _mixFileWithMicrophone; - // VoEVolumeControl - bool _mute; - float _panLeft; - float _panRight; - float _outputGain; - // VoEDtmf - bool _playOutbandDtmfEvent; - bool _playInbandDtmfEvent; - // VoeRTP_RTCP - uint32_t _lastLocalTimeStamp; - int8_t _lastPayloadType; - bool _includeAudioLevelIndication; - // VoENetwork - AudioFrame::SpeechType _outputSpeechType; - // VoEVideoSync - mutable rtc::CriticalSection video_sync_lock_; - uint32_t _average_jitter_buffer_delay_us GUARDED_BY(video_sync_lock_); - uint32_t _previousTimestamp; - uint16_t _recPacketDelayMs GUARDED_BY(video_sync_lock_); - // VoEAudioProcessing - bool _RxVadDetection; - bool _rxAgcIsEnabled; - bool _rxNsIsEnabled; - bool restored_packet_in_use_; - // RtcpBandwidthObserver - rtc::scoped_ptr rtcp_observer_; - rtc::scoped_ptr network_predictor_; - // An associated send channel. - mutable rtc::CriticalSection assoc_send_channel_lock_; - ChannelOwner associate_send_channel_ GUARDED_BY(assoc_send_channel_lock_); + // uses + Statistics* _engineStatisticsPtr; + OutputMixer* _outputMixerPtr; + TransmitMixer* _transmitMixerPtr; + ProcessThread* _moduleProcessThreadPtr; + AudioDeviceModule* _audioDeviceModulePtr; + VoiceEngineObserver* _voiceEngineObserverPtr; // owned by base + rtc::CriticalSection* _callbackCritSectPtr; // owned by base + Transport* _transportPtr; // WebRtc socket or external transport + RMSLevel rms_level_; + rtc::scoped_ptr rx_audioproc_; // far end AudioProcessing + VoERxVadCallback* _rxVadObserverPtr; + int32_t _oldVadDecision; + int32_t _sendFrameType; // Send data is voice, 1-voice, 0-otherwise + // VoEBase + bool _externalMixing; + bool _mixFileWithMicrophone; + // VoEVolumeControl + bool _mute; + float _panLeft; + float _panRight; + float _outputGain; + // VoEDtmf + bool _playOutbandDtmfEvent; + bool _playInbandDtmfEvent; + // VoeRTP_RTCP + uint32_t _lastLocalTimeStamp; + int8_t _lastPayloadType; + bool _includeAudioLevelIndication; + // VoENetwork + AudioFrame::SpeechType _outputSpeechType; + // VoEVideoSync + mutable rtc::CriticalSection video_sync_lock_; + uint32_t _average_jitter_buffer_delay_us GUARDED_BY(video_sync_lock_); + uint32_t _previousTimestamp; + uint16_t _recPacketDelayMs GUARDED_BY(video_sync_lock_); + // VoEAudioProcessing + bool _RxVadDetection; + bool _rxAgcIsEnabled; + bool _rxNsIsEnabled; + bool restored_packet_in_use_; + // RtcpBandwidthObserver + rtc::scoped_ptr rtcp_observer_; + rtc::scoped_ptr network_predictor_; + // An associated send channel. + mutable rtc::CriticalSection assoc_send_channel_lock_; + ChannelOwner associate_send_channel_ GUARDED_BY(assoc_send_channel_lock_); - bool pacing_enabled_; - PacketRouter* packet_router_ = nullptr; - rtc::scoped_ptr feedback_observer_proxy_; - rtc::scoped_ptr seq_num_allocator_proxy_; - rtc::scoped_ptr rtp_packet_sender_proxy_; + bool pacing_enabled_; + PacketRouter* packet_router_ = nullptr; + rtc::scoped_ptr feedback_observer_proxy_; + rtc::scoped_ptr seq_num_allocator_proxy_; + rtc::scoped_ptr rtp_packet_sender_proxy_; }; } // namespace voe