mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00

This should mostly be a noop, but in a follow up cl we will insert all packets after splitting, which will allow for adapting the delay to FEC (both RED and codec inband) that is useful for decoding (i.e. not already covered by primary packets). A slight behavior change is that reordered packets are no longer included in max delay calculation. Implementation details: - A map ordered by RTP timestamp is used to store the arrivals. - When inserting new packets, we check if the timestamp is too old, already exists or if the packet is fully covered by another packet (based on timestamp and packet duration). - Separate deques are used to keep track of "min" and "max" arrivals (as defined by ordering operators). The queues maintain a strictly increasing/decreasing order so that min/max is always at begin(). Bug: webrtc:13322 Change-Id: I8b6cf5afff77b4adc3c29745b95627e955715b5a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337184 Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org> Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41656}
110 lines
4 KiB
C++
110 lines
4 KiB
C++
/*
|
|
* 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_AUDIO_CODING_NETEQ_PACKET_ARRIVAL_HISTORY_H_
|
|
#define MODULES_AUDIO_CODING_NETEQ_PACKET_ARRIVAL_HISTORY_H_
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <deque>
|
|
#include <map>
|
|
|
|
#include "api/neteq/tick_timer.h"
|
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// Stores timing information about previously received packets.
|
|
// The history has a fixed window size beyond which old data is automatically
|
|
// pruned.
|
|
class PacketArrivalHistory {
|
|
public:
|
|
explicit PacketArrivalHistory(const TickTimer* tick_timer,
|
|
int window_size_ms);
|
|
virtual ~PacketArrivalHistory() = default;
|
|
|
|
// Insert packet with `rtp_timestamp` into the history. Returns true if the
|
|
// packet was inserted, false if the timestamp is too old or if the timestamp
|
|
// already exists.
|
|
bool Insert(uint32_t rtp_timestamp, int packet_length_samples);
|
|
|
|
// The delay for `rtp_timestamp` at time `now` is calculated as
|
|
// `(now - p.arrival_timestamp) - (rtp_timestamp - p.rtp_timestamp)` where `p`
|
|
// is chosen as the packet arrival in the history that maximizes the delay.
|
|
virtual int GetDelayMs(uint32_t rtp_timestamp) const;
|
|
|
|
// Get the maximum packet arrival delay observed in the history, excluding
|
|
// reordered packets.
|
|
virtual int GetMaxDelayMs() const;
|
|
|
|
bool IsNewestRtpTimestamp(uint32_t rtp_timestamp) const;
|
|
|
|
void Reset();
|
|
|
|
void set_sample_rate(int sample_rate) {
|
|
sample_rate_khz_ = sample_rate / 1000;
|
|
}
|
|
|
|
size_t size() const { return history_.size(); }
|
|
|
|
private:
|
|
struct PacketArrival {
|
|
PacketArrival(int64_t rtp_timestamp,
|
|
int64_t arrival_timestamp,
|
|
int length_samples)
|
|
: rtp_timestamp(rtp_timestamp),
|
|
arrival_timestamp(arrival_timestamp),
|
|
length_samples(length_samples) {}
|
|
PacketArrival() = default;
|
|
int64_t rtp_timestamp;
|
|
int64_t arrival_timestamp;
|
|
int length_samples;
|
|
bool operator==(const PacketArrival& other) const {
|
|
return rtp_timestamp == other.rtp_timestamp &&
|
|
arrival_timestamp == other.arrival_timestamp &&
|
|
length_samples == other.length_samples;
|
|
}
|
|
bool operator!=(const PacketArrival& other) const {
|
|
return !(*this == other);
|
|
}
|
|
bool operator<=(const PacketArrival& other) const {
|
|
return arrival_timestamp - rtp_timestamp <=
|
|
other.arrival_timestamp - other.rtp_timestamp;
|
|
}
|
|
bool operator>=(const PacketArrival& other) const {
|
|
return arrival_timestamp - rtp_timestamp >=
|
|
other.arrival_timestamp - other.rtp_timestamp;
|
|
}
|
|
bool contains(const PacketArrival& other) const {
|
|
return rtp_timestamp <= other.rtp_timestamp &&
|
|
rtp_timestamp + length_samples >=
|
|
other.rtp_timestamp + other.length_samples;
|
|
}
|
|
};
|
|
int GetPacketArrivalDelayMs(const PacketArrival& packet_arrival) const;
|
|
// Checks if the packet is older than the window size.
|
|
bool IsObsolete(const PacketArrival& packet_arrival) const;
|
|
// Check if the packet exists or fully overlaps with a packet in the history.
|
|
bool Contains(const PacketArrival& packet_arrival) const;
|
|
const TickTimer* tick_timer_;
|
|
const int window_size_ms_;
|
|
int sample_rate_khz_ = 0;
|
|
RtpTimestampUnwrapper timestamp_unwrapper_;
|
|
// Packet history ordered by rtp timestamp.
|
|
std::map<int64_t, PacketArrival> history_;
|
|
// Tracks min/max packet arrivals in `history_` in ascending/descending order.
|
|
// Reordered packets are excluded.
|
|
std::deque<PacketArrival> min_packet_arrivals_;
|
|
std::deque<PacketArrival> max_packet_arrivals_;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // MODULES_AUDIO_CODING_NETEQ_PACKET_ARRIVAL_HISTORY_H_
|