diff options
Diffstat (limited to 'third_party/libwebrtc/audio/voip/audio_channel.cc')
-rw-r--r-- | third_party/libwebrtc/audio/voip/audio_channel.cc | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/third_party/libwebrtc/audio/voip/audio_channel.cc b/third_party/libwebrtc/audio/voip/audio_channel.cc new file mode 100644 index 0000000000..4650d195f2 --- /dev/null +++ b/third_party/libwebrtc/audio/voip/audio_channel.cc @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "audio/voip/audio_channel.h" + +#include <utility> +#include <vector> + +#include "api/audio_codecs/audio_format.h" +#include "api/task_queue/task_queue_factory.h" +#include "modules/rtp_rtcp/include/receive_statistics.h" +#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" +#include "rtc_base/location.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +namespace { + +constexpr int kRtcpReportIntervalMs = 5000; + +} // namespace + +AudioChannel::AudioChannel( + Transport* transport, + uint32_t local_ssrc, + TaskQueueFactory* task_queue_factory, + AudioMixer* audio_mixer, + rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) + : audio_mixer_(audio_mixer) { + RTC_DCHECK(task_queue_factory); + RTC_DCHECK(audio_mixer); + + Clock* clock = Clock::GetRealTimeClock(); + receive_statistics_ = ReceiveStatistics::Create(clock); + + RtpRtcpInterface::Configuration rtp_config; + rtp_config.clock = clock; + rtp_config.audio = true; + rtp_config.receive_statistics = receive_statistics_.get(); + rtp_config.rtcp_report_interval_ms = kRtcpReportIntervalMs; + rtp_config.outgoing_transport = transport; + rtp_config.local_media_ssrc = local_ssrc; + + rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(rtp_config); + + rtp_rtcp_->SetSendingMediaStatus(false); + rtp_rtcp_->SetRTCPStatus(RtcpMode::kCompound); + + ingress_ = std::make_unique<AudioIngress>(rtp_rtcp_.get(), clock, + receive_statistics_.get(), + std::move(decoder_factory)); + egress_ = + std::make_unique<AudioEgress>(rtp_rtcp_.get(), clock, task_queue_factory); + + // Set the instance of audio ingress to be part of audio mixer for ADM to + // fetch audio samples to play. + audio_mixer_->AddSource(ingress_.get()); +} + +AudioChannel::~AudioChannel() { + if (egress_->IsSending()) { + StopSend(); + } + if (ingress_->IsPlaying()) { + StopPlay(); + } + + audio_mixer_->RemoveSource(ingress_.get()); + + // TODO(bugs.webrtc.org/11581): unclear if we still need to clear `egress_` + // here. + egress_.reset(); + ingress_.reset(); +} + +bool AudioChannel::StartSend() { + // If encoder has not been set, return false. + if (!egress_->StartSend()) { + return false; + } + + // Start sending with RTP stack if it has not been sending yet. + if (!rtp_rtcp_->Sending()) { + rtp_rtcp_->SetSendingStatus(true); + } + return true; +} + +void AudioChannel::StopSend() { + egress_->StopSend(); + + // Deactivate RTP stack when both sending and receiving are stopped. + // SetSendingStatus(false) triggers the transmission of RTCP BYE + // message to remote endpoint. + if (!ingress_->IsPlaying() && rtp_rtcp_->Sending()) { + rtp_rtcp_->SetSendingStatus(false); + } +} + +bool AudioChannel::StartPlay() { + // If decoders have not been set, return false. + if (!ingress_->StartPlay()) { + return false; + } + + // If RTP stack is not sending then start sending as in recv-only mode, RTCP + // receiver report is expected. + if (!rtp_rtcp_->Sending()) { + rtp_rtcp_->SetSendingStatus(true); + } + return true; +} + +void AudioChannel::StopPlay() { + ingress_->StopPlay(); + + // Deactivate RTP stack only when both sending and receiving are stopped. + if (!rtp_rtcp_->SendingMedia() && rtp_rtcp_->Sending()) { + rtp_rtcp_->SetSendingStatus(false); + } +} + +IngressStatistics AudioChannel::GetIngressStatistics() { + IngressStatistics ingress_stats; + NetworkStatistics stats = ingress_->GetNetworkStatistics(); + ingress_stats.neteq_stats.total_samples_received = stats.totalSamplesReceived; + ingress_stats.neteq_stats.concealed_samples = stats.concealedSamples; + ingress_stats.neteq_stats.concealment_events = stats.concealmentEvents; + ingress_stats.neteq_stats.jitter_buffer_delay_ms = stats.jitterBufferDelayMs; + ingress_stats.neteq_stats.jitter_buffer_emitted_count = + stats.jitterBufferEmittedCount; + ingress_stats.neteq_stats.jitter_buffer_target_delay_ms = + stats.jitterBufferTargetDelayMs; + ingress_stats.neteq_stats.inserted_samples_for_deceleration = + stats.insertedSamplesForDeceleration; + ingress_stats.neteq_stats.removed_samples_for_acceleration = + stats.removedSamplesForAcceleration; + ingress_stats.neteq_stats.silent_concealed_samples = + stats.silentConcealedSamples; + ingress_stats.neteq_stats.fec_packets_received = stats.fecPacketsReceived; + ingress_stats.neteq_stats.fec_packets_discarded = stats.fecPacketsDiscarded; + ingress_stats.neteq_stats.delayed_packet_outage_samples = + stats.delayedPacketOutageSamples; + ingress_stats.neteq_stats.relative_packet_arrival_delay_ms = + stats.relativePacketArrivalDelayMs; + ingress_stats.neteq_stats.interruption_count = stats.interruptionCount; + ingress_stats.neteq_stats.total_interruption_duration_ms = + stats.totalInterruptionDurationMs; + ingress_stats.total_duration = ingress_->GetOutputTotalDuration(); + return ingress_stats; +} + +ChannelStatistics AudioChannel::GetChannelStatistics() { + ChannelStatistics channel_stat = ingress_->GetChannelStatistics(); + + StreamDataCounters rtp_stats, rtx_stats; + rtp_rtcp_->GetSendStreamDataCounters(&rtp_stats, &rtx_stats); + channel_stat.bytes_sent = + rtp_stats.transmitted.payload_bytes + rtx_stats.transmitted.payload_bytes; + channel_stat.packets_sent = + rtp_stats.transmitted.packets + rtx_stats.transmitted.packets; + + return channel_stat; +} + +} // namespace webrtc |