summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/pc/used_ids.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/pc/used_ids.h')
-rw-r--r--third_party/libwebrtc/pc/used_ids.h182
1 files changed, 182 insertions, 0 deletions
diff --git a/third_party/libwebrtc/pc/used_ids.h b/third_party/libwebrtc/pc/used_ids.h
new file mode 100644
index 0000000000..1236a786df
--- /dev/null
+++ b/third_party/libwebrtc/pc/used_ids.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef PC_USED_IDS_H_
+#define PC_USED_IDS_H_
+
+#include <set>
+#include <vector>
+
+#include "api/rtp_parameters.h"
+#include "media/base/codec.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+
+namespace cricket {
+template <typename IdStruct>
+class UsedIds {
+ public:
+ UsedIds(int min_allowed_id, int max_allowed_id)
+ : min_allowed_id_(min_allowed_id),
+ max_allowed_id_(max_allowed_id),
+ next_id_(max_allowed_id) {}
+ virtual ~UsedIds() {}
+
+ // Loops through all Id in `ids` and changes its id if it is
+ // already in use by another IdStruct. Call this methods with all Id
+ // in a session description to make sure no duplicate ids exists.
+ // Note that typename Id must be a type of IdStruct.
+ template <typename Id>
+ void FindAndSetIdUsed(std::vector<Id>* ids) {
+ for (const Id& id : *ids) {
+ FindAndSetIdUsed(&id);
+ }
+ }
+
+ // Finds and sets an unused id if the `idstruct` id is already in use.
+ void FindAndSetIdUsed(IdStruct* idstruct) {
+ const int original_id = idstruct->id;
+ int new_id = idstruct->id;
+
+ if (original_id > max_allowed_id_ || original_id < min_allowed_id_) {
+ // If the original id is not in range - this is an id that can't be
+ // dynamically changed.
+ return;
+ }
+
+ if (IsIdUsed(original_id)) {
+ new_id = FindUnusedId();
+ // Duplicate id found. Reassign from the original id to the new.
+ idstruct->id = new_id;
+ }
+ SetIdUsed(new_id);
+ }
+
+ protected:
+ virtual bool IsIdUsed(int new_id) {
+ return id_set_.find(new_id) != id_set_.end();
+ }
+ const int min_allowed_id_;
+ const int max_allowed_id_;
+
+ private:
+ // Returns the first unused id in reverse order.
+ // This hopefully reduces the risk of more collisions. We want to change the
+ // default ids as little as possible. This function is virtual and can be
+ // overriden if the search for unused IDs should follow a specific pattern.
+ virtual int FindUnusedId() {
+ while (IsIdUsed(next_id_) && next_id_ >= min_allowed_id_) {
+ --next_id_;
+ }
+ RTC_DCHECK(next_id_ >= min_allowed_id_);
+ return next_id_;
+ }
+
+ void SetIdUsed(int new_id) {
+ RTC_DCHECK(new_id >= min_allowed_id_);
+ RTC_DCHECK(new_id <= max_allowed_id_);
+ RTC_DCHECK(!IsIdUsed(new_id));
+ id_set_.insert(new_id);
+ }
+ int next_id_;
+ std::set<int> id_set_;
+};
+
+// Helper class used for finding duplicate RTP payload types among audio, video
+// and data codecs. When bundle is used the payload types may not collide.
+class UsedPayloadTypes : public UsedIds<Codec> {
+ public:
+ UsedPayloadTypes()
+ : UsedIds<Codec>(kFirstDynamicPayloadTypeLowerRange,
+ kLastDynamicPayloadTypeUpperRange) {}
+
+ protected:
+ bool IsIdUsed(int new_id) override {
+ // Range marked for RTCP avoidance is "used".
+ if (new_id > kLastDynamicPayloadTypeLowerRange &&
+ new_id < kFirstDynamicPayloadTypeUpperRange)
+ return true;
+ return UsedIds<Codec>::IsIdUsed(new_id);
+ }
+
+ private:
+ static const int kFirstDynamicPayloadTypeLowerRange = 35;
+ static const int kLastDynamicPayloadTypeLowerRange = 63;
+
+ static const int kFirstDynamicPayloadTypeUpperRange = 96;
+ static const int kLastDynamicPayloadTypeUpperRange = 127;
+};
+
+// Helper class used for finding duplicate RTP Header extension ids among
+// audio and video extensions.
+class UsedRtpHeaderExtensionIds : public UsedIds<webrtc::RtpExtension> {
+ public:
+ enum class IdDomain {
+ // Only allocate IDs that fit in one-byte header extensions.
+ kOneByteOnly,
+ // Prefer to allocate one-byte header extension IDs, but overflow to
+ // two-byte if none are left.
+ kTwoByteAllowed,
+ };
+
+ explicit UsedRtpHeaderExtensionIds(IdDomain id_domain)
+ : UsedIds<webrtc::RtpExtension>(
+ webrtc::RtpExtension::kMinId,
+ id_domain == IdDomain::kTwoByteAllowed
+ ? webrtc::RtpExtension::kMaxId
+ : webrtc::RtpExtension::kOneByteHeaderExtensionMaxId),
+ id_domain_(id_domain),
+ next_extension_id_(webrtc::RtpExtension::kOneByteHeaderExtensionMaxId) {
+ }
+
+ private:
+ // Returns the first unused id in reverse order from the max id of one byte
+ // header extensions. This hopefully reduce the risk of more collisions. We
+ // want to change the default ids as little as possible. If no unused id is
+ // found and two byte header extensions are enabled (i.e.,
+ // `extmap_allow_mixed_` is true), search for unused ids from 15 to 255.
+ int FindUnusedId() override {
+ if (next_extension_id_ <=
+ webrtc::RtpExtension::kOneByteHeaderExtensionMaxId) {
+ // First search in reverse order from the max id of one byte header
+ // extensions.
+ while (IsIdUsed(next_extension_id_) &&
+ next_extension_id_ >= min_allowed_id_) {
+ --next_extension_id_;
+ }
+ }
+
+ if (id_domain_ == IdDomain::kTwoByteAllowed) {
+ if (next_extension_id_ < min_allowed_id_) {
+ // We have searched among all one-byte IDs without finding an unused ID,
+ // continue at the first two-byte ID.
+ next_extension_id_ =
+ webrtc::RtpExtension::kOneByteHeaderExtensionMaxId + 1;
+ }
+
+ if (next_extension_id_ >
+ webrtc::RtpExtension::kOneByteHeaderExtensionMaxId) {
+ while (IsIdUsed(next_extension_id_) &&
+ next_extension_id_ <= max_allowed_id_) {
+ ++next_extension_id_;
+ }
+ }
+ }
+ RTC_DCHECK(next_extension_id_ >= min_allowed_id_);
+ RTC_DCHECK(next_extension_id_ <= max_allowed_id_);
+ return next_extension_id_;
+ }
+
+ const IdDomain id_domain_;
+ int next_extension_id_;
+};
+
+} // namespace cricket
+
+#endif // PC_USED_IDS_H_