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