Stop hard-coding default IDs for RTP extensions

Hard-coding default values forces IDs over 14 to be used even
when we offer less than 15 different extensions.

Note that the code relies on MergeRtpHdrExts for making sure
that extension IDs are kept consistent and non-colliding between
different streams (audio/video).

Bug: webrtc:10288
Change-Id: I3e59f7ddc8ca43cea91084a6b7f36df70fb6be4a
Reviewed-on: https://webrtc-review.googlesource.com/c/121646
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26622}
diff --git a/api/DEPS b/api/DEPS
index bc80704..f5a0201 100644
--- a/api/DEPS
+++ b/api/DEPS
@@ -150,6 +150,10 @@
     "+rtc_base/logging.h",
   ],
 
+  "rtp_parameters\.h": [
+    "+rtc_base/deprecation.h",
+  ],
+
   "rtp_receiver_interface\.h": [
     "+rtc_base/ref_count.h",
   ],
diff --git a/api/rtp_parameters.h b/api/rtp_parameters.h
index 90e4a4c..6138c37 100644
--- a/api/rtp_parameters.h
+++ b/api/rtp_parameters.h
@@ -18,6 +18,7 @@
 
 #include "absl/types/optional.h"
 #include "api/media_types.h"
+#include "rtc_base/deprecation.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -258,53 +259,64 @@
   // Header extension for audio levels, as defined in:
   // http://tools.ietf.org/html/draft-ietf-avtext-client-to-mixer-audio-level-03
   static const char kAudioLevelUri[];
-  static const int kAudioLevelDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kAudioLevelDefaultId;
 
   // Header extension for RTP timestamp offset, see RFC 5450 for details:
   // http://tools.ietf.org/html/rfc5450
   static const char kTimestampOffsetUri[];
-  static const int kTimestampOffsetDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kTimestampOffsetDefaultId;
 
   // Header extension for absolute send time, see url for details:
   // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
   static const char kAbsSendTimeUri[];
-  static const int kAbsSendTimeDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kAbsSendTimeDefaultId;
 
   // Header extension for coordination of video orientation, see url for
   // details:
   // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ts_126114v120700p.pdf
   static const char kVideoRotationUri[];
-  static const int kVideoRotationDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kVideoRotationDefaultId;
 
   // Header extension for video content type. E.g. default or screenshare.
   static const char kVideoContentTypeUri[];
-  static const int kVideoContentTypeDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kVideoContentTypeDefaultId;
 
   // Header extension for video timing.
   static const char kVideoTimingUri[];
-  static const int kVideoTimingDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kVideoTimingDefaultId;
 
   // Header extension for video frame marking.
   static const char kFrameMarkingUri[];
-  static const int kFrameMarkingDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kFrameMarkingDefaultId;
 
   // Experimental codec agnostic frame descriptor.
   static const char kGenericFrameDescriptorUri[];
-  static const int kGenericFrameDescriptorDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kGenericFrameDescriptorDefaultId;
 
   // Header extension for transport sequence number, see url for details:
   // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions
   static const char kTransportSequenceNumberUri[];
   static const char kTransportSequenceNumberV2Uri[];
-  static const int kTransportSequenceNumberDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kTransportSequenceNumberDefaultId;
 
   static const char kPlayoutDelayUri[];
-  static const int kPlayoutDelayDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kPlayoutDelayDefaultId;
 
   // Header extension for identifying media section within a transport.
   // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-49#section-15
   static const char kMidUri[];
-  static const int kMidDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kMidDefaultId;
 
   // Encryption of Header Extensions, see RFC 6904 for details:
   // https://tools.ietf.org/html/rfc6904
@@ -312,15 +324,18 @@
 
   // Header extension for color space information.
   static const char kColorSpaceUri[];
-  static const int kColorSpaceDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kColorSpaceDefaultId;
 
   // Header extension for RIDs and Repaired RIDs
   // https://tools.ietf.org/html/draft-ietf-avtext-rid-09
   // https://tools.ietf.org/html/draft-ietf-mmusic-rid-15
   static const char kRidUri[];
