Skip to content

Commit 540bfdc

Browse files
committed
formats: Limit memory consumption when recording data for duplicate checking
1 parent 9c1ffc2 commit 540bfdc

2 files changed

Lines changed: 20 additions & 29 deletions

File tree

src/formats/h26x.cc

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ constexpr int GARBAGE_COLLECTION_INTERVAL_MS = 100;
4646
// any value less than 30 minutes is ok here, since that is how long it takes to go through all timestamps
4747
constexpr int TIME_TO_KEEP_TRACK_OF_PREVIOUS_FRAMES_MS = 5000;
4848

49-
// how many RTP timestamps get saved for duplicate detection
50-
// there is 90 000 timestamps in one second -> 5 sec is 450 000
51-
constexpr int RECEIVED_FRAMES = 450000;
52-
5349
static inline uint8_t determine_start_prefix_precense(uint32_t value, bool& additional_byte)
5450
{
5551
additional_byte = false;
@@ -101,8 +97,8 @@ uvgrtp::formats::h26x::h26x(std::shared_ptr<uvgrtp::socket> socket, std::shared_
10197
media(socket, rtp, rce_flags),
10298
queued_(),
10399
access_units_(),
104-
received_frames_(),
105-
received_info_(),
100+
seen_order_(),
101+
seen_packets_(),
106102
fragments_(),
107103
dropped_ts_(),
108104
dropped_in_order_(),
@@ -642,27 +638,21 @@ rtp_error_t uvgrtp::formats::h26x::handle_aggregation_packet(uvgrtp::frame::rtp_
642638

643639
bool uvgrtp::formats::h26x::is_duplicate_frame(uint32_t timestamp, uint16_t seq_num)
644640
{
645-
if (received_info_.find(timestamp) != received_info_.end()) {
646-
if (std::find(received_info_.at(timestamp).begin(), received_info_.at(timestamp).end(), seq_num) != received_info_.at(timestamp).end()) {
647-
UVG_LOG_WARN("duplicate ts and seq num received, discarding frame");
648-
return true;
649-
}
641+
while (!seen_order_.empty() &&
642+
uvgrtp::clock::hrc::diff_now(seen_order_.front().arrival) > TIME_TO_KEEP_TRACK_OF_PREVIOUS_FRAMES_MS)
643+
{
644+
seen_packets_.erase(seen_order_.front().key);
645+
seen_order_.pop_front();
650646
}
651-
pkt_stats stats = {timestamp, seq_num};
652647

653-
// Save the received ts and seq num
654-
if (received_info_.find(timestamp) == received_info_.end()) {
655-
received_info_.insert({timestamp, {seq_num}});
648+
const uint64_t key = (uint64_t(timestamp) << 16) | uint64_t(seq_num);
649+
if (seen_packets_.find(key) != seen_packets_.end()) {
650+
UVG_LOG_WARN("duplicate ts and seq num received, discarding frame");
651+
return true;
656652
}
657-
else {
658-
received_info_.at(timestamp).push_back(seq_num);
659-
}
660-
received_frames_.push_back(stats);
661653

662-
if (received_frames_.size() > RECEIVED_FRAMES) {
663-
received_info_.erase(received_frames_.front().ts);
664-
received_frames_.pop_front();
665-
}
654+
seen_packets_.insert(key);
655+
seen_order_.push_back({ key, uvgrtp::clock::hrc::now() });
666656
return false;
667657
}
668658

src/formats/h26x.hh

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,14 @@ namespace uvgrtp {
186186
std::deque<uvgrtp::frame::rtp_frame*> queued_;
187187
std::unordered_map<uint32_t, access_unit_info> access_units_;
188188

189-
// Save received RTP frame stats, used to check for duplicates in is_duplicate_frame()
190-
struct pkt_stats {
191-
uint32_t ts;
192-
uint16_t seq;
189+
struct seen_packet {
190+
uint64_t key;
191+
uvgrtp::clock::hrc::hrc_t arrival;
193192
};
194-
std::deque<pkt_stats> received_frames_;
195-
std::unordered_map<uint32_t, std::vector<uint16_t>> received_info_;
193+
194+
// Time-window duplicate tracking (key = (timestamp << 16) | seq)
195+
std::deque<seen_packet> seen_order_;
196+
std::unordered_set<uint64_t> seen_packets_;
196197

197198
// Holds all possible fragments with sequence number
198199
std::unordered_map<uint16_t, uvgrtp::frame::rtp_frame*> fragments_;

0 commit comments

Comments
 (0)