Fix for RTX in combination with pacing.
Retransmissions didn't get sent over RTX when pacing was enabled since
the pacer didn't keep track of whether a packet was a retransmit or not.
BUG=1811
TEST=trybots
R=pbos@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/3779004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5117 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/pacing/include/mock/mock_paced_sender.h b/webrtc/modules/pacing/include/mock/mock_paced_sender.h
index c8f2a18..3841ef3 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 @@
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 3bd9896..a0c1f1d 100644
--- a/webrtc/modules/pacing/include/paced_sender.h
+++ b/webrtc/modules/pacing/include/paced_sender.h
@@ -43,8 +43,10 @@
// 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 @@
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 @@
// 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 49e8ef8..ed9d29a 100644
--- a/webrtc/modules/pacing/paced_sender.cc
+++ b/webrtc/modules/pacing/paced_sender.cc
@@ -36,16 +36,18 @@
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 @@
}
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 @@
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 @@
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 @@
}
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 286c097..66a3383 100644
--- a/webrtc/modules/pacing/paced_sender_unittest.cc
+++ b/webrtc/modules/pacing/paced_sender_unittest.cc
@@ -24,8 +24,9 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
}
// 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 @@
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 @@
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 @@
// 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 @@
// 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 4409e8e..c0e6183 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
+++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
@@ -324,8 +324,10 @@
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 fd7b9a9..09c3ca6 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 @@
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 6caa188..f910a18 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 @@
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 @@
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 @@
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 d7b2035..b29ec57 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 @@
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 d4980f2..5c63b58 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -532,16 +532,6 @@
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 @@
// 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 @@
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 @@
// 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 @@
"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 @@
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 e0ead82..afa57f1 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
@@ -167,7 +167,8 @@
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 83ee7f6..b1f1b50 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 @@
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, 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 @@
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, 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 @@
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 @@
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 5bddda4..889842e 100644
--- a/webrtc/video_engine/vie_encoder.cc
+++ b/webrtc/video_engine/vie_encoder.cc
@@ -118,8 +118,9 @@
}
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 @@
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 7177f8f..f80699c 100644
--- a/webrtc/video_engine/vie_encoder.h
+++ b/webrtc/video_engine/vie_encoder.h
@@ -181,7 +181,7 @@
// 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;