diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index 4a627e15a1..4cb4396553 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -652,6 +652,7 @@ if (rtc_include_tests) { "../../api/transport/rtp:dependency_descriptor", "../../api/units:data_rate", "../../api/units:data_size", + "../../api/units:frequency", "../../api/units:time_delta", "../../api/units:timestamp", "../../api/video:encoded_image", diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc index 8d57f39e98..6b4c756d44 100644 --- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -15,6 +15,9 @@ #include "absl/strings/string_view.h" #include "api/rtc_event_log/rtc_event.h" +#include "api/units/frequency.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" #include "api/video/video_codec_constants.h" #include "api/video/video_timing.h" #include "logging/rtc_event_log/mock/mock_rtc_event_log.h" @@ -67,7 +70,7 @@ const uint32_t kFlexFecSsrc = 45678; const uint64_t kStartTime = 123456789; const uint8_t kPayloadData[] = {47, 11, 32, 93, 89}; constexpr TimeDelta kDefaultExpectedRetransmissionTime = TimeDelta::Millis(125); -constexpr uint32_t kTimestampTicksPerMs = 90; // 90kHz clock. +constexpr Frequency kRtpClockRate = Frequency::Hertz(90'000); constexpr absl::string_view kMid = "mid"; constexpr absl::string_view kRid = "f"; constexpr bool kMarkerBit = true; @@ -101,6 +104,11 @@ class MockRtpPacketPacer : public RtpPacketSender { MOCK_METHOD(void, RemovePacketsForSsrc, (uint32_t), (override)); }; +uint32_t ToRtpTimestamp(Timestamp time) { + return static_cast((time - Timestamp::Zero()) * kRtpClockRate) & + 0xFFFF'FFFF; +} + } // namespace class RtpSenderTest : public ::testing::Test { @@ -172,22 +180,22 @@ class RtpSenderTest : public ::testing::Test { std::unique_ptr BuildRtpPacket(int payload_type, bool marker_bit, - uint32_t timestamp, - int64_t capture_time_ms) { + uint32_t rtp_timestamp, + Timestamp capture_time) { auto packet = rtp_sender_->AllocatePacket(); packet->SetPayloadType(payload_type); packet->set_packet_type(RtpPacketMediaType::kVideo); packet->SetMarker(marker_bit); - packet->SetTimestamp(timestamp); - packet->set_capture_time(Timestamp::Millis(capture_time_ms)); + packet->SetTimestamp(rtp_timestamp); + packet->set_capture_time(capture_time); return packet; } - std::unique_ptr SendPacket(int64_t capture_time_ms, + std::unique_ptr SendPacket(Timestamp capture_time, int payload_length) { - uint32_t timestamp = capture_time_ms * 90; + uint32_t rtp_timestamp = ToRtpTimestamp(capture_time); auto packet = - BuildRtpPacket(kPayload, kMarkerBit, timestamp, capture_time_ms); + BuildRtpPacket(kPayload, kMarkerBit, rtp_timestamp, capture_time); packet->AllocatePayload(payload_length); packet->set_allow_retransmission(true); @@ -198,11 +206,10 @@ class RtpSenderTest : public ::testing::Test { } std::unique_ptr SendGenericPacket() { - const int64_t kCaptureTimeMs = clock_->TimeInMilliseconds(); // Use maximum allowed size to catch corner cases when packet is dropped // because of lack of capacity for the media packet, or for an rtx packet // containing the media packet. - return SendPacket(kCaptureTimeMs, + return SendPacket(/*capture_time=*/clock_->CurrentTime(), /*payload_length=*/rtp_sender_->MaxRtpPacketSize() - rtp_sender_->ExpectedPerPacketOverhead()); } @@ -333,32 +340,31 @@ TEST_F(RtpSenderTest, PaddingAlwaysAllowedOnAudio) { } TEST_F(RtpSenderTest, SendToNetworkForwardsPacketsToPacer) { - auto packet = BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, 0); + auto packet = + BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, Timestamp::Zero()); Timestamp now = clock_->CurrentTime(); EXPECT_CALL(mock_paced_sender_, EnqueuePackets(ElementsAre(AllOf( Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::capture_time, now)))))); - EXPECT_TRUE( - rtp_sender_->SendToNetwork(std::make_unique(*packet))); + EXPECT_TRUE(rtp_sender_->SendToNetwork(std::move(packet))); } TEST_F(RtpSenderTest, ReSendPacketForwardsPacketsToPacer) { packet_history_->SetStorePacketsStatus( RtpPacketHistory::StorageMode::kStoreAndCull, 10); - int64_t now_ms = clock_->TimeInMilliseconds(); - auto packet = BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, now_ms); + Timestamp now = clock_->CurrentTime(); + auto packet = BuildRtpPacket(kPayload, kMarkerBit, kTimestamp, now); packet->SetSequenceNumber(kSeqNum); packet->set_allow_retransmission(true); - packet_history_->PutRtpPacket(std::move(packet), Timestamp::Millis(now_ms)); + packet_history_->PutRtpPacket(std::move(packet), now); EXPECT_CALL(mock_paced_sender_, EnqueuePackets(ElementsAre(AllOf( Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc)), Pointee(Property(&RtpPacketToSend::SequenceNumber, kSeqNum)), - Pointee(Property(&RtpPacketToSend::capture_time, - Timestamp::Millis(now_ms))), + Pointee(Property(&RtpPacketToSend::capture_time, now)), Pointee(Property(&RtpPacketToSend::packet_type, RtpPacketMediaType::kRetransmission)))))); EXPECT_TRUE(rtp_sender_->ReSendPacket(kSeqNum)); @@ -370,7 +376,7 @@ TEST_F(RtpSenderTest, SendPadding) { constexpr int kNumPaddingPackets = 4; EXPECT_CALL(mock_paced_sender_, EnqueuePackets); std::unique_ptr media_packet = - SendPacket(/*capture_time_ms=*/clock_->TimeInMilliseconds(), + SendPacket(/*capture_time=*/clock_->CurrentTime(), /*payload_size=*/100); sequencer_->Sequence(*media_packet); @@ -403,7 +409,7 @@ TEST_F(RtpSenderTest, SendPadding) { &RtpPacketToSend::Timestamp, Gt(media_packet->Timestamp())))))); std::unique_ptr next_media_packet = - SendPacket(/*capture_time_ms=*/clock_->TimeInMilliseconds(), + SendPacket(/*capture_time=*/clock_->CurrentTime(), /*payload_size=*/100); } @@ -501,17 +507,16 @@ TEST_F(RtpSenderTest, AllowPaddingAsFirstPacketOnRtxWithAbsSendTime) { TEST_F(RtpSenderTest, UpdatesTimestampsOnPlainRtxPadding) { EnableRtx(); // Timestamps as set based on capture time in RtpSenderTest. - const int64_t start_time = clock_->TimeInMilliseconds(); - const uint32_t start_timestamp = start_time * kTimestampTicksPerMs; + const Timestamp start_time = clock_->CurrentTime(); + const uint32_t start_timestamp = ToRtpTimestamp(start_time); // Start by sending one media packet. EXPECT_CALL( mock_paced_sender_, - EnqueuePackets(ElementsAre( - AllOf(Pointee(Property(&RtpPacketToSend::padding_size, 0u)), - Pointee(Property(&RtpPacketToSend::Timestamp, start_timestamp)), - Pointee(Property(&RtpPacketToSend::capture_time, - Timestamp::Millis(start_time))))))); + EnqueuePackets(ElementsAre(AllOf( + Pointee(Property(&RtpPacketToSend::padding_size, 0u)), + Pointee(Property(&RtpPacketToSend::Timestamp, start_timestamp)), + Pointee(Property(&RtpPacketToSend::capture_time, start_time)))))); std::unique_ptr media_packet = SendPacket(start_time, /*payload_size=*/600); sequencer_->Sequence(*media_packet); @@ -526,9 +531,8 @@ TEST_F(RtpSenderTest, UpdatesTimestampsOnPlainRtxPadding) { Each(Pointee(AllOf( Property(&RtpPacketToSend::padding_size, kMaxPaddingLength), Property(&RtpPacketToSend::Timestamp, - start_timestamp + (kTimestampTicksPerMs * kTimeDiff.ms())), - Property(&RtpPacketToSend::capture_time, - Timestamp::Millis(start_time) + kTimeDiff))))); + start_timestamp + kRtpClockRate * kTimeDiff), + Property(&RtpPacketToSend::capture_time, start_time + kTimeDiff))))); } TEST_F(RtpSenderTest, KeepsTimestampsOnPayloadPadding) { @@ -536,37 +540,35 @@ TEST_F(RtpSenderTest, KeepsTimestampsOnPayloadPadding) { TransportSequenceNumber::Uri(), kTransportSequenceNumberExtensionId)); EnableRtx(); // Timestamps as set based on capture time in RtpSenderTest. - const int64_t start_time = clock_->TimeInMilliseconds(); - const uint32_t start_timestamp = start_time * kTimestampTicksPerMs; + const Timestamp start_time = clock_->CurrentTime(); + const uint32_t start_timestamp = ToRtpTimestamp(start_time); const size_t kPayloadSize = 200; const size_t kRtxHeaderSize = 2; // Start by sending one media packet and putting in the packet history. EXPECT_CALL( mock_paced_sender_, - EnqueuePackets(ElementsAre( - AllOf(Pointee(Property(&RtpPacketToSend::padding_size, 0u)), - Pointee(Property(&RtpPacketToSend::Timestamp, start_timestamp)), - Pointee(Property(&RtpPacketToSend::capture_time, - Timestamp::Millis(start_time))))))); + EnqueuePackets(ElementsAre(AllOf( + Pointee(Property(&RtpPacketToSend::padding_size, 0u)), + Pointee(Property(&RtpPacketToSend::Timestamp, start_timestamp)), + Pointee(Property(&RtpPacketToSend::capture_time, start_time)))))); std::unique_ptr media_packet = SendPacket(start_time, kPayloadSize); - packet_history_->PutRtpPacket(std::move(media_packet), - Timestamp::Millis(start_time)); + packet_history_->PutRtpPacket(std::move(media_packet), start_time); // Advance time before sending padding. const TimeDelta kTimeDiff = TimeDelta::Millis(17); time_controller_.AdvanceTime(kTimeDiff); // Timestamps on payload padding should be set to original. - EXPECT_THAT(GeneratePadding(/*target_size_bytes=*/100), - Each(AllOf(Pointee(Property(&RtpPacketToSend::padding_size, 0u)), - Pointee(Property(&RtpPacketToSend::payload_size, - kPayloadSize + kRtxHeaderSize)), - Pointee(Property(&RtpPacketToSend::Timestamp, - start_timestamp)), - Pointee(Property(&RtpPacketToSend::capture_time, - Timestamp::Millis(start_time)))))); + EXPECT_THAT( + GeneratePadding(/*target_size_bytes=*/100), + Each(AllOf( + Pointee(Property(&RtpPacketToSend::padding_size, 0u)), + Pointee(Property(&RtpPacketToSend::payload_size, + kPayloadSize + kRtxHeaderSize)), + Pointee(Property(&RtpPacketToSend::Timestamp, start_timestamp)), + Pointee(Property(&RtpPacketToSend::capture_time, start_time))))); } // Test that the MID header extension is included on sent packets when @@ -830,8 +832,8 @@ TEST_F(RtpSenderTest, RespectsNackBitrateLimit) { std::vector sequence_numbers; for (int32_t i = 0; i < kNumPackets; ++i) { std::unique_ptr packet = - BuildRtpPacket(kPayload, /*marker_bit=*/true, /*timestamp=*/0, - /*capture_time_ms=*/clock_->TimeInMilliseconds()); + BuildRtpPacket(kPayload, /*marker_bit=*/true, /*rtp_timestamp=*/0, + /*capture_time=*/clock_->CurrentTime()); packet->set_allow_retransmission(true); sequencer_->Sequence(*packet); sequence_numbers.push_back(packet->SequenceNumber()); @@ -982,7 +984,7 @@ TEST_F(RtpSenderTest, SendPacketHandlesRetransmissionHistory) { // Build a media packet and put in the packet history. std::unique_ptr packet = - BuildRtpPacket(kPayload, true, 0, clock_->TimeInMilliseconds()); + BuildRtpPacket(kPayload, true, 0, clock_->CurrentTime()); const uint16_t media_sequence_number = packet->SequenceNumber(); packet->set_allow_retransmission(true); packet_history_->PutRtpPacket(std::move(packet), clock_->CurrentTime()); @@ -1009,7 +1011,7 @@ TEST_F(RtpSenderTest, MarksRetransmittedPackets) { // Build a media packet and put in the packet history. std::unique_ptr packet = - BuildRtpPacket(kPayload, true, 0, clock_->TimeInMilliseconds()); + BuildRtpPacket(kPayload, true, 0, clock_->CurrentTime()); const uint16_t media_sequence_number = packet->SequenceNumber(); packet->set_allow_retransmission(true); packet_history_->PutRtpPacket(std::move(packet), clock_->CurrentTime()); @@ -1040,7 +1042,7 @@ TEST_F(RtpSenderTest, GeneratedPaddingHasBweExtensions) { // Put a packet in the history, in order to facilitate payload padding. std::unique_ptr packet = - BuildRtpPacket(kPayload, true, 0, clock_->TimeInMilliseconds()); + BuildRtpPacket(kPayload, true, 0, clock_->CurrentTime()); packet->set_allow_retransmission(true); packet->SetPayloadSize(kMinPaddingSize); packet->set_packet_type(RtpPacketMediaType::kVideo); @@ -1082,7 +1084,7 @@ TEST_F(RtpSenderTest, GeneratePaddingResendsOldPacketsWithRtx) { const size_t kPayloadPacketSize = kMinPaddingSize; std::unique_ptr packet = - BuildRtpPacket(kPayload, true, 0, clock_->TimeInMilliseconds()); + BuildRtpPacket(kPayload, true, 0, clock_->CurrentTime()); packet->set_allow_retransmission(true); packet->SetPayloadSize(kPayloadPacketSize); packet->set_packet_type(RtpPacketMediaType::kVideo); @@ -1131,7 +1133,7 @@ TEST_F(RtpSenderTest, LimitsPayloadPaddingSize) { // Send a dummy video packet so it ends up in the packet history. const size_t kPayloadPacketSize = 1234u; std::unique_ptr packet = - BuildRtpPacket(kPayload, true, 0, clock_->TimeInMilliseconds()); + BuildRtpPacket(kPayload, true, 0, clock_->CurrentTime()); packet->set_allow_retransmission(true); packet->SetPayloadSize(kPayloadPacketSize); packet->set_packet_type(RtpPacketMediaType::kVideo); @@ -1171,7 +1173,7 @@ TEST_F(RtpSenderTest, GeneratePaddingCreatesPurePaddingWithoutRtx) { // Send a dummy video packet so it ends up in the packet history. Since we // are not using RTX, it should never be used as padding. std::unique_ptr packet = - BuildRtpPacket(kPayload, true, 0, clock_->TimeInMilliseconds()); + BuildRtpPacket(kPayload, true, 0, clock_->CurrentTime()); packet->set_allow_retransmission(true); packet->SetPayloadSize(kPayloadPacketSize); packet->set_packet_type(RtpPacketMediaType::kVideo); @@ -1247,23 +1249,21 @@ TEST_F(RtpSenderTest, SetsCaptureTimeOnRtxRetransmissions) { EnableRtx(); // Put a packet in the packet history, with current time as capture time. - const int64_t start_time_ms = clock_->TimeInMilliseconds(); + const Timestamp start_time = clock_->CurrentTime(); std::unique_ptr packet = - BuildRtpPacket(kPayload, kMarkerBit, start_time_ms, - /*capture_time_ms=*/start_time_ms); + BuildRtpPacket(kPayload, kMarkerBit, /*rtp_timestamp=*/0, + /*capture_time=*/start_time); packet->set_allow_retransmission(true); sequencer_->Sequence(*packet); - packet_history_->PutRtpPacket(std::move(packet), - Timestamp::Millis(start_time_ms)); + packet_history_->PutRtpPacket(std::move(packet), start_time); // Advance time, request an RTX retransmission. Capture timestamp should be // preserved. time_controller_.AdvanceTime(TimeDelta::Millis(10)); - EXPECT_CALL( - mock_paced_sender_, - EnqueuePackets(ElementsAre(Pointee(Property( - &RtpPacketToSend::capture_time, Timestamp::Millis(start_time_ms)))))); + EXPECT_CALL(mock_paced_sender_, + EnqueuePackets(ElementsAre(Pointee( + Property(&RtpPacketToSend::capture_time, start_time))))); EXPECT_GT(rtp_sender_->ReSendPacket(kSeqNum), 0); } @@ -1274,14 +1274,12 @@ TEST_F(RtpSenderTest, IgnoresNackAfterDisablingMedia) { packet_history_->SetRtt(kRtt); // Put a packet in the history. - const int64_t start_time_ms = clock_->TimeInMilliseconds(); + const Timestamp start_time = clock_->CurrentTime(); std::unique_ptr packet = - BuildRtpPacket(kPayload, kMarkerBit, start_time_ms, - /*capture_time_ms=*/start_time_ms); + BuildRtpPacket(kPayload, kMarkerBit, 0, /*capture_time=*/start_time); packet->set_allow_retransmission(true); sequencer_->Sequence(*packet); - packet_history_->PutRtpPacket(std::move(packet), - Timestamp::Millis(start_time_ms)); + packet_history_->PutRtpPacket(std::move(packet), start_time); // Disable media sending and try to retransmit the packet, it should fail. rtp_sender_->SetSendingMediaStatus(false); @@ -1300,15 +1298,13 @@ TEST_F(RtpSenderTest, DoesntFecProtectRetransmissions) { packet_history_->SetRtt(kRtt); // Put a fec protected packet in the history. - const int64_t start_time_ms = clock_->TimeInMilliseconds(); + const Timestamp start_time = clock_->CurrentTime(); std::unique_ptr packet = - BuildRtpPacket(kPayload, kMarkerBit, start_time_ms, - /*capture_time_ms=*/start_time_ms); + BuildRtpPacket(kPayload, kMarkerBit, 0, start_time); packet->set_allow_retransmission(true); packet->set_fec_protect_packet(true); sequencer_->Sequence(*packet); - packet_history_->PutRtpPacket(std::move(packet), - Timestamp::Millis(start_time_ms)); + packet_history_->PutRtpPacket(std::move(packet), start_time); // Re-send packet, the retransmitted packet should not have the FEC protection // flag set.