blob: c7a23371b5179fd58d4e7799833cbe9d2764eb46 [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
11#ifndef MODULES_PACING_PACKET_QUEUE2_H_
12#define MODULES_PACING_PACKET_QUEUE2_H_
13
14#include <map>
15#include <queue>
16#include <set>
17
18#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
19
20namespace webrtc {
21
22class PacketQueue2 {
23 public:
24 explicit PacketQueue2(const Clock* clock);
25 virtual ~PacketQueue2();
26
27 struct Packet {
28 Packet(RtpPacketSender::Priority priority,
29 uint32_t ssrc,
30 uint16_t seq_number,
31 int64_t capture_time_ms,
32 int64_t enqueue_time_ms,
33 size_t length_in_bytes,
34 bool retransmission,
35 uint64_t enqueue_order);
36
37 Packet(const Packet& other);
38
39 virtual ~Packet();
40
41 bool operator<(const Packet& other) const {
42 if (priority != other.priority)
43 return priority > other.priority;
44 if (retransmission != other.retransmission)
45 return other.retransmission;
46
47 return enqueue_order > other.enqueue_order;
48 }
49
50 RtpPacketSender::Priority priority;
51 uint32_t ssrc;
52 uint16_t sequence_number;
53 int64_t capture_time_ms; // Absolute time of frame capture.
54 int64_t enqueue_time_ms; // Absolute time of pacer queue entry.
55 size_t bytes;
56 bool retransmission;
57 uint64_t enqueue_order;
58 std::multiset<int64_t>::iterator enqueue_time_it;
59 };
60
61 void Push(const Packet& packet);
62 const Packet& Top();
63 void Pop();
64
65 bool Empty() const;
66 size_t SizeInPackets() const;
67 uint64_t SizeInBytes() const;
68
69 int64_t OldestEnqueueTimeMs() const;
70 int64_t AverageQueueTimeMs() const;
71 void UpdateQueueTime(int64_t timestamp_ms);
72 void SetPauseState(bool paused, int64_t timestamp_ms);
73
74 struct StreamPrioKey {
75 StreamPrioKey() = default;
76 StreamPrioKey(RtpPacketSender::Priority priority, int64_t bytes)
77 : priority(priority), bytes(bytes) {}
78
79 bool operator<(const StreamPrioKey& other) const {
80 if (priority != other.priority)
81 return priority < other.priority;
82 return bytes > other.bytes;
83 }
84
85 const RtpPacketSender::Priority priority;
86 const size_t bytes;
87 };
88
89 struct Stream {
90 Stream();
91
92 virtual ~Stream();
93
94 size_t bytes;
95 uint32_t ssrc;
96 std::priority_queue<Packet> packet_queue;
97
98 // Whenever a packet is inserted for this stream we check if |priority_it|
99 // points to an element in |stream_priorities_|, and if it does it means
100 // this stream has already been scheduled, and if the scheduled priority is
101 // lower than the priority of the incoming packet we reschedule this stream
102 // with the higher priority.
103 std::multimap<StreamPrioKey, uint32_t>::iterator priority_it;
104 };
105
106 private:
107 static constexpr size_t kMaxLeadingBytes = 1400;
108
109 Stream* GetHighestPriorityStream();
110
111 // Just used to verify correctness.
112 bool IsSsrcScheduled(uint32_t ssrc) const;
113
114 const Clock* const clock_;
115 bool paused_ = false;
116 size_t size_packets_ = 0;
117 size_t size_bytes_ = 0;
118 size_t max_bytes_ = kMaxLeadingBytes;
119 int64_t time_last_updated_;
120 int64_t queue_time_sum_ms_ = 0;
121 int64_t pause_time_sum_ms_ = 0;
122
123 // A map of streams used to prioritize from which stream to send next. We use
124 // a multimap instead of a priority_queue since the priority of a stream can
125 // change as a new packet is inserted, and a multimap allows us to remove and
126 // then reinsert a StreamPrioKey if the priority has increased.
127 std::multimap<StreamPrioKey, uint32_t> stream_priorities_;
128
129 // A map of SSRCs to Streams.
130 std::map<uint32_t, Stream> streams_;
131
132 // The enqueue time of every packet currently in the queue. Used to figure out
133 // the age of the oldest packet in the queue.
134 std::multiset<int64_t> enqueue_times_;
135};
136} // namespace webrtc
137
138#endif // MODULES_PACING_PACKET_QUEUE2_H_