mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00

BlockingCall doesn't take rtc::Location parameter and thus most of the dependencies on location can be removed Bug: webrtc:11318 Change-Id: I91a17e342dd9a9e3e2c8f7fbe267474c98a8d0e5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274620 Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38045}
173 lines
5.6 KiB
C++
173 lines
5.6 KiB
C++
/*
|
|
* 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
|