Offer VideoLayersAllocation if field trial enabled

Enable using the field trial WebRTC-VideoLayersAllocationAdvertised/Enabled/

Bug: webrtc:1200
Change-Id: I7c1d94c6051aace8d22c16e0f2e2256dd7ade7fd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/189960
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32465}
diff --git a/api/rtp_parameters.cc b/api/rtp_parameters.cc
index 28acb68..57aa784 100644
--- a/api/rtp_parameters.cc
+++ b/api/rtp_parameters.cc
@@ -121,6 +121,7 @@
 constexpr char RtpExtension::kVideoTimingUri[];
 constexpr char RtpExtension::kGenericFrameDescriptorUri00[];
 constexpr char RtpExtension::kDependencyDescriptorUri[];
+constexpr char RtpExtension::kVideoLayersAllocationUri[];
 constexpr char RtpExtension::kTransportSequenceNumberUri[];
 constexpr char RtpExtension::kTransportSequenceNumberV2Uri[];
 constexpr char RtpExtension::kPlayoutDelayUri[];
@@ -161,7 +162,8 @@
          uri == webrtc::RtpExtension::kDependencyDescriptorUri ||
          uri == webrtc::RtpExtension::kColorSpaceUri ||
          uri == webrtc::RtpExtension::kRidUri ||
-         uri == webrtc::RtpExtension::kRepairedRidUri;
+         uri == webrtc::RtpExtension::kRepairedRidUri ||
+         uri == webrtc::RtpExtension::kVideoLayersAllocationUri;
 }
 
 bool RtpExtension::IsEncryptionSupported(absl::string_view uri) {
@@ -183,7 +185,8 @@
          uri == webrtc::RtpExtension::kVideoContentTypeUri ||
          uri == webrtc::RtpExtension::kMidUri ||
          uri == webrtc::RtpExtension::kRidUri ||
-         uri == webrtc::RtpExtension::kRepairedRidUri;
+         uri == webrtc::RtpExtension::kRepairedRidUri ||
+         uri == webrtc::RtpExtension::kVideoLayersAllocationUri;
 }
 
 const RtpExtension* RtpExtension::FindHeaderExtensionByUri(
diff --git a/api/rtp_parameters.h b/api/rtp_parameters.h
index b667bf8..369d277 100644
--- a/api/rtp_parameters.h
+++ b/api/rtp_parameters.h
@@ -318,6 +318,10 @@
       "https://aomediacodec.github.io/av1-rtp-spec/"
       "#dependency-descriptor-rtp-header-extension";
 
+  // Experimental extension for signalling target bitrate per layer.
+  static constexpr char kVideoLayersAllocationUri[] =
+      "http://www.webrtc.org/experiments/rtp-hdrext/video-layers-allocation00";
+
   // Header extension for transport sequence number, see url for details:
   // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions
   static constexpr char kTransportSequenceNumberUri[] =
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index 070968d..521e95d 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -638,6 +638,13 @@
       IsEnabled(trials_, "WebRTC-DependencyDescriptorAdvertised")
           ? webrtc::RtpTransceiverDirection::kSendRecv
           : webrtc::RtpTransceiverDirection::kStopped);
+
+  result.emplace_back(
+      webrtc::RtpExtension::kVideoLayersAllocationUri, id++,
+      IsEnabled(trials_, "WebRTC-VideoLayersAllocationAdvertised")
+          ? webrtc::RtpTransceiverDirection::kSendRecv
+          : webrtc::RtpTransceiverDirection::kStopped);
+
   return result;
 }
 
@@ -1302,15 +1309,21 @@
       video_config_.periodic_alr_bandwidth_probing;
   config.encoder_settings.experiment_cpu_load_estimator =
       video_config_.experiment_cpu_load_estimator;
-  // TODO(bugs.webrtc.org/12000): Enable allocation callback type
-  // VideoLayersAllocation if RtpVideoLayersAllocationExtension has been
-  // negotiated in `send_rtp_extensions_`.
-  config.encoder_settings.allocation_cb_type =
-      IsEnabled(call_->trials(), "WebRTC-Target-Bitrate-Rtcp")
-          ? webrtc::VideoStreamEncoderSettings::BitrateAllocationCallbackType::
-                kVideoBitrateAllocation
-          : webrtc::VideoStreamEncoderSettings::BitrateAllocationCallbackType::
-                kVideoBitrateAllocationWhenScreenSharing;
+  using TargetBitrateType =
+      webrtc::VideoStreamEncoderSettings::BitrateAllocationCallbackType;
+  if (send_rtp_extensions_ &&
+      webrtc::RtpExtension::FindHeaderExtensionByUri(
+          *send_rtp_extensions_,
+          webrtc::RtpExtension::kVideoLayersAllocationUri)) {
+    config.encoder_settings.allocation_cb_type =
+        TargetBitrateType::kVideoLayersAllocation;
+  } else if (IsEnabled(call_->trials(), "WebRTC-Target-Bitrate-Rtcp")) {
+    config.encoder_settings.allocation_cb_type =
+        TargetBitrateType::kVideoBitrateAllocation;
+  } else {
+    config.encoder_settings.allocation_cb_type =
+        TargetBitrateType::kVideoBitrateAllocationWhenScreenSharing;
+  }
   config.encoder_settings.encoder_factory = encoder_factory_;
   config.encoder_settings.bitrate_allocator_factory =
       bitrate_allocator_factory_;
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 9b2b48d..44984c5 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -381,6 +381,23 @@
   ExpectRtpCapabilitySupport(RtpExtension::kDependencyDescriptorUri, true);
 }
 
+TEST_F(WebRtcVideoEngineTest, AdvertiseVideoLayersAllocation) {
+  ExpectRtpCapabilitySupport(RtpExtension::kVideoLayersAllocationUri, false);
+}
+
+class WebRtcVideoEngineTestWithVideoLayersAllocation
+    : public WebRtcVideoEngineTest {
+ public:
+  WebRtcVideoEngineTestWithVideoLayersAllocation()
+      : WebRtcVideoEngineTest(
+            "WebRTC-VideoLayersAllocationAdvertised/Enabled/") {}
+};
+
+TEST_F(WebRtcVideoEngineTestWithVideoLayersAllocation,
+       AdvertiseVideoLayersAllocation) {
+  ExpectRtpCapabilitySupport(RtpExtension::kVideoLayersAllocationUri, true);
+}
+
 TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
   // Allocate the source first to prevent early destruction before channel's
   // dtor is called.