Implement RTCRtpSender/Receiver.getCapabilities()

Intent: https://groups.google.com/a/chromium.org/d/msg/blink-dev/_ktwAuFRUAg/mh_ECO41AQAJ

Bug: 857451
Change-Id: I8c1973e0346a9db71c4dc1fbfc82e3396c48c5ad
Reviewed-on: https://chromium-review.googlesource.com/1133386
Commit-Queue: Florent Castelli <orphis@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Henrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576562}
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index d57e983..d0c4b1b 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -620,4 +620,30 @@
   audio_device_ = new rtc::RefCountedObject<WebRtcAudioDeviceImpl>();
 }
 
+std::unique_ptr<webrtc::RtpCapabilities>
+PeerConnectionDependencyFactory::GetSenderCapabilities(
+    const std::string& kind) {
+  if (kind == "audio") {
+    return std::make_unique<webrtc::RtpCapabilities>(
+        GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO));
+  } else if (kind == "video") {
+    return std::make_unique<webrtc::RtpCapabilities>(
+        GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO));
+  }
+  return nullptr;
+}
+
+std::unique_ptr<webrtc::RtpCapabilities>
+PeerConnectionDependencyFactory::GetReceiverCapabilities(
+    const std::string& kind) {
+  if (kind == "audio") {
+    return std::make_unique<webrtc::RtpCapabilities>(
+        GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO));
+  } else if (kind == "video") {
+    return std::make_unique<webrtc::RtpCapabilities>(
+        GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO));
+  }
+  return nullptr;
+}
+
 }  // namespace content
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
index 8f1cbd2..db7919f 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.h
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -94,6 +94,13 @@
       int sdp_mline_index,
       const std::string& sdp);
 
+  // Returns the most optimistic view of the capabilities of the system for
+  // sending or receiving media of the given kind ("audio" or "video").
+  virtual std::unique_ptr<webrtc::RtpCapabilities> GetSenderCapabilities(
+      const std::string& kind);
+  virtual std::unique_ptr<webrtc::RtpCapabilities> GetReceiverCapabilities(
+      const std::string& kind);
+
   WebRtcAudioDeviceImpl* GetWebRtcAudioDevice();
 
   void EnsureInitialized();
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index b77c77c..a9b86c6 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -898,6 +898,28 @@
   return std::make_unique<ImageCaptureFrameGrabber>();
 }
 
+//------------------------------------------------------------------------------
+
+std::unique_ptr<webrtc::RtpCapabilities>
+RendererBlinkPlatformImpl::GetRtpSenderCapabilities(
+    const blink::WebString& kind) {
+  PeerConnectionDependencyFactory* pc_dependency_factory =
+      RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
+  pc_dependency_factory->EnsureInitialized();
+  return pc_dependency_factory->GetSenderCapabilities(kind.Utf8());
+}
+
+std::unique_ptr<webrtc::RtpCapabilities>
+RendererBlinkPlatformImpl::GetRtpReceiverCapabilities(
+    const blink::WebString& kind) {
+  PeerConnectionDependencyFactory* pc_dependency_factory =
+      RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
+  pc_dependency_factory->EnsureInitialized();
+  return pc_dependency_factory->GetReceiverCapabilities(kind.Utf8());
+}
+
+//------------------------------------------------------------------------------
+
 void RendererBlinkPlatformImpl::UpdateWebRTCAPICount(
     blink::WebRTCAPIName api_name) {
   UpdateWebRTCMethodCount(api_name);
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index e3626b2..bebcd93 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -171,6 +171,10 @@
       blink::WebMediaPlayer* web_media_player) override;
   std::unique_ptr<blink::WebImageCaptureFrameGrabber>
   CreateImageCaptureFrameGrabber() override;
+  std::unique_ptr<webrtc::RtpCapabilities> GetRtpSenderCapabilities(
+      const blink::WebString& kind) override;
+  std::unique_ptr<webrtc::RtpCapabilities> GetRtpReceiverCapabilities(
+      const blink::WebString& kind) override;
   void UpdateWebRTCAPICount(blink::WebRTCAPIName api_name) override;
   std::unique_ptr<blink::WebSocketHandshakeThrottle>
   CreateWebSocketHandshakeThrottle() override;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpCapabilities-helper.js b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpCapabilities-helper.js
index 72f54405..fb297c3 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpCapabilities-helper.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpCapabilities-helper.js
@@ -31,7 +31,7 @@
     validateCodecCapability(codec);
   }
 
