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 17 matching lines...) Expand all Loading... |
28 #include "webrtc/modules/audio_device/include/audio_device.h" | 28 #include "webrtc/modules/audio_device/include/audio_device.h" |
29 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 29 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
30 #include "webrtc/modules/include/module_common_types.h" | 30 #include "webrtc/modules/include/module_common_types.h" |
31 #include "webrtc/modules/pacing/packet_router.h" | 31 #include "webrtc/modules/pacing/packet_router.h" |
32 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" | 32 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" |
33 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | 33 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
34 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | 34 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
35 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" | 35 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" |
36 #include "webrtc/modules/utility/include/process_thread.h" | 36 #include "webrtc/modules/utility/include/process_thread.h" |
37 #include "webrtc/system_wrappers/include/trace.h" | 37 #include "webrtc/system_wrappers/include/trace.h" |
38 #include "webrtc/voice_engine/include/voe_external_media.h" | |
39 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" | 38 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" |
40 #include "webrtc/voice_engine/output_mixer.h" | 39 #include "webrtc/voice_engine/output_mixer.h" |
41 #include "webrtc/voice_engine/statistics.h" | 40 #include "webrtc/voice_engine/statistics.h" |
42 #include "webrtc/voice_engine/transmit_mixer.h" | 41 #include "webrtc/voice_engine/transmit_mixer.h" |
43 #include "webrtc/voice_engine/utility.h" | 42 #include "webrtc/voice_engine/utility.h" |
44 | 43 |
45 namespace webrtc { | 44 namespace webrtc { |
46 namespace voe { | 45 namespace voe { |
47 | 46 |
48 namespace { | 47 namespace { |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 // stage) | 694 // stage) |
696 AudioFrameOperations::Scale(left_pan, right_pan, *audioFrame); | 695 AudioFrameOperations::Scale(left_pan, right_pan, *audioFrame); |
697 } | 696 } |
698 | 697 |
699 // Mix decoded PCM output with file if file mixing is enabled | 698 // Mix decoded PCM output with file if file mixing is enabled |
700 if (state.output_file_playing) { | 699 if (state.output_file_playing) { |
701 MixAudioWithFile(*audioFrame, audioFrame->sample_rate_hz_); | 700 MixAudioWithFile(*audioFrame, audioFrame->sample_rate_hz_); |
702 muted = false; // We may have added non-zero samples. | 701 muted = false; // We may have added non-zero samples. |
703 } | 702 } |
704 | 703 |
705 // External media | |
706 if (_outputExternalMedia) { | |
707 rtc::CritScope cs(&_callbackCritSect); | |
708 const bool isStereo = (audioFrame->num_channels_ == 2); | |
709 if (_outputExternalMediaCallbackPtr) { | |
710 _outputExternalMediaCallbackPtr->Process( | |
711 _channelId, kPlaybackPerChannel, (int16_t*)audioFrame->data_, | |
712 audioFrame->samples_per_channel_, audioFrame->sample_rate_hz_, | |
713 isStereo); | |
714 } | |
715 } | |
716 | |
717 // Record playout if enabled | 704 // Record playout if enabled |
718 { | 705 { |
719 rtc::CritScope cs(&_fileCritSect); | 706 rtc::CritScope cs(&_fileCritSect); |
720 | 707 |
721 if (_outputFileRecording && output_file_recorder_) { | 708 if (_outputFileRecording && output_file_recorder_) { |
722 output_file_recorder_->RecordAudioToFile(*audioFrame); | 709 output_file_recorder_->RecordAudioToFile(*audioFrame); |
723 } | 710 } |
724 } | 711 } |
725 | 712 |
726 // Measure audio level (0-9) | 713 // Measure audio level (0-9) |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 rtp_payload_registry_.get())), | 887 rtp_payload_registry_.get())), |
901 telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()), | 888 telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()), |
902 _outputAudioLevel(), | 889 _outputAudioLevel(), |
903 _externalTransport(false), | 890 _externalTransport(false), |
904 // Avoid conflict with other channels by adding 1024 - 1026, | 891 // Avoid conflict with other channels by adding 1024 - 1026, |
905 // won't use as much as 1024 channels. | 892 // won't use as much as 1024 channels. |
906 _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), | 893 _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), |
907 _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), | 894 _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), |
908 _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), | 895 _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), |
909 _outputFileRecording(false), | 896 _outputFileRecording(false), |
910 _outputExternalMedia(false), | |
911 _inputExternalMediaCallbackPtr(NULL), | |
912 _outputExternalMediaCallbackPtr(NULL), | |
913 _timeStamp(0), // This is just an offset, RTP module will add it's own | 897 _timeStamp(0), // This is just an offset, RTP module will add it's own |
914 // random offset | 898 // random offset |
915 ntp_estimator_(Clock::GetRealTimeClock()), | 899 ntp_estimator_(Clock::GetRealTimeClock()), |
916 playout_timestamp_rtp_(0), | 900 playout_timestamp_rtp_(0), |
917 playout_timestamp_rtcp_(0), | 901 playout_timestamp_rtcp_(0), |
918 playout_delay_ms_(0), | 902 playout_delay_ms_(0), |
919 _numberOfDiscardedPackets(0), | 903 _numberOfDiscardedPackets(0), |
920 send_sequence_number_(0), | 904 send_sequence_number_(0), |
921 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), | 905 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), |
922 capture_start_rtp_time_stamp_(-1), | 906 capture_start_rtp_time_stamp_(-1), |
923 capture_start_ntp_time_ms_(-1), | 907 capture_start_ntp_time_ms_(-1), |
924 _engineStatisticsPtr(NULL), | 908 _engineStatisticsPtr(NULL), |
925 _outputMixerPtr(NULL), | 909 _outputMixerPtr(NULL), |
926 _transmitMixerPtr(NULL), | 910 _transmitMixerPtr(NULL), |
927 _moduleProcessThreadPtr(NULL), | 911 _moduleProcessThreadPtr(NULL), |
928 _audioDeviceModulePtr(NULL), | 912 _audioDeviceModulePtr(NULL), |
929 _voiceEngineObserverPtr(NULL), | 913 _voiceEngineObserverPtr(NULL), |
930 _callbackCritSectPtr(NULL), | 914 _callbackCritSectPtr(NULL), |
931 _transportPtr(NULL), | 915 _transportPtr(NULL), |
932 _sendFrameType(0), | 916 _sendFrameType(0), |
933 _externalMixing(false), | |
934 _mixFileWithMicrophone(false), | 917 _mixFileWithMicrophone(false), |
935 input_mute_(false), | 918 input_mute_(false), |
936 previous_frame_muted_(false), | 919 previous_frame_muted_(false), |
937 _panLeft(1.0f), | 920 _panLeft(1.0f), |
938 _panRight(1.0f), | 921 _panRight(1.0f), |
939 _outputGain(1.0f), | 922 _outputGain(1.0f), |
940 _lastLocalTimeStamp(0), | 923 _lastLocalTimeStamp(0), |
941 _lastPayloadType(0), | 924 _lastPayloadType(0), |
942 _includeAudioLevelIndication(false), | 925 _includeAudioLevelIndication(false), |
943 transport_overhead_per_packet_(0), | 926 transport_overhead_per_packet_(0), |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); | 968 statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); |
986 rtp_receive_statistics_->RegisterRtcpStatisticsCallback( | 969 rtp_receive_statistics_->RegisterRtcpStatisticsCallback( |
987 statistics_proxy_.get()); | 970 statistics_proxy_.get()); |
988 } | 971 } |
989 | 972 |
990 Channel::~Channel() { | 973 Channel::~Channel() { |
991 rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL); | 974 rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL); |
992 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, _channelId), | 975 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, _channelId), |
993 "Channel::~Channel() - dtor"); | 976 "Channel::~Channel() - dtor"); |
994 | 977 |
995 if (_outputExternalMedia) { | |
996 DeRegisterExternalMediaProcessing(kPlaybackPerChannel); | |
997 } | |
998 if (channel_state_.Get().input_external_media) { | |
999 DeRegisterExternalMediaProcessing(kRecordingPerChannel); | |
1000 } | |
1001 StopSend(); | 978 StopSend(); |
1002 StopPlayout(); | 979 StopPlayout(); |
1003 | 980 |
1004 { | 981 { |
1005 rtc::CritScope cs(&_fileCritSect); | 982 rtc::CritScope cs(&_fileCritSect); |
1006 if (input_file_player_) { | 983 if (input_file_player_) { |
1007 input_file_player_->RegisterModuleFileCallback(NULL); | 984 input_file_player_->RegisterModuleFileCallback(NULL); |
1008 input_file_player_->StopPlayingFile(); | 985 input_file_player_->StopPlayingFile(); |
1009 } | 986 } |
1010 if (output_file_player_) { | 987 if (output_file_player_) { |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 return decoder_factory_; | 1154 return decoder_factory_; |
1178 } | 1155 } |
1179 | 1156 |
1180 int32_t Channel::StartPlayout() { | 1157 int32_t Channel::StartPlayout() { |
1181 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 1158 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
1182 "Channel::StartPlayout()"); | 1159 "Channel::StartPlayout()"); |
1183 if (channel_state_.Get().playing) { | 1160 if (channel_state_.Get().playing) { |
1184 return 0; | 1161 return 0; |
1185 } | 1162 } |
1186 | 1163 |
1187 if (!_externalMixing) { | 1164 // Add participant as candidates for mixing. |
1188 // Add participant as candidates for mixing. | 1165 if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) { |
1189 if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) { | 1166 _engineStatisticsPtr->SetLastError( |
1190 _engineStatisticsPtr->SetLastError( | 1167 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, |
1191 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, | 1168 "StartPlayout() failed to add participant to mixer"); |
1192 "StartPlayout() failed to add participant to mixer"); | 1169 return -1; |
1193 return -1; | |
1194 } | |
1195 } | 1170 } |
1196 | 1171 |
1197 channel_state_.SetPlaying(true); | 1172 channel_state_.SetPlaying(true); |
1198 if (RegisterFilePlayingToMixer() != 0) | 1173 if (RegisterFilePlayingToMixer() != 0) |
1199 return -1; | 1174 return -1; |
1200 | 1175 |
1201 return 0; | 1176 return 0; |
1202 } | 1177 } |
1203 | 1178 |
1204 int32_t Channel::StopPlayout() { | 1179 int32_t Channel::StopPlayout() { |
1205 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 1180 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
1206 "Channel::StopPlayout()"); | 1181 "Channel::StopPlayout()"); |
1207 if (!channel_state_.Get().playing) { | 1182 if (!channel_state_.Get().playing) { |
1208 return 0; | 1183 return 0; |
1209 } | 1184 } |
1210 | 1185 |
1211 if (!_externalMixing) { | 1186 // Remove participant as candidates for mixing |
1212 // Remove participant as candidates for mixing | 1187 if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) { |
1213 if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) { | 1188 _engineStatisticsPtr->SetLastError( |
1214 _engineStatisticsPtr->SetLastError( | 1189 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, |
1215 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, | 1190 "StopPlayout() failed to remove participant from mixer"); |
1216 "StopPlayout() failed to remove participant from mixer"); | 1191 return -1; |
1217 return -1; | |
1218 } | |
1219 } | 1192 } |
1220 | 1193 |
1221 channel_state_.SetPlaying(false); | 1194 channel_state_.SetPlaying(false); |
1222 _outputAudioLevel.Clear(); | 1195 _outputAudioLevel.Clear(); |
1223 | 1196 |
1224 return 0; | 1197 return 0; |
1225 } | 1198 } |
1226 | 1199 |
1227 int32_t Channel::StartSend() { | 1200 int32_t Channel::StartSend() { |
1228 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 1201 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2817 return 0xFFFFFFFF; | 2790 return 0xFFFFFFFF; |
2818 } | 2791 } |
2819 | 2792 |
2820 if (channel_state_.Get().input_file_playing) { | 2793 if (channel_state_.Get().input_file_playing) { |
2821 MixOrReplaceAudioWithFile(mixingFrequency); | 2794 MixOrReplaceAudioWithFile(mixingFrequency); |
2822 } | 2795 } |
2823 | 2796 |
2824 bool is_muted = InputMute(); // Cache locally as InputMute() takes a lock. | 2797 bool is_muted = InputMute(); // Cache locally as InputMute() takes a lock. |
2825 AudioFrameOperations::Mute(&_audioFrame, previous_frame_muted_, is_muted); | 2798 AudioFrameOperations::Mute(&_audioFrame, previous_frame_muted_, is_muted); |
2826 | 2799 |
2827 if (channel_state_.Get().input_external_media) { | |
2828 rtc::CritScope cs(&_callbackCritSect); | |
2829 const bool isStereo = (_audioFrame.num_channels_ == 2); | |
2830 if (_inputExternalMediaCallbackPtr) { | |
2831 _inputExternalMediaCallbackPtr->Process( | |
2832 _channelId, kRecordingPerChannel, (int16_t*)_audioFrame.data_, | |
2833 _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_, | |
2834 isStereo); | |
2835 } | |
2836 } | |
2837 | |
2838 if (_includeAudioLevelIndication) { | 2800 if (_includeAudioLevelIndication) { |
2839 size_t length = | 2801 size_t length = |
2840 _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; | 2802 _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; |
2841 RTC_CHECK_LE(length, sizeof(_audioFrame.data_)); | 2803 RTC_CHECK_LE(length, sizeof(_audioFrame.data_)); |
2842 if (is_muted && previous_frame_muted_) { | 2804 if (is_muted && previous_frame_muted_) { |
2843 rms_level_.AnalyzeMuted(length); | 2805 rms_level_.AnalyzeMuted(length); |
2844 } else { | 2806 } else { |
2845 rms_level_.Analyze( | 2807 rms_level_.Analyze( |
2846 rtc::ArrayView<const int16_t>(_audioFrame.data_, length)); | 2808 rtc::ArrayView<const int16_t>(_audioFrame.data_, length)); |
2847 } | 2809 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2919 void Channel::SetTransportOverhead(size_t transport_overhead_per_packet) { | 2881 void Channel::SetTransportOverhead(size_t transport_overhead_per_packet) { |
2920 transport_overhead_per_packet_ = transport_overhead_per_packet; | 2882 transport_overhead_per_packet_ = transport_overhead_per_packet; |
2921 UpdateOverheadForEncoder(); | 2883 UpdateOverheadForEncoder(); |
2922 } | 2884 } |
2923 | 2885 |
2924 void Channel::OnOverheadChanged(size_t overhead_bytes_per_packet) { | 2886 void Channel::OnOverheadChanged(size_t overhead_bytes_per_packet) { |
2925 rtp_overhead_per_packet_ = overhead_bytes_per_packet; | 2887 rtp_overhead_per_packet_ = overhead_bytes_per_packet; |
2926 UpdateOverheadForEncoder(); | 2888 UpdateOverheadForEncoder(); |
2927 } | 2889 } |
2928 | 2890 |
2929 int Channel::RegisterExternalMediaProcessing(ProcessingTypes type, | |
2930 VoEMediaProcess& processObject) { | |
2931 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | |
2932 "Channel::RegisterExternalMediaProcessing()"); | |
2933 | |
2934 rtc::CritScope cs(&_callbackCritSect); | |
2935 | |
2936 if (kPlaybackPerChannel == type) { | |
2937 if (_outputExternalMediaCallbackPtr) { | |
2938 _engineStatisticsPtr->SetLastError( | |
2939 VE_INVALID_OPERATION, kTraceError, | |
2940 "Channel::RegisterExternalMediaProcessing() " | |
2941 "output external media already enabled"); | |
2942 return -1; | |
2943 } | |
2944 _outputExternalMediaCallbackPtr = &processObject; | |
2945 _outputExternalMedia = true; | |
2946 } else if (kRecordingPerChannel == type) { | |
2947 if (_inputExternalMediaCallbackPtr) { | |
2948 _engineStatisticsPtr->SetLastError( | |
2949 VE_INVALID_OPERATION, kTraceError, | |
2950 "Channel::RegisterExternalMediaProcessing() " | |
2951 "output external media already enabled"); | |
2952 return -1; | |
2953 } | |
2954 _inputExternalMediaCallbackPtr = &processObject; | |
2955 channel_state_.SetInputExternalMedia(true); | |
2956 } | |
2957 return 0; | |
2958 } | |
2959 | |
2960 int Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) { | |
2961 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | |
2962 "Channel::DeRegisterExternalMediaProcessing()"); | |
2963 | |
2964 rtc::CritScope cs(&_callbackCritSect); | |
2965 | |
2966 if (kPlaybackPerChannel == type) { | |
2967 if (!_outputExternalMediaCallbackPtr) { | |
2968 _engineStatisticsPtr->SetLastError( | |
2969 VE_INVALID_OPERATION, kTraceWarning, | |
2970 "Channel::DeRegisterExternalMediaProcessing() " | |
2971 "output external media already disabled"); | |
2972 return 0; | |
2973 } | |
2974 _outputExternalMedia = false; | |
2975 _outputExternalMediaCallbackPtr = NULL; | |
2976 } else if (kRecordingPerChannel == type) { | |
2977 if (!_inputExternalMediaCallbackPtr) { | |
2978 _engineStatisticsPtr->SetLastError( | |
2979 VE_INVALID_OPERATION, kTraceWarning, | |
2980 "Channel::DeRegisterExternalMediaProcessing() " | |
2981 "input external media already disabled"); | |
2982 return 0; | |
2983 } | |
2984 channel_state_.SetInputExternalMedia(false); | |
2985 _inputExternalMediaCallbackPtr = NULL; | |
2986 } | |
2987 | |
2988 return 0; | |
2989 } | |
2990 | |
2991 int Channel::SetExternalMixing(bool enabled) { | |
2992 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | |
2993 "Channel::SetExternalMixing(enabled=%d)", enabled); | |
2994 | |
2995 if (channel_state_.Get().playing) { | |
2996 _engineStatisticsPtr->SetLastError( | |
2997 VE_INVALID_OPERATION, kTraceError, | |
2998 "Channel::SetExternalMixing() " | |
2999 "external mixing cannot be changed while playing."); | |
3000 return -1; | |
3001 } | |
3002 | |
3003 _externalMixing = enabled; | |
3004 | |
3005 return 0; | |
3006 } | |
3007 | |
3008 int Channel::GetNetworkStatistics(NetworkStatistics& stats) { | 2891 int Channel::GetNetworkStatistics(NetworkStatistics& stats) { |
3009 return audio_coding_->GetNetworkStatistics(&stats); | 2892 return audio_coding_->GetNetworkStatistics(&stats); |
3010 } | 2893 } |
3011 | 2894 |
3012 void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const { | 2895 void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const { |
3013 audio_coding_->GetDecodingCallStatistics(stats); | 2896 audio_coding_->GetDecodingCallStatistics(stats); |
3014 } | 2897 } |
3015 | 2898 |
3016 bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms, | 2899 bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms, |
3017 int* playout_buffer_delay_ms) const { | 2900 int* playout_buffer_delay_ms) const { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3324 int64_t min_rtt = 0; | 3207 int64_t min_rtt = 0; |
3325 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != | 3208 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != |
3326 0) { | 3209 0) { |
3327 return 0; | 3210 return 0; |
3328 } | 3211 } |
3329 return rtt; | 3212 return rtt; |
3330 } | 3213 } |
3331 | 3214 |
3332 } // namespace voe | 3215 } // namespace voe |
3333 } // namespace webrtc | 3216 } // namespace webrtc |
OLD | NEW |