Index: talk/media/webrtc/webrtcvoiceengine.cc |
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc |
index fd93535bea0672c35b64e13e80d1d794475a0dd2..a90acf233c713001f7eb54fa85c344c547d354df 100644 |
--- a/talk/media/webrtc/webrtcvoiceengine.cc |
+++ b/talk/media/webrtc/webrtcvoiceengine.cc |
@@ -1321,6 +1321,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
: channel_(ch), |
voe_audio_transport_(voe_audio_transport), |
call_(call) { |
+ RTC_DCHECK(ch >= 0); |
RTC_DCHECK(call); |
webrtc::AudioSendStream::Config config(nullptr); |
config.voe_channel_id = channel_; |
@@ -1329,6 +1330,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
RTC_DCHECK(stream_); |
} |
~WebRtcAudioSendStream() override { |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
Stop(); |
call_->DestroyAudioSendStream(stream_); |
} |
@@ -1338,7 +1340,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
// This method is called on the libjingle worker thread. |
// TODO(xians): Make sure Start() is called only once. |
void Start(AudioRenderer* renderer) { |
- rtc::CritScope lock(&lock_); |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
RTC_DCHECK(renderer); |
if (renderer_) { |
RTC_DCHECK(renderer_ == renderer); |
@@ -1348,11 +1350,16 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
renderer_ = renderer; |
} |
+ webrtc::AudioSendStream::Stats GetStats() const { |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
+ return stream_->GetStats(); |
+ } |
+ |
// Stops rendering by setting the sink of the renderer to nullptr. No data |
// callback will be received after this method. |
// This method is called on the libjingle worker thread. |
void Stop() { |
- rtc::CritScope lock(&lock_); |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
if (renderer_) { |
renderer_->SetSink(nullptr); |
renderer_ = nullptr; |
@@ -1366,6 +1373,9 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
int sample_rate, |
int number_of_channels, |
size_t number_of_frames) override { |
+ RTC_DCHECK(!thread_checker_.CalledOnValidThread()); |
+ // TODO(solenberg): Move to c-tor once we're not using FakeWebRtcVoiceEngine |
+ // anymore. |
RTC_DCHECK(voe_audio_transport_); |
voe_audio_transport_->OnData(channel_, |
audio_data, |
@@ -1378,16 +1388,20 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
// Callback from the |renderer_| when it is going away. In case Start() has |
// never been called, this callback won't be triggered. |
void OnClose() override { |
- rtc::CritScope lock(&lock_); |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
// Set |renderer_| to nullptr to make sure no more callback will get into |
// the renderer. |
renderer_ = nullptr; |
} |
// Accessor to the VoE channel ID. |
- int channel() const { return channel_; } |
+ int channel() const { |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
+ return channel_; |
+ } |
private: |
+ rtc::ThreadChecker thread_checker_; |
const int channel_ = -1; |
webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
webrtc::Call* call_ = nullptr; |
@@ -1398,9 +1412,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
// goes away. |
AudioRenderer* renderer_ = nullptr; |
- // Protects |renderer_| in Start(), Stop() and OnClose(). |
- rtc::CriticalSection lock_; |
- |
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
}; |
@@ -1433,7 +1444,6 @@ WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, |
desired_send_(SEND_NOTHING), |
send_(SEND_NOTHING), |
call_(call) { |
- RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; |
RTC_DCHECK(nullptr != call); |
engine->RegisterChannel(this); |
@@ -2618,109 +2628,36 @@ bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { |
bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { |
RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
+ RTC_DCHECK(info); |
- bool echo_metrics_on = false; |
- // These can take on valid negative values, so use the lowest possible level |
- // as default rather than -1. |
- int echo_return_loss = -100; |
- int echo_return_loss_enhancement = -100; |
- // These can also be negative, but in practice -1 is only used to signal |
- // insufficient data, since the resolution is limited to multiples of 4 ms. |
- int echo_delay_median_ms = -1; |
- int echo_delay_std_ms = -1; |
- if (engine()->voe()->processing()->GetEcMetricsStatus( |
- echo_metrics_on) != -1 && echo_metrics_on) { |
- // TODO(ajm): we may want to use VoECallReport::GetEchoMetricsSummary |
- // here, but it appears to be unsuitable currently. Revisit after this is |
- // investigated: http://b/issue?id=5666755 |
- int erl, erle, rerl, anlp; |
- if (engine()->voe()->processing()->GetEchoMetrics( |
- erl, erle, rerl, anlp) != -1) { |
- echo_return_loss = erl; |
- echo_return_loss_enhancement = erle; |
- } |
- |
- int median, std; |
- float dummy; |
- if (engine()->voe()->processing()->GetEcDelayMetrics( |
- median, std, dummy) != -1) { |
- echo_delay_median_ms = median; |
- echo_delay_std_ms = std; |
- } |
- } |
- |
- for (const auto& ch : send_streams_) { |
- const int channel = ch.second->channel(); |
- |
- // Fill in the sender info, based on what we know, and what the |
- // remote side told us it got from its RTCP report. |
+ // Get SSRC and stats for each sender. |
+ RTC_DCHECK(info->senders.size() == 0); |
+ for (const auto& stream : send_streams_) { |
+ webrtc::AudioSendStream::Stats stats = stream.second->GetStats(); |
VoiceSenderInfo sinfo; |
- |
- webrtc::CallStatistics cs = {0}; |
- unsigned int ssrc = 0; |
- if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || |
- engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { |
- continue; |
- } |
- |
- sinfo.add_ssrc(ssrc); |
- sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; |
- sinfo.bytes_sent = cs.bytesSent; |
- sinfo.packets_sent = cs.packetsSent; |
- // RTT isn't known until a RTCP report is received. Until then, VoiceEngine |
- // returns 0 to indicate an error value. |
- sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; |
- |
- // Get data from the last remote RTCP report. Use default values if no data |
- // available. |
- sinfo.fraction_lost = -1.0; |
- sinfo.jitter_ms = -1; |
- sinfo.packets_lost = -1; |
- sinfo.ext_seqnum = -1; |
- std::vector<webrtc::ReportBlock> receive_blocks; |
- webrtc::CodecInst codec = {0}; |
- if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( |
- channel, &receive_blocks) != -1 && |
- engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { |
- for (const webrtc::ReportBlock& block : receive_blocks) { |
- // Lookup report for send ssrc only. |
- if (block.source_SSRC == sinfo.ssrc()) { |
- // Convert Q8 to floating point. |
- sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256; |
- // Convert samples to milliseconds. |
- if (codec.plfreq / 1000 > 0) { |
- sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000); |
- } |
- sinfo.packets_lost = block.cumulative_num_packets_lost; |
- sinfo.ext_seqnum = block.extended_highest_sequence_number; |
- break; |
- } |
- } |
- } |
- |
- // Local speech level. |
- unsigned int level = 0; |
- sinfo.audio_level = (engine()->voe()->volume()-> |
- GetSpeechInputLevelFullRange(level) != -1) ? level : -1; |
- |
- // TODO(xians): We are injecting the same APM logging to all the send |
- // channels here because there is no good way to know which send channel |
- // is using the APM. The correct fix is to allow the send channels to have |
- // their own APM so that we can feed the correct APM logging to different |
- // send channels. See issue crbug/264611 . |
- sinfo.echo_return_loss = echo_return_loss; |
- sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; |
- sinfo.echo_delay_median_ms = echo_delay_median_ms; |
- sinfo.echo_delay_std_ms = echo_delay_std_ms; |
- // TODO(ajm): Re-enable this metric once we have a reliable implementation. |
- sinfo.aec_quality_min = -1; |
+ sinfo.add_ssrc(stats.local_ssrc); |
+ sinfo.bytes_sent = stats.bytes_sent; |
+ sinfo.packets_sent = stats.packets_sent; |
+ sinfo.packets_lost = stats.packets_lost; |
+ sinfo.fraction_lost = stats.fraction_lost; |
+ sinfo.codec_name = stats.codec_name; |
+ sinfo.ext_seqnum = stats.ext_seqnum; |
+ sinfo.jitter_ms = stats.jitter_ms; |
+ sinfo.rtt_ms = stats.rtt_ms; |
+ sinfo.audio_level = stats.audio_level; |
+ sinfo.aec_quality_min = stats.aec_quality_min; |
+ sinfo.echo_delay_median_ms = stats.echo_delay_median_ms; |
+ sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; |
+ sinfo.echo_return_loss = stats.echo_return_loss; |
+ sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; |
sinfo.typing_noise_detected = typing_noise_detected_; |
- |
+ // TODO(solenberg): Move to AudioSendStream. |
+ // sinfo.typing_noise_detected = stats.typing_noise_detected; |
info->senders.push_back(sinfo); |
} |
- // Get the SSRC and stats for each receiver. |
- info->receivers.clear(); |
+ // Get SSRC and stats for each receiver. |
+ RTC_DCHECK(info->receivers.size() == 0); |
for (const auto& stream : receive_streams_) { |
webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); |
VoiceReceiverInfo rinfo; |