diff --git a/webrtc/modules/pacing/include/mock/mock_paced_sender.h b/webrtc/modules/pacing/include/mock/mock_paced_sender.h index c8f2a180f8..3841ef3753 100644 --- a/webrtc/modules/pacing/include/mock/mock_paced_sender.h +++ b/webrtc/modules/pacing/include/mock/mock_paced_sender.h @@ -22,11 +22,12 @@ namespace webrtc { class MockPacedSender : public PacedSender { public: MockPacedSender() : PacedSender(NULL, 0, 0) {} - MOCK_METHOD5(SendPacket, bool(Priority priority, + MOCK_METHOD6(SendPacket, bool(Priority priority, uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms, - int bytes)); + int bytes, + bool retransmission)); MOCK_CONST_METHOD0(QueueInMs, int()); MOCK_CONST_METHOD0(QueueInPackets, int()); }; diff --git a/webrtc/modules/pacing/include/paced_sender.h b/webrtc/modules/pacing/include/paced_sender.h index 3bd9896719..a0c1f1dfc1 100644 --- a/webrtc/modules/pacing/include/paced_sender.h +++ b/webrtc/modules/pacing/include/paced_sender.h @@ -43,8 +43,10 @@ class PacedSender : public Module { // module again. // Called when it's time to send a queued packet. // Returns false if packet cannot be sent. - virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms) = 0; + virtual bool TimeToSendPacket(uint32_t ssrc, + uint16_t sequence_number, + int64_t capture_time_ms, + bool retransmission) = 0; // Called when it's a good time to send a padding data. virtual int TimeToSendPadding(int bytes) = 0; protected: @@ -80,7 +82,8 @@ class PacedSender : public Module { uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms, - int bytes); + int bytes, + bool retransmission); // Returns the time since the oldest queued packet was captured. virtual int QueueInMs() const; @@ -99,7 +102,8 @@ class PacedSender : public Module { // Local helper function to GetNextPacket. void GetNextPacketFromList(paced_sender::PacketList* packets, - uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms); + uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms, + bool* retransmission); // Updates the number of bytes that can be sent for the next time interval. void UpdateBytesPerInterval(uint32_t delta_time_in_ms); diff --git a/webrtc/modules/pacing/paced_sender.cc b/webrtc/modules/pacing/paced_sender.cc index 49e8ef829b..ed9d29a0fa 100644 --- a/webrtc/modules/pacing/paced_sender.cc +++ b/webrtc/modules/pacing/paced_sender.cc @@ -36,16 +36,18 @@ namespace webrtc { namespace paced_sender { struct Packet { Packet(uint32_t ssrc, uint16_t seq_number, int64_t capture_time_ms, - int length_in_bytes) + int length_in_bytes, bool retransmission) : ssrc_(ssrc), sequence_number_(seq_number), capture_time_ms_(capture_time_ms), - bytes_(length_in_bytes) { + bytes_(length_in_bytes), + retransmission_(retransmission) { } uint32_t ssrc_; uint16_t sequence_number_; int64_t capture_time_ms_; int bytes_; + bool retransmission_; }; // STL list style class which prevents duplicates in the list. @@ -170,7 +172,8 @@ void PacedSender::UpdateBitrate(int target_bitrate_kbps, } bool PacedSender::SendPacket(Priority priority, uint32_t ssrc, - uint16_t sequence_number, int64_t capture_time_ms, int bytes) { + uint16_t sequence_number, int64_t capture_time_ms, int bytes, + bool retransmission) { CriticalSectionScoped cs(critsect_.get()); if (!enabled_) { @@ -198,7 +201,8 @@ bool PacedSender::SendPacket(Priority priority, uint32_t ssrc, break; } packet_list->push_back(paced_sender::Packet(ssrc, sequence_number, - capture_time_ms, bytes)); + capture_time_ms, bytes, + retransmission)); return false; } @@ -253,14 +257,16 @@ int32_t PacedSender::Process() { uint32_t ssrc; uint16_t sequence_number; int64_t capture_time_ms; + bool retransmission; paced_sender::PacketList* packet_list; while (ShouldSendNextPacket(&packet_list)) { GetNextPacketFromList(packet_list, &ssrc, &sequence_number, - &capture_time_ms); + &capture_time_ms, &retransmission); critsect_->Leave(); const bool success = callback_->TimeToSendPacket(ssrc, sequence_number, - capture_time_ms); + capture_time_ms, + retransmission); critsect_->Enter(); // If packet cannot be sent then keep it in packet list and exit early. // There's no need to send more packets. @@ -339,12 +345,14 @@ bool PacedSender::ShouldSendNextPacket(paced_sender::PacketList** packet_list) { } void PacedSender::GetNextPacketFromList(paced_sender::PacketList* packets, - uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms) { + uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms, + bool* retransmission) { paced_sender::Packet packet = packets->front(); UpdateMediaBytesSent(packet.bytes_); *sequence_number = packet.sequence_number_; *ssrc = packet.ssrc_; *capture_time_ms = packet.capture_time_ms_; + *retransmission = packet.retransmission_; } // MUST have critsect_ when calling. diff --git a/webrtc/modules/pacing/paced_sender_unittest.cc b/webrtc/modules/pacing/paced_sender_unittest.cc index 286c09747b..66a3383112 100644 --- a/webrtc/modules/pacing/paced_sender_unittest.cc +++ b/webrtc/modules/pacing/paced_sender_unittest.cc @@ -24,8 +24,9 @@ static const float kPaceMultiplier = 1.5f; class MockPacedSenderCallback : public PacedSender::Callback { public: - MOCK_METHOD3(TimeToSendPacket, - bool(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms)); + MOCK_METHOD4(TimeToSendPacket, + bool(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms, + bool retransmission)); MOCK_METHOD1(TimeToSendPadding, int(int bytes)); }; @@ -35,7 +36,7 @@ class PacedSenderPadding : public PacedSender::Callback { PacedSenderPadding() : padding_sent_(0) {} bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms) { + int64_t capture_time_ms, bool retransmission) { return true; } @@ -65,11 +66,12 @@ class PacedSenderTest : public ::testing::Test { void SendAndExpectPacket(PacedSender::Priority priority, uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms, int size) { + int64_t capture_time_ms, int size, + bool retransmission) { EXPECT_FALSE(send_bucket_->SendPacket(priority, ssrc, - sequence_number, capture_time_ms, size)); + sequence_number, capture_time_ms, size, retransmission)); EXPECT_CALL(callback_, TimeToSendPacket( - ssrc, sequence_number, capture_time_ms)) + ssrc, sequence_number, capture_time_ms, false)) .Times(1) .WillRepeatedly(Return(true)); } @@ -84,34 +86,34 @@ TEST_F(PacedSenderTest, QueuePacket) { int64_t capture_time_ms = 56789; // Due to the multiplicative factor we can send 3 packets not 2 packets. SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number, capture_time_ms, 250)); + sequence_number, capture_time_ms, 250, false)); send_bucket_->Process(); EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); EXPECT_CALL(callback_, - TimeToSendPacket(ssrc, sequence_number, capture_time_ms)).Times(0); + TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false)).Times(0); TickTime::AdvanceFakeClock(4); EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess()); TickTime::AdvanceFakeClock(1); EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); EXPECT_CALL(callback_, TimeToSendPacket( - ssrc, sequence_number++, capture_time_ms)) + ssrc, sequence_number++, capture_time_ms, false)) .Times(1) .WillRepeatedly(Return(true)); send_bucket_->Process(); sequence_number++; SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + sequence_number++, capture_time_ms, 250, false)); send_bucket_->Process(); } @@ -123,11 +125,11 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) { // Due to the multiplicative factor we can send 3 packets not 2 packets. for (int i = 0; i < 3; ++i) { SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); } for (int j = 0; j < 30; ++j) { EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + sequence_number++, capture_time_ms, 250, false)); } send_bucket_->Process(); EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); @@ -135,7 +137,7 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) { EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); TickTime::AdvanceFakeClock(5); EXPECT_CALL(callback_, - TimeToSendPacket(ssrc, _, capture_time_ms)) + TimeToSendPacket(ssrc, _, capture_time_ms, false)) .Times(3) .WillRepeatedly(Return(true)); EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); @@ -146,13 +148,13 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) { EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); EXPECT_EQ(0, send_bucket_->Process()); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number, capture_time_ms, 250)); + sequence_number, capture_time_ms, 250, false)); send_bucket_->Process(); } @@ -165,16 +167,16 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) { // Due to the multiplicative factor we can send 3 packets not 2 packets. for (int i = 0; i < 3; ++i) { SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); } queued_sequence_number = sequence_number; for (int j = 0; j < 30; ++j) { // Send in duplicate packets. EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number, capture_time_ms, 250)); + sequence_number, capture_time_ms, 250, false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + sequence_number++, capture_time_ms, 250, false)); } EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); send_bucket_->Process(); @@ -184,7 +186,7 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) { for (int i = 0; i < 3; ++i) { EXPECT_CALL(callback_, TimeToSendPacket(ssrc, queued_sequence_number++, - capture_time_ms)) + capture_time_ms, false)) .Times(1) .WillRepeatedly(Return(true)); } @@ -196,13 +198,13 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) { EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); EXPECT_EQ(0, send_bucket_->Process()); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + sequence_number++, capture_time_ms, 250, false)); send_bucket_->Process(); } @@ -214,11 +216,11 @@ TEST_F(PacedSenderTest, Padding) { send_bucket_->UpdateBitrate(kTargetBitrate, kTargetBitrate, kTargetBitrate); // Due to the multiplicative factor we can send 3 packets not 2 packets. SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); // No padding is expected since we have sent too much already. EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); @@ -261,7 +263,7 @@ TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) { int64_t start_time = TickTime::MillisecondTimestamp(); while (TickTime::MillisecondTimestamp() - start_time < kBitrateWindow) { SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); TickTime::AdvanceFakeClock(kTimeStep); EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1). WillOnce(Return(250)); @@ -282,7 +284,7 @@ TEST_F(PacedSenderTest, VerifyMaxPaddingBitrate) { int64_t start_time = TickTime::MillisecondTimestamp(); while (TickTime::MillisecondTimestamp() - start_time < kBitrateWindow) { SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); TickTime::AdvanceFakeClock(kTimeStep); EXPECT_CALL(callback_, TimeToSendPadding(500)).Times(1). WillOnce(Return(250)); @@ -307,7 +309,7 @@ TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) { int media_payload = rand() % 100 + 200; // [200, 300] bytes. EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, capture_time_ms, - media_payload)); + media_payload, false)); media_bytes += media_payload; TickTime::AdvanceFakeClock(kTimeStep); send_bucket_->Process(); @@ -325,26 +327,27 @@ TEST_F(PacedSenderTest, Priority) { // Due to the multiplicative factor we can send 3 packets not 2 packets. SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); send_bucket_->Process(); // Expect normal and low priority to be queued and high to pass through. EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kLowPriority, - ssrc_low_priority, sequence_number++, capture_time_ms_low_priority, 250)); + ssrc_low_priority, sequence_number++, capture_time_ms_low_priority, 250, + false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + ssrc, sequence_number++, capture_time_ms, 250, false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + ssrc, sequence_number++, capture_time_ms, 250, false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kHighPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + ssrc, sequence_number++, capture_time_ms, 250, false)); // Expect all high and normal priority to be sent out first. EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); - EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms)) + EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false)) .Times(3) .WillRepeatedly(Return(true)); @@ -354,7 +357,7 @@ TEST_F(PacedSenderTest, Priority) { EXPECT_EQ(0, send_bucket_->Process()); EXPECT_CALL(callback_, TimeToSendPacket( - ssrc_low_priority, _, capture_time_ms_low_priority)) + ssrc_low_priority, _, capture_time_ms_low_priority, false)) .Times(1) .WillRepeatedly(Return(true)); @@ -376,31 +379,32 @@ TEST_F(PacedSenderTest, Pause) { // Due to the multiplicative factor we can send 3 packets not 2 packets. SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, - capture_time_ms, 250); + capture_time_ms, 250, false); send_bucket_->Process(); send_bucket_->Pause(); // Expect everything to be queued. EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kLowPriority, - ssrc_low_priority, sequence_number++, second_capture_time_ms, 250)); + ssrc_low_priority, sequence_number++, second_capture_time_ms, 250, + false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + ssrc, sequence_number++, capture_time_ms, 250, false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + ssrc, sequence_number++, capture_time_ms, 250, false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kHighPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + ssrc, sequence_number++, capture_time_ms, 250, false)); EXPECT_EQ(TickTime::MillisecondTimestamp() - capture_time_ms, send_bucket_->QueueInMs()); // Expect no packet to come out while paused. EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); - EXPECT_CALL(callback_, TimeToSendPacket(_, _, _)).Times(0); + EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _)).Times(0); for (int i = 0; i < 10; ++i) { TickTime::AdvanceFakeClock(5); @@ -409,7 +413,7 @@ TEST_F(PacedSenderTest, Pause) { } // Expect high prio packets to come out first followed by all packets in the // way they were added. - EXPECT_CALL(callback_, TimeToSendPacket(_, _, capture_time_ms)) + EXPECT_CALL(callback_, TimeToSendPacket(_, _, capture_time_ms, false)) .Times(3) .WillRepeatedly(Return(true)); send_bucket_->Resume(); @@ -419,7 +423,7 @@ TEST_F(PacedSenderTest, Pause) { EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); EXPECT_EQ(0, send_bucket_->Process()); - EXPECT_CALL(callback_, TimeToSendPacket(_, _, second_capture_time_ms)) + EXPECT_CALL(callback_, TimeToSendPacket(_, _, second_capture_time_ms, false)) .Times(1) .WillRepeatedly(Return(true)); EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); @@ -439,18 +443,20 @@ TEST_F(PacedSenderTest, ResendPacket) { ssrc, sequence_number, capture_time_ms, - 250)); + 250, + false)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, sequence_number + 1, capture_time_ms + 1, - 250)); + 250, + false)); TickTime::AdvanceFakeClock(10000); EXPECT_EQ(TickTime::MillisecondTimestamp() - capture_time_ms, send_bucket_->QueueInMs()); // Fails to send first packet so only one call. EXPECT_CALL(callback_, TimeToSendPacket( - ssrc, sequence_number, capture_time_ms)) + ssrc, sequence_number, capture_time_ms, false)) .Times(1) .WillOnce(Return(false)); TickTime::AdvanceFakeClock(10000); @@ -462,11 +468,11 @@ TEST_F(PacedSenderTest, ResendPacket) { // Fails to send second packet. EXPECT_CALL(callback_, TimeToSendPacket( - ssrc, sequence_number, capture_time_ms)) + ssrc, sequence_number, capture_time_ms, false)) .Times(1) .WillOnce(Return(true)); EXPECT_CALL(callback_, TimeToSendPacket( - ssrc, sequence_number + 1, capture_time_ms + 1)) + ssrc, sequence_number + 1, capture_time_ms + 1, false)) .Times(1) .WillOnce(Return(false)); TickTime::AdvanceFakeClock(10000); @@ -478,7 +484,7 @@ TEST_F(PacedSenderTest, ResendPacket) { // Send second packet and queue becomes empty. EXPECT_CALL(callback_, TimeToSendPacket( - ssrc, sequence_number + 1, capture_time_ms + 1)) + ssrc, sequence_number + 1, capture_time_ms + 1, false)) .Times(1) .WillOnce(Return(true)); TickTime::AdvanceFakeClock(10000); diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h index 4409e8e398..c0e6183d14 100644 --- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -324,8 +324,10 @@ class RtpRtcp : public Module { const RTPFragmentationHeader* fragmentation = NULL, const RTPVideoHeader* rtpVideoHdr = NULL) = 0; - virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms) = 0; + virtual bool TimeToSendPacket(uint32_t ssrc, + uint16_t sequence_number, + int64_t capture_time_ms, + bool retransmission) = 0; virtual int TimeToSendPadding(int bytes) = 0; diff --git a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index fd7b9a942f..09c3ca623f 100644 --- a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -111,8 +111,9 @@ class MockRtpRtcp : public RtpRtcp { const uint32_t payloadSize, const RTPFragmentationHeader* fragmentation, const RTPVideoHeader* rtpVideoHdr)); - MOCK_METHOD3(TimeToSendPacket, - bool(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms)); + MOCK_METHOD4(TimeToSendPacket, + bool(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms, + bool retransmission)); MOCK_METHOD1(TimeToSendPadding, int(int bytes)); MOCK_METHOD3(RegisterRtcpObservers, diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 6caa18883e..f910a18135 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -660,7 +660,8 @@ int32_t ModuleRtpRtcpImpl::SendOutgoingData( bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms) { + int64_t capture_time_ms, + bool retransmission) { WEBRTC_TRACE( kTraceStream, kTraceRtpRtcp, @@ -676,7 +677,8 @@ bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc, if (no_child_modules) { // Don't send from default module. if (SendingMedia() && ssrc == rtp_sender_.SSRC()) { - return rtp_sender_.TimeToSendPacket(sequence_number, capture_time_ms); + return rtp_sender_.TimeToSendPacket(sequence_number, capture_time_ms, + retransmission); } } else { CriticalSectionScoped lock(critical_section_module_ptrs_.get()); @@ -684,7 +686,8 @@ bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc, while (it != child_modules_.end()) { if ((*it)->SendingMedia() && ssrc == (*it)->rtp_sender_.SSRC()) { return (*it)->rtp_sender_.TimeToSendPacket(sequence_number, - capture_time_ms); + capture_time_ms, + retransmission); } ++it; } diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index d7b2035a02..b29ec5713f 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -126,8 +126,10 @@ class ModuleRtpRtcpImpl : public RtpRtcp { const RTPFragmentationHeader* fragmentation = NULL, const RTPVideoHeader* rtp_video_hdr = NULL) OVERRIDE; - virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms) OVERRIDE; + virtual bool TimeToSendPacket(uint32_t ssrc, + uint16_t sequence_number, + int64_t capture_time_ms, + bool retransmission) OVERRIDE; // Returns the number of padding bytes actually sent, which can be more or // less than |bytes|. virtual int TimeToSendPadding(int bytes) OVERRIDE; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index d4980f2ead..5c63b58ee1 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -532,16 +532,6 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, uint32_t min_resend_time) { return 0; } - uint8_t data_buffer_rtx[IP_PACKET_SIZE]; - if (rtx_ != kRtxOff) { - BuildRtxPacket(data_buffer, &length, data_buffer_rtx); - buffer_to_send_ptr = data_buffer_rtx; - } - - ModuleRTPUtility::RTPHeaderParser rtp_parser(data_buffer, length); - RTPHeader header; - rtp_parser.Parse(header); - // Store the time when the packet was last sent or added to pacer. packet_history_->UpdateResendTime(packet_id); @@ -554,6 +544,10 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, uint32_t min_resend_time) { // re-transmit and not new payload data. } + + ModuleRTPUtility::RTPHeaderParser rtp_parser(data_buffer, length); + RTPHeader header; + rtp_parser.Parse(header); TRACE_EVENT_INSTANT2("webrtc_rtp", "RTPSender::ReSendPacket", "timestamp", header.timestamp, "seqnum", header.sequenceNumber); @@ -563,13 +557,20 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, uint32_t min_resend_time) { header.ssrc, header.sequenceNumber, capture_time_ms, - length - header.headerLength)) { + length - header.headerLength, + true)) { // We can't send the packet right now. // We will be called when it is time. return length; } } + uint8_t data_buffer_rtx[IP_PACKET_SIZE]; + if (rtx_ != kRtxOff) { + BuildRtxPacket(data_buffer, &length, data_buffer_rtx); + buffer_to_send_ptr = data_buffer_rtx; + } + if (SendPacketToNetwork(buffer_to_send_ptr, length)) { return length; } @@ -710,11 +711,13 @@ void RTPSender::UpdateNACKBitRate(const uint32_t bytes, // Called from pacer when we can send the packet. bool RTPSender::TimeToSendPacket(uint16_t sequence_number, - int64_t capture_time_ms) { + int64_t capture_time_ms, + bool retransmission) { StorageType type; uint16_t length = IP_PACKET_SIZE; uint8_t data_buffer[IP_PACKET_SIZE]; int64_t stored_time_ms; + uint8_t *buffer_to_send_ptr = data_buffer; if (packet_history_ == NULL) { // Packet cannot be found. Allow sending to continue. @@ -734,19 +737,26 @@ bool RTPSender::TimeToSendPacket(uint16_t sequence_number, "timestamp", rtp_header.timestamp, "seqnum", sequence_number); + uint8_t data_buffer_rtx[IP_PACKET_SIZE]; + if (retransmission && rtx_ != kRtxOff) { + BuildRtxPacket(data_buffer, &length, data_buffer_rtx); + buffer_to_send_ptr = data_buffer_rtx; + } + int64_t now_ms = clock_->TimeInMilliseconds(); int64_t diff_ms = now_ms - capture_time_ms; bool updated_transmission_time_offset = - UpdateTransmissionTimeOffset(data_buffer, length, rtp_header, diff_ms); + UpdateTransmissionTimeOffset(buffer_to_send_ptr, length, rtp_header, + diff_ms); bool updated_abs_send_time = - UpdateAbsoluteSendTime(data_buffer, length, rtp_header, now_ms); + UpdateAbsoluteSendTime(buffer_to_send_ptr, length, rtp_header, now_ms); if (updated_transmission_time_offset || updated_abs_send_time) { // Update stored packet in case of receiving a re-transmission request. - packet_history_->ReplaceRTPHeader(data_buffer, + packet_history_->ReplaceRTPHeader(buffer_to_send_ptr, rtp_header.sequenceNumber, rtp_header.headerLength); } - return SendPacketToNetwork(data_buffer, length); + return SendPacketToNetwork(buffer_to_send_ptr, length); } int RTPSender::TimeToSendPadding(int bytes) { @@ -822,7 +832,7 @@ int32_t RTPSender::SendToNetwork( if (paced_sender_ && storage != kDontStore) { if (!paced_sender_->SendPacket(priority, rtp_header.ssrc, rtp_header.sequenceNumber, capture_time_ms, - payload_length)) { + payload_length, false)) { // We can't send the packet right now. // We will be called when it is time. return 0; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h index e0ead82225..afa57f1536 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -167,7 +167,8 @@ class RTPSender : public Bitrate, public RTPSenderInterface { const RTPHeader &rtp_header, const int64_t now_ms) const; - bool TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms); + bool TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms, + bool retransmission); int TimeToSendPadding(int bytes); // NACK. diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc index 83ee7f68df..b1f1b50fe7 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -82,7 +82,7 @@ class RtpSenderTest : public ::testing::Test { transport_(), kMarkerBit(true) { EXPECT_CALL(mock_paced_sender_, - SendPacket(_, _, _, _, _)).WillRepeatedly(testing::Return(true)); + SendPacket(_, _, _, _, _, _)).WillRepeatedly(testing::Return(true)); } virtual void SetUp() { @@ -344,7 +344,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithHeaderExtensions) { TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) { EXPECT_CALL(mock_paced_sender_, - SendPacket(PacedSender::kNormalPriority, _, kSeqNum, _, _)). + SendPacket(PacedSender::kNormalPriority, _, kSeqNum, _, _, _)). WillOnce(testing::Return(false)); rtp_sender_->SetStorePacketsStatus(true, 10); @@ -373,7 +373,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) { const int kStoredTimeInMs = 100; fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs); - rtp_sender_->TimeToSendPacket(kSeqNum, capture_time_ms); + rtp_sender_->TimeToSendPacket(kSeqNum, capture_time_ms, false); // Process send bucket. Packet should now be sent. EXPECT_EQ(1, transport_.packets_sent_); @@ -398,7 +398,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) { TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) { EXPECT_CALL(mock_paced_sender_, - SendPacket(PacedSender::kNormalPriority, _, kSeqNum, _, _)). + SendPacket(PacedSender::kNormalPriority, _, kSeqNum, _, _, _)). WillOnce(testing::Return(false)); rtp_sender_->SetStorePacketsStatus(true, 10); @@ -425,7 +425,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) { EXPECT_EQ(0, transport_.packets_sent_); EXPECT_CALL(mock_paced_sender_, - SendPacket(PacedSender::kHighPriority, _, kSeqNum, _, _)). + SendPacket(PacedSender::kHighPriority, _, kSeqNum, _, _, _)). WillOnce(testing::Return(false)); const int kStoredTimeInMs = 100; @@ -434,7 +434,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) { EXPECT_EQ(rtp_length, rtp_sender_->ReSendPacket(kSeqNum)); EXPECT_EQ(0, transport_.packets_sent_); - rtp_sender_->TimeToSendPacket(kSeqNum, capture_time_ms); + rtp_sender_->TimeToSendPacket(kSeqNum, capture_time_ms, false); // Process send bucket. Packet should now be sent. EXPECT_EQ(1, transport_.packets_sent_); diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index 5bddda47c5..889842e129 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -118,8 +118,9 @@ class ViEPacedSenderCallback : public PacedSender::Callback { } virtual ~ViEPacedSenderCallback() {} virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms) { - return owner_->TimeToSendPacket(ssrc, sequence_number, capture_time_ms); + int64_t capture_time_ms, bool retransmission) { + return owner_->TimeToSendPacket(ssrc, sequence_number, capture_time_ms, + retransmission); } virtual int TimeToSendPadding(int bytes) { return owner_->TimeToSendPadding(bytes); @@ -515,10 +516,12 @@ int32_t ViEEncoder::ScaleInputImage(bool enable) { return 0; } -bool ViEEncoder::TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms) { +bool ViEEncoder::TimeToSendPacket(uint32_t ssrc, + uint16_t sequence_number, + int64_t capture_time_ms, + bool retransmission) { return default_rtp_rtcp_->TimeToSendPacket(ssrc, sequence_number, - capture_time_ms); + capture_time_ms, retransmission); } int ViEEncoder::TimeToSendPadding(int bytes) { diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h index 7177f8ff62..f80699cc66 100644 --- a/webrtc/video_engine/vie_encoder.h +++ b/webrtc/video_engine/vie_encoder.h @@ -181,7 +181,7 @@ class ViEEncoder // Called by PacedSender. bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, - int64_t capture_time_ms); + int64_t capture_time_ms, bool retransmission); int TimeToSendPadding(int bytes); private: bool EncoderPaused() const;