-  static const int kRidDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kRidDefaultId;
   static const char kRepairedRidUri[];
-  static const int kRepairedRidDefaultId;
+  // TODO(bugs.webrtc.org/10288): Remove once dependencies have been updated.
+  RTC_DEPRECATED static const int kRepairedRidDefaultId;
 
   // Inclusive min and max IDs for two-byte header extensions and one-byte
   // header extensions, per RFC8285 Section 4.2-4.3.
diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc
index 6f6a198..d9ac876 100644
--- a/logging/rtc_event_log/rtc_event_log_parser.cc
+++ b/logging/rtc_event_log/rtc_event_log_parser.cc
@@ -919,22 +919,26 @@
 //             audio streams. Tracking bug: webrtc:6399
 webrtc::RtpHeaderExtensionMap
 ParsedRtcEventLog::GetDefaultHeaderExtensionMap() {
+  // Values from before the default RTP header extension IDs were removed.
+  constexpr int kAudioLevelDefaultId = 1;
+  constexpr int kTimestampOffsetDefaultId = 2;
+  constexpr int kAbsSendTimeDefaultId = 3;
+  constexpr int kVideoRotationDefaultId = 4;
+  constexpr int kTransportSequenceNumberDefaultId = 5;
+  constexpr int kPlayoutDelayDefaultId = 6;
+  constexpr int kVideoContentTypeDefaultId = 7;
+  constexpr int kVideoTimingDefaultId = 8;
+
   webrtc::RtpHeaderExtensionMap default_map;
-  default_map.Register<AudioLevel>(webrtc::RtpExtension::kAudioLevelDefaultId);
-  default_map.Register<TransmissionOffset>(
-      webrtc::RtpExtension::kTimestampOffsetDefaultId);
-  default_map.Register<AbsoluteSendTime>(
-      webrtc::RtpExtension::kAbsSendTimeDefaultId);
-  default_map.Register<VideoOrientation>(
-      webrtc::RtpExtension::kVideoRotationDefaultId);
-  default_map.Register<VideoContentTypeExtension>(
-      webrtc::RtpExtension::kVideoContentTypeDefaultId);
-  default_map.Register<VideoTimingExtension>(
-      webrtc::RtpExtension::kVideoTimingDefaultId);
+  default_map.Register<AudioLevel>(kAudioLevelDefaultId);
+  default_map.Register<TransmissionOffset>(kTimestampOffsetDefaultId);
+  default_map.Register<AbsoluteSendTime>(kAbsSendTimeDefaultId);
+  default_map.Register<VideoOrientation>(kVideoRotationDefaultId);
   default_map.Register<TransportSequenceNumber>(
-      webrtc::RtpExtension::kTransportSequenceNumberDefaultId);
-  default_map.Register<PlayoutDelayLimits>(
-      webrtc::RtpExtension::kPlayoutDelayDefaultId);
+      kTransportSequenceNumberDefaultId);
+  default_map.Register<PlayoutDelayLimits>(kPlayoutDelayDefaultId);
+  default_map.Register<VideoContentTypeExtension>(kVideoContentTypeDefaultId);
+  default_map.Register<VideoTimingExtension>(kVideoTimingDefaultId);
   return default_map;
 }
 
