tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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