tor-browser

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

JsepTrack.h (12402B)


      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 _JSEPTRACK_H_
      6 #define _JSEPTRACK_H_
      7 
      8 #include <mozilla/UniquePtr.h>
      9 
     10 #include <algorithm>
     11 #include <functional>
     12 #include <map>
     13 #include <string>
     14 #include <vector>
     15 
     16 #include "jsep/JsepTrackEncoding.h"
     17 #include "jsep/SsrcGenerator.h"
     18 #include "libwebrtcglue/RtpRtcpConfig.h"
     19 #include "mozilla/Preferences.h"
     20 #include "nsError.h"
     21 #include "sdp/Sdp.h"
     22 #include "sdp/SdpAttribute.h"
     23 #include "sdp/SdpMediaSection.h"
     24 namespace mozilla {
     25 
     26 class JsepTrackNegotiatedDetails {
     27 public:
     28  JsepTrackNegotiatedDetails()
     29      : mTias(0), mRtpRtcpConf(webrtc::RtcpMode::kCompound, true) {}
     30 
     31  JsepTrackNegotiatedDetails(const JsepTrackNegotiatedDetails& orig)
     32      : mExtmap(orig.mExtmap),
     33        mTias(orig.mTias),
     34        mRtpRtcpConf(orig.mRtpRtcpConf) {
     35    for (const auto& encoding : orig.mEncodings) {
     36      mEncodings.emplace_back(new JsepTrackEncoding(*encoding));
     37    }
     38  }
     39 
     40  size_t GetEncodingCount() const { return mEncodings.size(); }
     41 
     42  const JsepTrackEncoding& GetEncoding(size_t index) const {
     43    MOZ_RELEASE_ASSERT(index < mEncodings.size());
     44    return *mEncodings[index];
     45  }
     46 
     47  void TruncateEncodings(size_t aSize) {
     48    if (mEncodings.size() < aSize) {
     49      MOZ_ASSERT(false);
     50      return;
     51    }
     52    mEncodings.resize(aSize);
     53  }
     54 
     55  const SdpExtmapAttributeList::Extmap* GetExt(
     56      const std::string& ext_name) const {
     57    auto it = mExtmap.find(ext_name);
     58    if (it != mExtmap.end()) {
     59      return &it->second;
     60    }
     61    return nullptr;
     62  }
     63 
     64  void ForEachRTPHeaderExtension(
     65      const std::function<void(const SdpExtmapAttributeList::Extmap& extmap)>&
     66          fn) const {
     67    for (const auto& entry : mExtmap) {
     68      fn(entry.second);
     69    }
     70  }
     71 
     72  uint32_t GetTias() const { return mTias; }
     73 
     74  RtpRtcpConfig GetRtpRtcpConfig() const { return mRtpRtcpConf; }
     75 
     76 private:
     77  friend class JsepTrack;
     78 
     79  std::map<std::string, SdpExtmapAttributeList::Extmap> mExtmap;
     80  std::vector<UniquePtr<JsepTrackEncoding>> mEncodings;
     81  uint32_t mTias;  // bits per second
     82  RtpRtcpConfig mRtpRtcpConf;
     83 };
     84 
     85 class JsepTrack {
     86 public:
     87  JsepTrack(mozilla::SdpMediaSection::MediaType type, sdp::Direction direction)
     88      : mType(type),
     89        mDirection(direction),
     90        mActive(false),
     91        mRemoteSetSendBit(false) {}
     92 
     93  virtual ~JsepTrack() {}
     94 
     95  void UpdateStreamIds(const std::vector<std::string>& streamIds) {
     96    mStreamIds = streamIds;
     97  }
     98 
     99  void SetTrackId(const std::string& aTrackId) { mTrackId = aTrackId; }
    100 
    101  void ClearStreamIds() { mStreamIds.clear(); }
    102 
    103  void RecvTrackSetRemote(const Sdp& aSdp, const SdpMediaSection& aMsection);
    104  void RecvTrackSetLocal(const SdpMediaSection& aMsection);
    105 
    106  // This is called whenever a remote description is set; we do not wait for
    107  // offer/answer to complete, since there's nothing to actually negotiate here.
    108  void SendTrackSetRemote(SsrcGenerator& aSsrcGenerator,
    109                          const SdpMediaSection& aRemoteMsection);
    110 
    111  JsepTrack(const JsepTrack& orig) { *this = orig; }
    112 
    113  JsepTrack(JsepTrack&& orig) = default;
    114  JsepTrack& operator=(JsepTrack&& rhs) = default;
    115 
    116  JsepTrack& operator=(const JsepTrack& rhs) {
    117    if (this != &rhs) {
    118      mType = rhs.mType;
    119      mStreamIds = rhs.mStreamIds;
    120      mTrackId = rhs.mTrackId;
    121      mCNAME = rhs.mCNAME;
    122      mDirection = rhs.mDirection;
    123      mRids = rhs.mRids;
    124      mSsrcs = rhs.mSsrcs;
    125      mSsrcToRtxSsrc = rhs.mSsrcToRtxSsrc;
    126      mActive = rhs.mActive;
    127      mRemoteSetSendBit = rhs.mRemoteSetSendBit;
    128      mReceptive = rhs.mReceptive;
    129      mMaxEncodings = rhs.mMaxEncodings;
    130      mInHaveRemote = rhs.mInHaveRemote;
    131      mRtxIsAllowed = rhs.mRtxIsAllowed;
    132      mUsePreferredCodecsOrder = rhs.mUsePreferredCodecsOrder;
    133      mFecCodec = rhs.mFecCodec;
    134      mAudioPreferredCodec = rhs.mAudioPreferredCodec;
    135      mVideoPreferredCodec = rhs.mVideoPreferredCodec;
    136      mUniqueReceivePayloadTypes = rhs.mUniqueReceivePayloadTypes;
    137      mReceivePayloadTypes = rhs.mReceivePayloadTypes;
    138      mOtherReceivePayloadTypes = rhs.mOtherReceivePayloadTypes;
    139 
    140      mPrototypeCodecs.clear();
    141      for (const auto& codec : rhs.mPrototypeCodecs) {
    142        mPrototypeCodecs.emplace_back(codec->Clone());
    143      }
    144      if (rhs.mNegotiatedDetails) {
    145        mNegotiatedDetails.reset(
    146            new JsepTrackNegotiatedDetails(*rhs.mNegotiatedDetails));
    147      }
    148    }
    149    return *this;
    150  }
    151 
    152  virtual mozilla::SdpMediaSection::MediaType GetMediaType() const {
    153    return mType;
    154  }
    155 
    156  virtual const std::vector<std::string>& GetStreamIds() const {
    157    return mStreamIds;
    158  }
    159 
    160  virtual const std::string& GetCNAME() const { return mCNAME; }
    161 
    162  virtual void SetCNAME(const std::string& cname) { mCNAME = cname; }
    163 
    164  virtual sdp::Direction GetDirection() const { return mDirection; }
    165 
    166  virtual const std::vector<uint32_t>& GetSsrcs() const { return mSsrcs; }
    167 
    168  virtual std::vector<uint32_t> GetRtxSsrcs() const {
    169    std::vector<uint32_t> result;
    170    if (mRtxIsAllowed &&
    171        Preferences::GetBool("media.peerconnection.video.use_rtx", false) &&
    172        !mSsrcToRtxSsrc.empty()) {
    173      MOZ_ASSERT(mSsrcToRtxSsrc.size() == mSsrcs.size());
    174      for (const auto ssrc : mSsrcs) {
    175        auto it = mSsrcToRtxSsrc.find(ssrc);
    176        MOZ_ASSERT(it != mSsrcToRtxSsrc.end());
    177        result.push_back(it->second);
    178      }
    179    }
    180    return result;
    181  }
    182 
    183  virtual void EnsureSsrcs(SsrcGenerator& ssrcGenerator, size_t aNumber);
    184 
    185  bool GetActive() const { return mActive; }
    186 
    187  void SetActive(bool active) { mActive = active; }
    188 
    189  bool GetRemoteSetSendBit() const { return mRemoteSetSendBit; }
    190  bool GetReceptive() const { return mReceptive; }
    191 
    192  void PopulatePreferredCodecs(
    193      const std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs,
    194      bool aUsePreferredCodecsOrder);
    195 
    196  virtual void PopulateCodecs(
    197      const std::vector<UniquePtr<JsepCodecDescription>>& prototype,
    198      bool aUsePreferredCodecsOrder = false);
    199 
    200  template <class UnaryFunction>
    201  void ForEachCodec(UnaryFunction func) {
    202    std::for_each(mPrototypeCodecs.begin(), mPrototypeCodecs.end(), func);
    203  }
    204 
    205  template <class BinaryPredicate>
    206  void SortCodecs(BinaryPredicate sorter) {
    207    std::stable_sort(mPrototypeCodecs.begin(), mPrototypeCodecs.end(), sorter);
    208  }
    209 
    210  // These two are non-const because this is where ssrcs are chosen.
    211  virtual void AddToOffer(SsrcGenerator& ssrcGenerator, SdpMediaSection* offer);
    212  virtual void AddToAnswer(const SdpMediaSection& offer,
    213                           SsrcGenerator& ssrcGenerator,
    214                           SdpMediaSection* answer);
    215 
    216  virtual nsresult Negotiate(const SdpMediaSection& answer,
    217                             const SdpMediaSection& remote,
    218                             const SdpMediaSection& local);
    219  static void SetReceivePayloadTypes(std::vector<JsepTrack*>& tracks,
    220                                     bool localOffer = false);
    221  virtual void GetNegotiatedPayloadTypes(
    222      std::vector<uint16_t>* payloadTypes) const;
    223 
    224  // This will be set when negotiation is carried out.
    225  virtual const JsepTrackNegotiatedDetails* GetNegotiatedDetails() const {
    226    if (mNegotiatedDetails) {
    227      return mNegotiatedDetails.get();
    228    }
    229    return nullptr;
    230  }
    231 
    232  virtual JsepTrackNegotiatedDetails* GetNegotiatedDetails() {
    233    if (mNegotiatedDetails) {
    234      return mNegotiatedDetails.get();
    235    }
    236    return nullptr;
    237  }
    238 
    239  virtual void ClearNegotiatedDetails() { mNegotiatedDetails.reset(); }
    240 
    241  void SetRids(const std::vector<std::string>& aRids);
    242  void ClearRids() { mRids.clear(); }
    243  const std::vector<std::string>& GetRids() const { return mRids; }
    244 
    245  void AddToMsection(const std::vector<std::string>& aRids,
    246                     sdp::Direction direction, SsrcGenerator& ssrcGenerator,
    247                     bool rtxEnabled, SdpMediaSection* msection);
    248 
    249  // See Bug 1642419, this can be removed when all sites are working with RTX.
    250  void SetRtxIsAllowed(bool aRtxIsAllowed) { mRtxIsAllowed = aRtxIsAllowed; }
    251 
    252  void SetMaxEncodings(size_t aMax);
    253  bool IsInHaveRemote() const { return mInHaveRemote; }
    254 
    255  const std::string& GetFecCodecName() const { return mFecCodec; }
    256  const std::string& GetAudioPreferredCodec() const {
    257    return mAudioPreferredCodec;
    258  }
    259  const std::string& GetVideoPreferredCodec() const {
    260    return mVideoPreferredCodec;
    261  }
    262 
    263  void ResetReceivePayloadTypes() {
    264    mUniqueReceivePayloadTypes.clear();
    265    mOtherReceivePayloadTypes.clear();
    266  }
    267 
    268  const std::vector<uint8_t>& GetUniqueReceivePayloadTypes() const {
    269    return mUniqueReceivePayloadTypes;
    270  }
    271 
    272  const std::vector<uint8_t>& GetOtherReceivePayloadTypes() const {
    273    return mOtherReceivePayloadTypes;
    274  }
    275 
    276 private:
    277  std::vector<UniquePtr<JsepCodecDescription>> GetCodecClones() const;
    278  static void EnsureNoDuplicatePayloadTypes(
    279      std::vector<UniquePtr<JsepCodecDescription>>* codecs);
    280  static void GetPayloadTypes(
    281      const std::vector<UniquePtr<JsepCodecDescription>>& codecs,
    282      std::vector<uint16_t>* pts);
    283  void AddToMsection(const std::vector<UniquePtr<JsepCodecDescription>>& codecs,
    284                     SdpMediaSection* msection) const;
    285  void GetRids(const SdpMediaSection& msection, sdp::Direction direction,
    286               std::vector<SdpRidAttributeList::Rid>* rids) const;
    287  void CreateEncodings(
    288      const SdpMediaSection& remote,
    289      const std::vector<UniquePtr<JsepCodecDescription>>& negotiatedCodecs,
    290      JsepTrackNegotiatedDetails* details);
    291  // Identifies codecs we want to store for logging purposes.
    292  void MaybeStoreCodecToLog(const std::string& codec,
    293                            SdpMediaSection::MediaType type);
    294  virtual std::vector<UniquePtr<JsepCodecDescription>> NegotiateCodecs(
    295      const SdpMediaSection& remote, bool remoteIsOffer,
    296      Maybe<const SdpMediaSection&> local);
    297 
    298  void UpdateSsrcs(SsrcGenerator& ssrcGenerator, size_t encodings);
    299  void PruneSsrcs(size_t aNumSsrcs);
    300  bool IsRtxEnabled(
    301      const std::vector<UniquePtr<JsepCodecDescription>>& codecs) const;
    302 
    303  mozilla::SdpMediaSection::MediaType mType;
    304  // These are the ids that everyone outside of JsepSession care about
    305  std::vector<std::string> mStreamIds;
    306  std::string mTrackId;
    307  std::string mCNAME;
    308  sdp::Direction mDirection;
    309  std::vector<UniquePtr<JsepCodecDescription>> mPrototypeCodecs;
    310  // List of rids. May be initially populated from JS, or from a remote SDP.
    311  // Can be updated by remote SDP. If no negotiation has taken place at all,
    312  // this will be empty. If negotiation has taken place, but no simulcast
    313  // attr was negotiated, this will contain the empty string as a single
    314  // element. If a simulcast attribute was negotiated, this will contain the
    315  // negotiated rids.
    316  std::vector<std::string> mRids;
    317  UniquePtr<JsepTrackNegotiatedDetails> mNegotiatedDetails;
    318  // Storage of mSsrcs and mSsrcToRtxSsrc could be improved, see Bug 1990364
    319  std::vector<uint32_t> mSsrcs;
    320  std::map<uint32_t, uint32_t> mSsrcToRtxSsrc;
    321  bool mActive;
    322  bool mRemoteSetSendBit;
    323  // This is used to drive RTCRtpTransceiver.[[Receptive]]. Basically, this
    324  // denotes whether we are prepared to receive RTP. When we apply a local
    325  // description with the recv bit set, this is set to true, even if we have
    326  // not seen the remote description yet. If we apply either a local or remote
    327  // description without the recv bit set (from our perspective), this is set
    328  // to false.
    329  bool mReceptive = false;
    330  size_t mMaxEncodings = 3;
    331  bool mInHaveRemote = false;
    332 
    333  // See Bug 1642419, this can be removed when all sites are working with RTX.
    334  bool mRtxIsAllowed = true;
    335 
    336  // Used with setCodecPreferences to determine if an answer created should
    337  // match the order of preferred codecs.
    338  bool mUsePreferredCodecsOrder = false;
    339 
    340  // Codec names for logging
    341  std::string mFecCodec;
    342  std::string mAudioPreferredCodec;
    343  std::string mVideoPreferredCodec;
    344 
    345  // Only the unique PTs we are willing to receive, not necessarily all PTs.
    346  // Used for matching SSRC to PT as only unique PTs support for this.
    347  std::vector<uint8_t> mUniqueReceivePayloadTypes;
    348  std::vector<uint16_t> mReceivePayloadTypes;
    349  // Payload types that are registered to some track but not us.
    350  std::vector<uint8_t> mOtherReceivePayloadTypes;
    351 };
    352 
    353 }  // namespace mozilla
    354 
    355 #endif