diff --git a/logging/rtc_event_log/rtc_event_log_unittest.cc b/logging/rtc_event_log/rtc_event_log_unittest.cc
index f44f53e..103789d 100644
--- a/logging/rtc_event_log/rtc_event_log_unittest.cc
+++ b/logging/rtc_event_log/rtc_event_log_unittest.cc
@@ -52,20 +52,6 @@
 
 namespace {
 
-RtpHeaderExtensionMap ExtensionMapWithAllSupportedExtensions() {
-  RtpHeaderExtensionMap all_extensions;
-  all_extensions.Register<AudioLevel>(RtpExtension::kAudioLevelDefaultId);
-  all_extensions.Register<TransmissionOffset>(
-      RtpExtension::kTimestampOffsetDefaultId);
-  all_extensions.Register<AbsoluteSendTime>(
-      RtpExtension::kAbsSendTimeDefaultId);
-  all_extensions.Register<VideoOrientation>(
-      RtpExtension::kVideoRotationDefaultId);
-  all_extensions.Register<TransportSequenceNumber>(
-      RtpExtension::kTransportSequenceNumberDefaultId);
-  return all_extensions;
-}
-
 struct EventCounts {
   size_t audio_send_streams = 0;
   size_t audio_recv_streams = 0;
@@ -247,7 +233,7 @@
   // Force least one stream to use all header extensions, to ensure
   // (statistically) that every extension is tested in packet creation.
   RtpHeaderExtensionMap all_extensions =
-      ExtensionMapWithAllSupportedExtensions();
+      ParsedRtcEventLog::GetDefaultHeaderExtensionMap();
 
   clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000);
   uint32_t ssrc = prng_.Rand<uint32_t>();
@@ -276,7 +262,7 @@
   // Force least one stream to use all header extensions, to ensure
   // (statistically) that every extension is tested in packet creation.
   RtpHeaderExtensionMap all_extensions =
-      ExtensionMapWithAllSupportedExtensions();
+      ParsedRtcEventLog::GetDefaultHeaderExtensionMap();
 
   clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000);
   uint32_t ssrc = prng_.Rand<uint32_t>();
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index 5d8a173..88f9000 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -467,37 +467,28 @@
 
 RtpCapabilities WebRtcVideoEngine::GetCapabilities() const {
   RtpCapabilities capabilities;
+  int id = 1;
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kTimestampOffsetUri,
-                           webrtc::RtpExtension::kTimestampOffsetDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kTimestampOffsetUri, id++));
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kAbsSendTimeUri,
-                           webrtc::RtpExtension::kAbsSendTimeDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kAbsSendTimeUri, id++));
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kVideoRotationUri,
-                           webrtc::RtpExtension::kVideoRotationDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kVideoRotationUri, id++));
   capabilities.header_extensions.push_back(webrtc::RtpExtension(
-      webrtc::RtpExtension::kTransportSequenceNumberUri,
-      webrtc::RtpExtension::kTransportSequenceNumberDefaultId));
+      webrtc::RtpExtension::kTransportSequenceNumberUri, id++));
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kPlayoutDelayUri,
-                           webrtc::RtpExtension::kPlayoutDelayDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kPlayoutDelayUri, id++));
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kVideoContentTypeUri,
-                           webrtc::RtpExtension::kVideoContentTypeDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kVideoContentTypeUri, id++));
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kVideoTimingUri,
-                           webrtc::RtpExtension::kVideoTimingDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kVideoTimingUri, id++));
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kFrameMarkingUri,
-                           webrtc::RtpExtension::kFrameMarkingDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kFrameMarkingUri, id++));
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kColorSpaceUri,
-                           webrtc::RtpExtension::kColorSpaceDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kColorSpaceUri, id++));
   if (webrtc::field_trial::IsEnabled("WebRTC-GenericDescriptorAdvertised")) {
     capabilities.header_extensions.push_back(webrtc::RtpExtension(
-        webrtc::RtpExtension::kGenericFrameDescriptorUri,
-        webrtc::RtpExtension::kGenericFrameDescriptorDefaultId));
+        webrtc::RtpExtension::kGenericFrameDescriptorUri, id++));
   }
 
   return capabilities;
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index ef45779..482da39 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -243,7 +243,7 @@
   VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
       const std::vector<VideoCodec>& codecs);
 
-  void TestExtendedEncoderOveruse(bool use_external_encoder);
+  void ExpectRtpCapabilitySupport(const char* uri, bool supported) const;
 
   // Has to be the first one, so it is initialized before the call or there is a
   // race condition in the clock access.
@@ -278,43 +278,43 @@
 }
 
 TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
-  RtpCapabilities capabilities = engine_.GetCapabilities();
-  EXPECT_THAT(
-      capabilities.header_extensions,
-      testing::Contains(RtpExtension(RtpExtension::kTimestampOffsetUri,
-                                     RtpExtension::kTimestampOffsetDefaultId)));
+  ExpectRtpCapabilitySupport(RtpExtension::kTimestampOffsetUri, true);
 }
 
 TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
