blob: f9684c69c03290215920365a42eb59df4464f9fa [file] [log] [blame]
* Copyright 2019 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.
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "api/crypto/crypto_options.h"
#include "api/transport/datagram_transport_interface.h"
#include "api/transport/media/media_transport_interface.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/packet_transport_internal.h"
#include "pc/rtp_transport_internal.h"
#include "rtc_base/buffer.h"
#include "rtc_base/buffer_queue.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/stream.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/thread_checker.h"
namespace webrtc {
constexpr int kDatagramDtlsAdaptorComponent = -1;
// RTP transport which uses the DatagramTransportInterface to send and receive
// packets.
class DatagramRtpTransport : public RtpTransportInternal,
public webrtc::DatagramSinkInterface,
public webrtc::MediaTransportStateCallback {
const std::vector<webrtc::RtpExtension>& rtp_header_extensions,
cricket::IceTransportInternal* ice_transport,
DatagramTransportInterface* datagram_transport);
~DatagramRtpTransport() override;
// =====================================================
// Overrides for webrtc::DatagramTransportSinkInterface
// and MediaTransportStateCallback
// =====================================================
void OnDatagramReceived(rtc::ArrayView<const uint8_t> data) override;
void OnDatagramSent(webrtc::DatagramId datagram_id) override;
void OnDatagramAcked(const webrtc::DatagramAck& ack) override;
void OnDatagramLost(webrtc::DatagramId datagram_id) override;
void OnStateChanged(webrtc::MediaTransportState state) override;
// =====================================================
// RtpTransportInternal overrides
// =====================================================
bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketOptions& options,
int flags) override;
bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketOptions& options,
int flags) override;
const std::string& transport_name() const override;
// Datagram transport always muxes RTCP.
bool rtcp_mux_enabled() const override { return true; }
void SetRtcpMuxEnabled(bool enable) override {}
int SetRtpOption(rtc::Socket::Option opt, int value) override;
int SetRtcpOption(rtc::Socket::Option opt, int value) override;
bool IsReadyToSend() const override;
bool IsWritable(bool rtcp) const override;
bool IsSrtpActive() const override { return false; }
void UpdateRtpHeaderExtensionMap(
const cricket::RtpHeaderExtensions& header_extensions) override;
bool RegisterRtpDemuxerSink(const RtpDemuxerCriteria& criteria,
RtpPacketSinkInterface* sink) override;
bool UnregisterRtpDemuxerSink(RtpPacketSinkInterface* sink) override;
// RTP/RTCP packet info stored for each sent packet.
struct SentPacketInfo {
// RTP packet info with ssrc and transport sequence number.
SentPacketInfo(int64_t packet_id,
uint32_t ssrc,
uint16_t transport_sequence_number)
: ssrc(ssrc),
packet_id(packet_id) {}
// Packet info without SSRC and transport sequence number used for RTCP
// packets, RTP packets when transport sequence number is not provided or
// when feedback translation is disabled.
explicit SentPacketInfo(int64_t packet_id) : packet_id(packet_id) {}
SentPacketInfo() = default;
absl::optional<uint32_t> ssrc;
// Transport sequence number (if it was provided in outgoing RTP packet).
// It is used to re-create RTCP feedback packets from datagram ACKs.
absl::optional<uint16_t> transport_sequence_number;
// Packet id from rtc::PacketOptions. It is required to propagage sent
// notification up the stack (SignalSentPacket).
int64_t packet_id = 0;
// Finds SentPacketInfo for given |datagram_id| and removes map entry.
// Returns false if entry was not found.
bool GetAndRemoveSentPacketInfo(webrtc::DatagramId datagram_id,
SentPacketInfo* sent_packet_info);
// Sends datagram to datagram_transport.
bool SendDatagram(rtc::ArrayView<const uint8_t> data,
webrtc::DatagramId datagram_id);
// Propagates network route changes from ICE.
void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route);
rtc::ThreadChecker thread_checker_;
cricket::IceTransportInternal* ice_transport_;
webrtc::DatagramTransportInterface* datagram_transport_;
RtpDemuxer rtp_demuxer_;
MediaTransportState state_ = MediaTransportState::kPending;
// Extension map for parsing transport sequence numbers.
webrtc::RtpHeaderExtensionMap rtp_header_extension_map_;
// Keeps information about sent RTP packet until they are Acked or Lost.
std::map<webrtc::DatagramId, SentPacketInfo> sent_rtp_packet_map_;
// Current datagram_id, incremented after each sent RTP packets.
// Datagram id is passed to datagram transport when we send datagram and we
// get it back in notifications about Sent, Acked and Lost datagrams.
int64_t current_datagram_id_ = 0;
// TODO(sukhanov): Previous nonzero timestamp is required for workaround for
// zero timestamps received, which sometimes are received from datagram
// transport. Investigate if we can eliminate zero timestamps.
int64_t previous_nonzero_timestamp_us_ = 0;
// Disable datagram to RTCP feedback translation and enable RTCP feedback
// loop (note that having both RTCP and datagram feedback loops is
// inefficient, but can be useful in tests and experiments).
const bool disable_datagram_to_rtcp_feeback_translation_;
} // namespace webrtc