tor-browser

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

audio_egress.h (6048B)


      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 #ifndef AUDIO_VOIP_AUDIO_EGRESS_H_
     12 #define AUDIO_VOIP_AUDIO_EGRESS_H_
     13 
     14 #include <cstddef>
     15 #include <cstdint>
     16 #include <memory>
     17 #include <optional>
     18 
     19 #include "api/audio_codecs/audio_format.h"
     20 #include "api/environment/environment.h"
     21 #include "api/sequence_checker.h"
     22 #include "api/task_queue/task_queue_base.h"
     23 #include "audio/audio_level.h"
     24 #include "call/audio_sender.h"
     25 #include "modules/audio_coding/include/audio_coding_module.h"
     26 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
     27 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
     28 #include "modules/rtp_rtcp/source/rtp_sender_audio.h"
     29 #include "rtc_base/synchronization/mutex.h"
     30 #include "rtc_base/system/no_unique_address.h"
     31 #include "rtc_base/thread_annotations.h"
     32 
     33 namespace webrtc {
     34 
     35 // AudioEgress receives input samples from AudioDeviceModule via
     36 // AudioTransportImpl through AudioSender interface. Once it encodes the sample
     37 // via selected encoder through AudioPacketizationCallback interface, the
     38 // encoded payload will be packetized by the RTP stack, resulting in ready to
     39 // send RTP packet to remote endpoint.
     40 //
     41 // TaskQueue is used to encode and send RTP asynchrounously as some OS platform
     42 // uses the same thread for both audio input and output sample deliveries which
     43 // can affect audio quality.
     44 //
     45 // Note that this class is originally based on ChannelSend in
     46 // audio/channel_send.cc with non-audio related logic trimmed as aimed for
     47 // smaller footprint.
     48 class AudioEgress : public AudioSender, public AudioPacketizationCallback {
     49 public:
     50  AudioEgress(const Environment& env, RtpRtcpInterface* rtp_rtcp);
     51  ~AudioEgress() override;
     52 
     53  // Set the encoder format and payload type for AudioCodingModule.
     54  // It's possible to change the encoder type during its active usage.
     55  // `payload_type` must be the type that is negotiated with peer through
     56  // offer/answer.
     57  void SetEncoder(int payload_type,
     58                  const SdpAudioFormat& encoder_format,
     59                  std::unique_ptr<AudioEncoder> encoder);
     60 
     61  // Start or stop sending operation of AudioEgress. This will start/stop
     62  // the RTP stack also causes encoder queue thread to start/stop
     63  // processing input audio samples. StartSend will return false if
     64  // a send codec has not been set.
     65  bool StartSend();
     66  void StopSend();
     67 
     68  // Query the state of the RTP stack. This returns true if StartSend()
     69  // called and false if StopSend() is called.
     70  bool IsSending() const;
     71 
     72  // Enable or disable Mute state.
     73  void SetMute(bool mute);
     74 
     75  // Retrieve current encoder format info. This returns encoder format set
     76  // by SetEncoder() and if encoder is not set, this will return nullopt.
     77  std::optional<SdpAudioFormat> GetEncoderFormat() const {
     78    MutexLock lock(&lock_);
     79    return encoder_format_;
     80  }
     81 
     82  // Register the payload type and sample rate for DTMF (RFC 4733) payload.
     83  void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz);
     84 
     85  // Send DTMF named event as specified by
     86  // https://tools.ietf.org/html/rfc4733#section-3.2
     87  // `duration_ms` specifies the duration of DTMF packets that will be emitted
     88  // in place of real RTP packets instead.
     89  // This will return true when requested dtmf event is successfully scheduled
     90  // otherwise false when the dtmf queue reached maximum of 20 events.
     91  bool SendTelephoneEvent(int dtmf_event, int duration_ms);
     92 
     93  // See comments on LevelFullRange, TotalEnergy, TotalDuration from
     94  // audio/audio_level.h.
     95  int GetInputAudioLevel() const { return input_audio_level_.LevelFullRange(); }
     96  double GetInputTotalEnergy() const {
     97    return input_audio_level_.TotalEnergy();
     98  }
     99  double GetInputTotalDuration() const {
    100    return input_audio_level_.TotalDuration();
    101  }
    102 
    103  // Implementation of AudioSender interface.
    104  void SendAudioData(std::unique_ptr<AudioFrame> audio_frame) override;
    105 
    106  // Implementation of AudioPacketizationCallback interface.
    107  int32_t SendData(AudioFrameType frame_type,
    108                   uint8_t payload_type,
    109                   uint32_t timestamp,
    110                   const uint8_t* payload_data,
    111                   size_t payload_size) override;
    112 
    113 private:
    114  void SetEncoderFormat(const SdpAudioFormat& encoder_format) {
    115    MutexLock lock(&lock_);
    116    encoder_format_ = encoder_format;
    117  }
    118 
    119  mutable Mutex lock_;
    120 
    121  // Current encoder format selected by caller.
    122  std::optional<SdpAudioFormat> encoder_format_ RTC_GUARDED_BY(lock_);
    123 
    124  // Synchronization is handled internally by RtpRtcp.
    125  RtpRtcpInterface* const rtp_rtcp_;
    126 
    127  // Synchronization is handled internally by RTPSenderAudio.
    128  RTPSenderAudio rtp_sender_audio_;
    129 
    130  // Synchronization is handled internally by AudioCodingModule.
    131  const std::unique_ptr<AudioCodingModule> audio_coding_;
    132 
    133  // Synchronization is handled internally by voe::AudioLevel.
    134  voe::AudioLevel input_audio_level_;
    135 
    136  // Struct that holds all variables used by encoder task queue.
    137  struct EncoderContext {
    138    // Offset used to mark rtp timestamp in sample rate unit in
    139    // newly received audio frame from AudioTransport.
    140    uint32_t frame_rtp_timestamp_ = 0;
    141 
    142    // Flag to track mute state from caller. `previously_muted_` is used to
    143    // track previous state as part of input to AudioFrameOperations::Mute
    144    // to implement fading effect when (un)mute is invoked.
    145    bool mute_ = false;
    146    bool previously_muted_ = false;
    147  };
    148 
    149  EncoderContext encoder_context_ RTC_GUARDED_BY(encoder_queue_checker_);
    150 
    151  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> encoder_queue_;
    152  RTC_NO_UNIQUE_ADDRESS SequenceChecker encoder_queue_checker_;
    153 };
    154 
    155 }  // namespace webrtc
    156 
    157 #endif  // AUDIO_VOIP_AUDIO_EGRESS_H_