tor-browser

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

AudioConduit.h (12095B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef AUDIO_SESSION_H_
      6 #define AUDIO_SESSION_H_
      7 
      8 #include "MediaConduitInterface.h"
      9 #include "mozilla/Attributes.h"
     10 #include "mozilla/RWLock.h"
     11 #include "mozilla/ReentrantMonitor.h"
     12 #include "mozilla/StateMirroring.h"
     13 #include "mozilla/TimeStamp.h"
     14 
     15 /**
     16 * This file hosts several structures identifying different aspects of a RTP
     17 * Session.
     18 */
     19 namespace mozilla {
     20 
     21 struct DtmfEvent;
     22 
     23 /**
     24 * Concrete class for Audio session. Hooks up
     25 *  - media-source and target to external transport
     26 */
     27 class WebrtcAudioConduit : public AudioSessionConduit,
     28                           public webrtc::RtcpEventObserver {
     29 public:
     30  Maybe<int> ActiveSendPayloadType() const override;
     31  Maybe<int> ActiveRecvPayloadType() const override;
     32 
     33  void OnRtpReceived(webrtc::RtpPacketReceived&& aPacket,
     34                     webrtc::RTPHeader&& aHeader);
     35  void OnRtcpReceived(webrtc::CopyOnWriteBuffer&& aPacket);
     36 
     37  void OnRtcpBye() override;
     38  void OnRtcpTimeout() override;
     39 
     40  void SetTransportActive(bool aActive) override;
     41 
     42  MediaEventSourceExc<MediaPacket>& SenderRtpSendEvent() override {
     43    return mSenderRtpSendEvent;
     44  }
     45  MediaEventSourceExc<MediaPacket>& SenderRtcpSendEvent() override {
     46    return mSenderRtcpSendEvent;
     47  }
     48  MediaEventSourceExc<MediaPacket>& ReceiverRtcpSendEvent() override {
     49    return mReceiverRtcpSendEvent;
     50  }
     51  void ConnectReceiverRtpEvent(
     52      MediaEventSourceExc<webrtc::RtpPacketReceived, webrtc::RTPHeader>& aEvent)
     53      override {
     54    mReceiverRtpEventListener =
     55        aEvent.Connect(mCallThread, this, &WebrtcAudioConduit::OnRtpReceived);
     56  }
     57  void ConnectReceiverRtcpEvent(
     58      MediaEventSourceExc<webrtc::CopyOnWriteBuffer>& aEvent) override {
     59    mReceiverRtcpEventListener =
     60        aEvent.Connect(mCallThread, this, &WebrtcAudioConduit::OnRtcpReceived);
     61  }
     62  void ConnectSenderRtcpEvent(
     63      MediaEventSourceExc<webrtc::CopyOnWriteBuffer>& aEvent) override {
     64    mSenderRtcpEventListener =
     65        aEvent.Connect(mCallThread, this, &WebrtcAudioConduit::OnRtcpReceived);
     66  }
     67 
     68  Maybe<uint16_t> RtpSendBaseSeqFor(uint32_t aSsrc) const override;
     69 
     70  const dom::RTCStatsTimestampMaker& GetTimestampMaker() const override;
     71 
     72  void StopTransmitting();
     73  void StartTransmitting();
     74  void StopReceiving();
     75  void StartReceiving();
     76 
     77  /**
     78   * Function to deliver externally captured audio sample for encoding and
     79   * transport
     80   * @param frame [in]: AudioFrame in upstream's format for forwarding to the
     81   *                    send stream. Ownership is passed along.
     82   * NOTE: ConfigureSendMediaCodec() SHOULD be called before this function can
     83   * be invoked. This ensures the inserted audio-samples can be transmitted by
     84   * the conduit.
     85   */
     86  MediaConduitErrorCode SendAudioFrame(
     87      std::unique_ptr<webrtc::AudioFrame> frame) override;
     88 
     89  /**
     90   * Function to grab a decoded audio-sample from the media engine for
     91   * rendering / playout of length 10 milliseconds.
     92   *
     93   * @param samplingFreqHz [in]: Frequency of the sampling for playback in
     94   *                             Hertz (16000, 32000,..)
     95   * @param frame [in/out]: Pointer to an AudioFrame to which audio data will be
     96   *                        copied
     97   * NOTE: This function should be invoked every 10 milliseconds for the best
     98   *       performance
     99   * NOTE: ConfigureRecvMediaCodec() SHOULD be called before this function can
    100   *       be invoked
    101   * This ensures the decoded samples are ready for reading and playout is
    102   * enabled.
    103   */
    104  MediaConduitErrorCode GetAudioFrame(int32_t samplingFreqHz,
    105                                      webrtc::AudioFrame* frame) override;
    106 
    107  bool SendRtp(const uint8_t* aData, size_t aLength,
    108               const webrtc::PacketOptions& aOptions) override;
    109  bool SendSenderRtcp(const uint8_t* aData, size_t aLength) override;
    110  bool SendReceiverRtcp(const uint8_t* aData, size_t aLength) override;
    111 
    112  bool HasCodecPluginID(uint64_t aPluginID) const override { return false; }
    113 
    114  void SetJitterBufferTarget(DOMHighResTimeStamp aTargetMs) override;
    115 
    116  void DeliverPacket(webrtc::CopyOnWriteBuffer packet,
    117                     PacketType type) override;
    118 
    119  RefPtr<GenericPromise> Shutdown() override;
    120 
    121  // Call thread only.
    122  bool IsShutdown() const override;
    123 
    124  WebrtcAudioConduit(RefPtr<WebrtcCallWrapper> aCall,
    125                     nsCOMPtr<nsISerialEventTarget> aStsThread);
    126 
    127  virtual ~WebrtcAudioConduit();
    128 
    129  // Call thread.
    130  void InitControl(AudioConduitControlInterface* aControl) override;
    131 
    132  // Necessary Init steps on main thread.
    133  MediaConduitErrorCode Init();
    134 
    135  // Handle a DTMF event from mControl.mOnDtmfEventListener.
    136  void OnDtmfEvent(const DtmfEvent& aEvent);
    137 
    138  // Called when a parameter in mControl has changed. Call thread.
    139  void OnControlConfigChange();
    140 
    141  Ssrcs GetLocalSSRCs() const override;
    142  Maybe<Ssrc> GetRemoteSSRC() const override;
    143 
    144  void DisableSsrcChanges() override {
    145    MOZ_ASSERT(mCallThread->IsOnCurrentThread());
    146    mAllowSsrcChange = false;
    147  }
    148 
    149 private:
    150  /**
    151   * Override the remote ssrc configured on mRecvStreamConfig.
    152   *
    153   * Recreates and restarts the recv stream if needed. The overriden value is
    154   * overwritten the next time the mControl.mRemoteSsrc mirror changes value.
    155   *
    156   * Call thread only.
    157   */
    158  bool OverrideRemoteSSRC(uint32_t aSsrc);
    159 
    160 public:
    161  void UnsetRemoteSSRC(uint32_t aSsrc) override {}
    162 
    163  Maybe<webrtc::AudioReceiveStreamInterface::Stats> GetReceiverStats()
    164      const override;
    165  Maybe<webrtc::AudioSendStream::Stats> GetSenderStats() const override;
    166  Maybe<webrtc::CallBasicStats> GetCallStats() const override;
    167 
    168  bool IsSamplingFreqSupported(int freq) const override;
    169 
    170  MediaEventSource<void>& RtcpByeEvent() override { return mRtcpByeEvent; }
    171  MediaEventSource<void>& RtcpTimeoutEvent() override {
    172    return mRtcpTimeoutEvent;
    173  }
    174  MediaEventSource<void>& RtpPacketEvent() override { return mRtpPacketEvent; }
    175 
    176  const std::vector<webrtc::RtpSource>& GetUpstreamRtpSources() const override;
    177 
    178 private:
    179  WebrtcAudioConduit(const WebrtcAudioConduit& other) = delete;
    180  void operator=(const WebrtcAudioConduit& other) = delete;
    181 
    182  // Generate block size in sample length for a given sampling frequency
    183  unsigned int GetNum10msSamplesForFrequency(int samplingFreqHz) const;
    184 
    185  // Checks the codec to be applied
    186  static MediaConduitErrorCode ValidateCodecConfig(
    187      const AudioCodecConfig& codecInfo, bool send);
    188  /**
    189   * Of all extensions in aExtensions, returns a list of supported extensions.
    190   */
    191  static RtpExtList FilterExtensions(
    192      MediaSessionConduitLocalDirection aDirection,
    193      const RtpExtList& aExtensions);
    194  static webrtc::SdpAudioFormat CodecConfigToLibwebrtcFormat(
    195      const AudioCodecConfig& aConfig);
    196 
    197  // Call thread only, called before DeleteSendStream if streams need recreation
    198  void MemoSendStreamStats();
    199 
    200  void CreateSendStream();
    201  void DeleteSendStream();
    202  void CreateRecvStream();
    203  void DeleteRecvStream();
    204 
    205  // Call thread only.
    206  // Should only be called from Shutdown()
    207  void SetIsShutdown();
    208 
    209  // Are SSRC changes without signaling allowed or not.
    210  // Call thread only.
    211  bool mAllowSsrcChange = true;
    212 
    213  // Const so can be accessed on any thread. Most methods are called on the Call
    214  // thread.
    215  const RefPtr<WebrtcCallWrapper> mCall;
    216 
    217  // Set up in the ctor and then not touched. Called through by the streams on
    218  // any thread.
    219  WebrtcSendTransport mSendTransport;
    220  WebrtcReceiveTransport mRecvTransport;
    221 
    222  // Accessed only on the Call thread.
    223  webrtc::AudioReceiveStreamInterface::Config mRecvStreamConfig;
    224 
    225  // Written only on the Call thread. Guarded by mLock, except for reads on the
    226  // Call thread.
    227  webrtc::AudioReceiveStreamInterface* mRecvStream;
    228 
    229  // Accessed only on the Call thread.
    230  webrtc::AudioSendStream::Config mSendStreamConfig;
    231 
    232  // Written only on the Call thread. Guarded by mLock, except for reads on the
    233  // Call thread.
    234  webrtc::AudioSendStream* mSendStream;
    235 
    236  // If true => mSendStream started and not stopped
    237  // Written only on the Call thread.
    238  Atomic<bool> mSendStreamRunning;
    239  // If true => mRecvStream started and not stopped
    240  // Written only on the Call thread.
    241  Atomic<bool> mRecvStreamRunning;
    242 
    243  // Accessed only on the Call thread.
    244  bool mDtmfEnabled;
    245 
    246  mutable RWLock mLock MOZ_UNANNOTATED;
    247 
    248  // Call worker thread. All access to mCall->Call() happens here.
    249  const RefPtr<AbstractThread> mCallThread;
    250 
    251  // Socket transport service thread. Any thread.
    252  const nsCOMPtr<nsISerialEventTarget> mStsThread;
    253 
    254  // Target jitter buffer to be applied to the receive stream in milliseconds.
    255  uint16_t mJitterBufferTargetMs = 0;
    256 
    257  struct Control {
    258    // Mirrors and events that map to AudioConduitControlInterface for control.
    259    // Call thread only.
    260    Mirror<bool> mReceiving;
    261    Mirror<bool> mTransmitting;
    262    Mirror<Ssrcs> mLocalSsrcs;
    263    Mirror<std::string> mLocalCname;
    264    Mirror<std::string> mMid;
    265    Mirror<Ssrc> mRemoteSsrc;
    266    Mirror<std::string> mSyncGroup;
    267    Mirror<RtpExtList> mLocalRecvRtpExtensions;
    268    Mirror<RtpExtList> mLocalSendRtpExtensions;
    269    Mirror<Maybe<AudioCodecConfig>> mSendCodec;
    270    Mirror<std::vector<AudioCodecConfig>> mRecvCodecs;
    271    Mirror<RefPtr<FrameTransformerProxy>> mFrameTransformerProxySend;
    272    Mirror<RefPtr<FrameTransformerProxy>> mFrameTransformerProxyRecv;
    273    MediaEventListener mOnDtmfEventListener;
    274 
    275    // For caching mRemoteSsrc, since another caller may change the remote ssrc
    276    // in the stream config directly.
    277    Ssrc mConfiguredRemoteSsrc = 0;
    278    // For tracking changes to mSendCodec.
    279    Maybe<AudioCodecConfig> mConfiguredSendCodec;
    280    // For tracking changes to mRecvCodecs.
    281    std::vector<AudioCodecConfig> mConfiguredRecvCodecs;
    282 
    283    // For change tracking. Callthread only.
    284    RefPtr<FrameTransformerProxy> mConfiguredFrameTransformerProxySend;
    285    RefPtr<FrameTransformerProxy> mConfiguredFrameTransformerProxyRecv;
    286 
    287    Control() = delete;
    288    explicit Control(const RefPtr<AbstractThread>& aCallThread);
    289  } mControl;
    290 
    291  // WatchManager allowing Mirrors to trigger functions that will update the
    292  // webrtc.org configuration.
    293  WatchManager<WebrtcAudioConduit> mWatchManager;
    294 
    295  // Accessed from mStsThread. Last successfully polled RTT
    296  Maybe<DOMHighResTimeStamp> mRttSec;
    297 
    298  // Call thread only. ssrc -> base_seq
    299  std::map<uint32_t, uint16_t> mRtpSendBaseSeqs;
    300  // libwebrtc network thread only. ssrc -> base_seq.
    301  // To track changes needed to mRtpSendBaseSeqs.
    302  std::map<uint32_t, uint16_t> mRtpSendBaseSeqs_n;
    303 
    304  // Call thread only.
    305  Canonical<std::vector<webrtc::RtpSource>> mCanonicalRtpSources;
    306 
    307  // Main thread only mirror of mCanonicalRtpSources.
    308  Mirror<std::vector<webrtc::RtpSource>> mRtpSources;
    309 
    310  // Stores stats between a call to DeleteSendStream and CreateSendStream so
    311  // that we can continue to report outbound-rtp stats while waiting for codec
    312  // initialization.
    313  // It is mutable because we want to be able to invalidate the cache when a
    314  // GetStats call is made.
    315  // Call thread only.
    316  mutable Maybe<webrtc::AudioSendStream::Stats> mTransitionalSendStreamStats;
    317 
    318  // Thread safe
    319  Atomic<bool> mTransportActive = Atomic<bool>(false);
    320  MediaEventProducer<void> mRtcpByeEvent;
    321  MediaEventProducer<void> mRtcpTimeoutEvent;
    322  MediaEventProducer<void> mRtpPacketEvent;
    323  MediaEventProducerExc<MediaPacket> mSenderRtpSendEvent;
    324  MediaEventProducerExc<MediaPacket> mSenderRtcpSendEvent;
    325  MediaEventProducerExc<MediaPacket> mReceiverRtcpSendEvent;
    326 
    327  // Assigned and revoked on mStsThread. Listeners for receiving packets.
    328  MediaEventListener mReceiverRtpEventListener;   // Rtp-receiving pipeline
    329  MediaEventListener mReceiverRtcpEventListener;  // Rctp-receiving pipeline
    330  MediaEventListener mSenderRtcpEventListener;    // Rctp-sending pipeline
    331 
    332  // Whether the conduit is shutdown or not.
    333  // Call thread only.
    334  bool mIsShutdown = false;
    335 };
    336 
    337 }  // namespace mozilla
    338 
    339 #endif