Commit 42998e12 authored by Florent Castelli's avatar Florent Castelli Committed by Commit Bot

Implement RTCRtpReceiver.getParameters()

Intent: https://groups.google.com/a/chromium.org/d/msg/blink-dev/LXJUzctTVfM/p4J-WrzbBgAJ

Bug: 908911
Change-Id: I8e82cc588fb991458e2372fe1dcb9db459cd36b5
Reviewed-on: https://chromium-review.googlesource.com/c/1363276Reviewed-by: default avatarHenrik Boström <hbos@chromium.org>
Reviewed-by: default avatarPhilip Jägenstedt <foolip@chromium.org>
Commit-Queue: Florent Castelli <orphis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#615518}
parent 305f852f
......@@ -129,6 +129,12 @@ void FakeRTCRtpReceiver::GetStats(
NOTIMPLEMENTED();
}
std::unique_ptr<webrtc::RtpParameters> FakeRTCRtpReceiver::GetParameters()
const {
NOTIMPLEMENTED();
return nullptr;
}
FakeRTCRtpTransceiver::FakeRTCRtpTransceiver(
base::Optional<std::string> mid,
FakeRTCRtpSender sender,
......
......@@ -67,6 +67,7 @@ class CONTENT_EXPORT FakeRTCRtpReceiver : public blink::WebRTCRtpReceiver {
GetSources() override;
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>,
blink::RTCStatsFilter) override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
private:
blink::WebMediaStreamTrack track_;
......
......@@ -154,6 +154,11 @@ class RTCRtpReceiver::RTCRtpReceiverInternal
std::move(callback), filter));
}
std::unique_ptr<webrtc::RtpParameters> GetParameters() {
return std::make_unique<webrtc::RtpParameters>(
webrtc_receiver_->GetParameters());
}
private:
friend struct RTCRtpReceiver::RTCRtpReceiverInternalTraits;
......@@ -260,6 +265,10 @@ void RTCRtpReceiver::GetStats(
internal_->GetStats(std::move(callback), filter);
}
std::unique_ptr<webrtc::RtpParameters> RTCRtpReceiver::GetParameters() const {
return internal_->GetParameters();
}
RTCRtpReceiverOnlyTransceiver::RTCRtpReceiverOnlyTransceiver(
std::unique_ptr<blink::WebRTCRtpReceiver> receiver)
: receiver_(std::move(receiver)) {
......
......@@ -119,6 +119,7 @@ class CONTENT_EXPORT RTCRtpReceiver : public blink::WebRTCRtpReceiver {
GetSources() override;
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>,
blink::RTCStatsFilter) override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
private:
class RTCRtpReceiverInternal;
......
......@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/webrtc/api/rtpparameters.h"
namespace blink {
......@@ -34,6 +35,7 @@ class BLINK_PLATFORM_EXPORT WebRTCRtpReceiver {
GetSources() = 0;
virtual void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>,
RTCStatsFilter) = 0;
virtual std::unique_ptr<webrtc::RtpParameters> GetParameters() const = 0;
};
} // namespace blink
......
......@@ -637,10 +637,12 @@ modules_dictionary_idl_files =
"peerconnection/rtc_rtp_codec_capability.idl",
"peerconnection/rtc_rtp_codec_parameters.idl",
"peerconnection/rtc_rtp_coding_parameters.idl",
"peerconnection/rtc_rtp_decoding_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_receive_parameters.idl",
"peerconnection/rtc_rtp_send_parameters.idl",
"peerconnection/rtc_rtp_transceiver_init.idl",
"peerconnection/rtc_session_description_init.idl",
......
// 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/#dom-rtcrtpdecodingparameters
dictionary RTCRtpDecodingParameters : RTCRtpCodingParameters {
};
\ No newline at end of file
// 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/#rtcreceivertpparameters
dictionary RTCRtpReceiveParameters : RTCRtpParameters {
required sequence<RTCRtpDecodingParameters> encodings;
};
\ No newline at end of file
......@@ -8,6 +8,7 @@
#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/rtc_rtp_sender.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h"
#include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
......@@ -147,4 +148,44 @@ RTCRtpCapabilities* RTCRtpReceiver::getCapabilities(const String& kind) {
return capabilities;
}
RTCRtpReceiveParameters* RTCRtpReceiver::getParameters() {
RTCRtpReceiveParameters* parameters = RTCRtpReceiveParameters::Create();
std::unique_ptr<webrtc::RtpParameters> webrtc_parameters =
receiver_->GetParameters();
RTCRtcpParameters* rtcp = RTCRtcpParameters::Create();
rtcp->setReducedSize(webrtc_parameters->rtcp.reduced_size);
parameters->setRtcp(rtcp);
HeapVector<Member<RTCRtpDecodingParameters>> encodings;
encodings.ReserveCapacity(
SafeCast<wtf_size_t>(webrtc_parameters->encodings.size()));
for (const auto& webrtc_encoding : webrtc_parameters->encodings) {
RTCRtpDecodingParameters* encoding = RTCRtpDecodingParameters::Create();
if (!webrtc_encoding.rid.empty()) {
// TODO(orphis): Add rid when supported by WebRTC
}
encodings.push_back(encoding);
}
parameters->setEncodings(encodings);
HeapVector<Member<RTCRtpHeaderExtensionParameters>> headers;
headers.ReserveCapacity(
SafeCast<wtf_size_t>(webrtc_parameters->header_extensions.size()));
for (const auto& webrtc_header : webrtc_parameters->header_extensions) {
headers.push_back(ToRtpHeaderExtensionParameters(webrtc_header));
}
parameters->setHeaderExtensions(headers);
HeapVector<Member<RTCRtpCodecParameters>> codecs;
codecs.ReserveCapacity(
SafeCast<wtf_size_t>(webrtc_parameters->codecs.size()));
for (const auto& webrtc_codec : webrtc_parameters->codecs) {
codecs.push_back(ToRtpCodecParameters(webrtc_codec));
}
parameters->setCodecs(codecs);
return parameters;
}
} // namespace blink
......@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receive_parameters.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/member.h"
......@@ -33,6 +34,7 @@ class RTCRtpReceiver final : public ScriptWrappable {
static RTCRtpCapabilities* getCapabilities(const String& kind);
MediaStreamTrack* track() const;
RTCRtpReceiveParameters* getParameters();
const HeapVector<Member<RTCRtpContributingSource>>& getContributingSources();
ScriptPromise getStats(ScriptState*);
......
......@@ -6,7 +6,8 @@
[Exposed=Window]
interface RTCRtpReceiver {
readonly attribute MediaStreamTrack track;
static RTCRtpCapabilities? getCapabilities(DOMString kind);
static RTCRtpCapabilities? getCapabilities(DOMString kind);
RTCRtpReceiveParameters getParameters();
sequence<RTCRtpContributingSource> getContributingSources();
[CallWith=ScriptState] Promise<RTCStatsReport> getStats();
// TODO(hbos): Support every member of the spec. https://crbug.com/700916
......
......@@ -255,6 +255,37 @@ webrtc::RtpEncodingParameters ToRtpEncodingParameters(
return webrtc_encoding;
}
RTCRtpHeaderExtensionParameters* ToRtpHeaderExtensionParameters(
const webrtc::RtpHeaderExtensionParameters& webrtc_header) {
RTCRtpHeaderExtensionParameters* header =
RTCRtpHeaderExtensionParameters::Create();
header->setUri(webrtc_header.uri.c_str());
header->setId(webrtc_header.id);
header->setEncrypted(webrtc_header.encrypt);
return header;
}
RTCRtpCodecParameters* ToRtpCodecParameters(
const webrtc::RtpCodecParameters& webrtc_codec) {
RTCRtpCodecParameters* codec = RTCRtpCodecParameters::Create();
codec->setPayloadType(webrtc_codec.payload_type);
codec->setMimeType(WTF::String::FromUTF8(webrtc_codec.mime_type().c_str()));
if (webrtc_codec.clock_rate)
codec->setClockRate(webrtc_codec.clock_rate.value());
if (webrtc_codec.num_channels)
codec->setChannels(webrtc_codec.num_channels.value());
if (webrtc_codec.parameters.size()) {
std::string sdp_fmtp_line;
for (const auto& parameter : webrtc_codec.parameters) {
if (sdp_fmtp_line.size())
sdp_fmtp_line += ";";
sdp_fmtp_line += parameter.first + "=" + parameter.second;
}
codec->setSdpFmtpLine(sdp_fmtp_line.c_str());
}
return codec;
}
RTCRtpSender::RTCRtpSender(RTCPeerConnection* pc,
std::unique_ptr<WebRTCRtpSender> sender,
String kind,
......@@ -311,17 +342,17 @@ RTCRtpSendParameters* RTCRtpSender::getParameters() {
HeapVector<Member<RTCRtpEncodingParameters>> encodings;
encodings.ReserveCapacity(
SafeCast<wtf_size_t>(webrtc_parameters->encodings.size()));
for (const auto& web_encoding : webrtc_parameters->encodings) {
for (const auto& webrtc_encoding : webrtc_parameters->encodings) {
// TODO(orphis): Forward missing fields from the WebRTC library:
// codecPayloadType, dtx, ptime, maxFramerate, scaleResolutionDownBy, rid
RTCRtpEncodingParameters* encoding = RTCRtpEncodingParameters::Create();
encoding->setActive(web_encoding.active);
if (web_encoding.max_bitrate_bps)
encoding->setMaxBitrate(web_encoding.max_bitrate_bps.value());
encoding->setActive(webrtc_encoding.active);
if (webrtc_encoding.max_bitrate_bps)
encoding->setMaxBitrate(webrtc_encoding.max_bitrate_bps.value());
encoding->setPriority(
PriorityFromDouble(web_encoding.bitrate_priority).c_str());
PriorityFromDouble(webrtc_encoding.bitrate_priority).c_str());
encoding->setNetworkPriority(
PriorityFromDouble(web_encoding.network_priority).c_str());
PriorityFromDouble(webrtc_encoding.network_priority).c_str());
encodings.push_back(encoding);
}
parameters->setEncodings(encodings);
......@@ -329,36 +360,16 @@ RTCRtpSendParameters* RTCRtpSender::getParameters() {
HeapVector<Member<RTCRtpHeaderExtensionParameters>> headers;
headers.ReserveCapacity(
SafeCast<wtf_size_t>(webrtc_parameters->header_extensions.size()));
for (const auto& web_header : webrtc_parameters->header_extensions) {
auto* header = RTCRtpHeaderExtensionParameters::Create();
header->setUri(web_header.uri.c_str());
header->setId(web_header.id);
header->setEncrypted(web_header.encrypt);
headers.push_back(header);
for (const auto& webrtc_header : webrtc_parameters->header_extensions) {
headers.push_back(ToRtpHeaderExtensionParameters(webrtc_header));
}
parameters->setHeaderExtensions(headers);
HeapVector<Member<RTCRtpCodecParameters>> codecs;
codecs.ReserveCapacity(
SafeCast<wtf_size_t>(webrtc_parameters->codecs.size()));
for (const auto& web_codec : webrtc_parameters->codecs) {
auto* codec = RTCRtpCodecParameters::Create();
codec->setPayloadType(web_codec.payload_type);
codec->setMimeType(WTF::String::FromUTF8(web_codec.mime_type().c_str()));
if (web_codec.clock_rate)
codec->setClockRate(web_codec.clock_rate.value());
if (web_codec.num_channels)
codec->setChannels(web_codec.num_channels.value());
if (web_codec.parameters.size()) {
std::string sdp_fmtp_line;
for (const auto& parameter : web_codec.parameters) {
if (sdp_fmtp_line.size())
sdp_fmtp_line += ";";
sdp_fmtp_line += parameter.first + "=" + parameter.second;
}
codec->setSdpFmtpLine(sdp_fmtp_line.c_str());
}
codecs.push_back(codec);
for (const auto& webrtc_codec : webrtc_parameters->codecs) {
codecs.push_back(ToRtpCodecParameters(webrtc_codec));
}
parameters->setCodecs(codecs);
......
......@@ -26,6 +26,10 @@ class RTCRtpCapabilities;
webrtc::RtpEncodingParameters ToRtpEncodingParameters(
const RTCRtpEncodingParameters*);
RTCRtpHeaderExtensionParameters* ToRtpHeaderExtensionParameters(
const webrtc::RtpHeaderExtensionParameters& headers);
RTCRtpCodecParameters* ToRtpCodecParameters(
const webrtc::RtpCodecParameters& codecs);
// https://w3c.github.io/webrtc-pc/#rtcrtpsender-interface
class RTCRtpSender final : public ScriptWrappable {
......
......@@ -19,6 +19,8 @@ async function doOfferAnswerExchange(t, caller) {
const answer = await callee.createAnswer();
await callee.setLocalDescription(answer);
await caller.setRemoteDescription(answer);
return callee;
}
/*
......
This is a testharness.js-based test.
FAIL RTCRtpReceiver.prototype.getParameters Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument.
FAIL getParameters() with audio receiver promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
FAIL getParameters() with video receiver promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
FAIL getParameters() with simulcast video receiver promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
Harness: the test ran to completion.
......@@ -33,10 +33,51 @@
- transactionId and degradationPreference are left undefined.
*/
test(t => {
promise_test(async t => {
const pc = new RTCPeerConnection();
const { receiver } = pc.addTransceiver('audio');
const param = receiver.getParameters();
t.add_cleanup(() => pc.close());
pc.addTransceiver('audio');
const callee = await doOfferAnswerExchange(t, pc);
const param = callee.getReceivers()[0].getParameters();
validateReceiverRtpParameters(param);
});
assert_greater_than(param.headerExtensions.length, 0);
assert_greater_than(param.codecs.length, 0);
assert_equals(param.encodings.length, 1);
}, 'getParameters() with audio receiver');
promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
pc.addTransceiver('video');
const callee = await doOfferAnswerExchange(t, pc);
const param = callee.getReceivers()[0].getParameters();
validateReceiverRtpParameters(param);
assert_greater_than(param.headerExtensions.length, 0);
assert_greater_than(param.codecs.length, 0);
assert_equals(param.encodings.length, 1);
}, 'getParameters() with video receiver');
promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
pc.addTransceiver('video', {
sendEncodings: [
{ rid: "rid1" },
{ rid: "rid2" }
]
});
const callee = await doOfferAnswerExchange(t, pc);
const param = callee.getReceivers()[0].getParameters();
validateReceiverRtpParameters(param);
assert_greater_than(param.headerExtensions.length, 0);
assert_greater_than(param.codecs.length, 0);
assert_equals(param.encodings.length, 2, 'layer count must match');
assert_equals(param.encodings[0].rid, "rid1",
'simulcast rids must match');
assert_equals(param.encodings[1].rid, "rid2",
'simulcast rids must match');
}, 'getParameters() with simulcast video receiver');
</script>
......@@ -263,7 +263,7 @@ PASS RTCRtpReceiver interface: attribute track
FAIL RTCRtpReceiver interface: attribute transport assert_true: The prototype object must have a property "transport" expected true got false
FAIL RTCRtpReceiver interface: attribute rtcpTransport assert_true: The prototype object must have a property "rtcpTransport" expected true got false
PASS RTCRtpReceiver interface: operation getCapabilities(DOMString)
FAIL RTCRtpReceiver interface: operation getParameters() assert_own_property: interface prototype object missing non-static operation expected property "getParameters" missing
PASS RTCRtpReceiver interface: operation getParameters()
PASS RTCRtpReceiver interface: operation getContributingSources()
FAIL RTCRtpReceiver interface: operation getSynchronizationSources() assert_own_property: interface prototype object missing non-static operation expected property "getSynchronizationSources" missing
PASS RTCRtpReceiver interface: operation getStats()
......
......@@ -4893,6 +4893,7 @@ interface RTCRtpReceiver
getter track
method constructor
method getContributingSources
method getParameters
method getStats
interface RTCRtpSender
static method getCapabilities
......
This is a testharness.js-based test.
FAIL RTCRtpReceiver.prototype.getParameters receiver.getParameters is not a function
PASS getParameters() with audio receiver
PASS getParameters() with video receiver
FAIL getParameters() with simulcast video receiver promise_test: Unhandled rejection with value: object "OperationError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': Attempted to create an encoder with more than 1 encoding parameter."
Harness: the test ran to completion.
......@@ -263,7 +263,7 @@ PASS RTCRtpReceiver interface: attribute track
FAIL RTCRtpReceiver interface: attribute transport assert_true: The prototype object must have a property "transport" expected true got false
FAIL RTCRtpReceiver interface: attribute rtcpTransport assert_true: The prototype object must have a property "rtcpTransport" expected true got false
PASS RTCRtpReceiver interface: operation getCapabilities(DOMString)
FAIL RTCRtpReceiver interface: operation getParameters() assert_own_property: interface prototype object missing non-static operation expected property "getParameters" missing
PASS RTCRtpReceiver interface: operation getParameters()
PASS RTCRtpReceiver interface: operation getContributingSources()
FAIL RTCRtpReceiver interface: operation getSynchronizationSources() assert_own_property: interface prototype object missing non-static operation expected property "getSynchronizationSources" missing
PASS RTCRtpReceiver interface: operation getStats()
......@@ -274,7 +274,7 @@ FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').r
FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "rtcpTransport" with the proper type assert_inherits: property "rtcpTransport" not found in prototype chain
PASS RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getCapabilities(DOMString)" with the proper type
PASS RTCRtpReceiver interface: calling getCapabilities(DOMString) on new RTCPeerConnection().addTransceiver('audio').receiver with too few arguments must throw TypeError
FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getParameters()" with the proper type assert_inherits: property "getParameters" not found in prototype chain
PASS RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getParameters()" with the proper type
PASS RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getContributingSources()" with the proper type
FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getSynchronizationSources()" with the proper type assert_inherits: property "getSynchronizationSources" not found in prototype chain
PASS RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getStats()" with the proper type
......
......@@ -5676,6 +5676,7 @@ interface RTCRtpReceiver
getter track
method constructor
method getContributingSources
method getParameters
method getStats
interface RTCRtpSender
static method getCapabilities
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment