tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

packet_sequencer.cc (5847B)


      1 /*
      2 *  Copyright (c) 2021 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 #include "modules/rtp_rtcp/source/packet_sequencer.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <optional>
     16 
     17 #include "api/units/time_delta.h"
     18 #include "api/units/timestamp.h"
     19 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     20 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
     21 #include "rtc_base/checks.h"
     22 #include "rtc_base/random.h"
     23 #include "system_wrappers/include/clock.h"
     24 
     25 namespace webrtc {
     26 
     27 namespace {
     28 // RED header is first byte of payload, if present.
     29 constexpr size_t kRedForFecHeaderLength = 1;
     30 
     31 // Timestamps use a 90kHz clock.
     32 constexpr uint32_t kTimestampTicksPerMs = 90;
     33 }  // namespace
     34 
     35 PacketSequencer::PacketSequencer(uint32_t media_ssrc,
     36                                 std::optional<uint32_t> rtx_ssrc,
     37                                 bool require_marker_before_media_padding,
     38                                 Clock* clock)
     39    : media_ssrc_(media_ssrc),
     40      rtx_ssrc_(rtx_ssrc),
     41      require_marker_before_media_padding_(require_marker_before_media_padding),
     42      clock_(clock),
     43      media_sequence_number_(0),
     44      rtx_sequence_number_(0),
     45      last_payload_type_(-1),
     46      last_rtp_timestamp_(0),
     47      last_packet_marker_bit_(false) {
     48  Random random(clock_->TimeInMicroseconds());
     49  // Random start, 16 bits. Upper half of range is avoided in order to prevent
     50  // SRTP wraparound issues during startup. See this unit test for details:
     51  // SrtpSessionTest.ProtectUnprotectWrapAroundRocMismatch
     52  // Sequence number 0 is avoided for historical reasons, presumably to avoid
     53  // debugability or test usage conflicts.
     54  constexpr uint16_t kMaxInitRtpSeqNumber = 0x7fff;  // 2^15 - 1.
     55  media_sequence_number_ = random.Rand(1, kMaxInitRtpSeqNumber);
     56  rtx_sequence_number_ = random.Rand(1, kMaxInitRtpSeqNumber);
     57 }
     58 
     59 void PacketSequencer::Sequence(RtpPacketToSend& packet) {
     60  if (packet.Ssrc() == media_ssrc_) {
     61    if (packet.packet_type() == RtpPacketMediaType::kRetransmission) {
     62      // Retransmission of an already sequenced packet, ignore.
     63      return;
     64    } else if (packet.packet_type() == RtpPacketMediaType::kPadding) {
     65      PopulatePaddingFields(packet);
     66    }
     67    packet.SetSequenceNumber(media_sequence_number_++);
     68    if (packet.packet_type() != RtpPacketMediaType::kPadding) {
     69      UpdateLastPacketState(packet);
     70    }
     71  } else if (packet.Ssrc() == rtx_ssrc_) {
     72    if (packet.packet_type() == RtpPacketMediaType::kPadding) {
     73      PopulatePaddingFields(packet);
     74    }
     75    packet.SetSequenceNumber(rtx_sequence_number_++);
     76  } else {
     77    RTC_DCHECK_NOTREACHED() << "Unexpected ssrc " << packet.Ssrc();
     78  }
     79 }
     80 
     81 void PacketSequencer::SetRtpState(const RtpState& state) {
     82  media_sequence_number_ = state.sequence_number;
     83  last_rtp_timestamp_ = state.timestamp;
     84  last_capture_time_ = state.capture_time;
     85  last_timestamp_time_ = state.last_timestamp_time;
     86 }
     87 
     88 void PacketSequencer::PopulateRtpState(RtpState& state) const {
     89  state.sequence_number = media_sequence_number_;
     90  state.timestamp = last_rtp_timestamp_;
     91  state.capture_time = last_capture_time_;
     92  state.last_timestamp_time = last_timestamp_time_;
     93 }
     94 
     95 void PacketSequencer::UpdateLastPacketState(const RtpPacketToSend& packet) {
     96  // Remember marker bit to determine if padding can be inserted with
     97  // sequence number following `packet`.
     98  last_packet_marker_bit_ = packet.Marker();
     99  // Remember media payload type to use in the padding packet if rtx is
    100  // disabled.
    101  if (packet.is_red()) {
    102    RTC_DCHECK_GE(packet.payload_size(), kRedForFecHeaderLength);
    103    last_payload_type_ = packet.PayloadBuffer()[0];
    104  } else {
    105    last_payload_type_ = packet.PayloadType();
    106  }
    107  // Save timestamps to generate timestamp field and extensions for the padding.
    108  last_rtp_timestamp_ = packet.Timestamp();
    109  last_timestamp_time_ = clock_->CurrentTime();
    110  last_capture_time_ = packet.capture_time();
    111 }
    112 
    113 void PacketSequencer::PopulatePaddingFields(RtpPacketToSend& packet) {
    114  if (packet.Ssrc() == media_ssrc_) {
    115    RTC_DCHECK(CanSendPaddingOnMediaSsrc());
    116 
    117    packet.SetTimestamp(last_rtp_timestamp_);
    118    packet.set_capture_time(last_capture_time_);
    119    packet.SetPayloadType(last_payload_type_);
    120    return;
    121  }
    122 
    123  RTC_DCHECK(packet.Ssrc() == rtx_ssrc_);
    124  if (packet.payload_size() > 0) {
    125    // This is payload padding packet, don't update timestamp fields.
    126    return;
    127  }
    128 
    129  packet.SetTimestamp(last_rtp_timestamp_);
    130  packet.set_capture_time(last_capture_time_);
    131 
    132  // Only change the timestamp of padding packets sent over RTX.
    133  // Padding only packets over RTP has to be sent as part of a media
    134  // frame (and therefore the same timestamp).
    135  if (last_timestamp_time_ > Timestamp::Zero()) {
    136    TimeDelta since_last_media = clock_->CurrentTime() - last_timestamp_time_;
    137    packet.SetTimestamp(packet.Timestamp() +
    138                        since_last_media.ms() * kTimestampTicksPerMs);
    139    if (packet.capture_time() > Timestamp::Zero()) {
    140      packet.set_capture_time(packet.capture_time() + since_last_media);
    141    }
    142  }
    143 }
    144 
    145 bool PacketSequencer::CanSendPaddingOnMediaSsrc() const {
    146  if (last_payload_type_ == -1) {
    147    return false;
    148  }
    149 
    150  // Without RTX we can't send padding in the middle of frames.
    151  // For audio marker bits doesn't mark the end of a frame and frames
    152  // are usually a single packet, so for now we don't apply this rule
    153  // for audio.
    154  if (require_marker_before_media_padding_ && !last_packet_marker_bit_) {
    155    return false;
    156  }
    157 
    158  return true;
    159 }
    160 
    161 }  // namespace webrtc