In RemoteEstimatorProxy use Timestamp type
to assemble rtcp::TransportFeedback
Bug: webrtc:13757
Change-Id: I668d9e61d82b454a6884eff223804afc882d86a3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264900
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37192}
diff --git a/api/rtp_headers.h b/api/rtp_headers.h
index cf3d909..a640eb7 100644
--- a/api/rtp_headers.h
+++ b/api/rtp_headers.h
@@ -103,15 +103,6 @@
(1 << kAbsSendTimeFraction));
}
- TimeDelta GetAbsoluteSendTimeDelta(uint32_t previous_sendtime) const {
- RTC_DCHECK(hasAbsoluteSendTime);
- RTC_DCHECK(absoluteSendTime < (1ul << 24));
- RTC_DCHECK(previous_sendtime < (1ul << 24));
- int32_t delta =
- static_cast<int32_t>((absoluteSendTime - previous_sendtime) << 8) >> 8;
- return TimeDelta::Micros((delta * 1000000ll) / (1 << kAbsSendTimeFraction));
- }
-
bool hasTransmissionTimeOffset;
int32_t transmissionTimeOffset;
bool hasAbsoluteSendTime;
diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn
index 1cc69ae..9e2352f 100644
--- a/modules/remote_bitrate_estimator/BUILD.gn
+++ b/modules/remote_bitrate_estimator/BUILD.gn
@@ -128,6 +128,8 @@
"../../api/transport:network_control",
"../../api/units:data_rate",
"../../api/units:data_size",
+ "../../api/units:time_delta",
+ "../../api/units:timestamp",
"../../rtc_base",
"../../rtc_base:checks",
"../../rtc_base:random",
diff --git a/modules/remote_bitrate_estimator/packet_arrival_map.cc b/modules/remote_bitrate_estimator/packet_arrival_map.cc
index 72696f6..deeb208 100644
--- a/modules/remote_bitrate_estimator/packet_arrival_map.cc
+++ b/modules/remote_bitrate_estimator/packet_arrival_map.cc
@@ -18,19 +18,19 @@
constexpr size_t PacketArrivalTimeMap::kMaxNumberOfPackets;
void PacketArrivalTimeMap::AddPacket(int64_t sequence_number,
- int64_t arrival_time_ms) {
+ Timestamp arrival_time) {
if (!has_seen_packet_) {
// First packet.
has_seen_packet_ = true;
begin_sequence_number_ = sequence_number;
- arrival_times.push_back(arrival_time_ms);
+ arrival_times_.push_back(arrival_time);
return;
}
int64_t pos = sequence_number - begin_sequence_number_;
- if (pos >= 0 && pos < static_cast<int64_t>(arrival_times.size())) {
+ if (pos >= 0 && pos < static_cast<int64_t>(arrival_times_.size())) {
// The packet is within the buffer - no need to expand it.
- arrival_times[pos] = arrival_time_ms;
+ arrival_times_[pos] = arrival_time;
return;
}
@@ -38,14 +38,15 @@
// The packet goes before the current buffer. Expand to add packet, but only
// if it fits within kMaxNumberOfPackets.
size_t missing_packets = -pos;
- if (missing_packets + arrival_times.size() > kMaxNumberOfPackets) {
+ if (missing_packets + arrival_times_.size() > kMaxNumberOfPackets) {
// Don't expand the buffer further, as that would remove newly received
// packets.
return;
}
- arrival_times.insert(arrival_times.begin(), missing_packets, 0);
- arrival_times[0] = arrival_time_ms;
+ arrival_times_.insert(arrival_times_.begin(), missing_packets,
+ Timestamp::Zero());
+ arrival_times_[0] = arrival_time;
begin_sequence_number_ = sequence_number;
return;
}
@@ -55,20 +56,20 @@
if (static_cast<size_t>(pos) >= kMaxNumberOfPackets) {
// The buffer grows too large - old packets have to be removed.
size_t packets_to_remove = pos - kMaxNumberOfPackets + 1;
- if (packets_to_remove >= arrival_times.size()) {
- arrival_times.clear();
+ if (packets_to_remove >= arrival_times_.size()) {
+ arrival_times_.clear();
begin_sequence_number_ = sequence_number;
pos = 0;
} else {
// Also trim the buffer to remove leading non-received packets, to
// ensure that the buffer only spans received packets.
- while (packets_to_remove < arrival_times.size() &&
- arrival_times[packets_to_remove] == 0) {
+ while (packets_to_remove < arrival_times_.size() &&
+ arrival_times_[packets_to_remove] == Timestamp::Zero()) {
++packets_to_remove;
}
- arrival_times.erase(arrival_times.begin(),
- arrival_times.begin() + packets_to_remove);
+ arrival_times_.erase(arrival_times_.begin(),
+ arrival_times_.begin() + packets_to_remove);
begin_sequence_number_ += packets_to_remove;
pos -= packets_to_remove;
RTC_DCHECK_GE(pos, 0);
@@ -77,28 +78,29 @@
// Packets can be received out-of-order. If this isn't the next expected
// packet, add enough placeholders to fill the gap.
- size_t missing_gap_packets = pos - arrival_times.size();
+ size_t missing_gap_packets = pos - arrival_times_.size();
if (missing_gap_packets > 0) {
- arrival_times.insert(arrival_times.end(), missing_gap_packets, 0);
+ arrival_times_.insert(arrival_times_.end(), missing_gap_packets,
+ Timestamp::Zero());
}
- RTC_DCHECK_EQ(arrival_times.size(), pos);
- arrival_times.push_back(arrival_time_ms);
- RTC_DCHECK_LE(arrival_times.size(), kMaxNumberOfPackets);
+ RTC_DCHECK_EQ(arrival_times_.size(), pos);
+ arrival_times_.push_back(arrival_time);
+ RTC_DCHECK_LE(arrival_times_.size(), kMaxNumberOfPackets);
}
void PacketArrivalTimeMap::RemoveOldPackets(int64_t sequence_number,
- int64_t arrival_time_limit) {
- while (!arrival_times.empty() && begin_sequence_number_ < sequence_number &&
- arrival_times.front() <= arrival_time_limit) {
- arrival_times.pop_front();
+ Timestamp arrival_time_limit) {
+ while (!arrival_times_.empty() && begin_sequence_number_ < sequence_number &&
+ arrival_times_.front() <= arrival_time_limit) {
+ arrival_times_.pop_front();
++begin_sequence_number_;
}
}
bool PacketArrivalTimeMap::has_received(int64_t sequence_number) const {
int64_t pos = sequence_number - begin_sequence_number_;
- if (pos >= 0 && pos < static_cast<int64_t>(arrival_times.size()) &&
- arrival_times[pos] != 0) {
+ if (pos >= 0 && pos < static_cast<int64_t>(arrival_times_.size()) &&
+ arrival_times_[pos] != Timestamp::Zero()) {
return true;
}
return false;
@@ -108,9 +110,10 @@
if (sequence_number > begin_sequence_number_) {
size_t count =
std::min(static_cast<size_t>(sequence_number - begin_sequence_number_),
- arrival_times.size());
+ arrival_times_.size());
- arrival_times.erase(arrival_times.begin(), arrival_times.begin() + count);
+ arrival_times_.erase(arrival_times_.begin(),
+ arrival_times_.begin() + count);
begin_sequence_number_ += count;
}
}
diff --git a/modules/remote_bitrate_estimator/packet_arrival_map.h b/modules/remote_bitrate_estimator/packet_arrival_map.h
index 10659e0..8bda4a8 100644
--- a/modules/remote_bitrate_estimator/packet_arrival_map.h
+++ b/modules/remote_bitrate_estimator/packet_arrival_map.h
@@ -14,6 +14,7 @@
#include <cstdint>
#include <deque>
+#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
namespace webrtc {
@@ -43,15 +44,15 @@
// Returns the sequence number of the element just after the map, i.e. the
// sequence number that an `end()` iterator would represent.
int64_t end_sequence_number() const {
- return begin_sequence_number_ + arrival_times.size();
+ return begin_sequence_number_ + arrival_times_.size();
}
// Returns an element by `sequence_number`, which must be valid, i.e.
// between [begin_sequence_number, end_sequence_number).
- int64_t get(int64_t sequence_number) {
+ Timestamp get(int64_t sequence_number) {
int64_t pos = sequence_number - begin_sequence_number_;
- RTC_DCHECK(pos >= 0 && pos < static_cast<int64_t>(arrival_times.size()));
- return arrival_times[pos];
+ RTC_DCHECK(pos >= 0 && pos < static_cast<int64_t>(arrival_times_.size()));
+ return arrival_times_[pos];
}
// Clamps `sequence_number` between [begin_sequence_number,
@@ -63,19 +64,19 @@
// Records the fact that a packet with `sequence_number` arrived at
// `arrival_time_ms`.
- void AddPacket(int64_t sequence_number, int64_t arrival_time_ms);
+ void AddPacket(int64_t sequence_number, Timestamp arrival_time);
// Removes packets from the beginning of the map as long as they are received
// before `sequence_number` and with an age older than `arrival_time_limit`
- void RemoveOldPackets(int64_t sequence_number, int64_t arrival_time_limit);
+ void RemoveOldPackets(int64_t sequence_number, Timestamp arrival_time_limit);
private:
// Deque representing unwrapped sequence number -> time, where the index +
// `begin_sequence_number_` represents the packet's sequence number.
- std::deque<int64_t> arrival_times;
+ std::deque<Timestamp> arrival_times_;
// The unwrapped sequence number for the first element in
- // `arrival_times`.
+ // `arrival_times_`.
int64_t begin_sequence_number_ = 0;
// Indicates if this map has had any packet added to it. The first packet
diff --git a/modules/remote_bitrate_estimator/packet_arrival_map_test.cc b/modules/remote_bitrate_estimator/packet_arrival_map_test.cc
index afc7038..de50638 100644
--- a/modules/remote_bitrate_estimator/packet_arrival_map_test.cc
+++ b/modules/remote_bitrate_estimator/packet_arrival_map_test.cc
@@ -27,7 +27,7 @@
TEST(PacketArrivalMapTest, InsertsFirstItemIntoMap) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
+ map.AddPacket(42, Timestamp::Millis(10));
EXPECT_EQ(map.begin_sequence_number(), 42);
EXPECT_EQ(map.end_sequence_number(), 43);
@@ -43,8 +43,8 @@
TEST(PacketArrivalMapTest, InsertsWithGaps) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
- map.AddPacket(45, 11);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(45, Timestamp::Millis(11));
EXPECT_EQ(map.begin_sequence_number(), 42);
EXPECT_EQ(map.end_sequence_number(), 46);
@@ -55,10 +55,10 @@
EXPECT_TRUE(map.has_received(45));
EXPECT_FALSE(map.has_received(46));
- EXPECT_EQ(map.get(42), 10);
- EXPECT_EQ(map.get(43), 0);
- EXPECT_EQ(map.get(44), 0);
- EXPECT_EQ(map.get(45), 11);
+ EXPECT_EQ(map.get(42), Timestamp::Millis(10));
+ EXPECT_EQ(map.get(43), Timestamp::Zero());
+ EXPECT_EQ(map.get(44), Timestamp::Zero());
+ EXPECT_EQ(map.get(45), Timestamp::Millis(11));
EXPECT_EQ(map.clamp(-100), 42);
EXPECT_EQ(map.clamp(44), 44);
@@ -68,11 +68,11 @@
TEST(PacketArrivalMapTest, InsertsWithinBuffer) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
- map.AddPacket(45, 11);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(45, Timestamp::Millis(11));
- map.AddPacket(43, 12);
- map.AddPacket(44, 13);
+ map.AddPacket(43, Timestamp::Millis(12));
+ map.AddPacket(44, Timestamp::Millis(13));
EXPECT_EQ(map.begin_sequence_number(), 42);
EXPECT_EQ(map.end_sequence_number(), 46);
@@ -84,21 +84,21 @@
EXPECT_TRUE(map.has_received(45));
EXPECT_FALSE(map.has_received(46));
- EXPECT_EQ(map.get(42), 10);
- EXPECT_EQ(map.get(43), 12);
- EXPECT_EQ(map.get(44), 13);
- EXPECT_EQ(map.get(45), 11);
+ EXPECT_EQ(map.get(42), Timestamp::Millis(10));
+ EXPECT_EQ(map.get(43), Timestamp::Millis(12));
+ EXPECT_EQ(map.get(44), Timestamp::Millis(13));
+ EXPECT_EQ(map.get(45), Timestamp::Millis(11));
}
TEST(PacketArrivalMapTest, GrowsBufferAndRemoveOld) {
PacketArrivalTimeMap map;
constexpr int64_t kLargeSeq = 42 + PacketArrivalTimeMap::kMaxNumberOfPackets;
- map.AddPacket(42, 10);
- map.AddPacket(43, 11);
- map.AddPacket(44, 12);
- map.AddPacket(45, 13);
- map.AddPacket(kLargeSeq, 12);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(43, Timestamp::Millis(11));
+ map.AddPacket(44, Timestamp::Millis(12));
+ map.AddPacket(45, Timestamp::Millis(13));
+ map.AddPacket(kLargeSeq, Timestamp::Millis(12));
EXPECT_EQ(map.begin_sequence_number(), 43);
EXPECT_EQ(map.end_sequence_number(), kLargeSeq + 1);
@@ -120,10 +120,10 @@
PacketArrivalTimeMap map;
constexpr int64_t kLargeSeq = 42 + PacketArrivalTimeMap::kMaxNumberOfPackets;
- map.AddPacket(42, 10);
+ map.AddPacket(42, Timestamp::Millis(10));
// Missing: 43, 44
- map.AddPacket(45, 13);
- map.AddPacket(kLargeSeq, 12);
+ map.AddPacket(45, Timestamp::Millis(13));
+ map.AddPacket(kLargeSeq, Timestamp::Millis(12));
EXPECT_EQ(map.begin_sequence_number(), 45);
EXPECT_EQ(map.end_sequence_number(), kLargeSeq + 1);
@@ -140,8 +140,8 @@
constexpr int64_t kLargeSeq =
42 + 2 * PacketArrivalTimeMap::kMaxNumberOfPackets;
- map.AddPacket(42, 10);
- map.AddPacket(kLargeSeq, 12);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(kLargeSeq, Timestamp::Millis(12));
EXPECT_EQ(map.begin_sequence_number(), kLargeSeq);
EXPECT_EQ(map.end_sequence_number(), kLargeSeq + 1);
@@ -154,8 +154,8 @@
TEST(PacketArrivalMapTest, ExpandsBeforeBeginning) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
- map.AddPacket(-1000, 13);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(-1000, Timestamp::Millis(13));
EXPECT_EQ(map.begin_sequence_number(), -1000);
EXPECT_EQ(map.end_sequence_number(), 43);
@@ -170,10 +170,10 @@
TEST(PacketArrivalMapTest, ExpandingBeforeBeginningKeepsReceived) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
+ map.AddPacket(42, Timestamp::Millis(10));
constexpr int64_t kSmallSeq =
static_cast<int64_t>(42) - 2 * PacketArrivalTimeMap::kMaxNumberOfPackets;
- map.AddPacket(kSmallSeq, 13);
+ map.AddPacket(kSmallSeq, Timestamp::Millis(13));
EXPECT_EQ(map.begin_sequence_number(), 42);
EXPECT_EQ(map.end_sequence_number(), 43);
@@ -182,10 +182,10 @@
TEST(PacketArrivalMapTest, ErasesToRemoveElements) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
- map.AddPacket(43, 11);
- map.AddPacket(44, 12);
- map.AddPacket(45, 13);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(43, Timestamp::Millis(11));
+ map.AddPacket(44, Timestamp::Millis(12));
+ map.AddPacket(45, Timestamp::Millis(13));
map.EraseTo(44);
@@ -210,8 +210,8 @@
TEST(PacketArrivalMapTest, IsTolerantToWrongArgumentsForErase) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
- map.AddPacket(43, 11);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(43, Timestamp::Millis(11));
map.EraseTo(1);
@@ -227,14 +227,14 @@
TEST(PacketArrivalMapTest, EraseAllRemembersBeginningSeqNbr) {
PacketArrivalTimeMap map;
- map.AddPacket(42, 10);
- map.AddPacket(43, 11);
- map.AddPacket(44, 12);
- map.AddPacket(45, 13);
+ map.AddPacket(42, Timestamp::Millis(10));
+ map.AddPacket(43, Timestamp::Millis(11));
+ map.AddPacket(44, Timestamp::Millis(12));
+ map.AddPacket(45, Timestamp::Millis(13));
map.EraseTo(46);
- map.AddPacket(50, 10);
+ map.AddPacket(50, Timestamp::Millis(10));
EXPECT_EQ(map.begin_sequence_number(), 46);
EXPECT_EQ(map.end_sequence_number(), 51);
diff --git a/modules/remote_bitrate_estimator/remote_estimator_proxy.cc b/modules/remote_bitrate_estimator/remote_estimator_proxy.cc
index a570d5e..4691fa6 100644
--- a/modules/remote_bitrate_estimator/remote_estimator_proxy.cc
+++ b/modules/remote_bitrate_estimator/remote_estimator_proxy.cc
@@ -23,12 +23,28 @@
#include "system_wrappers/include/clock.h"
namespace webrtc {
-
+namespace {
// The maximum allowed value for a timestamp in milliseconds. This is lower
// than the numerical limit since we often convert to microseconds.
static constexpr int64_t kMaxTimeMs =
std::numeric_limits<int64_t>::max() / 1000;
+TimeDelta GetAbsoluteSendTimeDelta(uint32_t new_sendtime,
+ uint32_t previous_sendtime) {
+ static constexpr uint32_t kWrapAroundPeriod = 0x0100'0000;
+ RTC_DCHECK_LT(new_sendtime, kWrapAroundPeriod);
+ RTC_DCHECK_LT(previous_sendtime, kWrapAroundPeriod);
+ uint32_t delta = (new_sendtime - previous_sendtime) % kWrapAroundPeriod;
+ if (delta >= kWrapAroundPeriod / 2) {
+ // absolute send time wraps around, thus treat deltas larger than half of
+ // the wrap around period as negative. Ignore reordering of packets and
+ // treat them as they have approximately the same send time.
+ return TimeDelta::Zero();
+ }
+ return TimeDelta::Micros(int64_t{delta} * 1'000'000 / (1 << 18));
+}
+} // namespace
+
RemoteEstimatorProxy::RemoteEstimatorProxy(
Clock* clock,
TransportFeedbackSender feedback_sender,
@@ -54,14 +70,13 @@
RemoteEstimatorProxy::~RemoteEstimatorProxy() {}
void RemoteEstimatorProxy::MaybeCullOldPackets(int64_t sequence_number,
- int64_t arrival_time_ms) {
- if (periodic_window_start_seq_.has_value()) {
- if (*periodic_window_start_seq_ >=
- packet_arrival_times_.end_sequence_number()) {
- // Start new feedback packet, cull old packets.
- packet_arrival_times_.RemoveOldPackets(
- sequence_number, arrival_time_ms - send_config_.back_window->ms());
- }
+ Timestamp arrival_time) {
+ if (periodic_window_start_seq_ >=
+ packet_arrival_times_.end_sequence_number() &&
+ arrival_time - Timestamp::Zero() >= send_config_.back_window.Get()) {
+ // Start new feedback packet, cull old packets.
+ packet_arrival_times_.RemoveOldPackets(
+ sequence_number, arrival_time - send_config_.back_window.Get());
}
}
@@ -72,15 +87,30 @@
RTC_LOG(LS_WARNING) << "Arrival time out of bounds: " << arrival_time_ms;
return;
}
+ Packet packet = {.arrival_time = Timestamp::Millis(arrival_time_ms),
+ .size = DataSize::Bytes(header.headerLength + payload_size),
+ .ssrc = header.ssrc};
+ if (header.extension.hasTransportSequenceNumber) {
+ packet.transport_sequence_number = header.extension.transportSequenceNumber;
+ }
+ if (header.extension.hasAbsoluteSendTime) {
+ packet.absolute_send_time_24bits = header.extension.absoluteSendTime;
+ }
+ packet.feedback_request = header.extension.feedback_request;
+
+ IncomingPacket(packet);
+}
+
+void RemoteEstimatorProxy::IncomingPacket(Packet packet) {
MutexLock lock(&lock_);
- media_ssrc_ = header.ssrc;
+ media_ssrc_ = packet.ssrc;
int64_t seq = 0;
- if (header.extension.hasTransportSequenceNumber) {
- seq = unwrapper_.Unwrap(header.extension.transportSequenceNumber);
+ if (packet.transport_sequence_number.has_value()) {
+ seq = unwrapper_.Unwrap(*packet.transport_sequence_number);
if (send_periodic_feedback_) {
- MaybeCullOldPackets(seq, arrival_time_ms);
+ MaybeCullOldPackets(seq, packet.arrival_time);
if (!periodic_window_start_seq_ || seq < *periodic_window_start_seq_) {
periodic_window_start_seq_ = seq;
@@ -92,7 +122,7 @@
return;
}
- packet_arrival_times_.AddPacket(seq, arrival_time_ms);
+ packet_arrival_times_.AddPacket(seq, packet.arrival_time);
// Limit the range of sequence numbers to send feedback for.
if (!periodic_window_start_seq_.has_value() ||
@@ -102,24 +132,20 @@
packet_arrival_times_.begin_sequence_number();
}
- if (header.extension.feedback_request) {
+ if (packet.feedback_request) {
// Send feedback packet immediately.
- SendFeedbackOnRequest(seq, header.extension.feedback_request.value());
+ SendFeedbackOnRequest(seq, *packet.feedback_request);
}
}
- if (network_state_estimator_ && header.extension.hasAbsoluteSendTime) {
+ if (network_state_estimator_ && packet.absolute_send_time_24bits) {
PacketResult packet_result;
- packet_result.receive_time = Timestamp::Millis(arrival_time_ms);
- // Ignore reordering of packets and assume they have approximately the
- // same send time.
- abs_send_timestamp_ += std::max(
- header.extension.GetAbsoluteSendTimeDelta(previous_abs_send_time_),
- TimeDelta::Millis(0));
- previous_abs_send_time_ = header.extension.absoluteSendTime;
+ packet_result.receive_time = packet.arrival_time;
+ abs_send_timestamp_ += GetAbsoluteSendTimeDelta(
+ *packet.absolute_send_time_24bits, previous_abs_send_time_);
+ previous_abs_send_time_ = *packet.absolute_send_time_24bits;
packet_result.sent_packet.send_time = abs_send_timestamp_;
- packet_result.sent_packet.size =
- DataSize::Bytes(header.headerLength + payload_size) + packet_overhead_;
+ packet_result.sent_packet.size = packet.size + packet_overhead_;
packet_result.sent_packet.sequence_number = seq;
network_state_estimator_->OnReceivedPacket(packet_result);
}
@@ -274,8 +300,8 @@
int64_t next_sequence_number = begin_sequence_number_inclusive;
for (int64_t seq = start_seq; seq < end_seq; ++seq) {
- int64_t arrival_time_ms = packet_arrival_times_.get(seq);
- if (arrival_time_ms == 0) {
+ Timestamp arrival_time = packet_arrival_times_.get(seq);
+ if (arrival_time == Timestamp::Zero()) {
// Packet not received.
continue;
}
@@ -283,20 +309,18 @@
if (feedback_packet == nullptr) {
feedback_packet =
std::make_unique<rtcp::TransportFeedback>(include_timestamps);
- // TODO(sprang): Measure receive times in microseconds and remove the
- // conversions below.
feedback_packet->SetMediaSsrc(media_ssrc_);
// Base sequence number is the expected first sequence number. This is
// known, but we might not have actually received it, so the base time
// shall be the time of the first received packet in the feedback.
feedback_packet->SetBase(
static_cast<uint16_t>(begin_sequence_number_inclusive & 0xFFFF),
- arrival_time_ms * 1000);
+ arrival_time);
feedback_packet->SetFeedbackSequenceNumber(feedback_packet_count_++);
}
if (!feedback_packet->AddReceivedPacket(static_cast<uint16_t>(seq & 0xFFFF),
- arrival_time_ms * 1000)) {
+ arrival_time)) {
// Could not add timestamp, feedback packet might be full. Return and
// try again with a fresh packet.
break;
diff --git a/modules/remote_bitrate_estimator/remote_estimator_proxy.h b/modules/remote_bitrate_estimator/remote_estimator_proxy.h
index b4ec396..6aba92f 100644
--- a/modules/remote_bitrate_estimator/remote_estimator_proxy.h
+++ b/modules/remote_bitrate_estimator/remote_estimator_proxy.h
@@ -16,9 +16,12 @@
#include <memory>
#include <vector>
+#include "absl/types/optional.h"
#include "api/field_trials_view.h"
#include "api/transport/network_control.h"
#include "api/units/data_size.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "modules/remote_bitrate_estimator/packet_arrival_map.h"
#include "rtc_base/experiments/field_trial_parser.h"
@@ -47,6 +50,16 @@
NetworkStateEstimator* network_state_estimator);
~RemoteEstimatorProxy() override;
+ struct Packet {
+ Timestamp arrival_time;
+ DataSize size;
+ uint32_t ssrc;
+ absl::optional<uint32_t> absolute_send_time_24bits;
+ absl::optional<uint16_t> transport_sequence_number;
+ absl::optional<FeedbackRequest> feedback_request;
+ };
+ void IncomingPacket(Packet packet);
+
void IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header) override;
@@ -78,7 +91,7 @@
}
};
- void MaybeCullOldPackets(int64_t sequence_number, int64_t arrival_time_ms)
+ void MaybeCullOldPackets(int64_t sequence_number, Timestamp arrival_time)
RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
void SendPeriodicFeedbacks() RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
void SendFeedbackOnRequest(int64_t sequence_number,
diff --git a/modules/remote_bitrate_estimator/remote_estimator_proxy_unittest.cc b/modules/remote_bitrate_estimator/remote_estimator_proxy_unittest.cc
index 7ebfc8d..02d428f 100644
--- a/modules/remote_bitrate_estimator/remote_estimator_proxy_unittest.cc
+++ b/modules/remote_bitrate_estimator/remote_estimator_proxy_unittest.cc
@@ -17,12 +17,17 @@
#include "api/transport/network_types.h"
#include "api/transport/test/mock_network_control.h"
#include "api/units/data_size.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
#include "test/gtest.h"
+namespace webrtc {
+namespace {
+
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Invoke;
@@ -30,20 +35,18 @@
using ::testing::Return;
using ::testing::SizeIs;
-namespace webrtc {
-namespace {
-
-constexpr size_t kDefaultPacketSize = 100;
+constexpr DataSize kDefaultPacketSize = DataSize::Bytes(100);
constexpr uint32_t kMediaSsrc = 456;
constexpr uint16_t kBaseSeq = 10;
-constexpr int64_t kBaseTimeMs = 123;
-constexpr int64_t kMaxSmallDeltaMs =
- (rtcp::TransportFeedback::kDeltaScaleFactor * 0xFF) / 1000;
+constexpr Timestamp kBaseTime = Timestamp::Millis(123);
+constexpr TimeDelta kBaseTimeWrapAround =
+ rtcp::TransportFeedback::kDeltaTick * (int64_t{1} << 32);
+constexpr TimeDelta kMaxSmallDelta = rtcp::TransportFeedback::kDeltaTick * 0xFF;
-constexpr int kBackWindowMs = 500;
-constexpr int kMinSendIntervalMs = 50;
-constexpr int kMaxSendIntervalMs = 250;
-constexpr int kDefaultSendIntervalMs = 100;
+constexpr TimeDelta kBackWindow = TimeDelta::Millis(500);
+constexpr TimeDelta kMinSendInterval = TimeDelta::Millis(50);
+constexpr TimeDelta kMaxSendInterval = TimeDelta::Millis(250);
+constexpr TimeDelta kDefaultSendInterval = TimeDelta::Millis(100);
std::vector<uint16_t> SequenceNumbers(
const rtcp::TransportFeedback& feedback_packet) {
@@ -54,13 +57,20 @@
return sequence_numbers;
}
-std::vector<int64_t> TimestampsMs(
+std::vector<Timestamp> Timestamps(
const rtcp::TransportFeedback& feedback_packet) {
- std::vector<int64_t> timestamps;
- int64_t timestamp_us = feedback_packet.GetBaseTimeUs();
+ std::vector<Timestamp> timestamps;
+ Timestamp timestamp = feedback_packet.BaseTime();
+ // rtcp::TransportFeedback makes no promises about epoch of the base time,
+ // It may add several kBaseTimeWrapAround periods to make it large enough and
+ // thus to support negative deltas. Align it close to the kBaseTime to make
+ // tests expectations simpler.
+ if (timestamp > kBaseTime) {
+ timestamp -= (timestamp - kBaseTime).RoundTo(kBaseTimeWrapAround);
+ }
for (const auto& rtp_packet_received : feedback_packet.GetReceivedPackets()) {
- timestamp_us += rtp_packet_received.delta_us();
- timestamps.push_back(timestamp_us / 1000);
+ timestamp += rtp_packet_received.delta();
+ timestamps.push_back(timestamp);
}
return timestamps;
}
@@ -77,31 +87,17 @@
protected:
void IncomingPacket(
uint16_t seq,
- int64_t time_ms,
+ Timestamp arrival_time,
absl::optional<FeedbackRequest> feedback_request = absl::nullopt) {
- proxy_.IncomingPacket(time_ms, kDefaultPacketSize,
- CreateHeader(seq, feedback_request, absl::nullopt));
- }
-
- RTPHeader CreateHeader(absl::optional<uint16_t> transport_sequence,
- absl::optional<FeedbackRequest> feedback_request,
- absl::optional<uint32_t> absolute_send_time) {
- RTPHeader header;
- if (transport_sequence) {
- header.extension.hasTransportSequenceNumber = true;
- header.extension.transportSequenceNumber = transport_sequence.value();
- }
- header.extension.feedback_request = feedback_request;
- if (absolute_send_time) {
- header.extension.hasAbsoluteSendTime = true;
- header.extension.absoluteSendTime = absolute_send_time.value();
- }
- header.ssrc = kMediaSsrc;
- return header;
+ proxy_.IncomingPacket({.arrival_time = arrival_time,
+ .size = DataSize::Bytes(100),
+ .ssrc = kMediaSsrc,
+ .transport_sequence_number = seq,
+ .feedback_request = feedback_request});
}
void Process() {
- clock_.AdvanceTimeMilliseconds(kDefaultSendIntervalMs);
+ clock_.AdvanceTime(kDefaultSendInterval);
proxy_.Process();
}
@@ -114,7 +110,7 @@
};
TEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) {
- IncomingPacket(kBaseSeq, kBaseTimeMs);
+ IncomingPacket(kBaseSeq, kBaseTime);
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -127,16 +123,15 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs));
+ EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
}));
Process();
}
TEST_F(RemoteEstimatorProxyTest, DuplicatedPackets) {
- IncomingPacket(kBaseSeq, kBaseTimeMs);
- IncomingPacket(kBaseSeq, kBaseTimeMs + 1000);
+ IncomingPacket(kBaseSeq, kBaseTime);
+ IncomingPacket(kBaseSeq, kBaseTime + TimeDelta::Seconds(1));
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -149,8 +144,7 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs));
+ EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
return true;
}));
@@ -159,13 +153,13 @@
TEST_F(RemoteEstimatorProxyTest, FeedbackWithMissingStart) {
// First feedback.
- IncomingPacket(kBaseSeq, kBaseTimeMs);
- IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1000);
+ IncomingPacket(kBaseSeq, kBaseTime);
+ IncomingPacket(kBaseSeq + 1, kBaseTime + TimeDelta::Seconds(1));
EXPECT_CALL(feedback_sender_, Call);
Process();
// Second feedback starts with a missing packet (DROP kBaseSeq + 2).
- IncomingPacket(kBaseSeq + 3, kBaseTimeMs + 3000);
+ IncomingPacket(kBaseSeq + 3, kBaseTime + TimeDelta::Seconds(3));
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -178,17 +172,18 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 3));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + 3000));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + TimeDelta::Seconds(3)));
}));
Process();
}
TEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) {
- IncomingPacket(kBaseSeq, kBaseTimeMs);
- IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
- IncomingPacket(kBaseSeq + 2, kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1);
+ IncomingPacket(kBaseSeq, kBaseTime);
+ IncomingPacket(kBaseSeq + 1, kBaseTime + kMaxSmallDelta);
+ IncomingPacket(kBaseSeq + 2,
+ kBaseTime + (2 * kMaxSmallDelta) + TimeDelta::Millis(1));
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -201,20 +196,21 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq, kBaseSeq + 1, kBaseSeq + 2));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs, kBaseTimeMs + kMaxSmallDeltaMs,
- kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime, kBaseTime + kMaxSmallDelta,
+ kBaseTime + (2 * kMaxSmallDelta) +
+ TimeDelta::Millis(1)));
}));
Process();
}
TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
- static constexpr int64_t kTooLargeDelta =
- rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 16);
+ static constexpr TimeDelta kTooLargeDelta =
+ rtcp::TransportFeedback::kDeltaTick * (1 << 16);
- IncomingPacket(kBaseSeq, kBaseTimeMs);
- IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kTooLargeDelta);
+ IncomingPacket(kBaseSeq, kBaseTime);
+ IncomingPacket(kBaseSeq + 1, kBaseTime + kTooLargeDelta);
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -227,8 +223,7 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs));
+ EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
}))
.WillOnce(Invoke(
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
@@ -240,18 +235,18 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 1));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + kTooLargeDelta));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + kTooLargeDelta));
}));
Process();
}
TEST_F(RemoteEstimatorProxyTest, HandlesReorderingAndWrap) {
- const int64_t kDeltaMs = 1000;
+ const TimeDelta kDelta = TimeDelta::Seconds(1);
const uint16_t kLargeSeq = 62762;
- IncomingPacket(kBaseSeq, kBaseTimeMs);
- IncomingPacket(kLargeSeq, kBaseTimeMs + kDeltaMs);
+ IncomingPacket(kBaseSeq, kBaseTime);
+ IncomingPacket(kLargeSeq, kBaseTime + kDelta);
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -262,8 +257,8 @@
EXPECT_EQ(kLargeSeq, feedback_packet->GetBaseSequence());
EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + kDeltaMs, kBaseTimeMs));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + kDelta, kBaseTime));
}));
Process();
@@ -274,11 +269,11 @@
// When unwrapped, the sequeunce numbers of these 30 incoming packets, will
// span a range of roughly 650k packets. Test that we only send feedback for
// the last packets. Test for regression found in chromium:949020.
- const int64_t kDeltaMs = 1000;
+ const TimeDelta kDelta = TimeDelta::Seconds(1);
for (int i = 0; i < 10; ++i) {
- IncomingPacket(kBaseSeq + i, kBaseTimeMs + 3 * i * kDeltaMs);
- IncomingPacket(kBaseSeq + 20000 + i, kBaseTimeMs + (3 * i + 1) * kDeltaMs);
- IncomingPacket(kBaseSeq + 40000 + i, kBaseTimeMs + (3 * i + 2) * kDeltaMs);
+ IncomingPacket(kBaseSeq + i, kBaseTime + 3 * i * kDelta);
+ IncomingPacket(kBaseSeq + 20000 + i, kBaseTime + (3 * i + 1) * kDelta);
+ IncomingPacket(kBaseSeq + 40000 + i, kBaseTime + (3 * i + 2) * kDelta);
}
// Only expect feedback for the last two packets.
@@ -292,9 +287,9 @@
EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 20009, kBaseSeq + 40009));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + 28 * kDeltaMs,
- kBaseTimeMs + 29 * kDeltaMs));
+ EXPECT_THAT(
+ Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + 28 * kDelta, kBaseTime + 29 * kDelta));
}));
Process();
@@ -304,11 +299,11 @@
// This test is like HandlesMalformedSequenceNumbers but for negative wrap
// arounds. Test that we only send feedback for the packets with highest
// sequence numbers. Test for regression found in chromium:949020.
- const int64_t kDeltaMs = 1000;
+ const TimeDelta kDelta = TimeDelta::Seconds(1);
for (int i = 0; i < 10; ++i) {
- IncomingPacket(kBaseSeq + i, kBaseTimeMs + 3 * i * kDeltaMs);
- IncomingPacket(kBaseSeq + 40000 + i, kBaseTimeMs + (3 * i + 1) * kDeltaMs);
- IncomingPacket(kBaseSeq + 20000 + i, kBaseTimeMs + (3 * i + 2) * kDeltaMs);
+ IncomingPacket(kBaseSeq + i, kBaseTime + 3 * i * kDelta);
+ IncomingPacket(kBaseSeq + 40000 + i, kBaseTime + (3 * i + 1) * kDelta);
+ IncomingPacket(kBaseSeq + 20000 + i, kBaseTime + (3 * i + 2) * kDelta);
}
// Only expect feedback for the first two packets.
@@ -322,16 +317,16 @@
EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 40000, kBaseSeq));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + kDeltaMs, kBaseTimeMs));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + kDelta, kBaseTime));
}));
Process();
}
TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
- IncomingPacket(kBaseSeq, kBaseTimeMs);
- IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2);
+ IncomingPacket(kBaseSeq, kBaseTime);
+ IncomingPacket(kBaseSeq + 2, kBaseTime + TimeDelta::Millis(2));
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -344,13 +339,14 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq, kBaseSeq + 2));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs, kBaseTimeMs + 2));
+ EXPECT_THAT(
+ Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime, kBaseTime + TimeDelta::Millis(2)));
}));
Process();
- IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1);
+ IncomingPacket(kBaseSeq + 1, kBaseTime + TimeDelta::Millis(1));
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -363,17 +359,18 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 1, kBaseSeq + 2));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + 1, kBaseTimeMs + 2));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + TimeDelta::Millis(1),
+ kBaseTime + TimeDelta::Millis(2)));
}));
Process();
}
TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
- const int64_t kTimeoutTimeMs = kBaseTimeMs + kBackWindowMs;
+ const Timestamp kTimeoutTime = kBaseTime + kBackWindow;
- IncomingPacket(kBaseSeq + 2, kBaseTimeMs);
+ IncomingPacket(kBaseSeq + 2, kBaseTime);
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -383,13 +380,12 @@
feedback_packets[0].get());
EXPECT_EQ(kBaseSeq + 2, feedback_packet->GetBaseSequence());
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs));
+ EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
}));
Process();
- IncomingPacket(kBaseSeq + 3, kTimeoutTimeMs); // kBaseSeq + 2 times out here.
+ IncomingPacket(kBaseSeq + 3, kTimeoutTime); // kBaseSeq + 2 times out here.
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -399,16 +395,16 @@
feedback_packets[0].get());
EXPECT_EQ(kBaseSeq + 3, feedback_packet->GetBaseSequence());
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kTimeoutTimeMs));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kTimeoutTime));
}));
Process();
// New group, with sequence starting below the first so that they may be
// retransmitted.
- IncomingPacket(kBaseSeq, kBaseTimeMs - 1);
- IncomingPacket(kBaseSeq + 1, kTimeoutTimeMs - 1);
+ IncomingPacket(kBaseSeq, kBaseTime - TimeDelta::Millis(1));
+ IncomingPacket(kBaseSeq + 1, kTimeoutTime - TimeDelta::Millis(1));
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -420,9 +416,10 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq, kBaseSeq + 1, kBaseSeq + 3));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs - 1, kTimeoutTimeMs - 1,
- kTimeoutTimeMs));
+ EXPECT_THAT(
+ Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime - TimeDelta::Millis(1),
+ kTimeoutTime - TimeDelta::Millis(1), kTimeoutTime));
}));
Process();
@@ -434,13 +431,13 @@
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsDefaultOnUnkownBitrate) {
Process();
- EXPECT_EQ(kDefaultSendIntervalMs, proxy_.TimeUntilNextProcess());
+ EXPECT_EQ(proxy_.TimeUntilNextProcess(), kDefaultSendInterval.ms());
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMinIntervalOn300kbps) {
Process();
- proxy_.OnBitrateChanged(300000);
- EXPECT_EQ(kMinSendIntervalMs, proxy_.TimeUntilNextProcess());
+ proxy_.OnBitrateChanged(300'000);
+ EXPECT_EQ(proxy_.TimeUntilNextProcess(), kMinSendInterval.ms());
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn0kbps) {
@@ -449,13 +446,13 @@
// bitrate is small. We choose 0 bps as a special case, which also tests
// erroneous behaviors like division-by-zero.
proxy_.OnBitrateChanged(0);
- EXPECT_EQ(kMaxSendIntervalMs, proxy_.TimeUntilNextProcess());
+ EXPECT_EQ(proxy_.TimeUntilNextProcess(), kMaxSendInterval.ms());
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn20kbps) {
Process();
- proxy_.OnBitrateChanged(20000);
- EXPECT_EQ(kMaxSendIntervalMs, proxy_.TimeUntilNextProcess());
+ proxy_.OnBitrateChanged(20'000);
+ EXPECT_EQ(proxy_.TimeUntilNextProcess(), kMaxSendInterval.ms());
}
TEST_F(RemoteEstimatorProxyTest, TwccReportsUse5PercentOfAvailableBandwidth) {
@@ -477,16 +474,16 @@
TEST_F(RemoteEstimatorProxyOnRequestTest, ProcessDoesNotSendFeedback) {
proxy_.SetSendPeriodicFeedback(false);
- IncomingPacket(kBaseSeq, kBaseTimeMs);
+ IncomingPacket(kBaseSeq, kBaseTime);
EXPECT_CALL(feedback_sender_, Call).Times(0);
Process();
}
TEST_F(RemoteEstimatorProxyOnRequestTest, RequestSinglePacketFeedback) {
proxy_.SetSendPeriodicFeedback(false);
- IncomingPacket(kBaseSeq, kBaseTimeMs);
- IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
- IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2 * kMaxSmallDeltaMs);
+ IncomingPacket(kBaseSeq, kBaseTime);
+ IncomingPacket(kBaseSeq + 1, kBaseTime + kMaxSmallDelta);
+ IncomingPacket(kBaseSeq + 2, kBaseTime + 2 * kMaxSmallDelta);
EXPECT_CALL(feedback_sender_, Call)
.WillOnce(Invoke(
@@ -499,13 +496,13 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 3));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + 3 * kMaxSmallDeltaMs));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + 3 * kMaxSmallDelta));
}));
constexpr FeedbackRequest kSinglePacketFeedbackRequest = {
/*include_timestamps=*/true, /*sequence_count=*/1};
- IncomingPacket(kBaseSeq + 3, kBaseTimeMs + 3 * kMaxSmallDeltaMs,
+ IncomingPacket(kBaseSeq + 3, kBaseTime + 3 * kMaxSmallDelta,
kSinglePacketFeedbackRequest);
}
@@ -513,7 +510,7 @@
proxy_.SetSendPeriodicFeedback(false);
int i = 0;
for (; i < 10; ++i) {
- IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs);
+ IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta);
}
EXPECT_CALL(feedback_sender_, Call)
@@ -528,17 +525,17 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 6, kBaseSeq + 7, kBaseSeq + 8,
kBaseSeq + 9, kBaseSeq + 10));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + 6 * kMaxSmallDeltaMs,
- kBaseTimeMs + 7 * kMaxSmallDeltaMs,
- kBaseTimeMs + 8 * kMaxSmallDeltaMs,
- kBaseTimeMs + 9 * kMaxSmallDeltaMs,
- kBaseTimeMs + 10 * kMaxSmallDeltaMs));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + 6 * kMaxSmallDelta,
+ kBaseTime + 7 * kMaxSmallDelta,
+ kBaseTime + 8 * kMaxSmallDelta,
+ kBaseTime + 9 * kMaxSmallDelta,
+ kBaseTime + 10 * kMaxSmallDelta));
}));
constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
/*include_timestamps=*/true, /*sequence_count=*/5};
- IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs,
+ IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta,
kFivePacketsFeedbackRequest);
}
@@ -548,7 +545,7 @@
int i = 0;
for (; i < 10; ++i) {
if (i != 7 && i != 9)
- IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs);
+ IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta);
}
EXPECT_CALL(feedback_sender_, Call)
@@ -562,49 +559,51 @@
EXPECT_THAT(SequenceNumbers(*feedback_packet),
ElementsAre(kBaseSeq + 6, kBaseSeq + 8, kBaseSeq + 10));
- EXPECT_THAT(TimestampsMs(*feedback_packet),
- ElementsAre(kBaseTimeMs + 6 * kMaxSmallDeltaMs,
- kBaseTimeMs + 8 * kMaxSmallDeltaMs,
- kBaseTimeMs + 10 * kMaxSmallDeltaMs));
+ EXPECT_THAT(Timestamps(*feedback_packet),
+ ElementsAre(kBaseTime + 6 * kMaxSmallDelta,
+ kBaseTime + 8 * kMaxSmallDelta,
+ kBaseTime + 10 * kMaxSmallDelta));
}));
constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
/*include_timestamps=*/true, /*sequence_count=*/5};
- IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs,
+ IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta,
kFivePacketsFeedbackRequest);
}
TEST_F(RemoteEstimatorProxyTest, ReportsIncomingPacketToNetworkStateEstimator) {
Timestamp first_send_timestamp = Timestamp::Millis(0);
const DataSize kPacketOverhead = DataSize::Bytes(38);
- webrtc::RTPHeader first_header = CreateHeader(
- absl::nullopt, absl::nullopt, AbsoluteSendTime::MsTo24Bits(kBaseTimeMs));
proxy_.SetTransportOverhead(kPacketOverhead);
EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
.WillOnce(Invoke([&](const PacketResult& packet) {
- EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs));
- EXPECT_EQ(
- packet.sent_packet.size,
- DataSize::Bytes(kDefaultPacketSize + first_header.headerLength) +
- kPacketOverhead);
+ EXPECT_EQ(packet.receive_time, kBaseTime);
+ EXPECT_EQ(packet.sent_packet.size,
+ kDefaultPacketSize + kPacketOverhead);
first_send_timestamp = packet.sent_packet.send_time;
}));
// Incoming packet with abs sendtime but without transport sequence number.
- proxy_.IncomingPacket(kBaseTimeMs, kDefaultPacketSize, first_header);
+ proxy_.IncomingPacket({.arrival_time = kBaseTime,
+ .size = kDefaultPacketSize,
+ .ssrc = kMediaSsrc,
+ .absolute_send_time_24bits =
+ AbsoluteSendTime::MsTo24Bits(kBaseTime.ms())});
// Expect packet with older abs send time to be treated as sent at the same
// time as the previous packet due to reordering.
EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
.WillOnce(Invoke([&first_send_timestamp](const PacketResult& packet) {
- EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs));
+ EXPECT_EQ(packet.receive_time, kBaseTime);
EXPECT_EQ(packet.sent_packet.send_time, first_send_timestamp);
}));
proxy_.IncomingPacket(
- kBaseTimeMs, kDefaultPacketSize,
- CreateHeader(absl::nullopt, absl::nullopt,
- AbsoluteSendTime::MsTo24Bits(kBaseTimeMs - 12)));
+ {.arrival_time = kBaseTime,
+ .size = kDefaultPacketSize,
+ .ssrc = kMediaSsrc,
+ .absolute_send_time_24bits =
+ AbsoluteSendTime::MsTo24Bits(kBaseTime.ms() - 12)});
}
TEST_F(RemoteEstimatorProxyTest, IncomingPacketHandlesWrapInAbsSendTime) {
@@ -618,30 +617,36 @@
Timestamp first_send_timestamp = Timestamp::Millis(0);
EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
.WillOnce(Invoke([&first_send_timestamp](const PacketResult& packet) {
- EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs));
+ EXPECT_EQ(packet.receive_time, kBaseTime);
first_send_timestamp = packet.sent_packet.send_time;
}));
- proxy_.IncomingPacket(
- kBaseTimeMs, kDefaultPacketSize,
- CreateHeader(kBaseSeq, absl::nullopt, kFirstAbsSendTime));
+ proxy_.IncomingPacket({.arrival_time = kBaseTime,
+ .size = kDefaultPacketSize,
+ .ssrc = kMediaSsrc,
+ .absolute_send_time_24bits = kFirstAbsSendTime,
+ .transport_sequence_number = kBaseSeq});
EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
.WillOnce(Invoke([first_send_timestamp,
kExpectedAbsSendTimeDelta](const PacketResult& packet) {
- EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs + 123));
+ EXPECT_EQ(packet.receive_time, kBaseTime + TimeDelta::Millis(123));
EXPECT_EQ(packet.sent_packet.send_time.ms(),
(first_send_timestamp + kExpectedAbsSendTimeDelta).ms());
}));
- proxy_.IncomingPacket(
- kBaseTimeMs + 123, kDefaultPacketSize,
- CreateHeader(kBaseSeq + 1, absl::nullopt, kSecondAbsSendTime));
+ proxy_.IncomingPacket({.arrival_time = kBaseTime + TimeDelta::Millis(123),
+ .size = kDefaultPacketSize,
+ .ssrc = kMediaSsrc,
+ .absolute_send_time_24bits = kSecondAbsSendTime,
+ .transport_sequence_number = kBaseSeq + 1});
}
TEST_F(RemoteEstimatorProxyTest, SendTransportFeedbackAndNetworkStateUpdate) {
- proxy_.IncomingPacket(
- kBaseTimeMs, kDefaultPacketSize,
- CreateHeader(kBaseSeq, absl::nullopt,
- AbsoluteSendTime::MsTo24Bits(kBaseTimeMs - 1)));
+ proxy_.IncomingPacket({.arrival_time = kBaseTime,
+ .size = kDefaultPacketSize,
+ .ssrc = kMediaSsrc,
+ .absolute_send_time_24bits =
+ AbsoluteSendTime::MsTo24Bits(kBaseTime.ms() - 1),
+ .transport_sequence_number = kBaseSeq});
EXPECT_CALL(network_state_estimator_, GetCurrentEstimate())
.WillOnce(Return(NetworkStateEstimate()));
EXPECT_CALL(feedback_sender_, Call(SizeIs(2)));