From c136b0632621675f2dd7e8939c617ff2ceeaf3e6 Mon Sep 17 00:00:00 2001 From: Anton Sukhanov Date: Tue, 14 May 2019 14:53:42 -0700 Subject: [PATCH] Add datagram_transport and congestion_control interface This change introduces experimental datagram_transport interface and congestion_control interfaces. The goal is to integrate support for datagram transport in DTLS transport and set it up in a similar way we currently setup media_transport. Datagram transport will be injected in peer connection factory the same way media_transport is injected (we might even keep using the same factory which creates both media and datagram transports for now until we decided what to do next). Bug: webrtc:9719 Change-Id: I80e70ce8d3827664ac5f5f7e55b706fe2dd2fbef Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/136782 Commit-Queue: Anton Sukhanov Reviewed-by: Steve Anton Reviewed-by: Bjorn Mellem Cr-Commit-Position: refs/heads/master@{#27943} --- api/BUILD.gn | 2 + api/congestion_control_interface.h | 67 +++++++++++++++++++ api/datagram_transport_interface.h | 100 +++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 api/congestion_control_interface.h create mode 100644 api/datagram_transport_interface.h diff --git a/api/BUILD.gn b/api/BUILD.gn index 2512bd4657..b9c322967f 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -86,6 +86,7 @@ rtc_static_library("libjingle_peerconnection_api") { "bitrate_constraints.h", "candidate.cc", "candidate.h", + "congestion_control_interface.h", "crypto/crypto_options.cc", "crypto/crypto_options.h", "crypto/frame_decryptor_interface.h", @@ -93,6 +94,7 @@ rtc_static_library("libjingle_peerconnection_api") { "crypto_params.h", "data_channel_interface.cc", "data_channel_interface.h", + "datagram_transport_interface.h", "dtls_transport_interface.cc", "dtls_transport_interface.h", "dtmf_sender_interface.h", diff --git a/api/congestion_control_interface.h b/api/congestion_control_interface.h new file mode 100644 index 0000000000..2e822db1ea --- /dev/null +++ b/api/congestion_control_interface.h @@ -0,0 +1,67 @@ +/* Copyright 2018 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. + */ + +// This is EXPERIMENTAL interface for media and datagram transports. + +#ifndef API_CONGESTION_CONTROL_INTERFACE_H_ +#define API_CONGESTION_CONTROL_INTERFACE_H_ + +#include +#include +#include + +#include "api/media_transport_interface.h" +#include "api/units/data_rate.h" + +namespace webrtc { + +// Defines congestion control feedback interface for media and datagram +// transports. +class CongestionControlInterface { + public: + virtual ~CongestionControlInterface() = default; + + // Updates allocation limits. + virtual void SetAllocatedBitrateLimits( + const MediaTransportAllocatedBitrateLimits& limits) = 0; + + // Sets starting rate. + virtual void SetTargetBitrateLimits( + const MediaTransportTargetRateConstraints& target_rate_constraints) = 0; + + // Intended for receive side. AddRttObserver registers an observer to be + // called for each RTT measurement, typically once per ACK. Before media + // transport is destructed the observer must be unregistered. + // + // TODO(sukhanov): Looks like AddRttObserver and RemoveRttObserver were + // never implemented for media transport, so keeping noop implementation. + virtual void AddRttObserver(MediaTransportRttObserver* observer) {} + virtual void RemoveRttObserver(MediaTransportRttObserver* observer) {} + + // Adds a target bitrate observer. Before media transport is destructed + // the observer must be unregistered (by calling + // RemoveTargetTransferRateObserver). + // A newly registered observer will be called back with the latest recorded + // target rate, if available. + virtual void AddTargetTransferRateObserver( + TargetTransferRateObserver* observer) = 0; + + // Removes an existing |observer| from observers. If observer was never + // registered, an error is logged and method does nothing. + virtual void RemoveTargetTransferRateObserver( + TargetTransferRateObserver* observer) = 0; + + // Returns the last known target transfer rate as reported to the above + // observers. + virtual absl::optional GetLatestTargetTransferRate() = 0; +}; + +} // namespace webrtc + +#endif // API_CONGESTION_CONTROL_INTERFACE_H_ diff --git a/api/datagram_transport_interface.h b/api/datagram_transport_interface.h new file mode 100644 index 0000000000..d64c0f3c3b --- /dev/null +++ b/api/datagram_transport_interface.h @@ -0,0 +1,100 @@ +/* Copyright 2018 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. + */ + +// This is EXPERIMENTAL interface for media and datagram transports. + +#ifndef API_DATAGRAM_TRANSPORT_INTERFACE_H_ +#define API_DATAGRAM_TRANSPORT_INTERFACE_H_ + +#include +#include +#include + +#include "api/array_view.h" +#include "api/congestion_control_interface.h" +#include "api/media_transport_interface.h" +#include "api/rtc_error.h" +#include "api/units/data_rate.h" + +namespace rtc { +class PacketTransportInternal; +} // namespace rtc + +namespace webrtc { + +typedef int64_t DatagramId; + +// All sink methods are called on network thread. +class DatagramSinkInterface { + public: + virtual ~DatagramSinkInterface() {} + + // Called when new packet is received. + virtual void OnDatagramReceived(rtc::ArrayView data) = 0; + + // Called when datagram is actually sent (datragram can be delayed due + // to congestion control or fusing). |datagram_id| is same as passed in + // QuicTransportInterface::SendDatagram. + virtual void OnDatagramSent(DatagramId datagram_id) = 0; +}; + +// Datagram transport allows to send and receive unreliable packets (datagrams) +// and receive feedback from congestion control (via +// CongestionControlInterface). The idea is to send RTP packets as datagrams and +// have underlying implementation of datagram transport to use QUIC datagram +// protocol. +class DatagramTransportInterface { + public: + virtual ~DatagramTransportInterface() = default; + + // Connect the datagram transport to the ICE transport. + // The implementation must be able to ignore incoming packets that don't + // belong to it. + virtual void Connect(rtc::PacketTransportInternal* packet_transport) = 0; + + // Returns congestion control feedback interface or nullptr if datagram + // transport does not implement congestion control. + // + // Note that right now datagram transport is used without congestion control, + // but we plan to use it in the future. + virtual CongestionControlInterface* congestion_control() = 0; + + // Sets a state observer callback. Before datagram transport is destroyed, the + // callback must be unregistered by setting it to nullptr. + // A newly registered callback will be called with the current state. + // Datagram transport does not invoke this callback concurrently. + virtual void SetTransportStateCallback( + MediaTransportStateCallback* callback) = 0; + + // Start asynchronous send of datagram. The status returned by this method + // only pertains to the synchronous operations (e.g. serialization / + // packetization), not to the asynchronous operation. + // + // Datagrams larger than GetLargestDatagramSize() will fail and return error. + // + // Datagrams are sent in FIFO order. + virtual RTCError SendDatagram(rtc::ArrayView data, + DatagramId datagram_id) = 0; + + // Returns maximum size of datagram message, does not change. + // TODO(sukhanov): Because value may be undefined before connection setup + // is complete, consider returning error when called before connection is + // established. Currently returns hardcoded const, because integration + // prototype may call before connection is established. + virtual size_t GetLargestDatagramSize() const = 0; + + // Sets packet sink. Sink must be unset by calling + // SetDataTransportSink(nullptr) before the data transport is destroyed or + // before new sink is set. + virtual void SetDatagramSink(DatagramSinkInterface* sink) = 0; +}; + +} // namespace webrtc + +#endif // API_DATAGRAM_TRANSPORT_INTERFACE_H_