diff --git a/api/BUILD.gn b/api/BUILD.gn index 5f048fcdb6..0a0a501412 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -166,6 +166,7 @@ rtc_library("libjingle_peerconnection_api") { ":media_stream_interface", ":network_state_predictor_api", ":packet_socket_factory", + ":priority", ":rtc_error", ":rtc_stats_api", ":rtp_packet_info", @@ -303,6 +304,10 @@ rtc_source_set("rtp_transceiver_direction") { sources = [ "rtp_transceiver_direction.h" ] } +rtc_source_set("priority") { + sources = [ "priority.h" ] +} + rtc_library("rtp_parameters") { visibility = [ "*" ] sources = [ @@ -313,6 +318,7 @@ rtc_library("rtp_parameters") { ] deps = [ ":array_view", + ":priority", ":rtp_transceiver_direction", "../rtc_base:checks", "../rtc_base:stringutils", @@ -323,8 +329,8 @@ rtc_library("rtp_parameters") { } if (is_android) { - java_cpp_enum("rtp_parameters_enums") { - sources = [ "rtp_parameters.h" ] + java_cpp_enum("priority_enums") { + sources = [ "priority.h" ] } } diff --git a/api/data_channel_interface.h b/api/data_channel_interface.h index e08830feaf..5b2b1263ab 100644 --- a/api/data_channel_interface.h +++ b/api/data_channel_interface.h @@ -20,6 +20,7 @@ #include #include "absl/types/optional.h" +#include "api/priority.h" #include "api/rtc_error.h" #include "rtc_base/checks.h" #include "rtc_base/copy_on_write_buffer.h" @@ -61,6 +62,9 @@ struct DataChannelInit { // The stream id, or SID, for SCTP data channels. -1 if unset (see above). int id = -1; + + // https://w3c.github.io/webrtc-priority/#new-rtcdatachannelinit-member + absl::optional priority; }; // At the JavaScript level, data can be passed in as a string or a blob, so @@ -154,6 +158,7 @@ class RTC_EXPORT DataChannelInterface : public rtc::RefCountInterface { // If negotiated in-band, this ID will be populated once the DTLS role is // determined, and until then this will return -1. virtual int id() const = 0; + virtual Priority priority() const { return Priority::kLow; } virtual DataState state() const = 0; // When state is kClosed, and the DataChannel was not closed using // the closing procedure, returns the error information about the closing. diff --git a/api/priority.h b/api/priority.h new file mode 100644 index 0000000000..4953e453a3 --- /dev/null +++ b/api/priority.h @@ -0,0 +1,26 @@ +/* + * Copyright 2020 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 API_PRIORITY_H_ +#define API_PRIORITY_H_ + +namespace webrtc { + +// GENERATED_JAVA_ENUM_PACKAGE: org.webrtc +enum class Priority { + kVeryLow, + kLow, + kMedium, + kHigh, +}; + +} // namespace webrtc + +#endif // API_PRIORITY_H_ diff --git a/api/rtp_parameters.h b/api/rtp_parameters.h index 49c1e0c885..d7156db05b 100644 --- a/api/rtp_parameters.h +++ b/api/rtp_parameters.h @@ -20,6 +20,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/media_types.h" +#include "api/priority.h" #include "api/rtp_transceiver_direction.h" #include "rtc_base/system/rtc_export.h" @@ -93,14 +94,6 @@ enum class DegradationPreference { RTC_EXPORT extern const double kDefaultBitratePriority; -// GENERATED_JAVA_ENUM_PACKAGE: org.webrtc -enum class Priority { - kVeryLow, - kLow, - kMedium, - kHigh, -}; - struct RTC_EXPORT RtcpFeedback { RtcpFeedbackType type = RtcpFeedbackType::CCM; diff --git a/pc/BUILD.gn b/pc/BUILD.gn index a48a0469d9..f553f158d8 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -88,6 +88,7 @@ rtc_library("rtc_pc_base") { "../api:function_view", "../api:ice_transport_factory", "../api:libjingle_peerconnection_api", + "../api:priority", "../api:rtc_error", "../api:rtp_headers", "../api:rtp_parameters", @@ -236,6 +237,7 @@ rtc_library("peerconnection") { "../api:libjingle_peerconnection_api", "../api:media_stream_interface", "../api:network_state_predictor_api", + "../api:priority", "../api:rtc_error", "../api:rtc_event_log_output_file", "../api:rtc_stats_api", diff --git a/pc/data_channel.h b/pc/data_channel.h index c1de7c7a7a..7c7d220640 100644 --- a/pc/data_channel.h +++ b/pc/data_channel.h @@ -17,6 +17,7 @@ #include #include "api/data_channel_interface.h" +#include "api/priority.h" #include "api/proxy.h" #include "api/scoped_refptr.h" #include "media/base/media_channel.h" @@ -142,6 +143,9 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> { virtual std::string protocol() const { return config_.protocol; } virtual bool negotiated() const { return config_.negotiated; } virtual int id() const { return config_.id; } + virtual Priority priority() const { + return config_.priority ? *config_.priority : Priority::kLow; + } virtual int internal_id() const { return internal_id_; } virtual uint64_t buffered_amount() const; virtual void Close(); @@ -324,6 +328,7 @@ PROXY_CONSTMETHOD0(absl::optional, maxPacketLifeTime) PROXY_CONSTMETHOD0(std::string, protocol) PROXY_CONSTMETHOD0(bool, negotiated) PROXY_CONSTMETHOD0(int, id) +PROXY_CONSTMETHOD0(Priority, priority) PROXY_CONSTMETHOD0(DataState, state) PROXY_CONSTMETHOD0(RTCError, error) PROXY_CONSTMETHOD0(uint32_t, messages_sent) diff --git a/pc/sctp_utils.cc b/pc/sctp_utils.cc index 9cdff0e4da..1882a1525f 100644 --- a/pc/sctp_utils.cc +++ b/pc/sctp_utils.cc @@ -13,6 +13,7 @@ #include #include +#include "api/priority.h" #include "rtc_base/byte_buffer.h" #include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/logging.h" @@ -34,6 +35,15 @@ enum DataChannelOpenMessageChannelType { DCOMCT_UNORDERED_PARTIAL_TIME = 0x82, }; +// Values of priority in the DC open protocol message. +// These are compared against an integer, so are enum, not enum class. +enum DataChannelPriority { + DCO_PRIORITY_VERY_LOW = 128, + DCO_PRIORITY_LOW = 256, + DCO_PRIORITY_MEDIUM = 512, + DCO_PRIORITY_HIGH = 1024, +}; + bool IsOpenMessage(const rtc::CopyOnWriteBuffer& payload) { // Format defined at // http://tools.ietf.org/html/draft-jesup-rtcweb-data-protocol-04 @@ -76,6 +86,18 @@ bool ParseDataChannelOpenMessage(const rtc::CopyOnWriteBuffer& payload, << "Could not read OPEN message reliabilility prioirty."; return false; } + // Parse priority as defined in + // https://w3c.github.io/webrtc-priority/#rtcdatachannel-processing-steps + if (priority <= DCO_PRIORITY_VERY_LOW) { + config->priority = Priority::kVeryLow; + } else if (priority <= DCO_PRIORITY_LOW) { + config->priority = Priority::kLow; + } else if (priority <= DCO_PRIORITY_MEDIUM) { + config->priority = Priority::kMedium; + } else { + config->priority = Priority::kHigh; + } + uint32_t reliability_param; if (!buffer.ReadUInt32(&reliability_param)) { RTC_LOG(LS_WARNING) << "Could not read OPEN message reliabilility param."; @@ -146,6 +168,24 @@ bool WriteDataChannelOpenMessage(const std::string& label, uint8_t channel_type = 0; uint32_t reliability_param = 0; uint16_t priority = 0; + // Set priority according to + // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-12#section-6.4 + if (config.priority) { + switch (*config.priority) { + case Priority::kVeryLow: + priority = DCO_PRIORITY_VERY_LOW; + break; + case Priority::kLow: + priority = DCO_PRIORITY_LOW; + break; + case Priority::kMedium: + priority = DCO_PRIORITY_MEDIUM; + break; + case Priority::kHigh: + priority = DCO_PRIORITY_HIGH; + break; + } + } if (config.ordered) { if (config.maxRetransmits) { channel_type = DCOMCT_ORDERED_PARTIAL_RTXS; diff --git a/pc/sctp_utils_unittest.cc b/pc/sctp_utils_unittest.cc index 70c627714d..690a9dc523 100644 --- a/pc/sctp_utils_unittest.cc +++ b/pc/sctp_utils_unittest.cc @@ -45,6 +45,13 @@ class SctpUtilsTest : public ::testing::Test { } ASSERT_TRUE(buffer.ReadUInt16(&priority)); + if (config.priority) { + // Exact values are checked by round-trip conversion, but + // all values defined are greater than zero. + EXPECT_GT(priority, 0); + } else { + EXPECT_EQ(priority, 0); + } ASSERT_TRUE(buffer.ReadUInt32(&reliability)); if (config.maxRetransmits || config.maxRetransmitTime) { @@ -136,6 +143,27 @@ TEST_F(SctpUtilsTest, WriteParseOpenMessageWithMaxRetransmits) { EXPECT_FALSE(output_config.maxRetransmitTime); } +TEST_F(SctpUtilsTest, WriteParseOpenMessageWithPriority) { + webrtc::DataChannelInit config; + std::string label = "abc"; + config.protocol = "y"; + config.priority = webrtc::Priority::kVeryLow; + + rtc::CopyOnWriteBuffer packet; + ASSERT_TRUE(webrtc::WriteDataChannelOpenMessage(label, config, &packet)); + + VerifyOpenMessageFormat(packet, label, config); + + std::string output_label; + webrtc::DataChannelInit output_config; + ASSERT_TRUE(webrtc::ParseDataChannelOpenMessage(packet, &output_label, + &output_config)); + + EXPECT_EQ(label, output_label); + ASSERT_TRUE(output_config.priority); + EXPECT_EQ(*config.priority, *output_config.priority); +} + TEST_F(SctpUtilsTest, WriteParseAckMessage) { rtc::CopyOnWriteBuffer packet; webrtc::WriteDataChannelOpenAckMessage(&packet); diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index f4d05c1fde..f0e9c11b1a 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -326,7 +326,7 @@ if (is_android) { "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ - "//api:rtp_parameters_enums", + "//api:priority_enums", "//api/video:video_frame_enums", ] }