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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 : config_(config), audio_state_(audio_state) { | 59 : config_(config), audio_state_(audio_state) { |
60 LOG(LS_INFO) << "AudioSendStream: " << config_.ToString(); | 60 LOG(LS_INFO) << "AudioSendStream: " << config_.ToString(); |
61 RTC_DCHECK_NE(config_.voe_channel_id, -1); | 61 RTC_DCHECK_NE(config_.voe_channel_id, -1); |
62 RTC_DCHECK(audio_state_.get()); | 62 RTC_DCHECK(audio_state_.get()); |
63 | 63 |
64 VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine()); | 64 VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine()); |
65 channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id); | 65 channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id); |
66 channel_proxy_->SetRTCPStatus(true); | 66 channel_proxy_->SetRTCPStatus(true); |
67 channel_proxy_->SetLocalSSRC(config.rtp.ssrc); | 67 channel_proxy_->SetLocalSSRC(config.rtp.ssrc); |
68 channel_proxy_->SetRTCP_CNAME(config.rtp.c_name); | 68 channel_proxy_->SetRTCP_CNAME(config.rtp.c_name); |
69 | |
70 const int channel_id = config.voe_channel_id; | |
71 ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine()); | |
72 for (const auto& extension : config.rtp.extensions) { | 69 for (const auto& extension : config.rtp.extensions) { |
73 // One-byte-extension local identifiers are in the range 1-14 inclusive. | |
74 RTC_DCHECK_GE(extension.id, 1); | |
75 RTC_DCHECK_LE(extension.id, 14); | |
76 if (extension.name == RtpExtension::kAbsSendTime) { | 70 if (extension.name == RtpExtension::kAbsSendTime) { |
77 int error = rtp->SetSendAbsoluteSenderTimeStatus(channel_id, true, | 71 channel_proxy_->SetSendAbsoluteSenderTimeStatus(true, extension.id); |
78 extension.id); | |
79 RTC_DCHECK_EQ(0, error); | |
80 } else if (extension.name == RtpExtension::kAudioLevel) { | 72 } else if (extension.name == RtpExtension::kAudioLevel) { |
81 int error = rtp->SetSendAudioLevelIndicationStatus(channel_id, true, | 73 channel_proxy_->SetSendAudioLevelIndicationStatus(true, extension.id); |
82 extension.id); | |
83 RTC_DCHECK_EQ(0, error); | |
84 } else { | 74 } else { |
85 RTC_NOTREACHED() << "Registering unsupported RTP extension."; | 75 RTC_NOTREACHED() << "Registering unsupported RTP extension."; |
86 } | 76 } |
87 } | 77 } |
88 } | 78 } |
89 | 79 |
90 AudioSendStream::~AudioSendStream() { | 80 AudioSendStream::~AudioSendStream() { |
91 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 81 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
92 LOG(LS_INFO) << "~AudioSendStream: " << config_.ToString(); | 82 LOG(LS_INFO) << "~AudioSendStream: " << config_.ToString(); |
93 } | 83 } |
(...skipping 17 matching lines...) Expand all Loading... |
111 // RTC_DCHECK(!thread_checker_.CalledOnValidThread()); | 101 // RTC_DCHECK(!thread_checker_.CalledOnValidThread()); |
112 return false; | 102 return false; |
113 } | 103 } |
114 | 104 |
115 webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { | 105 webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { |
116 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 106 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
117 webrtc::AudioSendStream::Stats stats; | 107 webrtc::AudioSendStream::Stats stats; |
118 stats.local_ssrc = config_.rtp.ssrc; | 108 stats.local_ssrc = config_.rtp.ssrc; |
119 ScopedVoEInterface<VoEAudioProcessing> processing(voice_engine()); | 109 ScopedVoEInterface<VoEAudioProcessing> processing(voice_engine()); |
120 ScopedVoEInterface<VoECodec> codec(voice_engine()); | 110 ScopedVoEInterface<VoECodec> codec(voice_engine()); |
121 ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine()); | |
122 ScopedVoEInterface<VoEVolumeControl> volume(voice_engine()); | 111 ScopedVoEInterface<VoEVolumeControl> volume(voice_engine()); |
123 | 112 |
124 webrtc::CallStatistics call_stats = {0}; | 113 webrtc::CallStatistics call_stats = channel_proxy_->GetRTCPStatistics(); |
125 int error = rtp->GetRTCPStatistics(config_.voe_channel_id, call_stats); | |
126 RTC_DCHECK_EQ(0, error); | |
127 stats.bytes_sent = call_stats.bytesSent; | 114 stats.bytes_sent = call_stats.bytesSent; |
128 stats.packets_sent = call_stats.packetsSent; | 115 stats.packets_sent = call_stats.packetsSent; |
129 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine | 116 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine |
130 // returns 0 to indicate an error value. | 117 // returns 0 to indicate an error value. |
131 if (call_stats.rttMs > 0) { | 118 if (call_stats.rttMs > 0) { |
132 stats.rtt_ms = call_stats.rttMs; | 119 stats.rtt_ms = call_stats.rttMs; |
133 } | 120 } |
134 // TODO(solenberg): [was ajm]: Re-enable this metric once we have a reliable | 121 // TODO(solenberg): [was ajm]: Re-enable this metric once we have a reliable |
135 // implementation. | 122 // implementation. |
136 stats.aec_quality_min = -1; | 123 stats.aec_quality_min = -1; |
137 | 124 |
138 webrtc::CodecInst codec_inst = {0}; | 125 webrtc::CodecInst codec_inst = {0}; |
139 if (codec->GetSendCodec(config_.voe_channel_id, codec_inst) != -1) { | 126 if (codec->GetSendCodec(config_.voe_channel_id, codec_inst) != -1) { |
140 RTC_DCHECK_NE(codec_inst.pltype, -1); | 127 RTC_DCHECK_NE(codec_inst.pltype, -1); |
141 stats.codec_name = codec_inst.plname; | 128 stats.codec_name = codec_inst.plname; |
142 | 129 |
143 // Get data from the last remote RTCP report. | 130 // Get data from the last remote RTCP report. |
144 std::vector<webrtc::ReportBlock> blocks; | 131 for (const auto& block : channel_proxy_->GetRemoteRTCPReportBlocks()) { |
145 error = rtp->GetRemoteRTCPReportBlocks(config_.voe_channel_id, &blocks); | |
146 RTC_DCHECK_EQ(0, error); | |
147 for (const webrtc::ReportBlock& block : blocks) { | |
148 // Lookup report for send ssrc only. | 132 // Lookup report for send ssrc only. |
149 if (block.source_SSRC == stats.local_ssrc) { | 133 if (block.source_SSRC == stats.local_ssrc) { |
150 stats.packets_lost = block.cumulative_num_packets_lost; | 134 stats.packets_lost = block.cumulative_num_packets_lost; |
151 stats.fraction_lost = Q8ToFloat(block.fraction_lost); | 135 stats.fraction_lost = Q8ToFloat(block.fraction_lost); |
152 stats.ext_seqnum = block.extended_highest_sequence_number; | 136 stats.ext_seqnum = block.extended_highest_sequence_number; |
153 // Convert samples to milliseconds. | 137 // Convert samples to milliseconds. |
154 if (codec_inst.plfreq / 1000 > 0) { | 138 if (codec_inst.plfreq / 1000 > 0) { |
155 stats.jitter_ms = | 139 stats.jitter_ms = |
156 block.interarrival_jitter / (codec_inst.plfreq / 1000); | 140 block.interarrival_jitter / (codec_inst.plfreq / 1000); |
157 } | 141 } |
158 break; | 142 break; |
159 } | 143 } |
160 } | 144 } |
161 } | 145 } |
162 | 146 |
163 // Local speech level. | 147 // Local speech level. |
164 { | 148 { |
165 unsigned int level = 0; | 149 unsigned int level = 0; |
166 error = volume->GetSpeechInputLevelFullRange(level); | 150 int error = volume->GetSpeechInputLevelFullRange(level); |
167 RTC_DCHECK_EQ(0, error); | 151 RTC_DCHECK_EQ(0, error); |
168 stats.audio_level = static_cast<int32_t>(level); | 152 stats.audio_level = static_cast<int32_t>(level); |
169 } | 153 } |
170 | 154 |
171 bool echo_metrics_on = false; | 155 bool echo_metrics_on = false; |
172 error = processing->GetEcMetricsStatus(echo_metrics_on); | 156 int error = processing->GetEcMetricsStatus(echo_metrics_on); |
173 RTC_DCHECK_EQ(0, error); | 157 RTC_DCHECK_EQ(0, error); |
174 if (echo_metrics_on) { | 158 if (echo_metrics_on) { |
175 // These can also be negative, but in practice -1 is only used to signal | 159 // These can also be negative, but in practice -1 is only used to signal |
176 // insufficient data, since the resolution is limited to multiples of 4 ms. | 160 // insufficient data, since the resolution is limited to multiples of 4 ms. |
177 int median = -1; | 161 int median = -1; |
178 int std = -1; | 162 int std = -1; |
179 float dummy = 0.0f; | 163 float dummy = 0.0f; |
180 error = processing->GetEcDelayMetrics(median, std, dummy); | 164 error = processing->GetEcDelayMetrics(median, std, dummy); |
181 RTC_DCHECK_EQ(0, error); | 165 RTC_DCHECK_EQ(0, error); |
182 stats.echo_delay_median_ms = median; | 166 stats.echo_delay_median_ms = median; |
(...skipping 25 matching lines...) Expand all Loading... |
208 | 192 |
209 VoiceEngine* AudioSendStream::voice_engine() const { | 193 VoiceEngine* AudioSendStream::voice_engine() const { |
210 internal::AudioState* audio_state = | 194 internal::AudioState* audio_state = |
211 static_cast<internal::AudioState*>(audio_state_.get()); | 195 static_cast<internal::AudioState*>(audio_state_.get()); |
212 VoiceEngine* voice_engine = audio_state->voice_engine(); | 196 VoiceEngine* voice_engine = audio_state->voice_engine(); |
213 RTC_DCHECK(voice_engine); | 197 RTC_DCHECK(voice_engine); |
214 return voice_engine; | 198 return voice_engine; |
215 } | 199 } |
216 } // namespace internal | 200 } // namespace internal |
217 } // namespace webrtc | 201 } // namespace webrtc |
OLD | NEW |