blob: dcd25ad2ee7937ffdc24d849e9905064455c6b02 [file] [log] [blame]
philipel881829b2017-10-13 13:27:23 +02001/*
2 * Copyright (c) 2017 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
Sebastian Janssonb5374962018-02-07 13:26:38 +010011#ifndef MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_
12#define MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_
philipel881829b2017-10-13 13:27:23 +020013
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
Sebastian Jansson60570dc2018-09-13 17:11:06 +020017#include <list>
philipel881829b2017-10-13 13:27:23 +020018#include <map>
Erik Språng58ee1872019-06-18 16:20:11 +020019#include <memory>
philipel881829b2017-10-13 13:27:23 +020020#include <queue>
21#include <set>
22
Yves Gerey988cc082018-10-23 12:03:01 +020023#include "absl/types/optional.h"
Erik Språng7702c8a2019-07-30 22:36:02 +020024#include "api/transport/webrtc_key_value_config.h"
Erik Språng82d75a62019-08-09 22:44:47 +020025#include "api/units/data_size.h"
26#include "api/units/time_delta.h"
27#include "api/units/timestamp.h"
philipel881829b2017-10-13 13:27:23 +020028#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Erik Språng58ee1872019-06-18 16:20:11 +020029#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Yves Gerey988cc082018-10-23 12:03:01 +020030#include "system_wrappers/include/clock.h"
philipel881829b2017-10-13 13:27:23 +020031
32namespace webrtc {
33
Sebastian Jansson60570dc2018-09-13 17:11:06 +020034class RoundRobinPacketQueue {
philipel881829b2017-10-13 13:27:23 +020035 public:
Erik Språng82d75a62019-08-09 22:44:47 +020036 RoundRobinPacketQueue(Timestamp start_time,
Erik Språng7702c8a2019-07-30 22:36:02 +020037 const WebRtcKeyValueConfig* field_trials);
Sebastian Jansson60570dc2018-09-13 17:11:06 +020038 ~RoundRobinPacketQueue();
philipel881829b2017-10-13 13:27:23 +020039
Erik Språngf660e812019-09-01 12:26:44 +000040 struct QueuedPacket {
41 public:
42 QueuedPacket(
43 int priority,
44 RtpPacketToSend::Type type,
45 uint32_t ssrc,
46 uint16_t seq_number,
47 int64_t capture_time_ms,
48 Timestamp enqueue_time,
49 DataSize size,
50 bool retransmission,
51 uint64_t enqueue_order,
52 std::multiset<Timestamp>::iterator enqueue_time_it,
53 absl::optional<std::list<std::unique_ptr<RtpPacketToSend>>::iterator>
54 packet_it);
55 QueuedPacket(const QueuedPacket& rhs);
56 ~QueuedPacket();
57
58 bool operator<(const QueuedPacket& other) const;
59
60 int priority() const { return priority_; }
61 RtpPacketToSend::Type type() const { return type_; }
62 uint32_t ssrc() const { return ssrc_; }
63 uint16_t sequence_number() const { return sequence_number_; }
64 int64_t capture_time_ms() const { return capture_time_ms_; }
65 Timestamp enqueue_time() const { return enqueue_time_; }
66 DataSize size() const { return size_; }
67 bool is_retransmission() const { return retransmission_; }
68 uint64_t enqueue_order() const { return enqueue_order_; }
69 std::unique_ptr<RtpPacketToSend> ReleasePacket();
70
71 // For internal use.
72 absl::optional<std::list<std::unique_ptr<RtpPacketToSend>>::iterator>
73 PacketIterator() const {
74 return packet_it_;
75 }
76 std::multiset<Timestamp>::iterator EnqueueTimeIterator() const {
77 return enqueue_time_it_;
78 }
79 void SubtractPauseTime(TimeDelta pause_time_sum);
80
81 private:
82 RtpPacketToSend::Type type_;
83 int priority_;
84 uint32_t ssrc_;
85 uint16_t sequence_number_;
86 int64_t capture_time_ms_; // Absolute time of frame capture.
87 Timestamp enqueue_time_; // Absolute time of pacer queue entry.
88 DataSize size_;
89 bool retransmission_;
90 uint64_t enqueue_order_;
91 std::multiset<Timestamp>::iterator enqueue_time_it_;
92 // Iterator into |rtp_packets_| where the memory for RtpPacket is owned,
93 // if applicable.
94 absl::optional<std::list<std::unique_ptr<RtpPacketToSend>>::iterator>
95 packet_it_;
96 };
97
98 void Push(int priority,
99 RtpPacketToSend::Type type,
100 uint32_t ssrc,
101 uint16_t seq_number,
102 int64_t capture_time_ms,
103 Timestamp enqueue_time,
104 DataSize size,
105 bool retransmission,
106 uint64_t enqueue_order);
Erik Språng58ee1872019-06-18 16:20:11 +0200107 void Push(int priority,
Erik Språng82d75a62019-08-09 22:44:47 +0200108 Timestamp enqueue_time,
Erik Språng58ee1872019-06-18 16:20:11 +0200109 uint64_t enqueue_order,
110 std::unique_ptr<RtpPacketToSend> packet);
Erik Språngf660e812019-09-01 12:26:44 +0000111 QueuedPacket* BeginPop();
112 void CancelPop();
113 void FinalizePop();
philipel881829b2017-10-13 13:27:23 +0200114
Sebastian Jansson60570dc2018-09-13 17:11:06 +0200115 bool Empty() const;
116 size_t SizeInPackets() const;
Erik Språng82d75a62019-08-09 22:44:47 +0200117 DataSize Size() const;
Erik Språngeb487992019-11-14 14:15:15 +0100118 bool NextPacketIsAudio() const;
Sebastian Jansson60570dc2018-09-13 17:11:06 +0200119
Erik Språng82d75a62019-08-09 22:44:47 +0200120 Timestamp OldestEnqueueTime() const;
121 TimeDelta AverageQueueTime() const;
122 void UpdateQueueTime(Timestamp now);
123 void SetPauseState(bool paused, Timestamp now);
philipel881829b2017-10-13 13:27:23 +0200124
Sebastian Janssonb5374962018-02-07 13:26:38 +0100125 private:
philipel881829b2017-10-13 13:27:23 +0200126 struct StreamPrioKey {
Erik Språng82d75a62019-08-09 22:44:47 +0200127 StreamPrioKey(int priority, DataSize size)
128 : priority(priority), size(size) {}
philipel881829b2017-10-13 13:27:23 +0200129
130 bool operator<(const StreamPrioKey& other) const {
131 if (priority != other.priority)
132 return priority < other.priority;
Erik Språng82d75a62019-08-09 22:44:47 +0200133 return size < other.size;
philipel881829b2017-10-13 13:27:23 +0200134 }
135
Erik Språng58ee1872019-06-18 16:20:11 +0200136 const int priority;
Erik Språng82d75a62019-08-09 22:44:47 +0200137 const DataSize size;
philipel881829b2017-10-13 13:27:23 +0200138 };
139
140 struct Stream {
141 Stream();
Mirko Bonadeib471c902018-07-18 14:11:27 +0200142 Stream(const Stream&);
philipel881829b2017-10-13 13:27:23 +0200143
144 virtual ~Stream();
145
Erik Språng82d75a62019-08-09 22:44:47 +0200146 DataSize size;
philipel881829b2017-10-13 13:27:23 +0200147 uint32_t ssrc;
Erik Språng58ee1872019-06-18 16:20:11 +0200148 std::priority_queue<QueuedPacket> packet_queue;
philipel881829b2017-10-13 13:27:23 +0200149
150 // Whenever a packet is inserted for this stream we check if |priority_it|
151 // points to an element in |stream_priorities_|, and if it does it means
152 // this stream has already been scheduled, and if the scheduled priority is
153 // lower than the priority of the incoming packet we reschedule this stream
154 // with the higher priority.
155 std::multimap<StreamPrioKey, uint32_t>::iterator priority_it;
156 };
157
Erik Språngf660e812019-09-01 12:26:44 +0000158 void Push(QueuedPacket packet);
Erik Språng58ee1872019-06-18 16:20:11 +0200159
philipel881829b2017-10-13 13:27:23 +0200160 Stream* GetHighestPriorityStream();
161
162 // Just used to verify correctness.
163 bool IsSsrcScheduled(uint32_t ssrc) const;
164
Erik Språng82d75a62019-08-09 22:44:47 +0200165 Timestamp time_last_updated_;
Erik Språngf660e812019-09-01 12:26:44 +0000166 absl::optional<QueuedPacket> pop_packet_;
167 absl::optional<Stream*> pop_stream_;
philipelccdfcca2017-10-23 12:42:17 +0200168
Erik Språng82d75a62019-08-09 22:44:47 +0200169 bool paused_;
170 size_t size_packets_;
171 DataSize size_;
172 DataSize max_size_;
173 TimeDelta queue_time_sum_;
174 TimeDelta pause_time_sum_;
philipel881829b2017-10-13 13:27:23 +0200175
176 // A map of streams used to prioritize from which stream to send next. We use
177 // a multimap instead of a priority_queue since the priority of a stream can
178 // change as a new packet is inserted, and a multimap allows us to remove and
179 // then reinsert a StreamPrioKey if the priority has increased.
180 std::multimap<StreamPrioKey, uint32_t> stream_priorities_;
181
182 // A map of SSRCs to Streams.
183 std::map<uint32_t, Stream> streams_;
184
185 // The enqueue time of every packet currently in the queue. Used to figure out
186 // the age of the oldest packet in the queue.
Erik Språng82d75a62019-08-09 22:44:47 +0200187 std::multiset<Timestamp> enqueue_times_;
Erik Språng58ee1872019-06-18 16:20:11 +0200188
189 // List of RTP packets to be sent, not necessarily in the order they will be
190 // sent. PacketInfo.packet_it will point to an entry in this list, or the
191 // end iterator of this list if queue does not have direct ownership of the
192 // packet.
193 std::list<std::unique_ptr<RtpPacketToSend>> rtp_packets_;
Erik Språngf660e812019-09-01 12:26:44 +0000194
195 const bool send_side_bwe_with_overhead_;
philipel881829b2017-10-13 13:27:23 +0200196};
197} // namespace webrtc
198
Sebastian Janssonb5374962018-02-07 13:26:38 +0100199#endif // MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_