blob: e8cb19e9c745d6a0ba33829176cf9c76af24cc67 [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
14#include <map>
15#include <queue>
16#include <set>
17
Sebastian Janssonb5374962018-02-07 13:26:38 +010018#include "modules/pacing/packet_queue_interface.h"
philipel881829b2017-10-13 13:27:23 +020019#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
20
21namespace webrtc {
22
Sebastian Janssonb5374962018-02-07 13:26:38 +010023class RoundRobinPacketQueue : public PacketQueueInterface {
philipel881829b2017-10-13 13:27:23 +020024 public:
Sebastian Janssonb5374962018-02-07 13:26:38 +010025 explicit RoundRobinPacketQueue(const Clock* clock);
26 ~RoundRobinPacketQueue() override;
philipel881829b2017-10-13 13:27:23 +020027
Sebastian Janssonb5374962018-02-07 13:26:38 +010028 using Packet = PacketQueueInterface::Packet;
philipel881829b2017-10-13 13:27:23 +020029
philipelccdfcca2017-10-23 12:42:17 +020030 void Push(const Packet& packet) override;
31 const Packet& BeginPop() override;
32 void CancelPop(const Packet& packet) override;
33 void FinalizePop(const Packet& packet) override;
philipel881829b2017-10-13 13:27:23 +020034
philipelccdfcca2017-10-23 12:42:17 +020035 bool Empty() const override;
36 size_t SizeInPackets() const override;
37 uint64_t SizeInBytes() const override;
philipel881829b2017-10-13 13:27:23 +020038
philipelccdfcca2017-10-23 12:42:17 +020039 int64_t OldestEnqueueTimeMs() const override;
40 int64_t AverageQueueTimeMs() const override;
41 void UpdateQueueTime(int64_t timestamp_ms) override;
42 void SetPauseState(bool paused, int64_t timestamp_ms) override;
philipel881829b2017-10-13 13:27:23 +020043
Sebastian Janssonb5374962018-02-07 13:26:38 +010044 private:
philipel881829b2017-10-13 13:27:23 +020045 struct StreamPrioKey {
46 StreamPrioKey() = default;
47 StreamPrioKey(RtpPacketSender::Priority priority, int64_t bytes)
48 : priority(priority), bytes(bytes) {}
49
50 bool operator<(const StreamPrioKey& other) const {
51 if (priority != other.priority)
52 return priority < other.priority;
Ilya Nikolaevskiyc3216e12017-12-21 15:39:33 +010053 return bytes < other.bytes;
philipel881829b2017-10-13 13:27:23 +020054 }
55
56 const RtpPacketSender::Priority priority;
57 const size_t bytes;
58 };
59
60 struct Stream {
61 Stream();
Mirko Bonadeib471c902018-07-18 14:11:27 +020062 Stream(const Stream&);
philipel881829b2017-10-13 13:27:23 +020063
64 virtual ~Stream();
65
66 size_t bytes;
67 uint32_t ssrc;
68 std::priority_queue<Packet> packet_queue;
69
70 // Whenever a packet is inserted for this stream we check if |priority_it|
71 // points to an element in |stream_priorities_|, and if it does it means
72 // this stream has already been scheduled, and if the scheduled priority is
73 // lower than the priority of the incoming packet we reschedule this stream
74 // with the higher priority.
75 std::multimap<StreamPrioKey, uint32_t>::iterator priority_it;
76 };
77
philipel881829b2017-10-13 13:27:23 +020078 static constexpr size_t kMaxLeadingBytes = 1400;
79
80 Stream* GetHighestPriorityStream();
81
82 // Just used to verify correctness.
83 bool IsSsrcScheduled(uint32_t ssrc) const;
84
philipelccdfcca2017-10-23 12:42:17 +020085 int64_t time_last_updated_;
Danil Chapovalov0040b662018-06-18 10:48:16 +020086 absl::optional<Packet> pop_packet_;
87 absl::optional<Stream*> pop_stream_;
philipelccdfcca2017-10-23 12:42:17 +020088
philipel881829b2017-10-13 13:27:23 +020089 bool paused_ = false;
90 size_t size_packets_ = 0;
91 size_t size_bytes_ = 0;
92 size_t max_bytes_ = kMaxLeadingBytes;
philipel881829b2017-10-13 13:27:23 +020093 int64_t queue_time_sum_ms_ = 0;
94 int64_t pause_time_sum_ms_ = 0;
95
96 // A map of streams used to prioritize from which stream to send next. We use
97 // a multimap instead of a priority_queue since the priority of a stream can
98 // change as a new packet is inserted, and a multimap allows us to remove and
99 // then reinsert a StreamPrioKey if the priority has increased.
100 std::multimap<StreamPrioKey, uint32_t> stream_priorities_;
101
102 // A map of SSRCs to Streams.
103 std::map<uint32_t, Stream> streams_;
104
105 // The enqueue time of every packet currently in the queue. Used to figure out
106 // the age of the oldest packet in the queue.
107 std::multiset<int64_t> enqueue_times_;
108};
109} // namespace webrtc
110
Sebastian Janssonb5374962018-02-07 13:26:38 +0100111#endif // MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_