NetEq: Rectify the implementation of PacketBuffer::DiscardOldPackets
The implementation of this method did not follow the description in the method comment. It was supposed to delete all packets in a range [A, B], but if at least one packet in the buffer had a timestamp lower than A, then no packets at all were discarded. This is now fixed. BUG=webrtc:7937 Review-Url: https://codereview.webrtc.org/2969123003 Cr-Commit-Position: refs/heads/master@{#18903}
This commit is contained in:
committed by
Commit Bot
parent
440ea8cdff
commit
63d146b743
@ -221,15 +221,13 @@ int PacketBuffer::DiscardNextPacket(StatisticsCalculator* stats) {
|
|||||||
void PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit,
|
void PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit,
|
||||||
uint32_t horizon_samples,
|
uint32_t horizon_samples,
|
||||||
StatisticsCalculator* stats) {
|
StatisticsCalculator* stats) {
|
||||||
// TODO(minyue): the following implementation is wrong. It won't discard
|
const size_t old_size = buffer_.size();
|
||||||
// old packets if the buffer_.front() is newer than timestamp_limit -
|
buffer_.remove_if([timestamp_limit, horizon_samples](const Packet& p) {
|
||||||
// horizon_samples. https://bugs.chromium.org/p/webrtc/issues/detail?id=7937
|
return timestamp_limit != p.timestamp &&
|
||||||
while (!Empty() && timestamp_limit != buffer_.front().timestamp &&
|
IsObsoleteTimestamp(p.timestamp, timestamp_limit, horizon_samples);
|
||||||
IsObsoleteTimestamp(buffer_.front().timestamp, timestamp_limit,
|
});
|
||||||
horizon_samples)) {
|
if (old_size > buffer_.size()) {
|
||||||
if (DiscardNextPacket(stats) != kOK) {
|
stats->PacketsDiscarded(old_size - buffer_.size());
|
||||||
assert(false); // Must be ok by design.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,8 @@
|
|||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
using ::testing::StrictMock;
|
using ::testing::StrictMock;
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
|
using ::testing::InSequence;
|
||||||
|
using ::testing::MockFunction;
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -314,26 +316,40 @@ TEST(PacketBuffer, DiscardPackets) {
|
|||||||
// Discard them one by one and make sure that the right packets are at the
|
// Discard them one by one and make sure that the right packets are at the
|
||||||
// front of the buffer.
|
// front of the buffer.
|
||||||
constexpr int kDiscardPackets = 5;
|
constexpr int kDiscardPackets = 5;
|
||||||
|
|
||||||
|
// Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
|
||||||
|
// check ensures that exactly one call to PacketsDiscarded happens in each
|
||||||
|
// DiscardNextPacket call.
|
||||||
|
InSequence s;
|
||||||
|
MockFunction<void(int check_point_id)> check;
|
||||||
for (int i = 0; i < kDiscardPackets; ++i) {
|
for (int i = 0; i < kDiscardPackets; ++i) {
|
||||||
uint32_t ts;
|
uint32_t ts;
|
||||||
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
|
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
|
||||||
EXPECT_EQ(current_ts, ts);
|
EXPECT_EQ(current_ts, ts);
|
||||||
EXPECT_CALL(mock_stats, PacketsDiscarded(1)).Times(1);
|
EXPECT_CALL(mock_stats, PacketsDiscarded(1));
|
||||||
|
EXPECT_CALL(check, Call(i));
|
||||||
EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
|
EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
|
||||||
current_ts += ts_increment;
|
current_ts += ts_increment;
|
||||||
|
check.Call(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
|
constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
|
||||||
// This will not discard any packets because the oldest packet is newer than
|
// This will discard all remaining packets but one. The oldest packet is older
|
||||||
// the indicated horizon_samples.
|
// than the indicated horizon_samples, and will thus be left in the buffer.
|
||||||
|
constexpr size_t kSkipPackets = 1;
|
||||||
|
EXPECT_CALL(mock_stats, PacketsDiscarded(kRemainingPackets - kSkipPackets));
|
||||||
|
EXPECT_CALL(check, Call(17)); // Arbitrary id number.
|
||||||
buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
|
buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
|
||||||
kRemainingPackets * ts_increment, &mock_stats);
|
kRemainingPackets * ts_increment, &mock_stats);
|
||||||
|
check.Call(17); // Same arbitrary id number.
|
||||||
|
|
||||||
|
EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
|
||||||
uint32_t ts;
|
uint32_t ts;
|
||||||
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
|
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
|
||||||
EXPECT_EQ(current_ts, ts);
|
EXPECT_EQ(current_ts, ts);
|
||||||
|
|
||||||
// Discard all remaining packets.
|
// Discard all remaining packets.
|
||||||
EXPECT_CALL(mock_stats, PacketsDiscarded(1)).Times(kRemainingPackets);
|
EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
|
||||||
buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
|
buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
|
||||||
&mock_stats);
|
&mock_stats);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user