audio_channel.cc (6151B)
1 /* 2 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "audio/voip/audio_channel.h" 12 13 #include <cstdint> 14 #include <memory> 15 #include <utility> 16 17 #include "api/audio/audio_mixer.h" 18 #include "api/audio_codecs/audio_decoder_factory.h" 19 #include "api/call/transport.h" 20 #include "api/environment/environment.h" 21 #include "api/rtp_headers.h" 22 #include "api/scoped_refptr.h" 23 #include "api/voip/voip_statistics.h" 24 #include "audio/voip/audio_egress.h" 25 #include "audio/voip/audio_ingress.h" 26 #include "modules/audio_coding/include/audio_coding_module_typedefs.h" 27 #include "modules/rtp_rtcp/include/receive_statistics.h" 28 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 29 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" 30 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" 31 #include "rtc_base/checks.h" 32 33 namespace webrtc { 34 35 namespace { 36 37 constexpr int kRtcpReportIntervalMs = 5000; 38 39 } // namespace 40 41 AudioChannel::AudioChannel(const Environment& env, 42 Transport* transport, 43 uint32_t local_ssrc, 44 AudioMixer* audio_mixer, 45 scoped_refptr<AudioDecoderFactory> decoder_factory) 46 : audio_mixer_(audio_mixer) { 47 RTC_DCHECK(audio_mixer); 48 49 receive_statistics_ = ReceiveStatistics::Create(&env.clock()); 50 51 RtpRtcpInterface::Configuration rtp_config; 52 rtp_config.audio = true; 53 rtp_config.receive_statistics = receive_statistics_.get(); 54 rtp_config.rtcp_report_interval_ms = kRtcpReportIntervalMs; 55 rtp_config.outgoing_transport = transport; 56 rtp_config.local_media_ssrc = local_ssrc; 57 58 rtp_rtcp_ = std::make_unique<ModuleRtpRtcpImpl2>(env, rtp_config); 59 60 rtp_rtcp_->SetSendingMediaStatus(false); 61 rtp_rtcp_->SetRTCPStatus(RtcpMode::kCompound); 62 63 ingress_ = std::make_unique<AudioIngress>(env, rtp_rtcp_.get(), 64 receive_statistics_.get(), 65 std::move(decoder_factory)); 66 egress_ = std::make_unique<AudioEgress>(env, rtp_rtcp_.get()); 67 68 // Set the instance of audio ingress to be part of audio mixer for ADM to 69 // fetch audio samples to play. 70 audio_mixer_->AddSource(ingress_.get()); 71 } 72 73 AudioChannel::~AudioChannel() { 74 if (egress_->IsSending()) { 75 StopSend(); 76 } 77 if (ingress_->IsPlaying()) { 78 StopPlay(); 79 } 80 81 audio_mixer_->RemoveSource(ingress_.get()); 82 83 // TODO(bugs.webrtc.org/11581): unclear if we still need to clear `egress_` 84 // here. 85 egress_.reset(); 86 ingress_.reset(); 87 } 88 89 bool AudioChannel::StartSend() { 90 // If encoder has not been set, return false. 91 if (!egress_->StartSend()) { 92 return false; 93 } 94 95 // Start sending with RTP stack if it has not been sending yet. 96 if (!rtp_rtcp_->Sending()) { 97 rtp_rtcp_->SetSendingStatus(true); 98 } 99 return true; 100 } 101 102 void AudioChannel::StopSend() { 103 egress_->StopSend(); 104 105 // Deactivate RTP stack when both sending and receiving are stopped. 106 // SetSendingStatus(false) triggers the transmission of RTCP BYE 107 // message to remote endpoint. 108 if (!ingress_->IsPlaying() && rtp_rtcp_->Sending()) { 109 rtp_rtcp_->SetSendingStatus(false); 110 } 111 } 112 113 bool AudioChannel::StartPlay() { 114 // If decoders have not been set, return false. 115 if (!ingress_->StartPlay()) { 116 return false; 117 } 118 119 // If RTP stack is not sending then start sending as in recv-only mode, RTCP 120 // receiver report is expected. 121 if (!rtp_rtcp_->Sending()) { 122 rtp_rtcp_->SetSendingStatus(true); 123 } 124 return true; 125 } 126 127 void AudioChannel::StopPlay() { 128 ingress_->StopPlay(); 129 130 // Deactivate RTP stack only when both sending and receiving are stopped. 131 if (!rtp_rtcp_->SendingMedia() && rtp_rtcp_->Sending()) { 132 rtp_rtcp_->SetSendingStatus(false); 133 } 134 } 135 136 IngressStatistics AudioChannel::GetIngressStatistics() { 137 IngressStatistics ingress_stats; 138 NetworkStatistics stats = ingress_->GetNetworkStatistics(); 139 ingress_stats.neteq_stats.total_samples_received = stats.totalSamplesReceived; 140 ingress_stats.neteq_stats.concealed_samples = stats.concealedSamples; 141 ingress_stats.neteq_stats.concealment_events = stats.concealmentEvents; 142 ingress_stats.neteq_stats.jitter_buffer_delay_ms = stats.jitterBufferDelayMs; 143 ingress_stats.neteq_stats.jitter_buffer_emitted_count = 144 stats.jitterBufferEmittedCount; 145 ingress_stats.neteq_stats.jitter_buffer_target_delay_ms = 146 stats.jitterBufferTargetDelayMs; 147 ingress_stats.neteq_stats.inserted_samples_for_deceleration = 148 stats.insertedSamplesForDeceleration; 149 ingress_stats.neteq_stats.removed_samples_for_acceleration = 150 stats.removedSamplesForAcceleration; 151 ingress_stats.neteq_stats.silent_concealed_samples = 152 stats.silentConcealedSamples; 153 ingress_stats.neteq_stats.fec_packets_received = stats.fecPacketsReceived; 154 ingress_stats.neteq_stats.fec_packets_discarded = stats.fecPacketsDiscarded; 155 ingress_stats.neteq_stats.delayed_packet_outage_samples = 156 stats.delayedPacketOutageSamples; 157 ingress_stats.neteq_stats.relative_packet_arrival_delay_ms = 158 stats.relativePacketArrivalDelayMs; 159 ingress_stats.neteq_stats.interruption_count = stats.interruptionCount; 160 ingress_stats.neteq_stats.total_interruption_duration_ms = 161 stats.totalInterruptionDurationMs; 162 ingress_stats.total_duration = ingress_->GetOutputTotalDuration(); 163 return ingress_stats; 164 } 165 166 ChannelStatistics AudioChannel::GetChannelStatistics() { 167 ChannelStatistics channel_stat = ingress_->GetChannelStatistics(); 168 169 StreamDataCounters rtp_stats, rtx_stats; 170 rtp_rtcp_->GetSendStreamDataCounters(&rtp_stats, &rtx_stats); 171 channel_stat.bytes_sent = 172 rtp_stats.transmitted.payload_bytes + rtx_stats.transmitted.payload_bytes; 173 channel_stat.packets_sent = 174 rtp_stats.transmitted.packets + rtx_stats.transmitted.packets; 175 176 return channel_stat; 177 } 178 179 } // namespace webrtc