| /* |
| * Copyright (c) 2019 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_RTP_RTCP_SOURCE_RTP_SEQUENCE_NUMBER_MAP_H_ |
| #define MODULES_RTP_RTCP_SOURCE_RTP_SEQUENCE_NUMBER_MAP_H_ |
| |
| #include <cstddef> |
| #include <cstdint> |
| #include <deque> |
| |
| #include "absl/types/optional.h" |
| |
| namespace webrtc { |
| |
| // Records the association of RTP sequence numbers to timestamps and to whether |
| // the packet was first and/or last in the frame. |
| // |
| // 1. Limits number of entries. Whenever `max_entries` is about to be exceeded, |
| // the size is reduced by approximately 25%. |
| // 2. RTP sequence numbers wrap around relatively infrequently. |
| // This class therefore only remembers at most the last 2^15 RTP packets, |
| // so that the newest packet's sequence number is still AheadOf the oldest |
| // packet's sequence number. |
| // 3. Media frames are sometimes split into several RTP packets. |
| // In such a case, Insert() is expected to be called once for each packet. |
| // The timestamp is not expected to change between those calls. |
| class RtpSequenceNumberMap final { |
| public: |
| struct Info final { |
| Info(uint32_t timestamp, bool is_first, bool is_last) |
| : timestamp(timestamp), is_first(is_first), is_last(is_last) {} |
| |
| friend bool operator==(const Info& lhs, const Info& rhs) { |
| return lhs.timestamp == rhs.timestamp && lhs.is_first == rhs.is_first && |
| lhs.is_last == rhs.is_last; |
| } |
| |
| uint32_t timestamp; |
| bool is_first; |
| bool is_last; |
| }; |
| |
| explicit RtpSequenceNumberMap(size_t max_entries); |
| RtpSequenceNumberMap(const RtpSequenceNumberMap& other) = delete; |
| RtpSequenceNumberMap& operator=(const RtpSequenceNumberMap& other) = delete; |
| ~RtpSequenceNumberMap(); |
| |
| void InsertPacket(uint16_t sequence_number, Info info); |
| void InsertFrame(uint16_t first_sequence_number, |
| size_t packet_count, |
| uint32_t timestamp); |
| |
| absl::optional<Info> Get(uint16_t sequence_number) const; |
| |
| size_t AssociationCountForTesting() const; |
| |
| private: |
| struct Association { |
| explicit Association(uint16_t sequence_number) |
| : Association(sequence_number, Info(0, false, false)) {} |
| |
| Association(uint16_t sequence_number, Info info) |
| : sequence_number(sequence_number), info(info) {} |
| |
| uint16_t sequence_number; |
| Info info; |
| }; |
| |
| const size_t max_entries_; |
| |
| // The non-transitivity of AheadOf() would be problematic with a map, |
| // so we use a deque instead. |
| std::deque<Association> associations_; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // MODULES_RTP_RTCP_SOURCE_RTP_SEQUENCE_NUMBER_MAP_H_ |