round_robin_packet_queue.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  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. #ifndef MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_
  11. #define MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_
  12. #include <stddef.h>
  13. #include <stdint.h>
  14. #include <list>
  15. #include <map>
  16. #include <memory>
  17. #include <queue>
  18. #include <set>
  19. #include "absl/types/optional.h"
  20. #include "api/transport/webrtc_key_value_config.h"
  21. #include "api/units/data_size.h"
  22. #include "api/units/time_delta.h"
  23. #include "api/units/timestamp.h"
  24. #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
  25. #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
  26. #include "system_wrappers/include/clock.h"
  27. namespace webrtc {
  28. class RoundRobinPacketQueue {
  29. public:
  30. RoundRobinPacketQueue(Timestamp start_time,
  31. const WebRtcKeyValueConfig* field_trials);
  32. ~RoundRobinPacketQueue();
  33. void Push(int priority,
  34. Timestamp enqueue_time,
  35. uint64_t enqueue_order,
  36. std::unique_ptr<RtpPacketToSend> packet);
  37. std::unique_ptr<RtpPacketToSend> Pop();
  38. bool Empty() const;
  39. size_t SizeInPackets() const;
  40. DataSize Size() const;
  41. // If the next packet, that would be returned by Pop() if called
  42. // now, is an audio packet this method returns the enqueue time
  43. // of that packet. If queue is empty or top packet is not audio,
  44. // returns nullopt.
  45. absl::optional<Timestamp> LeadingAudioPacketEnqueueTime() const;
  46. Timestamp OldestEnqueueTime() const;
  47. TimeDelta AverageQueueTime() const;
  48. void UpdateQueueTime(Timestamp now);
  49. void SetPauseState(bool paused, Timestamp now);
  50. void SetIncludeOverhead();
  51. void SetTransportOverhead(DataSize overhead_per_packet);
  52. private:
  53. struct QueuedPacket {
  54. public:
  55. QueuedPacket(int priority,
  56. Timestamp enqueue_time,
  57. uint64_t enqueue_order,
  58. std::multiset<Timestamp>::iterator enqueue_time_it,
  59. std::unique_ptr<RtpPacketToSend> packet);
  60. QueuedPacket(const QueuedPacket& rhs);
  61. ~QueuedPacket();
  62. bool operator<(const QueuedPacket& other) const;
  63. int Priority() const;
  64. RtpPacketMediaType Type() const;
  65. uint32_t Ssrc() const;
  66. Timestamp EnqueueTime() const;
  67. bool IsRetransmission() const;
  68. uint64_t EnqueueOrder() const;
  69. RtpPacketToSend* RtpPacket() const;
  70. std::multiset<Timestamp>::iterator EnqueueTimeIterator() const;
  71. void UpdateEnqueueTimeIterator(std::multiset<Timestamp>::iterator it);
  72. void SubtractPauseTime(TimeDelta pause_time_sum);
  73. private:
  74. int priority_;
  75. Timestamp enqueue_time_; // Absolute time of pacer queue entry.
  76. uint64_t enqueue_order_;
  77. bool is_retransmission_; // Cached for performance.
  78. std::multiset<Timestamp>::iterator enqueue_time_it_;
  79. // Raw pointer since priority_queue doesn't allow for moving
  80. // out of the container.
  81. RtpPacketToSend* owned_packet_;
  82. };
  83. class PriorityPacketQueue : public std::priority_queue<QueuedPacket> {
  84. public:
  85. using const_iterator = container_type::const_iterator;
  86. const_iterator begin() const;
  87. const_iterator end() const;
  88. };
  89. struct StreamPrioKey {
  90. StreamPrioKey(int priority, DataSize size)
  91. : priority(priority), size(size) {}
  92. bool operator<(const StreamPrioKey& other) const {
  93. if (priority != other.priority)
  94. return priority < other.priority;
  95. return size < other.size;
  96. }
  97. const int priority;
  98. const DataSize size;
  99. };
  100. struct Stream {
  101. Stream();
  102. Stream(const Stream&);
  103. virtual ~Stream();
  104. DataSize size;
  105. uint32_t ssrc;
  106. PriorityPacketQueue packet_queue;
  107. // Whenever a packet is inserted for this stream we check if |priority_it|
  108. // points to an element in |stream_priorities_|, and if it does it means
  109. // this stream has already been scheduled, and if the scheduled priority is
  110. // lower than the priority of the incoming packet we reschedule this stream
  111. // with the higher priority.
  112. std::multimap<StreamPrioKey, uint32_t>::iterator priority_it;
  113. };
  114. void Push(QueuedPacket packet);
  115. DataSize PacketSize(const QueuedPacket& packet) const;
  116. void MaybePromoteSinglePacketToNormalQueue();
  117. Stream* GetHighestPriorityStream();
  118. // Just used to verify correctness.
  119. bool IsSsrcScheduled(uint32_t ssrc) const;
  120. DataSize transport_overhead_per_packet_;
  121. Timestamp time_last_updated_;
  122. bool paused_;
  123. size_t size_packets_;
  124. DataSize size_;
  125. DataSize max_size_;
  126. TimeDelta queue_time_sum_;
  127. TimeDelta pause_time_sum_;
  128. // A map of streams used to prioritize from which stream to send next. We use
  129. // a multimap instead of a priority_queue since the priority of a stream can
  130. // change as a new packet is inserted, and a multimap allows us to remove and
  131. // then reinsert a StreamPrioKey if the priority has increased.
  132. std::multimap<StreamPrioKey, uint32_t> stream_priorities_;
  133. // A map of SSRCs to Streams.
  134. std::map<uint32_t, Stream> streams_;
  135. // The enqueue time of every packet currently in the queue. Used to figure out
  136. // the age of the oldest packet in the queue.
  137. std::multiset<Timestamp> enqueue_times_;
  138. absl::optional<QueuedPacket> single_packet_queue_;
  139. bool include_overhead_;
  140. };
  141. } // namespace webrtc
  142. #endif // MODULES_PACING_ROUND_ROBIN_PACKET_QUEUE_H_