summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/audio/voip/audio_channel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/audio/voip/audio_channel.cc')
-rw-r--r--third_party/libwebrtc/audio/voip/audio_channel.cc173
1 files changed, 173 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..a70e33ec38
--- /dev/null
+++ b/third_party/libwebrtc/audio/voip/audio_channel.cc
@@ -0,0 +1,173 @@
+/*
+ * 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/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