-  RtpCapabilities capabilities = engine_.GetCapabilities();
-  EXPECT_THAT(
-      capabilities.header_extensions,
-      testing::Contains(RtpExtension(RtpExtension::kAbsSendTimeUri,
-                                     RtpExtension::kAbsSendTimeDefaultId)));
+  ExpectRtpCapabilitySupport(RtpExtension::kAbsSendTimeUri, true);
 }
 
 TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
-  RtpCapabilities capabilities = engine_.GetCapabilities();
-  EXPECT_THAT(capabilities.header_extensions,
-              testing::Contains(RtpExtension(
-                  RtpExtension::kTransportSequenceNumberUri,
-                  RtpExtension::kTransportSequenceNumberDefaultId)));
+  ExpectRtpCapabilitySupport(RtpExtension::kTransportSequenceNumberUri, true);
 }
 
 TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
-  RtpCapabilities capabilities = engine_.GetCapabilities();
-  EXPECT_THAT(
-      capabilities.header_extensions,
-      testing::Contains(RtpExtension(RtpExtension::kVideoRotationUri,
-                                     RtpExtension::kVideoRotationDefaultId)));
+  ExpectRtpCapabilitySupport(RtpExtension::kVideoRotationUri, true);
+}
+
+TEST_F(WebRtcVideoEngineTest, SupportsPlayoutDelayHeaderExtension) {
+  ExpectRtpCapabilitySupport(RtpExtension::kPlayoutDelayUri, true);
+}
+
+TEST_F(WebRtcVideoEngineTest, SupportsVideoContentTypeHeaderExtension) {
+  ExpectRtpCapabilitySupport(RtpExtension::kVideoContentTypeUri, true);
+}
+
+TEST_F(WebRtcVideoEngineTest, SupportsVideoTimingHeaderExtension) {
+  ExpectRtpCapabilitySupport(RtpExtension::kVideoTimingUri, true);
+}
+
+TEST_F(WebRtcVideoEngineTest, SupportsFrameMarkingHeaderExtension) {
+  ExpectRtpCapabilitySupport(RtpExtension::kFrameMarkingUri, true);
 }
 
 TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
-  RtpCapabilities capabilities = engine_.GetCapabilities();
-  EXPECT_THAT(
-      capabilities.header_extensions,
-      testing::Contains(RtpExtension(RtpExtension::kColorSpaceUri,
-                                     RtpExtension::kColorSpaceDefaultId)));
+  ExpectRtpCapabilitySupport(RtpExtension::kColorSpaceUri, true);
+}
+
+TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor) {
+  ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri, false);
 }
 
 class WebRtcVideoEngineTestWithGenericDescriptor
@@ -325,15 +325,7 @@
 };
 
 TEST_F(WebRtcVideoEngineTestWithGenericDescriptor, AdvertiseGenericDescriptor) {
-  RtpCapabilities capabilities = engine_.GetCapabilities();
-  ASSERT_FALSE(capabilities.header_extensions.empty());
-  for (const RtpExtension& extension : capabilities.header_extensions) {
-    if (extension.uri == RtpExtension::kGenericFrameDescriptorUri) {
-      EXPECT_EQ(RtpExtension::kGenericFrameDescriptorDefaultId, extension.id);
-      return;
-    }
-  }
-  FAIL() << "Generic descriptor extension not in header-extension list.";
+  ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri, true);
 }
 
 TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
@@ -702,6 +694,19 @@
   return channel;
 }
 