-  assert_greater_than(capabilities.codec, 0,
+  assert_greater_than(capabilities.codecs.length, 0,
     'Expect at least one codec capability available');
 
   assert_array_field(capabilities, 'headerExtensions');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getCapabilities-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getCapabilities-expected.txt
deleted file mode 100644
index 6548121..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getCapabilities-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL RTCRtpSender.getCapabilities('audio') should return RTCRtpCapabilities dictionary RTCRtpReceiver.getCapabilities is not a function
-FAIL RTCRtpSender.getCapabilities('video') should return RTCRtpCapabilities dictionary RTCRtpReceiver.getCapabilities is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getCapabilities.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getCapabilities.html
index fda7169..21dcae20 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getCapabilities.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getCapabilities.html
@@ -31,4 +31,9 @@
     validateRtpCapabilities(capabilities);
   }, `RTCRtpSender.getCapabilities('video') should return RTCRtpCapabilities dictionary`);
 
+  test(() => {
+    const capabilities = RTCRtpReceiver.getCapabilities('dummy');
+    assert_equals(capabilities, null);
+  }, `RTCRtpSender.getCapabilities('dummy') should return null`);
+
  </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getCapabilities-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getCapabilities-expected.txt
deleted file mode 100644
index ac2c7e3..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getCapabilities-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL RTCRtpSender.getCapabilities('audio') should return RTCRtpCapabilities dictionary RTCRtpSender.getCapabilities is not a function
-FAIL RTCRtpSender.getCapabilities('video') should return RTCRtpCapabilities dictionary RTCRtpSender.getCapabilities is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getCapabilities.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getCapabilities.html
index d4544ffec..3d41c620 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getCapabilities.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getCapabilities.html
@@ -37,4 +37,9 @@
     validateRtpCapabilities(capabilities);
   }, `RTCRtpSender.getCapabilities('video') should return RTCRtpCapabilities dictionary`);
 
+  test(() => {
+    const capabilities = RTCRtpSender.getCapabilities('dummy');
+    assert_equals(capabilities, null);
+  }, `RTCRtpSender.getCapabilities('dummy') should return null`);
+
  </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 368b54163..601a659 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -4833,12 +4833,14 @@
     getter timestamp
     method constructor
 interface RTCRtpReceiver
+    static method getCapabilities
     attribute @@toStringTag
     getter track
     method constructor
     method getContributingSources
     method getStats
 interface RTCRtpSender
+    static method getCapabilities
     attribute @@toStringTag
     getter dtmf
     getter track
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index f2f150f..7cab160 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -5476,12 +5476,14 @@
     getter timestamp
     method constructor
 interface RTCRtpReceiver
+    static method getCapabilities
     attribute @@toStringTag
     getter track
     method constructor
     method getContributingSources
     method getStats
 interface RTCRtpSender
+    static method getCapabilities
     attribute @@toStringTag
     getter dtmf
     getter track
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index 141cafd..f927253a 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -87,6 +87,10 @@
 class Local;
 }
 
