Pass packet retransmission information in PacketOptions.

bugs.webrtc.org/8439 introduces application data that could e.g. contain
timestamps. We would like to take different actions for this data
depending on whether this is the first time a packet is being sent.

Bug: webrtc:8906
Change-Id: Ib370d76beec2960d961bf44391930faa4b193479
Reviewed-on: https://webrtc-review.googlesource.com/77643
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Petter Strandmark <strandmark@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23426}
This commit is contained in:
Petter Strandmark
2018-05-29 08:43:35 +02:00
committed by Commit Bot
parent 2aae2733a7
commit 26bc6695cd
3 changed files with 36 additions and 7 deletions

View File

@ -29,6 +29,8 @@ struct PacketOptions {
// Additional data bound to the RTP packet for use in application code, // Additional data bound to the RTP packet for use in application code,
// outside of WebRTC. // outside of WebRTC.
std::vector<uint8_t> application_data; std::vector<uint8_t> application_data;
// Whether this is a retransmission of an earlier packet.
bool is_retransmit = false;
}; };
class Transport { class Transport {

View File

@ -594,6 +594,8 @@ size_t RTPSender::SendPadData(size_t bytes,
padding_packet.SetExtension<AbsoluteSendTime>( padding_packet.SetExtension<AbsoluteSendTime>(
AbsoluteSendTime::MsTo24Bits(now_ms)); AbsoluteSendTime::MsTo24Bits(now_ms));
PacketOptions options; PacketOptions options;
// Padding packets are never retransmissions.
options.is_retransmit = false;
bool has_transport_seq_num = bool has_transport_seq_num =
UpdateTransportSequenceNumber(&padding_packet, &options.packet_id); UpdateTransportSequenceNumber(&padding_packet, &options.packet_id);
padding_packet.SetPadding(padding_bytes_in_packet, &random_); padding_packet.SetPadding(padding_bytes_in_packet, &random_);
@ -811,6 +813,10 @@ bool RTPSender::PrepareAndSendPacket(std::unique_ptr<RtpPacketToSend> packet,
} }
PacketOptions options; PacketOptions options;
// If we are sending over RTX, it also means this is a retransmission.
// E.g. RTPSender::TrySendRedundantPayloads calls PrepareAndSendPacket with
// send_over_rtx = true but is_retransmit = false.
options.is_retransmit = is_retransmit || send_over_rtx;
if (UpdateTransportSequenceNumber(packet_to_send, &options.packet_id)) { if (UpdateTransportSequenceNumber(packet_to_send, &options.packet_id)) {
AddPacketToTransportFeedback(options.packet_id, *packet_to_send, AddPacketToTransportFeedback(options.packet_id, *packet_to_send,
pacing_info); pacing_info);
@ -946,6 +952,7 @@ bool RTPSender::SendToNetwork(std::unique_ptr<RtpPacketToSend> packet,
} }
PacketOptions options; PacketOptions options;
options.is_retransmit = false;
if (UpdateTransportSequenceNumber(packet.get(), &options.packet_id)) { if (UpdateTransportSequenceNumber(packet.get(), &options.packet_id)) {
AddPacketToTransportFeedback(options.packet_id, *packet.get(), AddPacketToTransportFeedback(options.packet_id, *packet.get(),
PacedPacketInfo()); PacedPacketInfo());

View File

@ -71,7 +71,7 @@ uint64_t ConvertMsToAbsSendTime(int64_t time_ms) {
class LoopbackTransportTest : public webrtc::Transport { class LoopbackTransportTest : public webrtc::Transport {
public: public:
LoopbackTransportTest() : total_bytes_sent_(0), last_packet_id_(-1) { LoopbackTransportTest() : total_bytes_sent_(0) {
receivers_extensions_.Register(kRtpExtensionTransmissionTimeOffset, receivers_extensions_.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId); kTransmissionTimeOffsetExtensionId);
receivers_extensions_.Register(kRtpExtensionAbsoluteSendTime, receivers_extensions_.Register(kRtpExtensionAbsoluteSendTime,
@ -90,7 +90,7 @@ class LoopbackTransportTest : public webrtc::Transport {
bool SendRtp(const uint8_t* data, bool SendRtp(const uint8_t* data,
size_t len, size_t len,
const PacketOptions& options) override { const PacketOptions& options) override {
last_packet_id_ = options.packet_id; last_options_ = options;
total_bytes_sent_ += len; total_bytes_sent_ += len;
sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_)); sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
EXPECT_TRUE(sent_packets_.back().Parse(data, len)); EXPECT_TRUE(sent_packets_.back().Parse(data, len));
@ -101,7 +101,7 @@ class LoopbackTransportTest : public webrtc::Transport {
int packets_sent() { return sent_packets_.size(); } int packets_sent() { return sent_packets_.size(); }
size_t total_bytes_sent_; size_t total_bytes_sent_;
int last_packet_id_; PacketOptions last_options_;
std::vector<RtpPacketReceived> sent_packets_; std::vector<RtpPacketReceived> sent_packets_;
private: private:
@ -467,7 +467,19 @@ TEST_P(RtpSenderTestWithoutPacer, SendsPacketsWithTransportSequenceNumber) {
uint16_t transport_seq_no; uint16_t transport_seq_no;
ASSERT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no)); ASSERT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
EXPECT_EQ(kTransportSequenceNumber, transport_seq_no); EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
EXPECT_EQ(transport_.last_packet_id_, transport_seq_no); EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
}
TEST_P(RtpSenderTestWithoutPacer, PacketOptionsNoRetransmission) {
rtp_sender_.reset(new RTPSender(
false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
&feedback_observer_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
&send_packet_observer_, &retransmission_rate_limiter_, nullptr, false));
rtp_sender_->SetSSRC(kSsrc);
SendGenericPayload();
EXPECT_FALSE(transport_.last_options_.is_retransmit);
} }
TEST_P(RtpSenderTestWithoutPacer, NoAllocationIfNotRegistered) { TEST_P(RtpSenderTestWithoutPacer, NoAllocationIfNotRegistered) {
@ -520,7 +532,7 @@ TEST_P(RtpSenderTest, SendsPacketsWithTransportSequenceNumber) {
uint16_t transport_seq_no; uint16_t transport_seq_no;
EXPECT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no)); EXPECT_TRUE(packet.GetExtension<TransportSequenceNumber>(&transport_seq_no));
EXPECT_EQ(kTransportSequenceNumber, transport_seq_no); EXPECT_EQ(kTransportSequenceNumber, transport_seq_no);
EXPECT_EQ(transport_.last_packet_id_, transport_seq_no); EXPECT_EQ(transport_.last_options_.packet_id, transport_seq_no);
} }
TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) { TEST_P(RtpSenderTest, WritesPacerExitToTimingExtension) {
@ -844,6 +856,7 @@ TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
fake_clock_.TimeInMilliseconds(), kIsRetransmit, fake_clock_.TimeInMilliseconds(), kIsRetransmit,
PacedPacketInfo()); PacedPacketInfo());
EXPECT_EQ(1, transport_.packets_sent()); EXPECT_EQ(1, transport_.packets_sent());
EXPECT_TRUE(transport_.last_options_.is_retransmit);
} }
TEST_P(RtpSenderTest, OnSendPacketNotUpdatedWithoutSeqNumAllocator) { TEST_P(RtpSenderTest, OnSendPacketNotUpdatedWithoutSeqNumAllocator) {
@ -925,20 +938,27 @@ TEST_P(RtpSenderTest, SendRedundantPayloads) {
EXPECT_EQ(kMaxPaddingSize, EXPECT_EQ(kMaxPaddingSize,
rtp_sender_->TimeToSendPadding(49, PacedPacketInfo())); rtp_sender_->TimeToSendPadding(49, PacedPacketInfo()));
PacketOptions options;
EXPECT_CALL(transport, EXPECT_CALL(transport,
SendRtp(_, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize, _)) SendRtp(_, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize, _))
.WillOnce(testing::Return(true)); .WillOnce(testing::DoAll(testing::SaveArg<2>(&options),
testing::Return(true)));
EXPECT_EQ(kPayloadSizes[0], EXPECT_EQ(kPayloadSizes[0],
rtp_sender_->TimeToSendPadding(500, PacedPacketInfo())); rtp_sender_->TimeToSendPadding(500, PacedPacketInfo()));
EXPECT_TRUE(options.is_retransmit);
EXPECT_CALL(transport, SendRtp(_, kPayloadSizes[kNumPayloadSizes - 1] + EXPECT_CALL(transport, SendRtp(_, kPayloadSizes[kNumPayloadSizes - 1] +
rtp_header_len + kRtxHeaderSize, rtp_header_len + kRtxHeaderSize,
_)) _))
.WillOnce(testing::Return(true)); .WillOnce(testing::Return(true));
options.is_retransmit = false;
EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _)) EXPECT_CALL(transport, SendRtp(_, kMaxPaddingSize + rtp_header_len, _))
.WillOnce(testing::Return(true)); .WillOnce(testing::DoAll(testing::SaveArg<2>(&options),
testing::Return(true)));
EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kMaxPaddingSize, EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kMaxPaddingSize,
rtp_sender_->TimeToSendPadding(999, PacedPacketInfo())); rtp_sender_->TimeToSendPadding(999, PacedPacketInfo()));
EXPECT_FALSE(options.is_retransmit);
} }
TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) { TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {