RTCRtpTransceiver.h (10324B)
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 #ifndef _TRANSCEIVERIMPL_H_ 5 #define _TRANSCEIVERIMPL_H_ 6 7 #include <string> 8 9 #include "ErrorList.h" 10 #include "RTCStatsReport.h" 11 #include "jsep/JsepSession.h" 12 #include "mozilla/RefPtr.h" 13 #include "mozilla/StateMirroring.h" 14 #include "mozilla/dom/MediaStreamTrack.h" 15 #include "mozilla/dom/RTCRtpCapabilitiesBinding.h" 16 #include "mozilla/dom/RTCRtpTransceiverBinding.h" 17 #include "nsCOMPtr.h" 18 #include "nsISerialEventTarget.h" 19 #include "nsTArray.h" 20 #include "transport/transportlayer.h" // For TransportLayer::State 21 22 class nsIPrincipal; 23 24 namespace mozilla { 25 class PeerIdentity; 26 class MediaSessionConduit; 27 class VideoSessionConduit; 28 class AudioSessionConduit; 29 struct AudioCodecConfig; 30 class VideoCodecConfig; // Why is this a class, but AudioCodecConfig a struct? 31 class MediaPipelineTransmit; 32 class MediaPipeline; 33 class MediaPipelineFilter; 34 class MediaTransportHandler; 35 class RTCStatsIdGenerator; 36 class WebrtcCallWrapper; 37 class JsepTrackNegotiatedDetails; 38 class PeerConnectionImpl; 39 enum class PrincipalPrivacy : uint8_t; 40 41 namespace dom { 42 class RTCDtlsTransport; 43 class RTCDTMFSender; 44 class RTCRtpTransceiver; 45 struct RTCRtpSourceEntry; 46 class RTCRtpReceiver; 47 class RTCRtpSender; 48 49 /** 50 * This is what ties all the various pieces that make up a transceiver 51 * together. This includes: 52 * MediaStreamTrack for rendering and capture 53 * MediaTransportHandler for RTP transmission/reception 54 * Audio/VideoConduit for feeding RTP/RTCP into webrtc.org for decoding, and 55 * feeding audio/video frames into webrtc.org for encoding into RTP/RTCP. 56 */ 57 class RTCRtpTransceiver : public nsISupports, public nsWrapperCache { 58 public: 59 /** 60 * |aSendTrack| might or might not be set. 61 */ 62 RTCRtpTransceiver( 63 nsPIDOMWindowInner* aWindow, bool aPrivacyNeeded, PeerConnectionImpl* aPc, 64 MediaTransportHandler* aTransportHandler, JsepSession* aJsepSession, 65 const std::string& aTransceiverId, bool aIsVideo, 66 nsISerialEventTarget* aStsThread, MediaStreamTrack* aSendTrack, 67 WebrtcCallWrapper* aCallWrapper, RTCStatsIdGenerator* aIdGenerator); 68 69 void Init(const RTCRtpTransceiverInit& aInit, ErrorResult& aRv); 70 71 bool IsValid() const { return !!mConduit; } 72 73 nsresult UpdateTransport(); 74 75 nsresult UpdateConduit(); 76 77 void UpdatePrincipalPrivacy(PrincipalPrivacy aPrivacy); 78 79 void ResetSync(); 80 81 nsresult SyncWithMatchingVideoConduits( 82 nsTArray<RefPtr<RTCRtpTransceiver>>& transceivers); 83 84 void Close(); 85 86 void BreakCycles(); 87 void Unlink(); 88 89 bool ConduitHasPluginID(uint64_t aPluginID); 90 91 // for webidl 92 JSObject* WrapObject(JSContext* aCx, 93 JS::Handle<JSObject*> aGivenProto) override; 94 nsPIDOMWindowInner* GetParentObject() const; 95 RTCRtpReceiver* Receiver() const { return mReceiver; } 96 RTCRtpSender* Sender() const { return mSender; } 97 RTCDtlsTransport* GetDtlsTransport() const { return mDtlsTransport; } 98 void GetKind(nsAString& aKind) const; 99 void GetMid(nsAString& aMid) const; 100 RTCRtpTransceiverDirection Direction() const { 101 if (mStopping) { 102 return RTCRtpTransceiverDirection::Stopped; 103 } 104 return mDirection; 105 } 106 void SetDirection(RTCRtpTransceiverDirection aDirection, ErrorResult& aRv); 107 Nullable<RTCRtpTransceiverDirection> GetCurrentDirection() { 108 if (mStopped) { 109 return RTCRtpTransceiverDirection::Stopped; 110 } 111 return mCurrentDirection; 112 } 113 void Stop(ErrorResult& aRv); 114 void SetCodecPreferences(const nsTArray<RTCRtpCodec>& aCodecs, 115 ErrorResult& aRv); 116 void SetDirectionInternal(RTCRtpTransceiverDirection aDirection); 117 bool HasBeenUsedToSend() const { return mHasBeenUsedToSend; } 118 119 bool CanSendDTMF() const; 120 bool Stopped() const { return mStopped; } 121 bool Stopping() const { return mStopping; } 122 void SyncToJsep(JsepSession& aSession) const; 123 void SyncFromJsep(const JsepSession& aSession); 124 std::string GetMidAscii() const; 125 126 void SetDtlsTransport(RTCDtlsTransport* aDtlsTransport); 127 void SaveStateForRollback(); 128 void RollbackToStableDtlsTransport(); 129 130 std::string GetTransportId() const { 131 return mJsepTransceiver.mTransport.mTransportId; 132 } 133 134 JsepTransceiver& GetJsepTransceiver() { return mJsepTransceiver; } 135 136 bool IsVideo() const; 137 138 bool IsSending() const; 139 140 bool IsReceiving() const; 141 142 bool ShouldRemove() const; 143 144 Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&> 145 GetNegotiatedSendCodecs() const; 146 147 Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&> 148 GetNegotiatedRecvCodecs() const; 149 150 struct PayloadTypes { 151 Maybe<int> mSendPayloadType; 152 Maybe<int> mRecvPayloadType; 153 }; 154 using ActivePayloadTypesPromise = MozPromise<PayloadTypes, nsresult, true>; 155 RefPtr<ActivePayloadTypesPromise> GetActivePayloadTypes() const; 156 157 MediaSessionConduit* GetConduit() const { return mConduit; } 158 159 const std::string& GetJsepTransceiverId() const { return mTransceiverId; } 160 161 void SetRemovedFromPc() { mHandlingUnlink = true; } 162 163 // nsISupports 164 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 165 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(RTCRtpTransceiver) 166 167 static void NegotiatedDetailsToAudioCodecConfigs( 168 const JsepTrackNegotiatedDetails& aDetails, 169 std::vector<AudioCodecConfig>* aConfigs); 170 171 static void NegotiatedDetailsToVideoCodecConfigs( 172 const JsepTrackNegotiatedDetails& aDetails, 173 std::vector<VideoCodecConfig>* aConfigs); 174 175 static void ToDomRtpCodec(const JsepCodecDescription& aCodec, 176 RTCRtpCodec* aDomCodec); 177 178 static void ToDomRtpCodecParameters( 179 const JsepCodecDescription& aCodec, 180 RTCRtpCodecParameters* aDomCodecParameters); 181 182 static void ToDomRtpCodecRtx(const JsepVideoCodecDescription& aCodec, 183 RTCRtpCodec* aDomCodec); 184 185 static void ToDomRtpCodecParametersRtx( 186 const JsepVideoCodecDescription& aCodec, 187 RTCRtpCodecParameters* aDomCodecParameters); 188 189 /* Returns a promise that will contain the stats in aStats, along with the 190 * codec stats (which is a PC-wide thing) */ 191 void ChainToDomPromiseWithCodecStats(nsTArray<RefPtr<RTCStatsPromise>> aStats, 192 const RefPtr<Promise>& aDomPromise); 193 194 /** 195 * Takes a set of codec stats (per-peerconnection) and a set of 196 * transceiver/transceiver-stats-promise tuples. Filters out all referenced 197 * codec stats based on the transceiver's transport and rtp stream stats. 198 * Finally returns the flattened stats containing the filtered codec stats and 199 * all given per-transceiver-stats. 200 */ 201 static RefPtr<RTCStatsPromise> ApplyCodecStats( 202 nsTArray<RTCCodecStats> aCodecStats, 203 nsTArray<std::tuple<RTCRtpTransceiver*, 204 RefPtr<RTCStatsPromise::AllPromiseType>>> 205 aTransceiverStatsPromises); 206 207 Canonical<std::string>& CanonicalMid() { return mMid; } 208 Canonical<std::string>& CanonicalSyncGroup() { return mSyncGroup; } 209 210 const std::vector<UniquePtr<JsepCodecDescription>>& GetPreferredCodecs() { 211 return mPreferredCodecs; 212 } 213 214 bool GetPreferredCodecsInUse() { return mPreferredCodecsInUse; } 215 216 private: 217 virtual ~RTCRtpTransceiver(); 218 void InitAudio(); 219 void InitVideo(const TrackingId& aRecvTrackingId); 220 void InitConduitControl(); 221 void StopImpl(); 222 void StopTransceiving(); 223 224 nsCOMPtr<nsPIDOMWindowInner> mWindow; 225 RefPtr<PeerConnectionImpl> mPc; 226 RefPtr<MediaTransportHandler> mTransportHandler; 227 const std::string mTransceiverId; 228 // Copy of latest from the JSEP engine. 229 JsepTransceiver mJsepTransceiver; 230 nsCOMPtr<nsISerialEventTarget> mStsThread; 231 // state for webrtc.org that is shared between all transceivers 232 RefPtr<WebrtcCallWrapper> mCallWrapper; 233 RefPtr<MediaStreamTrack> mSendTrack; 234 RefPtr<RTCStatsIdGenerator> mIdGenerator; 235 RefPtr<MediaSessionConduit> mConduit; 236 // The spec says both RTCRtpReceiver and RTCRtpSender have a slot for 237 // an RTCDtlsTransport. They are always the same, so we'll store it 238 // here. 239 RefPtr<RTCDtlsTransport> mDtlsTransport; 240 // The spec says both RTCRtpReceiver and RTCRtpSender have a slot for 241 // a last stable state RTCDtlsTransport. They are always the same, so 242 // we'll store it here. 243 RefPtr<RTCDtlsTransport> mLastStableDtlsTransport; 244 RefPtr<RTCRtpReceiver> mReceiver; 245 RefPtr<RTCRtpSender> mSender; 246 RTCRtpTransceiverDirection mDirection = RTCRtpTransceiverDirection::Sendrecv; 247 Nullable<RTCRtpTransceiverDirection> mCurrentDirection; 248 bool mStopped = false; 249 bool mStopping = false; 250 bool mShutdown = false; 251 bool mHasBeenUsedToSend = false; 252 PrincipalPrivacy mPrincipalPrivacy; 253 bool mShouldRemove = false; 254 bool mHasTransport = false; 255 bool mIsVideo; 256 // This is really nasty. Most of the time, PeerConnectionImpl needs to be in 257 // charge of unlinking each RTCRtpTransceiver, because it needs to perform 258 // stats queries on its way out, which requires all of the RTCRtpTransceivers 259 // (and their transitive dependencies) to stick around until those stats 260 // queries are finished. However, when an RTCRtpTransceiver is removed from 261 // the PeerConnectionImpl due to negotiation, the PeerConnectionImpl 262 // releases its reference, which means the PeerConnectionImpl cannot be in 263 // charge of the unlink anymore. We cannot do the unlink when this reference 264 // is released either, because RTCRtpTransceiver might have some work it needs 265 // to do first. Also, JS may be maintaining a reference to the 266 // RTCRtpTransceiver (or one of its dependencies), which means it must remain 267 // fully functional after it is removed (meaning it cannot release any of its 268 // dependencies, or vice versa). 269 bool mHandlingUnlink = false; 270 std::string mTransportId; 271 272 Canonical<std::string> mMid; 273 Canonical<std::string> mSyncGroup; 274 275 // Preferred codecs to be negotiated set by calling 276 // setCodecPreferences. 277 std::vector<UniquePtr<JsepCodecDescription>> mPreferredCodecs; 278 // Identifies if a preferred list and order of codecs is to be used. 279 // This is true if setCodecPreferences was called succesfully and passed 280 // codecs (not empty). 281 bool mPreferredCodecsInUse = false; 282 }; 283 284 } // namespace dom 285 286 } // namespace mozilla 287 288 #endif // _TRANSCEIVERIMPL_H_