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