+namespace webrtc {
+struct RtpCapabilities;
+}
+
 namespace blink {
 
 class InterfaceProvider;
@@ -598,6 +602,13 @@
   virtual std::unique_ptr<WebImageCaptureFrameGrabber>
   CreateImageCaptureFrameGrabber();
 
+  // Returns the most optimistic view of the capabilities of the system for
+  // sending or receiving media of the given kind ("audio" or "video").
+  virtual std::unique_ptr<webrtc::RtpCapabilities> GetRtpSenderCapabilities(
+      const WebString& kind);
+  virtual std::unique_ptr<webrtc::RtpCapabilities> GetRtpReceiverCapabilities(
+      const WebString& kind);
+
   virtual void UpdateWebRTCAPICount(WebRTCAPIName api_name) {}
 
   // WebSocket ----------------------------------------------------------
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
index 7e050c6..6b4961bd 100644
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -595,9 +595,12 @@
           "peerconnection/rtc_offer_options.idl",
           "peerconnection/rtc_peer_connection_ice_event_init.idl",
           "peerconnection/rtc_rtcp_parameters.idl",
+          "peerconnection/rtc_rtp_capabilities.idl",
+          "peerconnection/rtc_rtp_codec_capability.idl",
           "peerconnection/rtc_rtp_codec_parameters.idl",
           "peerconnection/rtc_rtp_coding_parameters.idl",
           "peerconnection/rtc_rtp_encoding_parameters.idl",
+          "peerconnection/rtc_rtp_header_extension_capability.idl",
           "peerconnection/rtc_rtp_header_extension_parameters.idl",
           "peerconnection/rtc_rtp_parameters.idl",
           "peerconnection/rtc_rtp_send_parameters.idl",
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.idl
new file mode 100644
index 0000000..d189f37
--- /dev/null
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.idl
@@ -0,0 +1,9 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://w3c.github.io/webrtc-pc/#rtcrtpcapabilities*
+dictionary RTCRtpCapabilities {
+    required sequence<RTCRtpCodecCapability>           codecs;
+    required sequence<RTCRtpHeaderExtensionCapability> headerExtensions;
+};
\ No newline at end of file
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.idl
new file mode 100644
index 0000000..345d84ca
--- /dev/null
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.idl
@@ -0,0 +1,11 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://w3c.github.io/webrtc-pc/#rtcrtpcodeccapability*
+dictionary RTCRtpCodecCapability {
+    required DOMString      mimeType;
+    required unsigned long  clockRate;
+             unsigned short channels;
+             DOMString      sdpFmtpLine;
+};
\ No newline at end of file
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl
new file mode 100644
index 0000000..388f11b
--- /dev/null
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl
@@ -0,0 +1,8 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://w3c.github.io/webrtc-pc/#rtcrtpheaderextensioncapability*
+dictionary RTCRtpHeaderExtensionCapability {
+    DOMString uri;
+};
\ No newline at end of file
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index 5e2cf66..faa91366 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -7,9 +7,11 @@
 #include "third_party/blink/public/platform/web_media_stream.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_rtc_rtp_contributing_source.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.h"
 #include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
 #include "third_party/blink/renderer/platform/bindings/microtask.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/webrtc/api/rtpparameters.h"
 
 namespace blink {
 
@@ -92,4 +94,49 @@
   ScriptWrappable::Trace(visitor);
 }
 
+void RTCRtpReceiver::getCapabilities(
+    const String& kind,
+    base::Optional<RTCRtpCapabilities>& capabilities) {
+  if (kind != "audio" && kind != "video")
+    return;
+
+  capabilities = RTCRtpCapabilities{};
+
+  std::unique_ptr<webrtc::RtpCapabilities> rtc_capabilities =
+      blink::Platform::Current()->GetRtpSenderCapabilities(kind);
+
+  HeapVector<RTCRtpCodecCapability> codecs;
+  codecs.ReserveInitialCapacity(rtc_capabilities->codecs.size());
+  for (const auto& rtc_codec : rtc_capabilities->codecs) {
+    codecs.emplace_back();
+    auto& codec = codecs.back();
+    codec.setMimeType(WTF::String::FromUTF8(rtc_codec.mime_type().c_str()));
+    if (rtc_codec.clock_rate)
+      codec.setClockRate(rtc_codec.clock_rate.value());
+    if (rtc_codec.num_channels)
+      codec.setChannels(rtc_codec.num_channels.value());
+    if (rtc_codec.parameters.size()) {
+      std::string sdp_fmtp_line;
+      for (const auto& parameter : rtc_codec.parameters) {
+        if (sdp_fmtp_line.size())
+          sdp_fmtp_line += ";";
+        sdp_fmtp_line += parameter.first + "=" + parameter.second;
+      }
+      codec.setSdpFmtpLine(sdp_fmtp_line.c_str());
+    }
+  }
+  capabilities->setCodecs(codecs);
+
+  HeapVector<RTCRtpHeaderExtensionCapability> header_extensions;
+  header_extensions.ReserveInitialCapacity(
+      rtc_capabilities->header_extensions.size());
+  for (const auto& rtc_header_extension : rtc_capabilities->header_extensions) {
+    header_extensions.emplace_back();
+    auto& header_extension = header_extensions.back();
+    header_extension.setUri(
+        WTF::String::FromUTF8(rtc_header_extension.uri.c_str()));
+  }
+  capabilities->setHeaderExtensions(header_extensions);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
index 33dc326..fcc57a5 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
@@ -7,6 +7,7 @@
 
 #include <map>
 
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
@@ -17,6 +18,7 @@
 #include "third_party/blink/renderer/platform/heap/visitor.h"
 
 namespace blink {
+class RTCRtpCapabilities;
 
 // https://w3c.github.io/webrtc-pc/#rtcrtpreceiver-interface
 class RTCRtpReceiver final : public ScriptWrappable {
@@ -28,6 +30,9 @@
                  MediaStreamTrack*,
                  MediaStreamVector);
 
+  static void getCapabilities(const String& kind,
+                              base::Optional<RTCRtpCapabilities>& result);
+
   MediaStreamTrack* track() const;
   const HeapVector<Member<RTCRtpContributingSource>>& getContributingSources();
   ScriptPromise getStats(ScriptState*);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl
index 39c10496..c31fddb 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl
@@ -6,6 +6,7 @@
 [Exposed=Window]
 interface RTCRtpReceiver {
     readonly attribute MediaStreamTrack track;
+    static RTCRtpCapabilities?             getCapabilities(DOMString kind);
     sequence<RTCRtpContributingSource> getContributingSources();
     [CallWith=ScriptState] Promise<RTCStatsReport> getStats();
     // TODO(hbos): Support every member of the spec. https://crbug.com/700916
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index 5ac0337f..b8ebccb7 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h"
 
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -11,6 +12,7 @@
 #include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h"
 #include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -439,4 +441,49 @@
   ScriptWrappable::Trace(visitor);
 }
 
+void RTCRtpSender::getCapabilities(
+    const String& kind,
+    base::Optional<RTCRtpCapabilities>& capabilities) {
+  if (kind != "audio" && kind != "video")
+    return;
+
+  capabilities = RTCRtpCapabilities{};
+
+  std::unique_ptr<webrtc::RtpCapabilities> rtc_capabilities =
+      blink::Platform::Current()->GetRtpSenderCapabilities(kind);
+
+  HeapVector<RTCRtpCodecCapability> codecs;
+  codecs.ReserveInitialCapacity(rtc_capabilities->codecs.size());
+  for (const auto& rtc_codec : rtc_capabilities->codecs) {
+    codecs.emplace_back();
+    auto& codec = codecs.back();
+    codec.setMimeType(WTF::String::FromUTF8(rtc_codec.mime_type().c_str()));
+    if (rtc_codec.clock_rate)
+      codec.setClockRate(rtc_codec.clock_rate.value());
+    if (rtc_codec.num_channels)
+      codec.setChannels(rtc_codec.num_channels.value());
+    if (rtc_codec.parameters.size()) {
+      std::string sdp_fmtp_line;
+      for (const auto& parameter : rtc_codec.parameters) {
+        if (sdp_fmtp_line.size())
+          sdp_fmtp_line += ";";
+        sdp_fmtp_line += parameter.first + "=" + parameter.second;
+      }
+      codec.setSdpFmtpLine(sdp_fmtp_line.c_str());
+    }
+  }
+  capabilities->setCodecs(codecs);
+
+  HeapVector<RTCRtpHeaderExtensionCapability> header_extensions;
+  header_extensions.ReserveInitialCapacity(
+      rtc_capabilities->header_extensions.size());
+  for (const auto& rtc_header_extension : rtc_capabilities->header_extensions) {
+    header_extensions.emplace_back();
+    auto& header_extension = header_extensions.back();
+    header_extension.setUri(
+        WTF::String::FromUTF8(rtc_header_extension.uri.c_str()));
+  }
+  capabilities->setHeaderExtensions(header_extensions);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
index fed78091..6b39859 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
@@ -20,6 +20,7 @@
 class MediaStreamTrack;
 class RTCDTMFSender;
 class RTCPeerConnection;
+class RTCRtpCapabilities;
 
 // https://w3c.github.io/webrtc-pc/#rtcrtpsender-interface
 class RTCRtpSender final : public ScriptWrappable {
@@ -37,6 +38,8 @@
   MediaStreamTrack* track();
   ScriptPromise replaceTrack(ScriptState*, MediaStreamTrack*);
   RTCDTMFSender* dtmf();
+  static void getCapabilities(const String& kind,
+                              base::Optional<RTCRtpCapabilities>& result);
   void getParameters(RTCRtpSendParameters&);
   ScriptPromise setParameters(ScriptState*, const RTCRtpSendParameters&);
   ScriptPromise getStats(ScriptState*);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
index 3c90914..dcf54c4 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
@@ -6,6 +6,7 @@
 [Exposed=Window]
 interface RTCRtpSender {
     readonly attribute MediaStreamTrack? track;
+    static RTCRtpCapabilities? getCapabilities(DOMString kind);
     [RuntimeEnabled=RTCRtpSenderParameters, CallWith=ScriptState] Promise<void> setParameters(optional RTCRtpSendParameters parameters);
     [RuntimeEnabled=RTCRtpSenderParameters] RTCRtpSendParameters getParameters();
     [Measure, CallWith=ScriptState] Promise<void> replaceTrack(MediaStreamTrack? withTrack);
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc
index dbb3e889..848cda3 100644
--- a/third_party/blink/renderer/platform/exported/platform.cc
+++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -64,6 +64,7 @@
 #include "third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h"
 #include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/webrtc/api/rtpparameters.h"
 
 namespace blink {
 
@@ -257,4 +258,14 @@
   return nullptr;
 }
 
+std::unique_ptr<webrtc::RtpCapabilities> Platform::GetRtpSenderCapabilities(
+    const WebString& kind) {
+  return nullptr;
+}
+
+std::unique_ptr<webrtc::RtpCapabilities> Platform::GetRtpReceiverCapabilities(
+    const WebString& kind) {
+  return nullptr;
+}
+
 }  // namespace blink