OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 } | 107 } |
108 | 108 |
109 webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { | 109 webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { |
110 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 110 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
111 webrtc::AudioSendStream::Stats stats; | 111 webrtc::AudioSendStream::Stats stats; |
112 stats.local_ssrc = config_.rtp.ssrc; | 112 stats.local_ssrc = config_.rtp.ssrc; |
113 ScopedVoEInterface<VoEAudioProcessing> processing(voice_engine()); | 113 ScopedVoEInterface<VoEAudioProcessing> processing(voice_engine()); |
114 ScopedVoEInterface<VoECodec> codec(voice_engine()); | 114 ScopedVoEInterface<VoECodec> codec(voice_engine()); |
115 ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine()); | 115 ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine()); |
116 ScopedVoEInterface<VoEVolumeControl> volume(voice_engine()); | 116 ScopedVoEInterface<VoEVolumeControl> volume(voice_engine()); |
117 unsigned int ssrc = 0; | 117 |
118 webrtc::CallStatistics call_stats = {0}; | 118 webrtc::CallStatistics call_stats = {0}; |
119 // TODO(solenberg): Change error code checking to RTC_CHECK_EQ(..., -1), if | 119 RTC_CHECK_EQ(0, rtp->GetRTCPStatistics(config_.voe_channel_id, call_stats)); |
120 // possible... | |
121 if (rtp->GetLocalSSRC(config_.voe_channel_id, ssrc) == -1 || | |
122 rtp->GetRTCPStatistics(config_.voe_channel_id, call_stats) == -1) { | |
123 return stats; | |
124 } | |
125 | |
126 stats.bytes_sent = call_stats.bytesSent; | 120 stats.bytes_sent = call_stats.bytesSent; |
127 stats.packets_sent = call_stats.packetsSent; | 121 stats.packets_sent = call_stats.packetsSent; |
122 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine | |
123 // returns 0 to indicate an error value. | |
124 if (call_stats.rttMs > 0) { | |
125 stats.rtt_ms = call_stats.rttMs; | |
126 } | |
127 // TODO(ajm): Re-enable this metric once we have a reliable implementation. | |
tommi
2015/11/12 16:24:43
assign this to peah? (or yourself?)
the sun
2015/11/12 16:38:17
Done.
| |
128 stats.aec_quality_min = -1; | |
128 | 129 |
129 webrtc::CodecInst codec_inst = {0}; | 130 webrtc::CodecInst codec_inst = {0}; |
130 if (codec->GetSendCodec(config_.voe_channel_id, codec_inst) != -1) { | 131 if (codec->GetSendCodec(config_.voe_channel_id, codec_inst) != -1) { |
131 RTC_DCHECK_NE(codec_inst.pltype, -1); | 132 RTC_DCHECK_NE(codec_inst.pltype, -1); |
132 stats.codec_name = codec_inst.plname; | 133 stats.codec_name = codec_inst.plname; |
133 | 134 |
134 // Get data from the last remote RTCP report. | 135 // Get data from the last remote RTCP report. |
135 std::vector<webrtc::ReportBlock> blocks; | 136 std::vector<webrtc::ReportBlock> blocks; |
136 if (rtp->GetRemoteRTCPReportBlocks(config_.voe_channel_id, &blocks) != -1) { | 137 RTC_CHECK_EQ(0, rtp->GetRemoteRTCPReportBlocks(config_.voe_channel_id, |
tommi
2015/11/12 16:24:43
is it preferable to do this at every call site whe
the sun
2015/11/12 16:38:17
It's a public API, used by 3rd parties. I can guar
| |
137 for (const webrtc::ReportBlock& block : blocks) { | 138 &blocks)); |
138 // Lookup report for send ssrc only. | 139 for (const webrtc::ReportBlock& block : blocks) { |
139 if (block.source_SSRC == stats.local_ssrc) { | 140 // Lookup report for send ssrc only. |
140 stats.packets_lost = block.cumulative_num_packets_lost; | 141 if (block.source_SSRC == stats.local_ssrc) { |
141 stats.fraction_lost = Q8ToFloat(block.fraction_lost); | 142 stats.packets_lost = block.cumulative_num_packets_lost; |
142 stats.ext_seqnum = block.extended_highest_sequence_number; | 143 stats.fraction_lost = Q8ToFloat(block.fraction_lost); |
143 // Convert samples to milliseconds. | 144 stats.ext_seqnum = block.extended_highest_sequence_number; |
144 if (codec_inst.plfreq / 1000 > 0) { | 145 // Convert samples to milliseconds. |
145 stats.jitter_ms = | 146 if (codec_inst.plfreq / 1000 > 0) { |
146 block.interarrival_jitter / (codec_inst.plfreq / 1000); | 147 stats.jitter_ms = |
147 } | 148 block.interarrival_jitter / (codec_inst.plfreq / 1000); |
148 break; | |
149 } | 149 } |
150 break; | |
150 } | 151 } |
151 } | 152 } |
152 } | 153 } |
153 | 154 |
154 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine | |
155 // returns 0 to indicate an error value. | |
156 if (call_stats.rttMs > 0) { | |
157 stats.rtt_ms = call_stats.rttMs; | |
158 } | |
159 | |
160 // Local speech level. | 155 // Local speech level. |
161 { | 156 { |
162 unsigned int level = 0; | 157 unsigned int level = 0; |
163 if (volume->GetSpeechInputLevelFullRange(level) != -1) { | 158 RTC_CHECK_EQ(0, volume->GetSpeechInputLevelFullRange(level)); |
tommi
2015/11/12 16:24:43
same question here and I guess other places.
the sun
2015/11/12 16:38:17
Acknowledged.
| |
164 stats.audio_level = static_cast<int32_t>(level); | 159 stats.audio_level = static_cast<int32_t>(level); |
165 } | |
166 } | 160 } |
167 | 161 |
168 // TODO(ajm): Re-enable this metric once we have a reliable implementation. | |
169 stats.aec_quality_min = -1; | |
170 | |
171 bool echo_metrics_on = false; | 162 bool echo_metrics_on = false; |
172 if (processing->GetEcMetricsStatus(echo_metrics_on) != -1 && | 163 RTC_CHECK_EQ(0, processing->GetEcMetricsStatus(echo_metrics_on)); |
173 echo_metrics_on) { | 164 if (echo_metrics_on) { |
174 // These can also be negative, but in practice -1 is only used to signal | 165 // These can also be negative, but in practice -1 is only used to signal |
175 // insufficient data, since the resolution is limited to multiples of 4 ms. | 166 // insufficient data, since the resolution is limited to multiples of 4 ms. |
176 int median = -1; | 167 int median = -1; |
177 int std = -1; | 168 int std = -1; |
178 float dummy = 0.0f; | 169 float dummy = 0.0f; |
179 if (processing->GetEcDelayMetrics(median, std, dummy) != -1) { | 170 RTC_CHECK_EQ(0, processing->GetEcDelayMetrics(median, std, dummy)); |
180 stats.echo_delay_median_ms = median; | 171 stats.echo_delay_median_ms = median; |
181 stats.echo_delay_std_ms = std; | 172 stats.echo_delay_std_ms = std; |
182 } | |
183 | 173 |
184 // These can take on valid negative values, so use the lowest possible level | 174 // These can take on valid negative values, so use the lowest possible level |
185 // as default rather than -1. | 175 // as default rather than -1. |
186 int erl = -100; | 176 int erl = -100; |
187 int erle = -100; | 177 int erle = -100; |
188 int dummy1 = 0; | 178 int dummy1 = 0; |
189 int dummy2 = 0; | 179 int dummy2 = 0; |
190 if (processing->GetEchoMetrics(erl, erle, dummy1, dummy2) != -1) { | 180 RTC_CHECK_EQ(0, processing->GetEchoMetrics(erl, erle, dummy1, dummy2)); |
191 stats.echo_return_loss = erl; | 181 stats.echo_return_loss = erl; |
192 stats.echo_return_loss_enhancement = erle; | 182 stats.echo_return_loss_enhancement = erle; |
193 } | |
194 } | 183 } |
195 | 184 |
196 internal::AudioState* audio_state = | 185 internal::AudioState* audio_state = |
197 static_cast<internal::AudioState*>(audio_state_.get()); | 186 static_cast<internal::AudioState*>(audio_state_.get()); |
198 stats.typing_noise_detected = audio_state->typing_noise_detected(); | 187 stats.typing_noise_detected = audio_state->typing_noise_detected(); |
199 | 188 |
200 return stats; | 189 return stats; |
201 } | 190 } |
202 | 191 |
203 const webrtc::AudioSendStream::Config& AudioSendStream::config() const { | 192 const webrtc::AudioSendStream::Config& AudioSendStream::config() const { |
204 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 193 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
205 return config_; | 194 return config_; |
206 } | 195 } |
207 | 196 |
208 VoiceEngine* AudioSendStream::voice_engine() const { | 197 VoiceEngine* AudioSendStream::voice_engine() const { |
209 internal::AudioState* audio_state = | 198 internal::AudioState* audio_state = |
210 static_cast<internal::AudioState*>(audio_state_.get()); | 199 static_cast<internal::AudioState*>(audio_state_.get()); |
211 VoiceEngine* voice_engine = audio_state->voice_engine(); | 200 VoiceEngine* voice_engine = audio_state->voice_engine(); |
212 RTC_DCHECK(voice_engine); | 201 RTC_DCHECK(voice_engine); |
213 return voice_engine; | 202 return voice_engine; |
214 } | 203 } |
215 } // namespace internal | 204 } // namespace internal |
216 } // namespace webrtc | 205 } // namespace webrtc |
OLD | NEW |