Avoid adding duplicates in pacer lists.
Review URL: https://webrtc-codereview.appspot.com/1329007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3899 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
cb60fb2e6c
commit
52aa019e98
@ -12,6 +12,7 @@
|
|||||||
#define WEBRTC_MODULES_PACED_SENDER_H_
|
#define WEBRTC_MODULES_PACED_SENDER_H_
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "webrtc/modules/interface/module.h"
|
#include "webrtc/modules/interface/module.h"
|
||||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||||
@ -89,14 +90,27 @@ class PacedSender : public Module {
|
|||||||
int bytes_;
|
int bytes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<Packet> PacketList;
|
// STL list style class which prevents duplicates in the list.
|
||||||
|
class PacketList {
|
||||||
|
public:
|
||||||
|
PacketList() {};
|
||||||
|
|
||||||
|
bool empty() const;
|
||||||
|
Packet front() const;
|
||||||
|
void pop_front();
|
||||||
|
void push_back(const Packet& packet);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::list<Packet> packet_list_;
|
||||||
|
std::set<uint16_t> sequence_number_set_;
|
||||||
|
};
|
||||||
|
|
||||||
// Checks if next packet in line can be transmitted. Returns true on success.
|
// Checks if next packet in line can be transmitted. Returns true on success.
|
||||||
bool GetNextPacket(uint32_t* ssrc, uint16_t* sequence_number,
|
bool GetNextPacket(uint32_t* ssrc, uint16_t* sequence_number,
|
||||||
int64_t* capture_time_ms);
|
int64_t* capture_time_ms);
|
||||||
|
|
||||||
// Local helper function to GetNextPacket.
|
// Local helper function to GetNextPacket.
|
||||||
void GetNextPacketFromList(std::list<Packet>* list,
|
void GetNextPacketFromList(PacketList* list,
|
||||||
uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms);
|
uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms);
|
||||||
|
|
||||||
// Updates the number of bytes that can be sent for the next time interval.
|
// Updates the number of bytes that can be sent for the next time interval.
|
||||||
|
@ -36,6 +36,29 @@ const int kMaxQueueTimeWithoutSendingMs = 30;
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
bool PacedSender::PacketList::empty() const {
|
||||||
|
return packet_list_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
PacedSender::Packet PacedSender::PacketList::front() const {
|
||||||
|
return packet_list_.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacedSender::PacketList::pop_front() {
|
||||||
|
PacedSender::Packet& packet = packet_list_.front();
|
||||||
|
packet_list_.pop_front();
|
||||||
|
sequence_number_set_.erase(packet.sequence_number_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacedSender::PacketList::push_back(const PacedSender::Packet& packet) {
|
||||||
|
if (sequence_number_set_.find(packet.sequence_number_) ==
|
||||||
|
sequence_number_set_.end()) {
|
||||||
|
// Don't insert duplicates.
|
||||||
|
packet_list_.push_back(packet);
|
||||||
|
sequence_number_set_.insert(packet.sequence_number_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PacedSender::PacedSender(Callback* callback, int target_bitrate_kbps)
|
PacedSender::PacedSender(Callback* callback, int target_bitrate_kbps)
|
||||||
: callback_(callback),
|
: callback_(callback),
|
||||||
enable_(false),
|
enable_(false),
|
||||||
@ -49,9 +72,6 @@ PacedSender::PacedSender(Callback* callback, int target_bitrate_kbps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PacedSender::~PacedSender() {
|
PacedSender::~PacedSender() {
|
||||||
high_priority_packets_.clear();
|
|
||||||
normal_priority_packets_.clear();
|
|
||||||
low_priority_packets_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacedSender::Pause() {
|
void PacedSender::Pause() {
|
||||||
@ -262,7 +282,7 @@ bool PacedSender::GetNextPacket(uint32_t* ssrc, uint16_t* sequence_number,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacedSender::GetNextPacketFromList(std::list<Packet>* list,
|
void PacedSender::GetNextPacketFromList(PacketList* list,
|
||||||
uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms) {
|
uint32_t* ssrc, uint16_t* sequence_number, int64_t* capture_time_ms) {
|
||||||
Packet packet = list->front();
|
Packet packet = list->front();
|
||||||
UpdateState(packet.bytes_);
|
UpdateState(packet.bytes_);
|
||||||
|
@ -111,6 +111,52 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) {
|
|||||||
sequence_number++, capture_time_ms, 250));
|
sequence_number++, capture_time_ms, 250));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
|
||||||
|
uint32_t ssrc = 12345;
|
||||||
|
uint16_t sequence_number = 1234;
|
||||||
|
int64_t capture_time_ms = 56789;
|
||||||
|
uint16_t queued_sequence_number;
|
||||||
|
|
||||||
|
// Due to the multiplicative factor we can send 3 packets not 2 packets.
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
|
||||||
|
sequence_number++, capture_time_ms, 250));
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
|
||||||
|
sequence_number++, capture_time_ms, 250));
|
||||||
|
}
|
||||||
|
EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
|
||||||
|
for (int k = 0; k < 10; ++k) {
|
||||||
|
EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
|
||||||
|
TickTime::AdvanceFakeClock(5);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
EXPECT_CALL(callback_, TimeToSendPacket(ssrc, queued_sequence_number++,
|
||||||
|
capture_time_ms)).Times(1);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
|
||||||
|
EXPECT_EQ(0, send_bucket_->Process());
|
||||||
|
}
|
||||||
|
EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
|
||||||
|
TickTime::AdvanceFakeClock(5);
|
||||||
|
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
|
||||||
|
EXPECT_EQ(0, send_bucket_->Process());
|
||||||
|
EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
|
||||||
|
sequence_number++, capture_time_ms, 250));
|
||||||
|
EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
|
||||||
|
sequence_number++, capture_time_ms, 250));
|
||||||
|
EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
|
||||||
|
sequence_number++, capture_time_ms, 250));
|
||||||
|
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
|
||||||
|
sequence_number++, capture_time_ms, 250));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PacedSenderTest, Padding) {
|
TEST_F(PacedSenderTest, Padding) {
|
||||||
uint32_t ssrc = 12345;
|
uint32_t ssrc = 12345;
|
||||||
uint16_t sequence_number = 1234;
|
uint16_t sequence_number = 1234;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user