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
This commit is contained in:
stefan@webrtc.org 2013-11-13 15:29:21 +00:00
parent 03f33709f8
commit 9b82f5a6ed
13 changed files with 154 additions and 113 deletions

View File

@ -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());
};

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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_);

View File

@ -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) {

View File

@ -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;