+void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
+                                                       bool supported) const {
+  const RtpCapabilities capabilities = engine_.GetCapabilities();
+  if (supported) {
+    EXPECT_THAT(capabilities.header_extensions,
+                testing::Contains(testing::Field(&RtpExtension::uri, uri)));
+  } else {
+    EXPECT_THAT(
+        capabilities.header_extensions,
+        testing::Each(testing::Field(&RtpExtension::uri, testing::StrNe(uri))));
+  }
+}
+
 TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
   encoder_factory_->AddSupportedVideoCodecType("VP8");
 
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index 691f7d7..07a47d7 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -556,13 +556,12 @@
 RtpCapabilities WebRtcVoiceEngine::GetCapabilities() const {
   RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
   RtpCapabilities capabilities;
+  int id = 1;
   capabilities.header_extensions.push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri,
-                           webrtc::RtpExtension::kAudioLevelDefaultId));
+      webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, id++));
   if (allocation_settings_.EnableTransportSequenceNumberExtension()) {
     capabilities.header_extensions.push_back(webrtc::RtpExtension(
-        webrtc::RtpExtension::kTransportSequenceNumberUri,
-        webrtc::RtpExtension::kTransportSequenceNumberDefaultId));
+        webrtc::RtpExtension::kTransportSequenceNumberUri, id++));
   }
 
   return capabilities;
diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc
index 663dd8c..a3ccee94 100644
--- a/media/engine/webrtc_voice_engine_unittest.cc
+++ b/media/engine/webrtc_voice_engine_unittest.cc
@@ -35,13 +35,14 @@
 #include "test/mock_audio_decoder_factory.h"
 #include "test/mock_audio_encoder_factory.h"
 
-using testing::_;
-using testing::ContainerEq;
-using testing::Field;
-using testing::Return;
-using testing::ReturnPointee;
-using testing::SaveArg;
-using testing::StrictMock;
+using ::testing::_;
+using ::testing::ContainerEq;
+using ::testing::Contains;
+using ::testing::Field;
+using ::testing::Return;
+using ::testing::ReturnPointee;
+using ::testing::SaveArg;
+using ::testing::StrictMock;
 
 namespace {
 using webrtc::BitrateConstraints;
@@ -2018,16 +2019,11 @@
 
 TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
        SupportsTransportSequenceNumberHeaderExtension) {
-  cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
-  ASSERT_FALSE(capabilities.header_extensions.empty());
-  for (const webrtc::RtpExtension& extension : capabilities.header_extensions) {
-    if (extension.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) {
-      EXPECT_EQ(webrtc::RtpExtension::kTransportSequenceNumberDefaultId,
-                extension.id);
-      return;
-    }
-  }
-  FAIL() << "Transport sequence number extension not in header-extension list.";
+  const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
+  EXPECT_THAT(capabilities.header_extensions,
+              Contains(testing::Field(
+                  "uri", &RtpExtension::uri,
+                  webrtc::RtpExtension::kTransportSequenceNumberUri)));
 }
 
 // Test support for audio level header extension.
diff --git a/pc/media_session.cc b/pc/media_session.cc
index e18c86a..19eb769 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -10,6 +10,7 @@
 
 #include "pc/media_session.h"
 
+#include <algorithm>
 #include <functional>
 #include <map>
 #include <memory>
@@ -51,6 +52,7 @@
     names->push_back(rtc::SrtpCryptoSuiteToName(crypto));
   }
 }
+
 }  // namespace
 
 namespace cricket {
@@ -1347,14 +1349,21 @@
 
 static void AddUnifiedPlanExtensions(RtpHeaderExtensions* extensions) {
   RTC_DCHECK(extensions);
+
+  rtc::UniqueNumberGenerator<int> unique_id_generator;
+  unique_id_generator.AddKnownId(0);  // The first valid RTP extension ID is 1.
+  for (const webrtc::RtpExtension& extension : *extensions) {
+    const bool collision_free = unique_id_generator.AddKnownId(extension.id);
+    RTC_DCHECK(collision_free);
+  }
+
   // Unified Plan also offers the MID and RID header extensions.
+  extensions->push_back(webrtc::RtpExtension(webrtc::RtpExtension::kMidUri,
+                                             unique_id_generator()));
+  extensions->push_back(webrtc::RtpExtension(webrtc::RtpExtension::kRidUri,
+                                             unique_id_generator()));
   extensions->push_back(webrtc::RtpExtension(
-      webrtc::RtpExtension::kMidUri, webrtc::RtpExtension::kMidDefaultId));
-  extensions->push_back(webrtc::RtpExtension(
-      webrtc::RtpExtension::kRidUri, webrtc::RtpExtension::kRidDefaultId));
-  extensions->push_back(
-      webrtc::RtpExtension(webrtc::RtpExtension::kRepairedRidUri,
-                           webrtc::RtpExtension::kRepairedRidDefaultId));
+      webrtc::RtpExtension::kRepairedRidUri, unique_id_generator()));
 }
 
 RtpHeaderExtensions
diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc
index b0409ea..3f7631e 100644
--- a/pc/media_session_unittest.cc
+++ b/pc/media_session_unittest.cc
@@ -4119,6 +4119,8 @@
   // Check to see that RID extensions were added to the extension list
   EXPECT_GE(result.size(), 2u);
   EXPECT_THAT(result, Contains(Field("uri", &RtpExtension::uri,
+                                     RtpExtension::kMidUri)));
+  EXPECT_THAT(result, Contains(Field("uri", &RtpExtension::uri,
                                      RtpExtension::kRidUri)));
   EXPECT_THAT(result, Contains(Field("uri", &RtpExtension::uri,
                                      RtpExtension::kRepairedRidUri)));
@@ -4139,6 +4141,8 @@
   // Check to see that RID extensions were added to the extension list
   EXPECT_GE(result.size(), 2u);
   EXPECT_THAT(result, Contains(Field("uri", &RtpExtension::uri,
+                                     RtpExtension::kMidUri)));
+  EXPECT_THAT(result, Contains(Field("uri", &RtpExtension::uri,
                                      RtpExtension::kRidUri)));
   EXPECT_THAT(result, Contains(Field("uri", &RtpExtension::uri,
                                      RtpExtension::kRepairedRidUri)));
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 67d9d4b..cb02610 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -553,6 +553,7 @@
       "../modules/video_coding:webrtc_multiplex",
       "../modules/video_coding:webrtc_vp8",
       "../modules/video_coding:webrtc_vp9",
+      "../rtc_base",
       "../rtc_base:checks",
       "../rtc_base:rate_limiter",
       "../rtc_base:rtc_base_approved",
diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc
index 41c0397..a517064 100644
--- a/video/video_send_stream_impl_unittest.cc
+++ b/video/video_send_stream_impl_unittest.cc
@@ -359,9 +359,9 @@
   test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
 
   test_queue_.SendTask([this] {
+    constexpr int kId = 1;
     config_.rtp.extensions.emplace_back(
-        RtpExtension::kTransportSequenceNumberUri,
-        RtpExtension::kTransportSequenceNumberDefaultId);
+        RtpExtension::kTransportSequenceNumberUri, kId);
     EXPECT_CALL(transport_controller_,
                 SetPacingFactor(kAlrProbingExperimentPaceMultiplier))
         .Times(1);
diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc
index 8338d84..bd5a03c 100644
--- a/video/video_send_stream_tests.cc
+++ b/video/video_send_stream_tests.cc
@@ -34,6 +34,7 @@
 #include "rtc_base/platform_thread.h"
 #include "rtc_base/rate_limiter.h"
 #include "rtc_base/time_utils.h"
+#include "rtc_base/unique_id_generator.h"
 #include "system_wrappers/include/sleep.h"
 #include "test/call_test.h"
 #include "test/configurable_frame_size_encoder.h"
@@ -3752,10 +3753,14 @@
     }
 
     if (configure_send_side_ && !has_send_side) {
+      rtc::UniqueNumberGenerator<int> unique_id_generator;
+      unique_id_generator.AddKnownId(0);  // First valid RTP extension ID is 1.
+      for (const RtpExtension& extension : send_config->rtp.extensions) {
+        unique_id_generator.AddKnownId(extension.id);
+      }
       // Want send side, not present by default, so add it.
       send_config->rtp.extensions.emplace_back(
-          RtpExtension::kTransportSequenceNumberUri,
-          RtpExtension::kTransportSequenceNumberDefaultId);
+          RtpExtension::kTransportSequenceNumberUri, unique_id_generator());
     }
 
     // ALR only enabled for screenshare.