diff --git a/api/transport/network_types.h b/api/transport/network_types.h index f45a35dbf0..f658b34494 100644 --- a/api/transport/network_types.h +++ b/api/transport/network_types.h @@ -103,7 +103,9 @@ struct PacedPacketInfo { struct SentPacket { Timestamp send_time = Timestamp::PlusInfinity(); + // Size of packet with overhead up to IP layer. DataSize size = DataSize::Zero(); + // Size of preceeding packets that are not part of feedback. DataSize prior_unacked_data = DataSize::Zero(); PacedPacketInfo pacing_info; // Transport independent sequence number, any tracked packet should have a diff --git a/api/units/timestamp.cc b/api/units/timestamp.cc index 0b9cdd9a21..fc4f419596 100644 --- a/api/units/timestamp.cc +++ b/api/units/timestamp.cc @@ -22,10 +22,12 @@ std::string ToString(Timestamp value) { } else if (value.IsMinusInfinity()) { sb << "-inf ms"; } else { - if (value.ms() % 1000 == 0) - sb << value.seconds() << " s"; - else + if (value.us() == 0 || (value.us() % 1000) != 0) + sb << value.us() << " us"; + else if (value.ms() % 1000 != 0) sb << value.ms() << " ms"; + else + sb << value.seconds() << " s"; } return sb.str(); } diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h index 259fbd4c74..82a8492466 100644 --- a/call/rtp_transport_controller_send.h +++ b/call/rtp_transport_controller_send.h @@ -179,7 +179,6 @@ class RtpTransportControllerSend final bool network_available_ RTC_GUARDED_BY(task_queue_); RepeatingTaskHandle pacer_queue_update_task_ RTC_GUARDED_BY(task_queue_); RepeatingTaskHandle controller_task_ RTC_GUARDED_BY(task_queue_); - // Protects access to last_packet_feedback_vector_ in feedback adapter. // TODO(srte): Remove this checker when feedback adapter runs on task queue. rtc::RaceChecker worker_race_; diff --git a/modules/congestion_controller/rtp/transport_feedback_adapter.cc b/modules/congestion_controller/rtp/transport_feedback_adapter.cc index e1395eb23c..b070b0e23a 100644 --- a/modules/congestion_controller/rtp/transport_feedback_adapter.cc +++ b/modules/congestion_controller/rtp/transport_feedback_adapter.cc @@ -25,69 +25,46 @@ #include "system_wrappers/include/field_trial.h" namespace webrtc { -namespace { -PacketResult NetworkPacketFeedbackFromRtpPacketFeedback( - const webrtc::PacketFeedback& pf) { - PacketResult feedback; - if (pf.arrival_time_ms == webrtc::PacketFeedback::kNotReceived) { - feedback.receive_time = Timestamp::PlusInfinity(); - } else { - feedback.receive_time = Timestamp::ms(pf.arrival_time_ms); - } - feedback.sent_packet.sequence_number = pf.sequence_number; - feedback.sent_packet.send_time = Timestamp::ms(pf.send_time_ms); - feedback.sent_packet.size = DataSize::bytes(pf.payload_size); - feedback.sent_packet.pacing_info = pf.pacing_info; - feedback.sent_packet.prior_unacked_data = - DataSize::bytes(pf.unacknowledged_data); - return feedback; -} -} // namespace -const int64_t kNoTimestamp = -1; -const int64_t kSendTimeHistoryWindowMs = 60000; +constexpr TimeDelta kSendTimeHistoryWindow = TimeDelta::Seconds<60>(); void InFlightBytesTracker::AddInFlightPacketBytes( const PacketFeedback& packet) { - RTC_DCHECK_NE(packet.send_time_ms, -1); - auto it = in_flight_bytes_.find({packet.local_net_id, packet.remote_net_id}); - if (it != in_flight_bytes_.end()) { - it->second += packet.payload_size; + RTC_DCHECK(packet.sent.send_time.IsFinite()); + auto it = in_flight_data_.find({packet.local_net_id, packet.remote_net_id}); + if (it != in_flight_data_.end()) { + it->second += packet.sent.size; } else { - in_flight_bytes_[{packet.local_net_id, packet.remote_net_id}] = - packet.payload_size; + in_flight_data_.insert( + {{packet.local_net_id, packet.remote_net_id}, packet.sent.size}); } } void InFlightBytesTracker::RemoveInFlightPacketBytes( const PacketFeedback& packet) { - if (packet.send_time_ms < 0) + if (packet.sent.send_time.IsInfinite()) return; - auto it = in_flight_bytes_.find({packet.local_net_id, packet.remote_net_id}); - if (it != in_flight_bytes_.end()) { - it->second -= packet.payload_size; - if (it->second == 0) - in_flight_bytes_.erase(it); + auto it = in_flight_data_.find({packet.local_net_id, packet.remote_net_id}); + if (it != in_flight_data_.end()) { + RTC_DCHECK_GE(it->second, packet.sent.size); + it->second -= packet.sent.size; + if (it->second.IsZero()) + in_flight_data_.erase(it); } } DataSize InFlightBytesTracker::GetOutstandingData( uint16_t local_net_id, uint16_t remote_net_id) const { - auto it = in_flight_bytes_.find({local_net_id, remote_net_id}); - if (it != in_flight_bytes_.end()) { - return DataSize::bytes(it->second); + auto it = in_flight_data_.find({local_net_id, remote_net_id}); + if (it != in_flight_data_.end()) { + return it->second; } else { return DataSize::Zero(); } } -TransportFeedbackAdapter::TransportFeedbackAdapter() - : packet_age_limit_ms_(kSendTimeHistoryWindowMs), - current_offset_ms_(kNoTimestamp), - last_timestamp_us_(kNoTimestamp), - local_net_id_(0), - remote_net_id_(0) {} +TransportFeedbackAdapter::TransportFeedbackAdapter() = default; TransportFeedbackAdapter::~TransportFeedbackAdapter() { RTC_DCHECK(observers_.empty()); @@ -120,72 +97,65 @@ void TransportFeedbackAdapter::AddPacket(const RtpPacketSendInfo& packet_info, { rtc::CritScope cs(&lock_); PacketFeedback packet; - packet.creation_time_ms = creation_time.ms(); - packet.sequence_number = + packet.creation_time = creation_time; + packet.sent.sequence_number = seq_num_unwrapper_.Unwrap(packet_info.transport_sequence_number); - packet.payload_size = packet_info.length + overhead_bytes; + packet.sent.size = DataSize::bytes(packet_info.length + overhead_bytes); packet.local_net_id = local_net_id_; packet.remote_net_id = remote_net_id_; - packet.pacing_info = packet_info.pacing_info; + packet.sent.pacing_info = packet_info.pacing_info; if (packet_info.has_rtp_sequence_number) { packet.ssrc = packet_info.ssrc; packet.rtp_sequence_number = packet_info.rtp_sequence_number; } while (!history_.empty() && - creation_time.ms() - history_.begin()->second.creation_time_ms > - packet_age_limit_ms_) { + creation_time - history_.begin()->second.creation_time > + kSendTimeHistoryWindow) { // TODO(sprang): Warn if erasing (too many) old items? - if (history_.begin()->second.sequence_number > last_ack_seq_num_) + if (history_.begin()->second.sent.sequence_number > last_ack_seq_num_) in_flight_.RemoveInFlightPacketBytes(history_.begin()->second); history_.erase(history_.begin()); } - history_.insert(std::make_pair(packet.sequence_number, packet)); + history_.insert(std::make_pair(packet.sent.sequence_number, packet)); } } absl::optional TransportFeedbackAdapter::ProcessSentPacket( const rtc::SentPacket& sent_packet) { rtc::CritScope cs(&lock_); + auto send_time = Timestamp::ms(sent_packet.send_time_ms); // TODO(srte): Only use one way to indicate that packet feedback is used. if (sent_packet.info.included_in_feedback || sent_packet.packet_id != -1) { int64_t unwrapped_seq_num = seq_num_unwrapper_.Unwrap(sent_packet.packet_id); auto it = history_.find(unwrapped_seq_num); if (it != history_.end()) { - bool packet_retransmit = it->second.send_time_ms >= 0; - it->second.send_time_ms = sent_packet.send_time_ms; - last_send_time_ms_ = - std::max(last_send_time_ms_, sent_packet.send_time_ms); + bool packet_retransmit = it->second.sent.send_time.IsFinite(); + it->second.sent.send_time = send_time; + last_send_time_ = std::max(last_send_time_, send_time); // TODO(srte): Don't do this on retransmit. - if (pending_untracked_size_ > 0) { - if (sent_packet.send_time_ms < last_untracked_send_time_ms_) + if (!pending_untracked_size_.IsZero()) { + if (send_time < last_untracked_send_time_) RTC_LOG(LS_WARNING) << "appending acknowledged data for out of order packet. (Diff: " - << last_untracked_send_time_ms_ - sent_packet.send_time_ms - << " ms.)"; - it->second.unacknowledged_data += pending_untracked_size_; - pending_untracked_size_ = 0; + << ToString(last_untracked_send_time_ - send_time) << " ms.)"; + it->second.sent.prior_unacked_data += pending_untracked_size_; + pending_untracked_size_ = DataSize::Zero(); } if (!packet_retransmit) { - if (it->second.sequence_number > last_ack_seq_num_) + if (it->second.sent.sequence_number > last_ack_seq_num_) in_flight_.AddInFlightPacketBytes(it->second); - auto packet = it->second; - SentPacket msg; - msg.size = DataSize::bytes(packet.payload_size); - msg.send_time = Timestamp::ms(packet.send_time_ms); - msg.sequence_number = packet.sequence_number; - msg.prior_unacked_data = DataSize::bytes(packet.unacknowledged_data); - msg.data_in_flight = GetOutstandingData(); - return msg; + it->second.sent.data_in_flight = GetOutstandingData(); + return it->second.sent; } } } else if (sent_packet.info.included_in_allocation) { - if (sent_packet.send_time_ms < last_send_time_ms_) { + if (send_time < last_send_time_) { RTC_LOG(LS_WARNING) << "ignoring untracked data for out of order packet."; } - pending_untracked_size_ += sent_packet.info.packet_size_bytes; - last_untracked_send_time_ms_ = - std::max(last_untracked_send_time_ms_, sent_packet.send_time_ms); + pending_untracked_size_ += + DataSize::bytes(sent_packet.info.packet_size_bytes); + last_untracked_send_time_ = std::max(last_untracked_send_time_, send_time); } return absl::nullopt; } @@ -205,22 +175,20 @@ TransportFeedbackAdapter::ProcessTransportFeedback( rtc::CritScope cs(&lock_); msg.prior_in_flight = in_flight_.GetOutstandingData(local_net_id_, remote_net_id_); - feedback_vector = ProcessTransportFeedbackInner(feedback, feedback_receive_time); - last_packet_feedback_vector_ = feedback_vector; - if (feedback_vector.empty()) return absl::nullopt; - for (const PacketFeedback& rtp_feedback : feedback_vector) { - msg.packet_feedbacks.push_back( - NetworkPacketFeedbackFromRtpPacketFeedback(rtp_feedback)); + for (const PacketFeedback& fb : feedback_vector) { + PacketResult res; + res.sent_packet = fb.sent; + res.receive_time = fb.receive_time; + msg.packet_feedbacks.push_back(res); } auto it = history_.find(last_ack_seq_num_); - if (it != history_.end() && - it->second.send_time_ms != PacketFeedback::kNoSendTime) { - msg.first_unacked_send_time = Timestamp::ms(it->second.send_time_ms); + if (it != history_.end()) { + msg.first_unacked_send_time = it->second.sent.send_time; } msg.data_in_flight = in_flight_.GetOutstandingData(local_net_id_, remote_net_id_); @@ -248,19 +216,21 @@ TransportFeedbackAdapter::ProcessTransportFeedbackInner( // Add timestamp deltas to a local time base selected on first packet arrival. // This won't be the true time base, but makes it easier to manually inspect // time stamps. - if (last_timestamp_us_ == kNoTimestamp) { - current_offset_ms_ = feedback_time.ms(); + if (last_timestamp_.IsInfinite()) { + current_offset_ = feedback_time; } else { - current_offset_ms_ += feedback.GetBaseDeltaUs(last_timestamp_us_) / 1000; + // TODO(srte): We shouldn't need to do rounding here. + current_offset_ += feedback.GetBaseDelta(last_timestamp_) + .RoundDownTo(TimeDelta::Millis<1>()); } - last_timestamp_us_ = feedback.GetBaseTimeUs(); + last_timestamp_ = feedback.GetBaseTime(); std::vector packet_feedback_vector; packet_feedback_vector.reserve(feedback.GetPacketStatusCount()); size_t failed_lookups = 0; size_t ignored = 0; - int64_t offset_us = 0; + TimeDelta packet_offset = TimeDelta::Zero(); for (const auto& packet : feedback.GetAllPackets()) { int64_t seq_num = seq_num_unwrapper_.Unwrap(packet.sequence_number()); @@ -280,7 +250,7 @@ TransportFeedbackAdapter::ProcessTransportFeedbackInner( continue; } - if (it->second.send_time_ms == PacketFeedback::kNoSendTime) { + if (it->second.sent.send_time.IsInfinite()) { // TODO(srte): Fix the tests that makes this happen and make this a // DCHECK. RTC_DLOG(LS_ERROR) @@ -289,13 +259,12 @@ TransportFeedbackAdapter::ProcessTransportFeedbackInner( } PacketFeedback packet_feedback = it->second; - if (!packet.received()) { - // Note: Element not removed from history because it might be reported - // as received by another feedback. - packet_feedback.arrival_time_ms = PacketFeedback::kNotReceived; - } else { - offset_us += packet.delta_us(); - packet_feedback.arrival_time_ms = current_offset_ms_ + (offset_us / 1000); + if (packet.received()) { + packet_offset += packet.delta(); + packet_feedback.receive_time = + current_offset_ + packet_offset.RoundDownTo(TimeDelta::Millis<1>()); + // Note: Lost packets are not removed from history because they might be + // reported as received by a later feedback. history_.erase(it); } if (packet_feedback.local_net_id == local_net_id_ && @@ -326,19 +295,10 @@ void TransportFeedbackAdapter::SignalObservers( std::vector selected_feedback; for (const auto& packet : feedback_vector) { if (packet.ssrc && absl::c_count(observer.first, *packet.ssrc) > 0) { - // If we found the ssrc, it means the the packet was in the - // history and we expect the the send time has been set. A reason why - // this would be false would be if ProcessTransportFeedback covering a - // packet would be called before ProcessSentPacket for the same - // packet. This should not happen if we handle ordering of events - // correctly. - RTC_DCHECK_NE(packet.send_time_ms, PacketFeedback::kNoSendTime); - StreamFeedbackObserver::StreamPacketInfo packet_info; packet_info.ssrc = *packet.ssrc; packet_info.rtp_sequence_number = packet.rtp_sequence_number; - packet_info.received = - packet.arrival_time_ms != PacketFeedback::kNotReceived; + packet_info.received = packet.receive_time.IsFinite(); selected_feedback.push_back(packet_info); } } @@ -348,10 +308,4 @@ void TransportFeedbackAdapter::SignalObservers( } } -std::vector -TransportFeedbackAdapter::GetTransportFeedbackVector() const { - rtc::CritScope cs(&lock_); - return last_packet_feedback_vector_; -} - } // namespace webrtc diff --git a/modules/congestion_controller/rtp/transport_feedback_adapter.h b/modules/congestion_controller/rtp/transport_feedback_adapter.h index ec4decbc8d..699c6ed489 100644 --- a/modules/congestion_controller/rtp/transport_feedback_adapter.h +++ b/modules/congestion_controller/rtp/transport_feedback_adapter.h @@ -28,36 +28,16 @@ namespace webrtc { struct PacketFeedback { PacketFeedback() = default; - static constexpr int kNotAProbe = -1; - static constexpr int64_t kNotReceived = -1; - static constexpr int64_t kNoSendTime = -1; - static constexpr int64_t kNoCreationTime = -1; - // NOTE! The variable |creation_time_ms| is not used when testing equality. - // This is due to |creation_time_ms| only being used by SendTimeHistory - // for book-keeping, and is of no interest outside that class. - // TODO(philipel): Remove |creation_time_ms| from PacketFeedback when cleaning - // up SendTimeHistory. // Time corresponding to when this object was created. - int64_t creation_time_ms = kNoCreationTime; + Timestamp creation_time = Timestamp::MinusInfinity(); + SentPacket sent; // Time corresponding to when the packet was received. Timestamped with the - // receiver's clock. For unreceived packet, the sentinel value kNotReceived - // is used. - int64_t arrival_time_ms = kNotReceived; - // Time corresponding to when the packet was sent, timestamped with the - // sender's clock. - int64_t send_time_ms = kNoSendTime; - // Session unique packet identifier, incremented with 1 for every packet - // generated by the sender. - int64_t sequence_number = 0; - // Size of the packet excluding RTP headers. - size_t payload_size = 0; - // Size of preceeding packets that are not part of feedback. - size_t unacknowledged_data = 0; + // receiver's clock. For unreceived packet, Timestamp::PlusInfinity() is used. + Timestamp receive_time = Timestamp::PlusInfinity(); + // The network route ids that this packet is associated with. uint16_t local_net_id = 0; uint16_t remote_net_id = 0; - // Pacing information about this packet. - PacedPacketInfo pacing_info; // The SSRC and RTP sequence number of the packet this feedback refers to. absl::optional ssrc; uint16_t rtp_sequence_number = 0; @@ -72,7 +52,7 @@ class InFlightBytesTracker { private: using RemoteAndLocalNetworkId = std::pair; - std::map in_flight_bytes_; + std::map in_flight_data_; }; class TransportFeedbackAdapter : public StreamFeedbackProvider { @@ -96,8 +76,6 @@ class TransportFeedbackAdapter : public StreamFeedbackProvider { const rtcp::TransportFeedback& feedback, Timestamp feedback_time); - std::vector GetTransportFeedbackVector() const; - void SetNetworkIds(uint16_t local_id, uint16_t remote_id); DataSize GetOutstandingData() const; @@ -115,11 +93,10 @@ class TransportFeedbackAdapter : public StreamFeedbackProvider { const std::vector& packet_feedback_vector); rtc::CriticalSection lock_; - - const int64_t packet_age_limit_ms_; - size_t pending_untracked_size_ RTC_GUARDED_BY(&lock_) = 0; - int64_t last_send_time_ms_ RTC_GUARDED_BY(&lock_) = -1; - int64_t last_untracked_send_time_ms_ RTC_GUARDED_BY(&lock_) = -1; + DataSize pending_untracked_size_ RTC_GUARDED_BY(&lock_) = DataSize::Zero(); + Timestamp last_send_time_ RTC_GUARDED_BY(&lock_) = Timestamp::MinusInfinity(); + Timestamp last_untracked_send_time_ RTC_GUARDED_BY(&lock_) = + Timestamp::MinusInfinity(); SequenceNumberUnwrapper seq_num_unwrapper_ RTC_GUARDED_BY(&lock_); std::map history_ RTC_GUARDED_BY(&lock_); @@ -128,12 +105,11 @@ class TransportFeedbackAdapter : public StreamFeedbackProvider { int64_t last_ack_seq_num_ RTC_GUARDED_BY(&lock_) = -1; InFlightBytesTracker in_flight_ RTC_GUARDED_BY(&lock_); - int64_t current_offset_ms_ RTC_GUARDED_BY(&lock_); - int64_t last_timestamp_us_ RTC_GUARDED_BY(&lock_); - std::vector last_packet_feedback_vector_ - RTC_GUARDED_BY(&lock_); - uint16_t local_net_id_ RTC_GUARDED_BY(&lock_); - uint16_t remote_net_id_ RTC_GUARDED_BY(&lock_); + Timestamp current_offset_ RTC_GUARDED_BY(&lock_) = Timestamp::MinusInfinity(); + TimeDelta last_timestamp_ RTC_GUARDED_BY(&lock_) = TimeDelta::MinusInfinity(); + + uint16_t local_net_id_ RTC_GUARDED_BY(&lock_) = 0; + uint16_t remote_net_id_ RTC_GUARDED_BY(&lock_) = 0; rtc::CriticalSection observers_lock_; // Maps a set of ssrcs to corresponding observer. Vectors are used rather than diff --git a/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc b/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc index 778935ed8c..e03bcc3750 100644 --- a/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc +++ b/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc @@ -36,8 +36,8 @@ const PacedPacketInfo kPacingInfo2(2, 14, 7000); const PacedPacketInfo kPacingInfo3(3, 20, 10000); const PacedPacketInfo kPacingInfo4(4, 22, 10000); -void ComparePacketFeedbackVectors(const std::vector& truth, - const std::vector& input) { +void ComparePacketFeedbackVectors(const std::vector& truth, + const std::vector& input) { ASSERT_EQ(truth.size(), input.size()); size_t len = truth.size(); // truth contains the input data for the test, and input is what will be @@ -47,32 +47,33 @@ void ComparePacketFeedbackVectors(const std::vector& truth, // base adjustment performed by the TransportFeedbackAdapter at the first // packet, the truth[x].arrival_time and input[x].arrival_time may not be // equal. However, the difference must be the same for all x. - int64_t arrival_time_delta = - truth[0].arrival_time_ms - input[0].arrival_time_ms; + TimeDelta arrival_time_delta = truth[0].receive_time - input[0].receive_time; for (size_t i = 0; i < len; ++i) { - RTC_CHECK(truth[i].arrival_time_ms != PacketFeedback::kNotReceived); - if (input[i].arrival_time_ms != PacketFeedback::kNotReceived) { - EXPECT_EQ(truth[i].arrival_time_ms, - input[i].arrival_time_ms + arrival_time_delta); + RTC_CHECK(truth[i].receive_time.IsFinite()); + if (input[i].receive_time.IsFinite()) { + EXPECT_EQ(truth[i].receive_time - input[i].receive_time, + arrival_time_delta); } - EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms); - EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number); - EXPECT_EQ(truth[i].payload_size, input[i].payload_size); - EXPECT_EQ(truth[i].pacing_info, input[i].pacing_info); + EXPECT_EQ(truth[i].sent_packet.send_time, input[i].sent_packet.send_time); + EXPECT_EQ(truth[i].sent_packet.sequence_number, + input[i].sent_packet.sequence_number); + EXPECT_EQ(truth[i].sent_packet.size, input[i].sent_packet.size); + EXPECT_EQ(truth[i].sent_packet.pacing_info, + input[i].sent_packet.pacing_info); } } -PacketFeedback CreatePacketFeedback(int64_t arrival_time_ms, - int64_t send_time_ms, - int64_t sequence_number, - size_t payload_size, - const PacedPacketInfo& pacing_info) { - PacketFeedback res; - res.arrival_time_ms = arrival_time_ms; - res.send_time_ms = send_time_ms; - res.sequence_number = sequence_number; - res.payload_size = payload_size; - res.pacing_info = pacing_info; +PacketResult CreatePacket(int64_t receive_time_ms, + int64_t send_time_ms, + int64_t sequence_number, + size_t payload_size, + const PacedPacketInfo& pacing_info) { + PacketResult res; + res.receive_time = Timestamp::ms(receive_time_ms); + res.sent_packet.send_time = Timestamp::ms(send_time_ms); + res.sent_packet.sequence_number = sequence_number; + res.sent_packet.size = DataSize::bytes(payload_size); + res.sent_packet.pacing_info = pacing_info; return res; } @@ -103,19 +104,20 @@ class TransportFeedbackAdapterTest : public ::testing::Test { int64_t rtt, int64_t now_ms) {} - void OnSentPacket(const PacketFeedback& packet_feedback) { + void OnSentPacket(const PacketResult& packet_feedback) { RtpPacketSendInfo packet_info; packet_info.ssrc = kSsrc; - packet_info.transport_sequence_number = packet_feedback.sequence_number; + packet_info.transport_sequence_number = + packet_feedback.sent_packet.sequence_number; packet_info.rtp_sequence_number = 0; packet_info.has_rtp_sequence_number = true; - packet_info.length = packet_feedback.payload_size; - packet_info.pacing_info = packet_feedback.pacing_info; + packet_info.length = packet_feedback.sent_packet.size.bytes(); + packet_info.pacing_info = packet_feedback.sent_packet.pacing_info; adapter_->AddPacket(RtpPacketSendInfo(packet_info), 0u, - Timestamp::ms(clock_.TimeInMilliseconds())); - adapter_->ProcessSentPacket(rtc::SentPacket(packet_feedback.sequence_number, - packet_feedback.send_time_ms, - rtc::PacketInfo())); + clock_.CurrentTime()); + adapter_->ProcessSentPacket(rtc::SentPacket( + packet_feedback.sent_packet.sequence_number, + packet_feedback.sent_packet.send_time.ms(), rtc::PacketInfo())); } static constexpr uint32_t kSsrc = 8492; @@ -128,39 +130,36 @@ TEST_F(TransportFeedbackAdapterTest, ObserverSanity) { MockStreamFeedbackObserver mock; adapter_->RegisterStreamFeedbackObserver({kSsrc}, &mock); - const std::vector packets = { - CreatePacketFeedback(100, 200, 0, 1000, kPacingInfo0), - CreatePacketFeedback(110, 210, 1, 2000, kPacingInfo0), - CreatePacketFeedback(120, 220, 2, 3000, kPacingInfo0)}; + const std::vector packets = { + CreatePacket(100, 200, 0, 1000, kPacingInfo0), + CreatePacket(110, 210, 1, 2000, kPacingInfo0), + CreatePacket(120, 220, 2, 3000, kPacingInfo0)}; rtcp::TransportFeedback feedback; - feedback.SetBase(packets[0].sequence_number, - packets[0].arrival_time_ms * 1000); + feedback.SetBase(packets[0].sent_packet.sequence_number, + packets[0].receive_time.us()); - for (const PacketFeedback& packet : packets) { + for (const auto& packet : packets) { OnSentPacket(packet); - EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, - packet.arrival_time_ms * 1000)); + EXPECT_TRUE(feedback.AddReceivedPacket(packet.sent_packet.sequence_number, + packet.receive_time.us())); } EXPECT_CALL(mock, OnPacketFeedbackVector(_)).Times(1); - adapter_->ProcessTransportFeedback( - feedback, Timestamp::ms(clock_.TimeInMilliseconds())); + adapter_->ProcessTransportFeedback(feedback, clock_.CurrentTime()); adapter_->DeRegisterStreamFeedbackObserver(&mock); - const PacketFeedback new_packet = - CreatePacketFeedback(130, 230, 3, 4000, kPacingInfo0); + auto new_packet = CreatePacket(130, 230, 3, 4000, kPacingInfo0); OnSentPacket(new_packet); rtcp::TransportFeedback second_feedback; - second_feedback.SetBase(new_packet.sequence_number, - new_packet.arrival_time_ms * 1000); + second_feedback.SetBase(new_packet.sent_packet.sequence_number, + new_packet.receive_time.us()); EXPECT_TRUE(second_feedback.AddReceivedPacket( - new_packet.sequence_number, new_packet.arrival_time_ms * 1000)); + new_packet.sent_packet.sequence_number, new_packet.receive_time.us())); EXPECT_CALL(mock, OnPacketFeedbackVector(_)).Times(0); - adapter_->ProcessTransportFeedback( - second_feedback, Timestamp::ms(clock_.TimeInMilliseconds())); + adapter_->ProcessTransportFeedback(second_feedback, clock_.CurrentTime()); } #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) @@ -180,163 +179,158 @@ TEST_F(TransportFeedbackAdapterTest, ObserverMissingDeRegistrationDeathTest) { #endif TEST_F(TransportFeedbackAdapterTest, AdaptsFeedbackAndPopulatesSendTimes) { - std::vector packets; - packets.push_back(CreatePacketFeedback(100, 200, 0, 1500, kPacingInfo0)); - packets.push_back(CreatePacketFeedback(110, 210, 1, 1500, kPacingInfo0)); - packets.push_back(CreatePacketFeedback(120, 220, 2, 1500, kPacingInfo0)); - packets.push_back(CreatePacketFeedback(130, 230, 3, 1500, kPacingInfo1)); - packets.push_back(CreatePacketFeedback(140, 240, 4, 1500, kPacingInfo1)); + std::vector packets; + packets.push_back(CreatePacket(100, 200, 0, 1500, kPacingInfo0)); + packets.push_back(CreatePacket(110, 210, 1, 1500, kPacingInfo0)); + packets.push_back(CreatePacket(120, 220, 2, 1500, kPacingInfo0)); + packets.push_back(CreatePacket(130, 230, 3, 1500, kPacingInfo1)); + packets.push_back(CreatePacket(140, 240, 4, 1500, kPacingInfo1)); - for (const PacketFeedback& packet : packets) + for (const auto& packet : packets) OnSentPacket(packet); rtcp::TransportFeedback feedback; - feedback.SetBase(packets[0].sequence_number, - packets[0].arrival_time_ms * 1000); + feedback.SetBase(packets[0].sent_packet.sequence_number, + packets[0].receive_time.us()); - for (const PacketFeedback& packet : packets) { - EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, - packet.arrival_time_ms * 1000)); + for (const auto& packet : packets) { + EXPECT_TRUE(feedback.AddReceivedPacket(packet.sent_packet.sequence_number, + packet.receive_time.us())); } feedback.Build(); - adapter_->ProcessTransportFeedback( - feedback, Timestamp::ms(clock_.TimeInMilliseconds())); - ComparePacketFeedbackVectors(packets, adapter_->GetTransportFeedbackVector()); + auto result = + adapter_->ProcessTransportFeedback(feedback, clock_.CurrentTime()); + ComparePacketFeedbackVectors(packets, result->packet_feedbacks); } TEST_F(TransportFeedbackAdapterTest, FeedbackVectorReportsUnreceived) { - std::vector sent_packets = { - CreatePacketFeedback(100, 220, 0, 1500, kPacingInfo0), - CreatePacketFeedback(110, 210, 1, 1500, kPacingInfo0), - CreatePacketFeedback(120, 220, 2, 1500, kPacingInfo0), - CreatePacketFeedback(130, 230, 3, 1500, kPacingInfo0), - CreatePacketFeedback(140, 240, 4, 1500, kPacingInfo0), - CreatePacketFeedback(150, 250, 5, 1500, kPacingInfo0), - CreatePacketFeedback(160, 260, 6, 1500, kPacingInfo0)}; + std::vector sent_packets = { + CreatePacket(100, 220, 0, 1500, kPacingInfo0), + CreatePacket(110, 210, 1, 1500, kPacingInfo0), + CreatePacket(120, 220, 2, 1500, kPacingInfo0), + CreatePacket(130, 230, 3, 1500, kPacingInfo0), + CreatePacket(140, 240, 4, 1500, kPacingInfo0), + CreatePacket(150, 250, 5, 1500, kPacingInfo0), + CreatePacket(160, 260, 6, 1500, kPacingInfo0)}; - for (const PacketFeedback& packet : sent_packets) + for (const auto& packet : sent_packets) OnSentPacket(packet); // Note: Important to include the last packet, as only unreceived packets in // between received packets can be inferred. - std::vector received_packets = { + std::vector received_packets = { sent_packets[0], sent_packets[2], sent_packets[6]}; rtcp::TransportFeedback feedback; - feedback.SetBase(received_packets[0].sequence_number, - received_packets[0].arrival_time_ms * 1000); + feedback.SetBase(received_packets[0].sent_packet.sequence_number, + received_packets[0].receive_time.us()); - for (const PacketFeedback& packet : received_packets) { - EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, - packet.arrival_time_ms * 1000)); + for (const auto& packet : received_packets) { + EXPECT_TRUE(feedback.AddReceivedPacket(packet.sent_packet.sequence_number, + packet.receive_time.us())); } feedback.Build(); - adapter_->ProcessTransportFeedback( - feedback, Timestamp::ms(clock_.TimeInMilliseconds())); - ComparePacketFeedbackVectors(sent_packets, - adapter_->GetTransportFeedbackVector()); + auto res = adapter_->ProcessTransportFeedback(feedback, clock_.CurrentTime()); + ComparePacketFeedbackVectors(sent_packets, res->packet_feedbacks); } TEST_F(TransportFeedbackAdapterTest, HandlesDroppedPackets) { - std::vector packets; - packets.push_back(CreatePacketFeedback(100, 200, 0, 1500, kPacingInfo0)); - packets.push_back(CreatePacketFeedback(110, 210, 1, 1500, kPacingInfo1)); - packets.push_back(CreatePacketFeedback(120, 220, 2, 1500, kPacingInfo2)); - packets.push_back(CreatePacketFeedback(130, 230, 3, 1500, kPacingInfo3)); - packets.push_back(CreatePacketFeedback(140, 240, 4, 1500, kPacingInfo4)); + std::vector packets; + packets.push_back(CreatePacket(100, 200, 0, 1500, kPacingInfo0)); + packets.push_back(CreatePacket(110, 210, 1, 1500, kPacingInfo1)); + packets.push_back(CreatePacket(120, 220, 2, 1500, kPacingInfo2)); + packets.push_back(CreatePacket(130, 230, 3, 1500, kPacingInfo3)); + packets.push_back(CreatePacket(140, 240, 4, 1500, kPacingInfo4)); const uint16_t kSendSideDropBefore = 1; const uint16_t kReceiveSideDropAfter = 3; - for (const PacketFeedback& packet : packets) { - if (packet.sequence_number >= kSendSideDropBefore) + for (const auto& packet : packets) { + if (packet.sent_packet.sequence_number >= kSendSideDropBefore) OnSentPacket(packet); } rtcp::TransportFeedback feedback; - feedback.SetBase(packets[0].sequence_number, - packets[0].arrival_time_ms * 1000); + feedback.SetBase(packets[0].sent_packet.sequence_number, + packets[0].receive_time.us()); - for (const PacketFeedback& packet : packets) { - if (packet.sequence_number <= kReceiveSideDropAfter) { - EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, - packet.arrival_time_ms * 1000)); + for (const auto& packet : packets) { + if (packet.sent_packet.sequence_number <= kReceiveSideDropAfter) { + EXPECT_TRUE(feedback.AddReceivedPacket(packet.sent_packet.sequence_number, + packet.receive_time.us())); } } feedback.Build(); - std::vector expected_packets( + std::vector expected_packets( packets.begin() + kSendSideDropBefore, packets.begin() + kReceiveSideDropAfter + 1); // Packets that have timed out on the send-side have lost the // information stored on the send-side. And they will not be reported to // observers since we won't know that they come from the same networks. - adapter_->ProcessTransportFeedback( - feedback, Timestamp::ms(clock_.TimeInMilliseconds())); - ComparePacketFeedbackVectors(expected_packets, - adapter_->GetTransportFeedbackVector()); + auto res = adapter_->ProcessTransportFeedback(feedback, clock_.CurrentTime()); + ComparePacketFeedbackVectors(expected_packets, res->packet_feedbacks); } TEST_F(TransportFeedbackAdapterTest, SendTimeWrapsBothWays) { int64_t kHighArrivalTimeMs = rtcp::TransportFeedback::kDeltaScaleFactor * static_cast(1 << 8) * static_cast((1 << 23) - 1) / 1000; - std::vector packets; - packets.push_back(CreatePacketFeedback(kHighArrivalTimeMs - 64, 200, 0, 1500, - PacedPacketInfo())); - packets.push_back(CreatePacketFeedback(kHighArrivalTimeMs + 64, 210, 1, 1500, - PacedPacketInfo())); - packets.push_back(CreatePacketFeedback(kHighArrivalTimeMs, 220, 2, 1500, - PacedPacketInfo())); + std::vector packets; + packets.push_back( + CreatePacket(kHighArrivalTimeMs - 64, 200, 0, 1500, PacedPacketInfo())); + packets.push_back( + CreatePacket(kHighArrivalTimeMs + 64, 210, 1, 1500, PacedPacketInfo())); + packets.push_back( + CreatePacket(kHighArrivalTimeMs, 220, 2, 1500, PacedPacketInfo())); - for (const PacketFeedback& packet : packets) + for (const auto& packet : packets) OnSentPacket(packet); for (size_t i = 0; i < packets.size(); ++i) { std::unique_ptr feedback( new rtcp::TransportFeedback()); - feedback->SetBase(packets[i].sequence_number, - packets[i].arrival_time_ms * 1000); + feedback->SetBase(packets[i].sent_packet.sequence_number, + packets[i].receive_time.us()); - EXPECT_TRUE(feedback->AddReceivedPacket(packets[i].sequence_number, - packets[i].arrival_time_ms * 1000)); + EXPECT_TRUE(feedback->AddReceivedPacket( + packets[i].sent_packet.sequence_number, packets[i].receive_time.us())); rtc::Buffer raw_packet = feedback->Build(); feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size()); - std::vector expected_packets; + std::vector expected_packets; expected_packets.push_back(packets[i]); - adapter_->ProcessTransportFeedback( - *feedback.get(), Timestamp::ms(clock_.TimeInMilliseconds())); - ComparePacketFeedbackVectors(expected_packets, - adapter_->GetTransportFeedbackVector()); + auto res = adapter_->ProcessTransportFeedback(*feedback.get(), + clock_.CurrentTime()); + ComparePacketFeedbackVectors(expected_packets, res->packet_feedbacks); } } TEST_F(TransportFeedbackAdapterTest, HandlesArrivalReordering) { - std::vector packets; - packets.push_back(CreatePacketFeedback(120, 200, 0, 1500, kPacingInfo0)); - packets.push_back(CreatePacketFeedback(110, 210, 1, 1500, kPacingInfo0)); - packets.push_back(CreatePacketFeedback(100, 220, 2, 1500, kPacingInfo0)); + std::vector packets; + packets.push_back(CreatePacket(120, 200, 0, 1500, kPacingInfo0)); + packets.push_back(CreatePacket(110, 210, 1, 1500, kPacingInfo0)); + packets.push_back(CreatePacket(100, 220, 2, 1500, kPacingInfo0)); - for (const PacketFeedback& packet : packets) + for (const auto& packet : packets) OnSentPacket(packet); rtcp::TransportFeedback feedback; - feedback.SetBase(packets[0].sequence_number, - packets[0].arrival_time_ms * 1000); + feedback.SetBase(packets[0].sent_packet.sequence_number, + packets[0].receive_time.us()); - for (const PacketFeedback& packet : packets) { - EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number, - packet.arrival_time_ms * 1000)); + for (const auto& packet : packets) { + EXPECT_TRUE(feedback.AddReceivedPacket(packet.sent_packet.sequence_number, + packet.receive_time.us())); } feedback.Build(); @@ -344,122 +338,126 @@ TEST_F(TransportFeedbackAdapterTest, HandlesArrivalReordering) { // Adapter keeps the packets ordered by sequence number (which is itself // assigned by the order of transmission). Reordering by some other criteria, // eg. arrival time, is up to the observers. - adapter_->ProcessTransportFeedback( - feedback, Timestamp::ms(clock_.TimeInMilliseconds())); - ComparePacketFeedbackVectors(packets, adapter_->GetTransportFeedbackVector()); + auto res = adapter_->ProcessTransportFeedback(feedback, clock_.CurrentTime()); + ComparePacketFeedbackVectors(packets, res->packet_feedbacks); } TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) { - std::vector sent_packets; - const int64_t kSmallDeltaUs = - rtcp::TransportFeedback::kDeltaScaleFactor * ((1 << 8) - 1); - const int64_t kLargePositiveDeltaUs = - rtcp::TransportFeedback::kDeltaScaleFactor * - std::numeric_limits::max(); - const int64_t kLargeNegativeDeltaUs = - rtcp::TransportFeedback::kDeltaScaleFactor * - std::numeric_limits::min(); + std::vector sent_packets; + // TODO(srte): Consider using us resolution in the constants. + const TimeDelta kSmallDelta = + TimeDelta::us(rtcp::TransportFeedback::kDeltaScaleFactor * 0xFF) + .RoundDownTo(TimeDelta::ms(1)); + const TimeDelta kLargePositiveDelta = + TimeDelta::us(rtcp::TransportFeedback::kDeltaScaleFactor * + std::numeric_limits::max()) + .RoundDownTo(TimeDelta::ms(1)); + const TimeDelta kLargeNegativeDelta = + TimeDelta::us(rtcp::TransportFeedback::kDeltaScaleFactor * + std::numeric_limits::min()) + .RoundDownTo(TimeDelta::ms(1)); - PacketFeedback packet_feedback; - packet_feedback.sequence_number = 1; - packet_feedback.send_time_ms = 100; - packet_feedback.arrival_time_ms = 200; - packet_feedback.payload_size = 1500; + PacketResult packet_feedback; + packet_feedback.sent_packet.sequence_number = 1; + packet_feedback.sent_packet.send_time = Timestamp::ms(100); + packet_feedback.receive_time = Timestamp::ms(200); + packet_feedback.sent_packet.size = DataSize::bytes(1500); sent_packets.push_back(packet_feedback); - packet_feedback.send_time_ms += kSmallDeltaUs / 1000; - packet_feedback.arrival_time_ms += kSmallDeltaUs / 1000; - ++packet_feedback.sequence_number; + // TODO(srte): This rounding maintains previous behavior, but should ot be + // required. + packet_feedback.sent_packet.send_time += kSmallDelta; + packet_feedback.receive_time += kSmallDelta; + ++packet_feedback.sent_packet.sequence_number; sent_packets.push_back(packet_feedback); - packet_feedback.send_time_ms += kLargePositiveDeltaUs / 1000; - packet_feedback.arrival_time_ms += kLargePositiveDeltaUs / 1000; - ++packet_feedback.sequence_number; + packet_feedback.sent_packet.send_time += kLargePositiveDelta; + packet_feedback.receive_time += kLargePositiveDelta; + ++packet_feedback.sent_packet.sequence_number; sent_packets.push_back(packet_feedback); - packet_feedback.send_time_ms += kLargeNegativeDeltaUs / 1000; - packet_feedback.arrival_time_ms += kLargeNegativeDeltaUs / 1000; - ++packet_feedback.sequence_number; + packet_feedback.sent_packet.send_time += kLargeNegativeDelta; + packet_feedback.receive_time += kLargeNegativeDelta; + ++packet_feedback.sent_packet.sequence_number; sent_packets.push_back(packet_feedback); // Too large, delta - will need two feedback messages. - packet_feedback.send_time_ms += (kLargePositiveDeltaUs + 1000) / 1000; - packet_feedback.arrival_time_ms += (kLargePositiveDeltaUs + 1000) / 1000; - ++packet_feedback.sequence_number; + packet_feedback.sent_packet.send_time += + kLargePositiveDelta + TimeDelta::ms(1); + packet_feedback.receive_time += kLargePositiveDelta + TimeDelta::ms(1); + ++packet_feedback.sent_packet.sequence_number; // Packets will be added to send history. - for (const PacketFeedback& packet : sent_packets) + for (const auto& packet : sent_packets) OnSentPacket(packet); OnSentPacket(packet_feedback); // Create expected feedback and send into adapter. std::unique_ptr feedback( new rtcp::TransportFeedback()); - feedback->SetBase(sent_packets[0].sequence_number, - sent_packets[0].arrival_time_ms * 1000); + feedback->SetBase(sent_packets[0].sent_packet.sequence_number, + sent_packets[0].receive_time.us()); - for (const PacketFeedback& packet : sent_packets) { - EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number, - packet.arrival_time_ms * 1000)); + for (const auto& packet : sent_packets) { + EXPECT_TRUE(feedback->AddReceivedPacket(packet.sent_packet.sequence_number, + packet.receive_time.us())); } - EXPECT_FALSE(feedback->AddReceivedPacket( - packet_feedback.sequence_number, packet_feedback.arrival_time_ms * 1000)); + EXPECT_FALSE( + feedback->AddReceivedPacket(packet_feedback.sent_packet.sequence_number, + packet_feedback.receive_time.us())); rtc::Buffer raw_packet = feedback->Build(); feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size()); - std::vector received_feedback; + std::vector received_feedback; EXPECT_TRUE(feedback.get() != nullptr); - adapter_->ProcessTransportFeedback( - *feedback.get(), Timestamp::ms(clock_.TimeInMilliseconds())); - ComparePacketFeedbackVectors(sent_packets, - adapter_->GetTransportFeedbackVector()); + auto res = + adapter_->ProcessTransportFeedback(*feedback.get(), clock_.CurrentTime()); + ComparePacketFeedbackVectors(sent_packets, res->packet_feedbacks); // Create a new feedback message and add the trailing item. feedback.reset(new rtcp::TransportFeedback()); - feedback->SetBase(packet_feedback.sequence_number, - packet_feedback.arrival_time_ms * 1000); - EXPECT_TRUE(feedback->AddReceivedPacket( - packet_feedback.sequence_number, packet_feedback.arrival_time_ms * 1000)); + feedback->SetBase(packet_feedback.sent_packet.sequence_number, + packet_feedback.receive_time.us()); + EXPECT_TRUE( + feedback->AddReceivedPacket(packet_feedback.sent_packet.sequence_number, + packet_feedback.receive_time.us())); raw_packet = feedback->Build(); feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size()); EXPECT_TRUE(feedback.get() != nullptr); - adapter_->ProcessTransportFeedback( - *feedback.get(), Timestamp::ms(clock_.TimeInMilliseconds())); { - std::vector expected_packets; + auto res = adapter_->ProcessTransportFeedback(*feedback.get(), + clock_.CurrentTime()); + std::vector expected_packets; expected_packets.push_back(packet_feedback); - ComparePacketFeedbackVectors(expected_packets, - adapter_->GetTransportFeedbackVector()); + ComparePacketFeedbackVectors(expected_packets, res->packet_feedbacks); } } TEST_F(TransportFeedbackAdapterTest, IgnoreDuplicatePacketSentCalls) { - const PacketFeedback packet = - CreatePacketFeedback(100, 200, 0, 1500, kPacingInfo0); + auto packet = CreatePacket(100, 200, 0, 1500, kPacingInfo0); // Add a packet and then mark it as sent. RtpPacketSendInfo packet_info; packet_info.ssrc = kSsrc; - packet_info.transport_sequence_number = packet.sequence_number; - packet_info.length = packet.payload_size; - packet_info.pacing_info = packet.pacing_info; - adapter_->AddPacket(packet_info, 0u, - Timestamp::ms(clock_.TimeInMilliseconds())); - absl::optional sent_packet = - adapter_->ProcessSentPacket(rtc::SentPacket( - packet.sequence_number, packet.send_time_ms, rtc::PacketInfo())); + packet_info.transport_sequence_number = packet.sent_packet.sequence_number; + packet_info.length = packet.sent_packet.size.bytes(); + packet_info.pacing_info = packet.sent_packet.pacing_info; + adapter_->AddPacket(packet_info, 0u, clock_.CurrentTime()); + absl::optional sent_packet = adapter_->ProcessSentPacket( + rtc::SentPacket(packet.sent_packet.sequence_number, + packet.sent_packet.send_time.ms(), rtc::PacketInfo())); EXPECT_TRUE(sent_packet.has_value()); // Call ProcessSentPacket() again with the same sequence number. This packet // has already been marked as sent and the call should be ignored. - absl::optional duplicate_packet = - adapter_->ProcessSentPacket(rtc::SentPacket( - packet.sequence_number, packet.send_time_ms, rtc::PacketInfo())); + absl::optional duplicate_packet = adapter_->ProcessSentPacket( + rtc::SentPacket(packet.sent_packet.sequence_number, + packet.sent_packet.send_time.ms(), rtc::PacketInfo())); EXPECT_FALSE(duplicate_packet.has_value()); } diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index fb1aca3bf3..55cda86435 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -106,6 +106,7 @@ rtc_library("rtp_rtcp_format") { "../../api:rtp_parameters", "../../api/audio_codecs:audio_codecs_api", "../../api/transport:network_control", + "../../api/units:time_delta", "../../api/video:video_frame", "../../api/video:video_rtp_headers", "../../common_video", diff --git a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc index 3dc4d8a3f7..2900fcec9e 100644 --- a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc +++ b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc @@ -376,6 +376,10 @@ int64_t TransportFeedback::GetBaseTimeUs() const { return static_cast(base_time_ticks_) * kBaseScaleFactor; } +TimeDelta TransportFeedback::GetBaseTime() const { + return TimeDelta::us(GetBaseTimeUs()); +} + int64_t TransportFeedback::GetBaseDeltaUs(int64_t prev_timestamp_us) const { int64_t delta = GetBaseTimeUs() - prev_timestamp_us; @@ -388,6 +392,10 @@ int64_t TransportFeedback::GetBaseDeltaUs(int64_t prev_timestamp_us) const { return delta; } +TimeDelta TransportFeedback::GetBaseDelta(TimeDelta prev_timestamp) const { + return TimeDelta::us(GetBaseDeltaUs(prev_timestamp.us())); +} + // De-serialize packet. bool TransportFeedback::Parse(const CommonHeader& packet) { RTC_DCHECK_EQ(packet.type(), kPacketType); diff --git a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h index 00c649663d..090abcc10a 100644 --- a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h +++ b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h @@ -14,6 +14,7 @@ #include #include +#include "api/units/time_delta.h" #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h" namespace webrtc { @@ -36,6 +37,7 @@ class TransportFeedback : public Rtpfb { uint16_t sequence_number() const { return sequence_number_; } int16_t delta_ticks() const { return delta_ticks_; } int32_t delta_us() const { return delta_ticks_ * kDeltaScaleFactor; } + TimeDelta delta() const { return TimeDelta::us(delta_us()); } bool received() const { return received_; } private: @@ -76,9 +78,11 @@ class TransportFeedback : public Rtpfb { // Get the reference time in microseconds, including any precision loss. int64_t GetBaseTimeUs() const; + TimeDelta GetBaseTime() const; // Get the unwrapped delta between current base time and |prev_timestamp_us|. int64_t GetBaseDeltaUs(int64_t prev_timestamp_us) const; + TimeDelta GetBaseDelta(TimeDelta prev_timestamp) const; // Does the feedback packet contain timestamp information? bool IncludeTimestamps() const { return include_timestamps_; }