1 /* 2 * Copyright 2019 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef PC_DATAGRAM_RTP_TRANSPORT_H_ 12 #define PC_DATAGRAM_RTP_TRANSPORT_H_ 13 14 #include <map> 15 #include <memory> 16 #include <string> 17 #include <vector> 18 19 #include "api/crypto/crypto_options.h" 20 #include "api/transport/datagram_transport_interface.h" 21 #include "api/transport/media/media_transport_interface.h" 22 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" 23 #include "modules/rtp_rtcp/source/rtp_header_extensions.h" 24 #include "p2p/base/ice_transport_internal.h" 25 #include "p2p/base/packet_transport_internal.h" 26 #include "pc/rtp_transport_internal.h" 27 #include "rtc_base/buffer.h" 28 #include "rtc_base/buffer_queue.h" 29 #include "rtc_base/constructor_magic.h" 30 #include "rtc_base/ssl_stream_adapter.h" 31 #include "rtc_base/stream.h" 32 #include "rtc_base/strings/string_builder.h" 33 #include "rtc_base/thread_checker.h" 34 35 namespace webrtc { 36 37 constexpr int kDatagramDtlsAdaptorComponent = -1; 38 39 // RTP transport which uses the DatagramTransportInterface to send and receive 40 // packets. 41 class DatagramRtpTransport : public RtpTransportInternal, 42 public webrtc::DatagramSinkInterface, 43 public webrtc::MediaTransportStateCallback { 44 public: 45 DatagramRtpTransport( 46 const std::vector<webrtc::RtpExtension>& rtp_header_extensions, 47 cricket::IceTransportInternal* ice_transport, 48 DatagramTransportInterface* datagram_transport); 49 50 ~DatagramRtpTransport() override; 51 52 // ===================================================== 53 // Overrides for webrtc::DatagramTransportSinkInterface 54 // and MediaTransportStateCallback 55 // ===================================================== 56 void OnDatagramReceived(rtc::ArrayView<const uint8_t> data) override; 57 58 void OnDatagramSent(webrtc::DatagramId datagram_id) override; 59 60 void OnDatagramAcked(const webrtc::DatagramAck& ack) override; 61 62 void OnDatagramLost(webrtc::DatagramId datagram_id) override; 63 64 void OnStateChanged(webrtc::MediaTransportState state) override; 65 66 // ===================================================== 67 // RtpTransportInternal overrides 68 // ===================================================== 69 bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet, 70 const rtc::PacketOptions& options, 71 int flags) override; 72 73 bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet, 74 const rtc::PacketOptions& options, 75 int flags) override; 76 77 const std::string& transport_name() const override; 78 79 // Datagram transport always muxes RTCP. rtcp_mux_enabled()80 bool rtcp_mux_enabled() const override { return true; } SetRtcpMuxEnabled(bool enable)81 void SetRtcpMuxEnabled(bool enable) override {} 82 83 int SetRtpOption(rtc::Socket::Option opt, int value) override; 84 int SetRtcpOption(rtc::Socket::Option opt, int value) override; 85 86 bool IsReadyToSend() const override; 87 88 bool IsWritable(bool rtcp) const override; 89 IsSrtpActive()90 bool IsSrtpActive() const override { return false; } 91 92 void UpdateRtpHeaderExtensionMap( 93 const cricket::RtpHeaderExtensions& header_extensions) override; 94 95 bool RegisterRtpDemuxerSink(const RtpDemuxerCriteria& criteria, 96 RtpPacketSinkInterface* sink) override; 97 98 bool UnregisterRtpDemuxerSink(RtpPacketSinkInterface* sink) override; 99 100 private: 101 // RTP/RTCP packet info stored for each sent packet. 102 struct SentPacketInfo { 103 // RTP packet info with ssrc and transport sequence number. SentPacketInfoSentPacketInfo104 SentPacketInfo(int64_t packet_id, 105 uint32_t ssrc, 106 uint16_t transport_sequence_number) 107 : ssrc(ssrc), 108 transport_sequence_number(transport_sequence_number), 109 packet_id(packet_id) {} 110 111 // Packet info without SSRC and transport sequence number used for RTCP 112 // packets, RTP packets when transport sequence number is not provided or 113 // when feedback translation is disabled. SentPacketInfoSentPacketInfo114 explicit SentPacketInfo(int64_t packet_id) : packet_id(packet_id) {} 115 116 SentPacketInfo() = default; 117 118 absl::optional<uint32_t> ssrc; 119 120 // Transport sequence number (if it was provided in outgoing RTP packet). 121 // It is used to re-create RTCP feedback packets from datagram ACKs. 122 absl::optional<uint16_t> transport_sequence_number; 123 124 // Packet id from rtc::PacketOptions. It is required to propagage sent 125 // notification up the stack (SignalSentPacket). 126 int64_t packet_id = 0; 127 }; 128 129 // Finds SentPacketInfo for given |datagram_id| and removes map entry. 130 // Returns false if entry was not found. 131 bool GetAndRemoveSentPacketInfo(webrtc::DatagramId datagram_id, 132 SentPacketInfo* sent_packet_info); 133 134 // Sends datagram to datagram_transport. 135 bool SendDatagram(rtc::ArrayView<const uint8_t> data, 136 webrtc::DatagramId datagram_id); 137 138 // Propagates network route changes from ICE. 139 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route); 140 141 rtc::ThreadChecker thread_checker_; 142 cricket::IceTransportInternal* ice_transport_; 143 webrtc::DatagramTransportInterface* datagram_transport_; 144 145 RtpDemuxer rtp_demuxer_; 146 147 MediaTransportState state_ = MediaTransportState::kPending; 148 149 // Extension map for parsing transport sequence numbers. 150 webrtc::RtpHeaderExtensionMap rtp_header_extension_map_; 151 152 // Keeps information about sent RTP packet until they are Acked or Lost. 153 std::map<webrtc::DatagramId, SentPacketInfo> sent_rtp_packet_map_; 154 155 // Current datagram_id, incremented after each sent RTP packets. 156 // Datagram id is passed to datagram transport when we send datagram and we 157 // get it back in notifications about Sent, Acked and Lost datagrams. 158 int64_t current_datagram_id_ = 0; 159 160 // TODO(sukhanov): Previous nonzero timestamp is required for workaround for 161 // zero timestamps received, which sometimes are received from datagram 162 // transport. Investigate if we can eliminate zero timestamps. 163 int64_t previous_nonzero_timestamp_us_ = 0; 164 165 // Disable datagram to RTCP feedback translation and enable RTCP feedback 166 // loop (note that having both RTCP and datagram feedback loops is 167 // inefficient, but can be useful in tests and experiments). 168 const bool disable_datagram_to_rtcp_feeback_translation_; 169 }; 170 171 } // namespace webrtc 172 173 #endif // PC_DATAGRAM_RTP_TRANSPORT_H_ 174