summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/jsep/JsepTransceiver.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webrtc/jsep/JsepTransceiver.h')
-rw-r--r--dom/media/webrtc/jsep/JsepTransceiver.h220
1 files changed, 220 insertions, 0 deletions
diff --git a/dom/media/webrtc/jsep/JsepTransceiver.h b/dom/media/webrtc/jsep/JsepTransceiver.h
new file mode 100644
index 0000000000..45afcee04f
--- /dev/null
+++ b/dom/media/webrtc/jsep/JsepTransceiver.h
@@ -0,0 +1,220 @@
+/* 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 _JSEPTRANSCEIVER_H_
+#define _JSEPTRANSCEIVER_H_
+
+#include <string>
+
+#include "sdp/SdpAttribute.h"
+#include "sdp/SdpMediaSection.h"
+#include "sdp/Sdp.h"
+#include "jsep/JsepTransport.h"
+#include "jsep/JsepTrack.h"
+
+#include "nsError.h"
+
+namespace mozilla {
+
+class JsepUuidGenerator {
+ public:
+ virtual ~JsepUuidGenerator() = default;
+ virtual bool Generate(std::string* id) = 0;
+ virtual JsepUuidGenerator* Clone() const = 0;
+};
+
+class JsepTransceiver {
+ public:
+ explicit JsepTransceiver(SdpMediaSection::MediaType type,
+ JsepUuidGenerator& aUuidGen,
+ SdpDirectionAttribute::Direction jsDirection =
+ SdpDirectionAttribute::kSendrecv)
+ : mJsDirection(jsDirection),
+ mSendTrack(type, sdp::kSend),
+ mRecvTrack(type, sdp::kRecv) {
+ if (!aUuidGen.Generate(&mUuid)) {
+ MOZ_CRASH();
+ }
+ }
+
+ JsepTransceiver(const JsepTransceiver& orig) = default;
+ JsepTransceiver(JsepTransceiver&& orig) = default;
+ JsepTransceiver& operator=(const JsepTransceiver& aRhs) = default;
+ JsepTransceiver& operator=(JsepTransceiver&& aRhs) = default;
+
+ ~JsepTransceiver() = default;
+
+ void Rollback(JsepTransceiver& oldTransceiver, bool aRemote) {
+ MOZ_ASSERT(oldTransceiver.GetMediaType() == GetMediaType());
+ MOZ_ASSERT(!oldTransceiver.IsNegotiated() || !oldTransceiver.HasLevel() ||
+ !HasLevel() || oldTransceiver.GetLevel() == GetLevel());
+ mTransport = oldTransceiver.mTransport;
+ if (aRemote) {
+ mLevel = oldTransceiver.mLevel;
+ mBundleLevel = oldTransceiver.mBundleLevel;
+ mSendTrack = oldTransceiver.mSendTrack;
+ }
+ mRecvTrack = oldTransceiver.mRecvTrack;
+
+ // Don't allow rollback to re-associate a transceiver.
+ if (!oldTransceiver.IsAssociated()) {
+ Disassociate();
+ }
+ }
+
+ bool IsAssociated() const { return !mMid.empty(); }
+
+ const std::string& GetMid() const {
+ MOZ_ASSERT(IsAssociated());
+ return mMid;
+ }
+
+ void Associate(const std::string& mid) {
+ MOZ_ASSERT(HasLevel());
+ mMid = mid;
+ }
+
+ void Disassociate() { mMid.clear(); }
+
+ bool HasLevel() const { return mLevel != SIZE_MAX; }
+
+ void SetLevel(size_t level) {
+ MOZ_ASSERT(level != SIZE_MAX);
+ MOZ_ASSERT(!HasLevel());
+ MOZ_ASSERT(!IsStopped());
+
+ mLevel = level;
+ }
+
+ void ClearLevel() {
+ MOZ_ASSERT(!IsAssociated());
+ mLevel = SIZE_MAX;
+ mBundleLevel = SIZE_MAX;
+ }
+
+ size_t GetLevel() const {
+ MOZ_ASSERT(HasLevel());
+ return mLevel;
+ }
+
+ void Stop() { mStopping = true; }
+
+ bool IsStopping() const { return mStopping; }
+
+ bool IsStopped() const { return mStopped; }
+
+ void SetStopped() { mStopped = true; }
+
+ bool IsFreeToUse() const { return !mStopping && !mStopped && !HasLevel(); }
+
+ void RestartDatachannelTransceiver() {
+ MOZ_RELEASE_ASSERT(GetMediaType() == SdpMediaSection::kApplication);
+ mStopping = false;
+ mStopped = false;
+ mCanRecycleMyMsection = false;
+ }
+
+ void SetRemoved() { mRemoved = true; }
+
+ bool IsRemoved() const { return mRemoved; }
+
+ bool HasBundleLevel() const { return mBundleLevel != SIZE_MAX; }
+
+ size_t BundleLevel() const {
+ MOZ_ASSERT(HasBundleLevel());
+ return mBundleLevel;
+ }
+
+ void SetBundleLevel(size_t aBundleLevel) {
+ MOZ_ASSERT(aBundleLevel != SIZE_MAX);
+ mBundleLevel = aBundleLevel;
+ }
+
+ void ClearBundleLevel() { mBundleLevel = SIZE_MAX; }
+
+ size_t GetTransportLevel() const {
+ MOZ_ASSERT(HasLevel());
+ if (HasBundleLevel()) {
+ return BundleLevel();
+ }
+ return GetLevel();
+ }
+
+ void SetAddTrackMagic() { mAddTrackMagic = true; }
+
+ bool HasAddTrackMagic() const { return mAddTrackMagic; }
+
+ void SetOnlyExistsBecauseOfSetRemote(bool aValue) {
+ mOnlyExistsBecauseOfSetRemote = aValue;
+ }
+
+ bool OnlyExistsBecauseOfSetRemote() const {
+ return mOnlyExistsBecauseOfSetRemote;
+ }
+
+ void SetNegotiated() {
+ MOZ_ASSERT(IsAssociated());
+ MOZ_ASSERT(HasLevel());
+ mNegotiated = true;
+ }
+
+ bool IsNegotiated() const { return mNegotiated; }
+
+ void SetCanRecycleMyMsection() { mCanRecycleMyMsection = true; }
+
+ bool CanRecycleMyMsection() const { return mCanRecycleMyMsection; }
+
+ const std::string& GetUuid() const { return mUuid; }
+
+ // Convenience function
+ SdpMediaSection::MediaType GetMediaType() const {
+ MOZ_ASSERT(mRecvTrack.GetMediaType() == mSendTrack.GetMediaType());
+ return mRecvTrack.GetMediaType();
+ }
+
+ bool HasTransport() const { return mTransport.mComponents != 0; }
+
+ bool HasOwnTransport() const {
+ if (HasTransport() &&
+ (!HasBundleLevel() || (GetLevel() == BundleLevel()))) {
+ return true;
+ }
+ return false;
+ }
+
+ // See Bug 1642419, this can be removed when all sites are working with RTX.
+ void SetRtxIsAllowed(bool aRtxIsAllowed) {
+ mSendTrack.SetRtxIsAllowed(aRtxIsAllowed);
+ mRecvTrack.SetRtxIsAllowed(aRtxIsAllowed);
+ }
+
+ // This is the direction JS wants. It might not actually happen.
+ SdpDirectionAttribute::Direction mJsDirection;
+
+ JsepTrack mSendTrack;
+ JsepTrack mRecvTrack;
+ JsepTransport mTransport;
+
+ private:
+ std::string mUuid;
+ // Stuff that is not negotiated
+ std::string mMid;
+ size_t mLevel = SIZE_MAX; // SIZE_MAX if no level
+ // Is this track pair sharing a transport with another?
+ size_t mBundleLevel = SIZE_MAX; // SIZE_MAX if no bundle level
+ // The w3c and IETF specs have a lot of "magical" behavior that happens
+ // when addTrack is used to create a transceiver. This was a deliberate
+ // design choice. Sadface.
+ bool mAddTrackMagic = false;
+ bool mOnlyExistsBecauseOfSetRemote = false;
+ bool mStopping = false;
+ bool mStopped = false;
+ bool mRemoved = false;
+ bool mNegotiated = false;
+ bool mCanRecycleMyMsection = false;
+};
+
+} // namespace mozilla
+
+#endif // _JSEPTRANSCEIVER_H_