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:
parent
03f33709f8
commit
9b82f5a6ed
@ -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());
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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_);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user