summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/jsapi/RTCRtpTransceiver.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webrtc/jsapi/RTCRtpTransceiver.h')
-rw-r--r--dom/media/webrtc/jsapi/RTCRtpTransceiver.h243
1 files changed, 243 insertions, 0 deletions
diff --git a/dom/media/webrtc/jsapi/RTCRtpTransceiver.h b/dom/media/webrtc/jsapi/RTCRtpTransceiver.h
new file mode 100644
index 0000000000..4830e465a0
--- /dev/null
+++ b/dom/media/webrtc/jsapi/RTCRtpTransceiver.h
@@ -0,0 +1,243 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef _TRANSCEIVERIMPL_H_
+#define _TRANSCEIVERIMPL_H_
+
+#include <string>
+#include "mozilla/StateMirroring.h"
+#include "mozilla/RefPtr.h"
+#include "nsCOMPtr.h"
+#include "nsISerialEventTarget.h"
+#include "nsTArray.h"
+#include "mozilla/dom/MediaStreamTrack.h"
+#include "ErrorList.h"
+#include "jsep/JsepSession.h"
+#include "transport/transportlayer.h" // For TransportLayer::State
+#include "mozilla/dom/RTCRtpTransceiverBinding.h"
+#include "RTCStatsReport.h"
+
+class nsIPrincipal;
+
+namespace mozilla {
+class PeerIdentity;
+class MediaSessionConduit;
+class VideoSessionConduit;
+class AudioSessionConduit;
+struct AudioCodecConfig;
+class VideoCodecConfig; // Why is this a class, but AudioCodecConfig a struct?
+class MediaPipelineTransmit;
+class MediaPipeline;
+class MediaPipelineFilter;
+class MediaTransportHandler;
+class RTCStatsIdGenerator;
+class WebrtcCallWrapper;
+class JsepTrackNegotiatedDetails;
+class PeerConnectionImpl;
+enum class PrincipalPrivacy : uint8_t;
+
+namespace dom {
+class RTCDtlsTransport;
+class RTCDTMFSender;
+class RTCRtpTransceiver;
+struct RTCRtpSourceEntry;
+class RTCRtpReceiver;
+class RTCRtpSender;
+
+/**
+ * This is what ties all the various pieces that make up a transceiver
+ * together. This includes:
+ * MediaStreamTrack for rendering and capture
+ * MediaTransportHandler for RTP transmission/reception
+ * Audio/VideoConduit for feeding RTP/RTCP into webrtc.org for decoding, and
+ * feeding audio/video frames into webrtc.org for encoding into RTP/RTCP.
+ */
+class RTCRtpTransceiver : public nsISupports, public nsWrapperCache {
+ public:
+ /**
+ * |aSendTrack| might or might not be set.
+ */
+ RTCRtpTransceiver(
+ nsPIDOMWindowInner* aWindow, bool aPrivacyNeeded, PeerConnectionImpl* aPc,
+ MediaTransportHandler* aTransportHandler, JsepSession* aJsepSession,
+ const std::string& aTransceiverId, bool aIsVideo,
+ nsISerialEventTarget* aStsThread, MediaStreamTrack* aSendTrack,
+ WebrtcCallWrapper* aCallWrapper, RTCStatsIdGenerator* aIdGenerator);
+
+ void Init(const RTCRtpTransceiverInit& aInit, ErrorResult& aRv);
+
+ bool IsValid() const { return !!mConduit; }
+
+ nsresult UpdateTransport();
+
+ nsresult UpdateConduit();
+
+ void UpdatePrincipalPrivacy(PrincipalPrivacy aPrivacy);
+
+ void ResetSync();
+
+ nsresult SyncWithMatchingVideoConduits(
+ nsTArray<RefPtr<RTCRtpTransceiver>>& transceivers);
+
+ void Close();
+
+ void BreakCycles();
+
+ bool ConduitHasPluginID(uint64_t aPluginID);
+
+ // for webidl
+ JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ nsPIDOMWindowInner* GetParentObject() const;
+ RTCRtpReceiver* Receiver() const { return mReceiver; }
+ RTCRtpSender* Sender() const { return mSender; }
+ RTCDtlsTransport* GetDtlsTransport() const { return mDtlsTransport; }
+ void GetKind(nsAString& aKind) const;
+ void GetMid(nsAString& aMid) const;
+ RTCRtpTransceiverDirection Direction() const { return mDirection; }
+ void SetDirection(RTCRtpTransceiverDirection aDirection, ErrorResult& aRv);
+ Nullable<RTCRtpTransceiverDirection> GetCurrentDirection() {
+ return mCurrentDirection;
+ }
+ void Stop(ErrorResult& aRv);
+ void SetDirectionInternal(RTCRtpTransceiverDirection aDirection);
+ bool HasBeenUsedToSend() const { return mHasBeenUsedToSend; }
+
+ bool CanSendDTMF() const;
+ bool Stopped() const { return mStopped; }
+ void SyncToJsep(JsepSession& aSession) const;
+ void SyncFromJsep(const JsepSession& aSession);
+ std::string GetMidAscii() const;
+
+ void SetDtlsTransport(RTCDtlsTransport* aDtlsTransport, bool aStable);
+ void RollbackToStableDtlsTransport();
+
+ std::string GetTransportId() const {
+ return mJsepTransceiver.mTransport.mTransportId;
+ }
+
+ JsepTransceiver& GetJsepTransceiver() { return mJsepTransceiver; }
+
+ bool IsVideo() const;
+
+ bool IsSending() const;
+
+ bool IsReceiving() const;
+
+ bool ShouldRemove() const;
+
+ Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&>
+ GetNegotiatedSendCodecs() const;
+
+ Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&>
+ GetNegotiatedRecvCodecs() const;
+
+ struct PayloadTypes {
+ Maybe<int> mSendPayloadType;
+ Maybe<int> mRecvPayloadType;
+ };
+ using ActivePayloadTypesPromise = MozPromise<PayloadTypes, nsresult, true>;
+ RefPtr<ActivePayloadTypesPromise> GetActivePayloadTypes() const;
+
+ MediaSessionConduit* GetConduit() const { return mConduit; }
+
+ const std::string& GetJsepTransceiverId() const { return mTransceiverId; }
+
+ void SetRemovedFromPc() { mHandlingUnlink = true; }
+
+ // nsISupports
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(RTCRtpTransceiver)
+
+ static void NegotiatedDetailsToAudioCodecConfigs(
+ const JsepTrackNegotiatedDetails& aDetails,
+ std::vector<AudioCodecConfig>* aConfigs);
+
+ static void NegotiatedDetailsToVideoCodecConfigs(
+ const JsepTrackNegotiatedDetails& aDetails,
+ std::vector<VideoCodecConfig>* aConfigs);
+
+ /* Returns a promise that will contain the stats in aStats, along with the
+ * codec stats (which is a PC-wide thing) */
+ void ChainToDomPromiseWithCodecStats(nsTArray<RefPtr<RTCStatsPromise>> aStats,
+ const RefPtr<Promise>& aDomPromise);
+
+ /**
+ * Takes a set of codec stats (per-peerconnection) and a set of
+ * transceiver/transceiver-stats-promise tuples. Filters out all referenced
+ * codec stats based on the transceiver's transport and rtp stream stats.
+ * Finally returns the flattened stats containing the filtered codec stats and
+ * all given per-transceiver-stats.
+ */
+ static RefPtr<RTCStatsPromise> ApplyCodecStats(
+ nsTArray<RTCCodecStats> aCodecStats,
+ nsTArray<std::tuple<RTCRtpTransceiver*,
+ RefPtr<RTCStatsPromise::AllPromiseType>>>
+ aTransceiverStatsPromises);
+
+ AbstractCanonical<std::string>* CanonicalMid() { return &mMid; }
+ AbstractCanonical<std::string>* CanonicalSyncGroup() { return &mSyncGroup; }
+
+ private:
+ virtual ~RTCRtpTransceiver();
+ void InitAudio();
+ void InitVideo(const TrackingId& aRecvTrackingId);
+ void InitConduitControl();
+ void StopImpl();
+
+ nsCOMPtr<nsPIDOMWindowInner> mWindow;
+ RefPtr<PeerConnectionImpl> mPc;
+ RefPtr<MediaTransportHandler> mTransportHandler;
+ const std::string mTransceiverId;
+ // Copy of latest from the JSEP engine.
+ JsepTransceiver mJsepTransceiver;
+ nsCOMPtr<nsISerialEventTarget> mStsThread;
+ // state for webrtc.org that is shared between all transceivers
+ RefPtr<WebrtcCallWrapper> mCallWrapper;
+ RefPtr<MediaStreamTrack> mSendTrack;
+ RefPtr<RTCStatsIdGenerator> mIdGenerator;
+ RefPtr<MediaSessionConduit> mConduit;
+ // The spec says both RTCRtpReceiver and RTCRtpSender have a slot for
+ // an RTCDtlsTransport. They are always the same, so we'll store it
+ // here.
+ RefPtr<RTCDtlsTransport> mDtlsTransport;
+ // The spec says both RTCRtpReceiver and RTCRtpSender have a slot for
+ // a last stable state RTCDtlsTransport. They are always the same, so
+ // we'll store it here.
+ RefPtr<RTCDtlsTransport> mLastStableDtlsTransport;
+ RefPtr<RTCRtpReceiver> mReceiver;
+ RefPtr<RTCRtpSender> mSender;
+ RTCRtpTransceiverDirection mDirection = RTCRtpTransceiverDirection::Sendrecv;
+ Nullable<RTCRtpTransceiverDirection> mCurrentDirection;
+ bool mStopped = false;
+ bool mShutdown = false;
+ bool mHasBeenUsedToSend = false;
+ PrincipalPrivacy mPrincipalPrivacy;
+ bool mShouldRemove = false;
+ bool mHasTransport = false;
+ bool mIsVideo;
+ // This is really nasty. Most of the time, PeerConnectionImpl needs to be in
+ // charge of unlinking each RTCRtpTransceiver, because it needs to perform
+ // stats queries on its way out, which requires all of the RTCRtpTransceivers
+ // (and their transitive dependencies) to stick around until those stats
+ // queries are finished. However, when an RTCRtpTransceiver is removed from
+ // the PeerConnectionImpl due to negotiation, the PeerConnectionImpl
+ // releases its reference, which means the PeerConnectionImpl cannot be in
+ // charge of the unlink anymore. We cannot do the unlink when this reference
+ // is released either, because RTCRtpTransceiver might have some work it needs
+ // to do first. Also, JS may be maintaining a reference to the
+ // RTCRtpTransceiver (or one of its dependencies), which means it must remain
+ // fully functional after it is removed (meaning it cannot release any of its
+ // dependencies, or vice versa).
+ bool mHandlingUnlink = false;
+ std::string mTransportId;
+
+ Canonical<std::string> mMid;
+ Canonical<std::string> mSyncGroup;
+};
+
+} // namespace dom
+
+} // namespace mozilla
+
+#endif // _TRANSCEIVERIMPL_H_