/* * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef MODULES_PACING_PRIORITIZED_PACKET_QUEUE_H_ #define MODULES_PACING_PRIORITIZED_PACKET_QUEUE_H_ #include #include #include #include #include #include "api/units/data_size.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "modules/pacing/pacing_controller.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" namespace webrtc { class PrioritizedPacketQueue : public PacingController::PacketQueue { public: explicit PrioritizedPacketQueue(Timestamp creation_time); PrioritizedPacketQueue(const PrioritizedPacketQueue&) = delete; PrioritizedPacketQueue& operator=(const PrioritizedPacketQueue&) = delete; void Push(Timestamp enqueue_time, std::unique_ptr packet) override; std::unique_ptr Pop() override; int SizeInPackets() const override; DataSize SizeInPayloadBytes() const override; const std::array& SizeInPacketsPerRtpPacketMediaType() const override; Timestamp LeadingAudioPacketEnqueueTime() const override; Timestamp OldestEnqueueTime() const override; TimeDelta AverageQueueTime() const override; void UpdateAverageQueueTime(Timestamp now) override; void SetPauseState(bool paused, Timestamp now) override; private: static constexpr int kNumPriorityLevels = 4; class QueuedPacket { public: DataSize PacketSize() const; std::unique_ptr packet; Timestamp enqueue_time; std::list::iterator enqueue_time_iterator; }; // Class containing packets for an RTP stream. // For each priority level, packets are simply stored in a fifo queue. class StreamQueue { public: explicit StreamQueue(Timestamp creation_time); StreamQueue(StreamQueue&&) = default; StreamQueue& operator=(StreamQueue&&) = default; StreamQueue(const StreamQueue&) = delete; StreamQueue& operator=(const StreamQueue&) = delete; // Enqueue packet at the given priority level. Returns true if the packet // count for that priority level went from zero to non-zero. bool EnqueuePacket(QueuedPacket packet, int priority_level); QueuedPacket DequePacket(int priority_level); bool HasPacketsAtPrio(int priority_level) const; bool IsEmpty() const; Timestamp LeadingAudioPacketEnqueueTime() const; Timestamp LastEnqueueTime() const; private: std::deque packets_[kNumPriorityLevels]; Timestamp last_enqueue_time_; }; // Cumulative sum, over all packets, of time spent in the queue. TimeDelta queue_time_sum_; // Cumulative sum of time the queue has spent in a paused state. TimeDelta pause_time_sum_; // Total number of packets stored in this queue. int size_packets_; // Total number of packets stored in this queue per RtpPacketMediaType. std::array size_packets_per_media_type_; // Sum of payload sizes for all packts stored in this queue. DataSize size_payload_; // The last time queue/pause time sums were updated. Timestamp last_update_time_; bool paused_; // Last time `streams_` was culled for inactive streams. Timestamp last_culling_time_; // Map from SSRC to packet queues for the associated RTP stream. std::unordered_map> streams_; // For each priority level, a queue of StreamQueues which have at least one // packet pending for that prio level. std::deque streams_by_prio_[kNumPriorityLevels]; // The first index into `stream_by_prio_` that is non-empty. int top_active_prio_level_; // Ordered list of enqueue times. Additions are always increasing and added to // the end. QueuedPacket instances have a iterators into this list for fast // removal. std::list enqueue_times_; }; } // namespace webrtc #endif // MODULES_PACING_PRIORITIZED_PACKET_QUEUE_H_