OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "webrtc/modules/utility/include/process_thread.h" | 33 #include "webrtc/modules/utility/include/process_thread.h" |
34 #include "webrtc/system_wrappers/include/trace.h" | 34 #include "webrtc/system_wrappers/include/trace.h" |
35 #include "webrtc/voice_engine/include/voe_base.h" | 35 #include "webrtc/voice_engine/include/voe_base.h" |
36 #include "webrtc/voice_engine/include/voe_external_media.h" | 36 #include "webrtc/voice_engine/include/voe_external_media.h" |
37 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" | 37 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" |
38 #include "webrtc/voice_engine/output_mixer.h" | 38 #include "webrtc/voice_engine/output_mixer.h" |
39 #include "webrtc/voice_engine/statistics.h" | 39 #include "webrtc/voice_engine/statistics.h" |
40 #include "webrtc/voice_engine/transmit_mixer.h" | 40 #include "webrtc/voice_engine/transmit_mixer.h" |
41 #include "webrtc/voice_engine/utility.h" | 41 #include "webrtc/voice_engine/utility.h" |
42 | 42 |
43 #if defined(_WIN32) | |
44 #include <Qos.h> | |
45 #endif | |
46 | |
47 namespace webrtc { | 43 namespace webrtc { |
48 namespace voe { | 44 namespace voe { |
49 | 45 |
50 const int kTelephoneEventAttenuationdB = 10; | 46 const int kTelephoneEventAttenuationdB = 10; |
51 | 47 |
52 class TransportFeedbackProxy : public TransportFeedbackObserver { | 48 class TransportFeedbackProxy : public TransportFeedbackObserver { |
53 public: | 49 public: |
54 TransportFeedbackProxy() : feedback_observer_(nullptr) { | 50 TransportFeedbackProxy() : feedback_observer_(nullptr) { |
55 pacer_thread_.DetachFromThread(); | 51 pacer_thread_.DetachFromThread(); |
56 network_thread_.DetachFromThread(); | 52 network_thread_.DetachFromThread(); |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 _externalTransport(false), | 752 _externalTransport(false), |
757 _inputFilePlayerPtr(NULL), | 753 _inputFilePlayerPtr(NULL), |
758 _outputFilePlayerPtr(NULL), | 754 _outputFilePlayerPtr(NULL), |
759 _outputFileRecorderPtr(NULL), | 755 _outputFileRecorderPtr(NULL), |
760 // Avoid conflict with other channels by adding 1024 - 1026, | 756 // Avoid conflict with other channels by adding 1024 - 1026, |
761 // won't use as much as 1024 channels. | 757 // won't use as much as 1024 channels. |
762 _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), | 758 _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), |
763 _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), | 759 _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), |
764 _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), | 760 _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), |
765 _outputFileRecording(false), | 761 _outputFileRecording(false), |
766 _inbandDtmfQueue(VoEModuleId(instanceId, channelId)), | |
767 _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)), | |
768 _outputExternalMedia(false), | 762 _outputExternalMedia(false), |
769 _inputExternalMediaCallbackPtr(NULL), | 763 _inputExternalMediaCallbackPtr(NULL), |
770 _outputExternalMediaCallbackPtr(NULL), | 764 _outputExternalMediaCallbackPtr(NULL), |
771 _timeStamp(0), // This is just an offset, RTP module will add it's own | 765 _timeStamp(0), // This is just an offset, RTP module will add it's own |
772 // random offset | 766 // random offset |
773 _sendTelephoneEventPayloadType(106), | |
774 ntp_estimator_(Clock::GetRealTimeClock()), | 767 ntp_estimator_(Clock::GetRealTimeClock()), |
775 jitter_buffer_playout_timestamp_(0), | 768 jitter_buffer_playout_timestamp_(0), |
776 playout_timestamp_rtp_(0), | 769 playout_timestamp_rtp_(0), |
777 playout_timestamp_rtcp_(0), | 770 playout_timestamp_rtcp_(0), |
778 playout_delay_ms_(0), | 771 playout_delay_ms_(0), |
779 _numberOfDiscardedPackets(0), | 772 _numberOfDiscardedPackets(0), |
780 send_sequence_number_(0), | 773 send_sequence_number_(0), |
781 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), | 774 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), |
782 capture_start_rtp_time_stamp_(-1), | 775 capture_start_rtp_time_stamp_(-1), |
783 capture_start_ntp_time_ms_(-1), | 776 capture_start_ntp_time_ms_(-1), |
784 _engineStatisticsPtr(NULL), | 777 _engineStatisticsPtr(NULL), |
785 _outputMixerPtr(NULL), | 778 _outputMixerPtr(NULL), |
786 _transmitMixerPtr(NULL), | 779 _transmitMixerPtr(NULL), |
787 _moduleProcessThreadPtr(NULL), | 780 _moduleProcessThreadPtr(NULL), |
788 _audioDeviceModulePtr(NULL), | 781 _audioDeviceModulePtr(NULL), |
789 _voiceEngineObserverPtr(NULL), | 782 _voiceEngineObserverPtr(NULL), |
790 _callbackCritSectPtr(NULL), | 783 _callbackCritSectPtr(NULL), |
791 _transportPtr(NULL), | 784 _transportPtr(NULL), |
792 _rxVadObserverPtr(NULL), | 785 _rxVadObserverPtr(NULL), |
793 _oldVadDecision(-1), | 786 _oldVadDecision(-1), |
794 _sendFrameType(0), | 787 _sendFrameType(0), |
795 _externalMixing(false), | 788 _externalMixing(false), |
796 _mixFileWithMicrophone(false), | 789 _mixFileWithMicrophone(false), |
797 _mute(false), | 790 _mute(false), |
798 _panLeft(1.0f), | 791 _panLeft(1.0f), |
799 _panRight(1.0f), | 792 _panRight(1.0f), |
800 _outputGain(1.0f), | 793 _outputGain(1.0f), |
801 _playOutbandDtmfEvent(false), | 794 _playOutbandDtmfEvent(false), |
802 _playInbandDtmfEvent(false), | |
803 _lastLocalTimeStamp(0), | 795 _lastLocalTimeStamp(0), |
804 _lastPayloadType(0), | 796 _lastPayloadType(0), |
805 _includeAudioLevelIndication(false), | 797 _includeAudioLevelIndication(false), |
806 _outputSpeechType(AudioFrame::kNormalSpeech), | 798 _outputSpeechType(AudioFrame::kNormalSpeech), |
807 _average_jitter_buffer_delay_us(0), | 799 _average_jitter_buffer_delay_us(0), |
808 _previousTimestamp(0), | 800 _previousTimestamp(0), |
809 _recPacketDelayMs(20), | 801 _recPacketDelayMs(20), |
810 _RxVadDetection(false), | 802 _RxVadDetection(false), |
811 _rxAgcIsEnabled(false), | 803 _rxAgcIsEnabled(false), |
812 _rxNsIsEnabled(false), | 804 _rxNsIsEnabled(false), |
(...skipping 12 matching lines...) Expand all Loading... |
825 if (config.Get<NetEqCapacityConfig>().enabled) { | 817 if (config.Get<NetEqCapacityConfig>().enabled) { |
826 // Clamping the buffer capacity at 20 packets. While going lower will | 818 // Clamping the buffer capacity at 20 packets. While going lower will |
827 // probably work, it makes little sense. | 819 // probably work, it makes little sense. |
828 acm_config.neteq_config.max_packets_in_buffer = | 820 acm_config.neteq_config.max_packets_in_buffer = |
829 std::max(20, config.Get<NetEqCapacityConfig>().capacity); | 821 std::max(20, config.Get<NetEqCapacityConfig>().capacity); |
830 } | 822 } |
831 acm_config.neteq_config.enable_fast_accelerate = | 823 acm_config.neteq_config.enable_fast_accelerate = |
832 config.Get<NetEqFastAccelerate>().enabled; | 824 config.Get<NetEqFastAccelerate>().enabled; |
833 audio_coding_.reset(AudioCodingModule::Create(acm_config)); | 825 audio_coding_.reset(AudioCodingModule::Create(acm_config)); |
834 | 826 |
835 _inbandDtmfQueue.ResetDtmf(); | |
836 _inbandDtmfGenerator.Init(); | |
837 _outputAudioLevel.Clear(); | 827 _outputAudioLevel.Clear(); |
838 | 828 |
839 RtpRtcp::Configuration configuration; | 829 RtpRtcp::Configuration configuration; |
840 configuration.audio = true; | 830 configuration.audio = true; |
841 configuration.outgoing_transport = this; | 831 configuration.outgoing_transport = this; |
842 configuration.audio_messages = this; | 832 configuration.audio_messages = this; |
843 configuration.receive_statistics = rtp_receive_statistics_.get(); | 833 configuration.receive_statistics = rtp_receive_statistics_.get(); |
844 configuration.bandwidth_callback = rtcp_observer_.get(); | 834 configuration.bandwidth_callback = rtcp_observer_.get(); |
845 if (pacing_enabled_) { | 835 if (pacing_enabled_) { |
846 configuration.paced_sender = rtp_packet_sender_proxy_.get(); | 836 configuration.paced_sender = rtp_packet_sender_proxy_.get(); |
(...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2230 if (_rtpRtcpModule->SendTelephoneEventOutband( | 2220 if (_rtpRtcpModule->SendTelephoneEventOutband( |
2231 event, duration_ms, kTelephoneEventAttenuationdB) != 0) { | 2221 event, duration_ms, kTelephoneEventAttenuationdB) != 0) { |
2232 _engineStatisticsPtr->SetLastError( | 2222 _engineStatisticsPtr->SetLastError( |
2233 VE_SEND_DTMF_FAILED, kTraceWarning, | 2223 VE_SEND_DTMF_FAILED, kTraceWarning, |
2234 "SendTelephoneEventOutband() failed to send event"); | 2224 "SendTelephoneEventOutband() failed to send event"); |
2235 return -1; | 2225 return -1; |
2236 } | 2226 } |
2237 return 0; | 2227 return 0; |
2238 } | 2228 } |
2239 | 2229 |
2240 int Channel::SendTelephoneEventInband(unsigned char eventCode, | |
2241 int lengthMs, | |
2242 int attenuationDb, | |
2243 bool playDtmfEvent) { | |
2244 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | |
2245 "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", | |
2246 playDtmfEvent); | |
2247 | |
2248 _playInbandDtmfEvent = playDtmfEvent; | |
2249 _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); | |
2250 | |
2251 return 0; | |
2252 } | |
2253 | |
2254 int Channel::SetSendTelephoneEventPayloadType(unsigned char type) { | 2230 int Channel::SetSendTelephoneEventPayloadType(unsigned char type) { |
2255 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 2231 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
2256 "Channel::SetSendTelephoneEventPayloadType()"); | 2232 "Channel::SetSendTelephoneEventPayloadType()"); |
2257 if (type > 127) { | 2233 if (type > 127) { |
2258 _engineStatisticsPtr->SetLastError( | 2234 _engineStatisticsPtr->SetLastError( |
2259 VE_INVALID_ARGUMENT, kTraceError, | 2235 VE_INVALID_ARGUMENT, kTraceError, |
2260 "SetSendTelephoneEventPayloadType() invalid type"); | 2236 "SetSendTelephoneEventPayloadType() invalid type"); |
2261 return -1; | 2237 return -1; |
2262 } | 2238 } |
2263 CodecInst codec = {}; | 2239 CodecInst codec = {}; |
2264 codec.plfreq = 8000; | 2240 codec.plfreq = 8000; |
2265 codec.pltype = type; | 2241 codec.pltype = type; |
2266 memcpy(codec.plname, "telephone-event", 16); | 2242 memcpy(codec.plname, "telephone-event", 16); |
2267 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { | 2243 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { |
2268 _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); | 2244 _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); |
2269 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { | 2245 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { |
2270 _engineStatisticsPtr->SetLastError( | 2246 _engineStatisticsPtr->SetLastError( |
2271 VE_RTP_RTCP_MODULE_ERROR, kTraceError, | 2247 VE_RTP_RTCP_MODULE_ERROR, kTraceError, |
2272 "SetSendTelephoneEventPayloadType() failed to register send" | 2248 "SetSendTelephoneEventPayloadType() failed to register send" |
2273 "payload type"); | 2249 "payload type"); |
2274 return -1; | 2250 return -1; |
2275 } | 2251 } |
2276 } | 2252 } |
2277 _sendTelephoneEventPayloadType = type; | |
2278 return 0; | 2253 return 0; |
2279 } | 2254 } |
2280 | 2255 |
2281 int Channel::GetSendTelephoneEventPayloadType(unsigned char& type) { | |
2282 type = _sendTelephoneEventPayloadType; | |
2283 return 0; | |
2284 } | |
2285 | |
2286 int Channel::UpdateRxVadDetection(AudioFrame& audioFrame) { | 2256 int Channel::UpdateRxVadDetection(AudioFrame& audioFrame) { |
2287 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), | 2257 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), |
2288 "Channel::UpdateRxVadDetection()"); | 2258 "Channel::UpdateRxVadDetection()"); |
2289 | 2259 |
2290 int vadDecision = 1; | 2260 int vadDecision = 1; |
2291 | 2261 |
2292 vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive) ? 1 : 0; | 2262 vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive) ? 1 : 0; |
2293 | 2263 |
2294 if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) { | 2264 if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) { |
2295 OnRxVadDetected(vadDecision); | 2265 OnRxVadDetected(vadDecision); |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3022 rtc::CritScope cs(&_callbackCritSect); | 2992 rtc::CritScope cs(&_callbackCritSect); |
3023 const bool isStereo = (_audioFrame.num_channels_ == 2); | 2993 const bool isStereo = (_audioFrame.num_channels_ == 2); |
3024 if (_inputExternalMediaCallbackPtr) { | 2994 if (_inputExternalMediaCallbackPtr) { |
3025 _inputExternalMediaCallbackPtr->Process( | 2995 _inputExternalMediaCallbackPtr->Process( |
3026 _channelId, kRecordingPerChannel, (int16_t*)_audioFrame.data_, | 2996 _channelId, kRecordingPerChannel, (int16_t*)_audioFrame.data_, |
3027 _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_, | 2997 _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_, |
3028 isStereo); | 2998 isStereo); |
3029 } | 2999 } |
3030 } | 3000 } |
3031 | 3001 |
3032 InsertInbandDtmfTone(); | |
3033 | |
3034 if (_includeAudioLevelIndication) { | 3002 if (_includeAudioLevelIndication) { |
3035 size_t length = | 3003 size_t length = |
3036 _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; | 3004 _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; |
3037 if (is_muted) { | 3005 if (is_muted) { |
3038 rms_level_.ProcessMuted(length); | 3006 rms_level_.ProcessMuted(length); |
3039 } else { | 3007 } else { |
3040 rms_level_.Process(_audioFrame.data_, length); | 3008 rms_level_.Process(_audioFrame.data_, length); |
3041 } | 3009 } |
3042 } | 3010 } |
3043 | 3011 |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3343 "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS | 3311 "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS |
3344 ") != " | 3312 ") != " |
3345 "fileSamples(%" PRIuS ")", | 3313 "fileSamples(%" PRIuS ")", |
3346 audioFrame.samples_per_channel_, fileSamples); | 3314 audioFrame.samples_per_channel_, fileSamples); |
3347 return -1; | 3315 return -1; |
3348 } | 3316 } |
3349 | 3317 |
3350 return 0; | 3318 return 0; |
3351 } | 3319 } |
3352 | 3320 |
3353 int Channel::InsertInbandDtmfTone() { | |
3354 // Check if we should start a new tone. | |
3355 if (_inbandDtmfQueue.PendingDtmf() && !_inbandDtmfGenerator.IsAddingTone() && | |
3356 _inbandDtmfGenerator.DelaySinceLastTone() > | |
3357 kMinTelephoneEventSeparationMs) { | |
3358 int8_t eventCode(0); | |
3359 uint16_t lengthMs(0); | |
3360 uint8_t attenuationDb(0); | |
3361 | |
3362 eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); | |
3363 _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); | |
3364 if (_playInbandDtmfEvent) { | |
3365 // Add tone to output mixer using a reduced length to minimize | |
3366 // risk of echo. | |
3367 _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, attenuationDb); | |
3368 } | |
3369 } | |
3370 | |
3371 if (_inbandDtmfGenerator.IsAddingTone()) { | |
3372 uint16_t frequency(0); | |
3373 _inbandDtmfGenerator.GetSampleRate(frequency); | |
3374 | |
3375 if (frequency != _audioFrame.sample_rate_hz_) { | |
3376 // Update sample rate of Dtmf tone since the mixing frequency | |
3377 // has changed. | |
3378 _inbandDtmfGenerator.SetSampleRate( | |
3379 (uint16_t)(_audioFrame.sample_rate_hz_)); | |
3380 // Reset the tone to be added taking the new sample rate into | |
3381 // account. | |
3382 _inbandDtmfGenerator.ResetTone(); | |
3383 } | |
3384 | |
3385 int16_t toneBuffer[320]; | |
3386 uint16_t toneSamples(0); | |
3387 // Get 10ms tone segment and set time since last tone to zero | |
3388 if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) { | |
3389 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), | |
3390 "Channel::EncodeAndSend() inserting Dtmf failed"); | |
3391 return -1; | |
3392 } | |
3393 | |
3394 // Replace mixed audio with DTMF tone. | |
3395 for (size_t sample = 0; sample < _audioFrame.samples_per_channel_; | |
3396 sample++) { | |
3397 for (size_t channel = 0; channel < _audioFrame.num_channels_; channel++) { | |
3398 const size_t index = sample * _audioFrame.num_channels_ + channel; | |
3399 _audioFrame.data_[index] = toneBuffer[sample]; | |
3400 } | |
3401 } | |
3402 | |
3403 assert(_audioFrame.samples_per_channel_ == toneSamples); | |
3404 } else { | |
3405 // Add 10ms to "delay-since-last-tone" counter | |
3406 _inbandDtmfGenerator.UpdateDelaySinceLastTone(); | |
3407 } | |
3408 return 0; | |
3409 } | |
3410 | |
3411 void Channel::UpdatePlayoutTimestamp(bool rtcp) { | 3321 void Channel::UpdatePlayoutTimestamp(bool rtcp) { |
3412 uint32_t playout_timestamp = 0; | 3322 uint32_t playout_timestamp = 0; |
3413 | 3323 |
3414 if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { | 3324 if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { |
3415 // This can happen if this channel has not been received any RTP packet. In | 3325 // This can happen if this channel has not been received any RTP packet. In |
3416 // this case, NetEq is not capable of computing playout timestamp. | 3326 // this case, NetEq is not capable of computing playout timestamp. |
3417 return; | 3327 return; |
3418 } | 3328 } |
3419 | 3329 |
3420 uint16_t delay_ms = 0; | 3330 uint16_t delay_ms = 0; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3649 int64_t min_rtt = 0; | 3559 int64_t min_rtt = 0; |
3650 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != | 3560 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != |
3651 0) { | 3561 0) { |
3652 return 0; | 3562 return 0; |
3653 } | 3563 } |
3654 return rtt; | 3564 return rtt; |
3655 } | 3565 } |
3656 | 3566 |
3657 } // namespace voe | 3567 } // namespace voe |
3658 } // namespace webrtc | 3568 } // namespace webrtc |
OLD | NEW |