Deliver reordered packets in arrival time order after parsing feedback message.

This is what the remote bitrate estimator expects.

BUG=5823
R=sprang@webrtc.org

Review URL: https://codereview.webrtc.org/1915993002 .

Cr-Commit-Position: refs/heads/master@{#12527}
This commit is contained in:
Stefan Holmer
2016-04-27 14:21:16 +02:00
parent 97cfd1ec05
commit ed9535e2ca
2 changed files with 59 additions and 4 deletions

View File

@ -10,6 +10,7 @@
#include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h"
#include <algorithm>
#include <limits>
#include "webrtc/base/checks.h"
@ -26,6 +27,17 @@ const int64_t kBaseTimestampScaleFactor =
rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 8);
const int64_t kBaseTimestampRangeSizeUs = kBaseTimestampScaleFactor * (1 << 24);
class PacketInfoComparator {
public:
inline bool operator()(const PacketInfo& lhs, const PacketInfo& rhs) {
if (lhs.arrival_time_ms != rhs.arrival_time_ms)
return lhs.arrival_time_ms < rhs.arrival_time_ms;
if (lhs.send_time_ms !== rhs.send_time_ms)
return lhs.send_time_ms < rhs.send_time_ms;
return lhs.sequence_number < rhs.sequence_number;
}
};
TransportFeedbackAdapter::TransportFeedbackAdapter(
BitrateController* bitrate_controller,
Clock* clock)
@ -104,6 +116,8 @@ void TransportFeedbackAdapter::OnTransportFeedback(
}
++sequence_number;
}
std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(),
PacketInfoComparator());
RTC_DCHECK(delta_it == delta_vec.end());
if (failed_lookups > 0) {
LOG(LS_WARNING) << "Failed to lookup send time for " << failed_lookups

View File

@ -223,6 +223,39 @@ TEST_F(TransportFeedbackAdapterTest, SendTimeWrapsBothWays) {
}
}
TEST_F(TransportFeedbackAdapterTest, HandlesReordering) {
std::vector<PacketInfo> packets;
packets.push_back(PacketInfo(120, 200, 0, 1500, true));
packets.push_back(PacketInfo(110, 210, 1, 1500, true));
packets.push_back(PacketInfo(100, 220, 2, 1500, true));
std::vector<PacketInfo> expected_packets;
expected_packets.push_back(packets[2]);
expected_packets.push_back(packets[1]);
expected_packets.push_back(packets[0]);
for (const PacketInfo& packet : packets)
OnSentPacket(packet);
rtcp::TransportFeedback feedback;
feedback.WithBase(packets[0].sequence_number,
packets[0].arrival_time_ms * 1000);
for (const PacketInfo& packet : packets) {
EXPECT_TRUE(feedback.WithReceivedPacket(packet.sequence_number,
packet.arrival_time_ms * 1000));
}
feedback.Build();
EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
.Times(1)
.WillOnce(Invoke([expected_packets,
this](const std::vector<PacketInfo>& feedback_vector) {
ComparePacketVectors(expected_packets, feedback_vector);
}));
adapter_->OnTransportFeedback(feedback);
}
TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
std::vector<PacketInfo> sent_packets;
const int64_t kSmallDeltaUs =
@ -257,6 +290,14 @@ TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
info.arrival_time_ms += (kLargePositiveDeltaUs + 1000) / 1000;
++info.sequence_number;
// Expected to be ordered on arrival time when the feedback message has been
// parsed.
std::vector<PacketInfo> expected_packets;
expected_packets.push_back(sent_packets[0]);
expected_packets.push_back(sent_packets[3]);
expected_packets.push_back(sent_packets[1]);
expected_packets.push_back(sent_packets[2]);
// Packets will be added to send history.
for (const PacketInfo& packet : sent_packets)
OnSentPacket(packet);
@ -284,9 +325,9 @@ TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
EXPECT_TRUE(feedback.get() != nullptr);
EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
.Times(1)
.WillOnce(Invoke([sent_packets, &received_feedback](
.WillOnce(Invoke([expected_packets, &received_feedback](
const std::vector<PacketInfo>& feedback_vector) {
EXPECT_EQ(sent_packets.size(), feedback_vector.size());
EXPECT_EQ(expected_packets.size(), feedback_vector.size());
received_feedback = feedback_vector;
}));
adapter_->OnTransportFeedback(*feedback.get());
@ -310,9 +351,9 @@ TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
}));
adapter_->OnTransportFeedback(*feedback.get());
sent_packets.push_back(info);
expected_packets.push_back(info);
ComparePacketVectors(sent_packets, received_feedback);
ComparePacketVectors(expected_packets, received_feedback);
}
} // namespace test