Include buffer size limits in NetEq config struct
This change includes max_packets_in_buffer and max_delay_ms in the NetEq config struct. The packet buffer is also no longer limited in terms of payload sizes (bytes), only number of packets. The old constants governing the packet buffer limits are deleted. BUG=3083 R=turaj@webrtc.org Review URL: https://webrtc-codereview.appspot.com/14389004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5989 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -765,13 +765,9 @@ bool AcmReceiver::GetSilence(int desired_sample_rate_hz, AudioFrame* frame) {
|
|||||||
// exceeds a threshold.
|
// exceeds a threshold.
|
||||||
int num_packets;
|
int num_packets;
|
||||||
int max_num_packets;
|
int max_num_packets;
|
||||||
int buffer_size_byte;
|
|
||||||
int max_buffer_size_byte;
|
|
||||||
const float kBufferingThresholdScale = 0.9f;
|
const float kBufferingThresholdScale = 0.9f;
|
||||||
neteq_->PacketBufferStatistics(&num_packets, &max_num_packets,
|
neteq_->PacketBufferStatistics(&num_packets, &max_num_packets);
|
||||||
&buffer_size_byte, &max_buffer_size_byte);
|
if (num_packets > max_num_packets * kBufferingThresholdScale) {
|
||||||
if (num_packets > max_num_packets * kBufferingThresholdScale ||
|
|
||||||
buffer_size_byte > max_buffer_size_byte * kBufferingThresholdScale) {
|
|
||||||
initial_delay_manager_->DisableBuffering();
|
initial_delay_manager_->DisableBuffering();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ TEST(DecisionLogic, CreateAndDestroy) {
|
|||||||
int fs_hz = 8000;
|
int fs_hz = 8000;
|
||||||
int output_size_samples = fs_hz / 100; // Samples per 10 ms.
|
int output_size_samples = fs_hz / 100; // Samples per 10 ms.
|
||||||
DecoderDatabase decoder_database;
|
DecoderDatabase decoder_database;
|
||||||
PacketBuffer packet_buffer(10, 1000);
|
PacketBuffer packet_buffer(10);
|
||||||
DelayPeakDetector delay_peak_detector;
|
DelayPeakDetector delay_peak_detector;
|
||||||
DelayManager delay_manager(240, &delay_peak_detector);
|
DelayManager delay_manager(240, &delay_peak_detector);
|
||||||
BufferLevelFilter buffer_level_filter;
|
BufferLevelFilter buffer_level_filter;
|
||||||
|
@@ -70,10 +70,15 @@ class NetEq {
|
|||||||
struct Config {
|
struct Config {
|
||||||
Config()
|
Config()
|
||||||
: sample_rate_hz(16000),
|
: sample_rate_hz(16000),
|
||||||
enable_audio_classifier(false) {}
|
enable_audio_classifier(false),
|
||||||
|
max_packets_in_buffer(50),
|
||||||
|
// |max_delay_ms| has the same effect as calling SetMaximumDelay().
|
||||||
|
max_delay_ms(2000) {}
|
||||||
|
|
||||||
int sample_rate_hz; // Initial vale. Will change with input data.
|
int sample_rate_hz; // Initial vale. Will change with input data.
|
||||||
bool enable_audio_classifier;
|
bool enable_audio_classifier;
|
||||||
|
int max_packets_in_buffer;
|
||||||
|
int max_delay_ms;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ReturnCodes {
|
enum ReturnCodes {
|
||||||
@@ -107,13 +112,9 @@ class NetEq {
|
|||||||
kFrameSplitError,
|
kFrameSplitError,
|
||||||
kRedundancySplitError,
|
kRedundancySplitError,
|
||||||
kPacketBufferCorruption,
|
kPacketBufferCorruption,
|
||||||
kOversizePacket,
|
|
||||||
kSyncPacketNotAccepted
|
kSyncPacketNotAccepted
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kMaxNumPacketsInBuffer = 50; // TODO(hlundin): Remove.
|
|
||||||
static const int kMaxBytesInBuffer = 113280; // TODO(hlundin): Remove.
|
|
||||||
|
|
||||||
// Creates a new NetEq object, with parameters set in |config|. The |config|
|
// Creates a new NetEq object, with parameters set in |config|. The |config|
|
||||||
// object will only have to be valid for the duration of the call to this
|
// object will only have to be valid for the duration of the call to this
|
||||||
// method.
|
// method.
|
||||||
@@ -179,7 +180,8 @@ class NetEq {
|
|||||||
|
|
||||||
// Sets a maximum delay in milliseconds for packet buffer. The latency will
|
// Sets a maximum delay in milliseconds for packet buffer. The latency will
|
||||||
// not exceed the given value, even required delay (given the channel
|
// not exceed the given value, even required delay (given the channel
|
||||||
// conditions) is higher.
|
// conditions) is higher. Calling this method has the same effect as setting
|
||||||
|
// the |max_delay_ms| value in the NetEq::Config struct.
|
||||||
virtual bool SetMaximumDelay(int delay_ms) = 0;
|
virtual bool SetMaximumDelay(int delay_ms) = 0;
|
||||||
|
|
||||||
// The smallest latency required. This is computed bases on inter-arrival
|
// The smallest latency required. This is computed bases on inter-arrival
|
||||||
@@ -249,9 +251,7 @@ class NetEq {
|
|||||||
|
|
||||||
// Current usage of packet-buffer and it's limits.
|
// Current usage of packet-buffer and it's limits.
|
||||||
virtual void PacketBufferStatistics(int* current_num_packets,
|
virtual void PacketBufferStatistics(int* current_num_packets,
|
||||||
int* max_num_packets,
|
int* max_num_packets) const = 0;
|
||||||
int* current_memory_size_bytes,
|
|
||||||
int* max_memory_size_bytes) const = 0;
|
|
||||||
|
|
||||||
// Get sequence number and timestamp of the latest RTP.
|
// Get sequence number and timestamp of the latest RTP.
|
||||||
// This method is to facilitate NACK.
|
// This method is to facilitate NACK.
|
||||||
|
@@ -19,8 +19,8 @@ namespace webrtc {
|
|||||||
|
|
||||||
class MockPacketBuffer : public PacketBuffer {
|
class MockPacketBuffer : public PacketBuffer {
|
||||||
public:
|
public:
|
||||||
MockPacketBuffer(size_t max_number_of_packets, size_t max_payload_memory)
|
MockPacketBuffer(size_t max_number_of_packets)
|
||||||
: PacketBuffer(max_number_of_packets, max_payload_memory) {}
|
: PacketBuffer(max_number_of_packets) {}
|
||||||
virtual ~MockPacketBuffer() { Die(); }
|
virtual ~MockPacketBuffer() { Die(); }
|
||||||
MOCK_METHOD0(Die, void());
|
MOCK_METHOD0(Die, void());
|
||||||
MOCK_METHOD0(Flush,
|
MOCK_METHOD0(Flush,
|
||||||
|
@@ -32,12 +32,12 @@ NetEq* NetEq::Create(const NetEq::Config& config) {
|
|||||||
BufferLevelFilter* buffer_level_filter = new BufferLevelFilter;
|
BufferLevelFilter* buffer_level_filter = new BufferLevelFilter;
|
||||||
DecoderDatabase* decoder_database = new DecoderDatabase;
|
DecoderDatabase* decoder_database = new DecoderDatabase;
|
||||||
DelayPeakDetector* delay_peak_detector = new DelayPeakDetector;
|
DelayPeakDetector* delay_peak_detector = new DelayPeakDetector;
|
||||||
DelayManager* delay_manager = new DelayManager(kMaxNumPacketsInBuffer,
|
DelayManager* delay_manager =
|
||||||
delay_peak_detector);
|
new DelayManager(config.max_packets_in_buffer, delay_peak_detector);
|
||||||
|
delay_manager->SetMaximumDelay(config.max_delay_ms);
|
||||||
DtmfBuffer* dtmf_buffer = new DtmfBuffer(config.sample_rate_hz);
|
DtmfBuffer* dtmf_buffer = new DtmfBuffer(config.sample_rate_hz);
|
||||||
DtmfToneGenerator* dtmf_tone_generator = new DtmfToneGenerator;
|
DtmfToneGenerator* dtmf_tone_generator = new DtmfToneGenerator;
|
||||||
PacketBuffer* packet_buffer = new PacketBuffer(kMaxNumPacketsInBuffer,
|
PacketBuffer* packet_buffer = new PacketBuffer(config.max_packets_in_buffer);
|
||||||
kMaxBytesInBuffer);
|
|
||||||
PayloadSplitter* payload_splitter = new PayloadSplitter;
|
PayloadSplitter* payload_splitter = new PayloadSplitter;
|
||||||
TimestampScaler* timestamp_scaler = new TimestampScaler(*decoder_database);
|
TimestampScaler* timestamp_scaler = new TimestampScaler(*decoder_database);
|
||||||
AccelerateFactory* accelerate_factory = new AccelerateFactory;
|
AccelerateFactory* accelerate_factory = new AccelerateFactory;
|
||||||
|
@@ -364,12 +364,9 @@ void NetEqImpl::FlushBuffers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NetEqImpl::PacketBufferStatistics(int* current_num_packets,
|
void NetEqImpl::PacketBufferStatistics(int* current_num_packets,
|
||||||
int* max_num_packets,
|
int* max_num_packets) const {
|
||||||
int* current_memory_size_bytes,
|
|
||||||
int* max_memory_size_bytes) const {
|
|
||||||
CriticalSectionScoped lock(crit_sect_.get());
|
CriticalSectionScoped lock(crit_sect_.get());
|
||||||
packet_buffer_->BufferStat(current_num_packets, max_num_packets,
|
packet_buffer_->BufferStat(current_num_packets, max_num_packets);
|
||||||
current_memory_size_bytes, max_memory_size_bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int NetEqImpl::DecodedRtpInfo(int* sequence_number, uint32_t* timestamp) const {
|
int NetEqImpl::DecodedRtpInfo(int* sequence_number, uint32_t* timestamp) const {
|
||||||
@@ -610,9 +607,6 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header,
|
|||||||
new_codec_ = true;
|
new_codec_ = true;
|
||||||
update_sample_rate_and_channels = true;
|
update_sample_rate_and_channels = true;
|
||||||
LOG_F(LS_WARNING) << "Packet buffer flushed";
|
LOG_F(LS_WARNING) << "Packet buffer flushed";
|
||||||
} else if (ret == PacketBuffer::kOversizePacket) {
|
|
||||||
LOG_F(LS_WARNING) << "Packet larger than packet buffer";
|
|
||||||
return kOversizePacket;
|
|
||||||
} else if (ret != PacketBuffer::kOK) {
|
} else if (ret != PacketBuffer::kOK) {
|
||||||
LOG_FERR1(LS_WARNING, InsertPacketList, packet_list.size());
|
LOG_FERR1(LS_WARNING, InsertPacketList, packet_list.size());
|
||||||
PacketBuffer::DeleteAllPackets(&packet_list);
|
PacketBuffer::DeleteAllPackets(&packet_list);
|
||||||
|
@@ -186,9 +186,7 @@ class NetEqImpl : public webrtc::NetEq {
|
|||||||
virtual void FlushBuffers();
|
virtual void FlushBuffers();
|
||||||
|
|
||||||
virtual void PacketBufferStatistics(int* current_num_packets,
|
virtual void PacketBufferStatistics(int* current_num_packets,
|
||||||
int* max_num_packets,
|
int* max_num_packets) const;
|
||||||
int* current_memory_size_bytes,
|
|
||||||
int* max_memory_size_bytes) const;
|
|
||||||
|
|
||||||
// Get sequence number and timestamp of the latest RTP.
|
// Get sequence number and timestamp of the latest RTP.
|
||||||
// This method is to facilitate NACK.
|
// This method is to facilitate NACK.
|
||||||
|
@@ -102,13 +102,13 @@ class NetEqImplTest : public ::testing::Test {
|
|||||||
delay_peak_detector_ = new DelayPeakDetector;
|
delay_peak_detector_ = new DelayPeakDetector;
|
||||||
}
|
}
|
||||||
if (use_mock_delay_manager_) {
|
if (use_mock_delay_manager_) {
|
||||||
mock_delay_manager_ = new MockDelayManager(NetEq::kMaxNumPacketsInBuffer,
|
mock_delay_manager_ = new MockDelayManager(config_.max_packets_in_buffer,
|
||||||
delay_peak_detector_);
|
delay_peak_detector_);
|
||||||
EXPECT_CALL(*mock_delay_manager_, set_streaming_mode(false)).Times(1);
|
EXPECT_CALL(*mock_delay_manager_, set_streaming_mode(false)).Times(1);
|
||||||
delay_manager_ = mock_delay_manager_;
|
delay_manager_ = mock_delay_manager_;
|
||||||
} else {
|
} else {
|
||||||
delay_manager_ =
|
delay_manager_ =
|
||||||
new DelayManager(NetEq::kMaxNumPacketsInBuffer, delay_peak_detector_);
|
new DelayManager(config_.max_packets_in_buffer, delay_peak_detector_);
|
||||||
}
|
}
|
||||||
if (use_mock_dtmf_buffer_) {
|
if (use_mock_dtmf_buffer_) {
|
||||||
mock_dtmf_buffer_ = new MockDtmfBuffer(config_.sample_rate_hz);
|
mock_dtmf_buffer_ = new MockDtmfBuffer(config_.sample_rate_hz);
|
||||||
@@ -123,12 +123,10 @@ class NetEqImplTest : public ::testing::Test {
|
|||||||
dtmf_tone_generator_ = new DtmfToneGenerator;
|
dtmf_tone_generator_ = new DtmfToneGenerator;
|
||||||
}
|
}
|
||||||
if (use_mock_packet_buffer_) {
|
if (use_mock_packet_buffer_) {
|
||||||
mock_packet_buffer_ = new MockPacketBuffer(NetEq::kMaxNumPacketsInBuffer,
|
mock_packet_buffer_ = new MockPacketBuffer(config_.max_packets_in_buffer);
|
||||||
NetEq::kMaxBytesInBuffer);
|
|
||||||
packet_buffer_ = mock_packet_buffer_;
|
packet_buffer_ = mock_packet_buffer_;
|
||||||
} else {
|
} else {
|
||||||
packet_buffer_ = new PacketBuffer(NetEq::kMaxNumPacketsInBuffer,
|
packet_buffer_ = new PacketBuffer(config_.max_packets_in_buffer);
|
||||||
NetEq::kMaxBytesInBuffer);
|
|
||||||
}
|
}
|
||||||
if (use_mock_payload_splitter_) {
|
if (use_mock_payload_splitter_) {
|
||||||
mock_payload_splitter_ = new MockPayloadSplitter;
|
mock_payload_splitter_ = new MockPayloadSplitter;
|
||||||
@@ -381,7 +379,7 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
|
|||||||
neteq_->RegisterPayloadType(kDecoderPCM16B, kPayloadType));
|
neteq_->RegisterPayloadType(kDecoderPCM16B, kPayloadType));
|
||||||
|
|
||||||
// Insert packets. The buffer should not flush.
|
// Insert packets. The buffer should not flush.
|
||||||
for (int i = 1; i <= NetEq::kMaxNumPacketsInBuffer; ++i) {
|
for (int i = 1; i <= config_.max_packets_in_buffer; ++i) {
|
||||||
EXPECT_EQ(NetEq::kOK,
|
EXPECT_EQ(NetEq::kOK,
|
||||||
neteq_->InsertPacket(
|
neteq_->InsertPacket(
|
||||||
rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
|
rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
|
||||||
|
@@ -945,18 +945,6 @@ TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(UnknownPayloadType)) {
|
|||||||
EXPECT_EQ(NetEq::kUnknownRtpPayloadType, neteq_->LastError());
|
EXPECT_EQ(NetEq::kUnknownRtpPayloadType, neteq_->LastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(OversizePacket)) {
|
|
||||||
// Payload size is greater than packet buffer size
|
|
||||||
const int kPayloadBytes = NetEq::kMaxBytesInBuffer + 1;
|
|
||||||
uint8_t payload[kPayloadBytes] = {0};
|
|
||||||
WebRtcRTPHeader rtp_info;
|
|
||||||
PopulateRtpInfo(0, 0, &rtp_info);
|
|
||||||
rtp_info.header.payloadType = 103; // iSAC, no packet splitting.
|
|
||||||
EXPECT_EQ(NetEq::kFail,
|
|
||||||
neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
|
|
||||||
EXPECT_EQ(NetEq::kOversizePacket, neteq_->LastError());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(DecoderError)) {
|
TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(DecoderError)) {
|
||||||
const int kPayloadBytes = 100;
|
const int kPayloadBytes = 100;
|
||||||
uint8_t payload[kPayloadBytes] = {0};
|
uint8_t payload[kPayloadBytes] = {0};
|
||||||
|
@@ -36,14 +36,8 @@ class NewTimestampIsLarger {
|
|||||||
const Packet* new_packet_;
|
const Packet* new_packet_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructor. The arguments define the maximum number of slots and maximum
|
PacketBuffer::PacketBuffer(size_t max_number_of_packets)
|
||||||
// payload memory (excluding RTP headers) that the buffer will accept.
|
: max_number_of_packets_(max_number_of_packets) {}
|
||||||
PacketBuffer::PacketBuffer(size_t max_number_of_packets,
|
|
||||||
size_t max_memory_bytes)
|
|
||||||
: max_number_of_packets_(max_number_of_packets),
|
|
||||||
max_memory_bytes_(max_memory_bytes),
|
|
||||||
current_memory_bytes_(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destructor. All packets in the buffer will be destroyed.
|
// Destructor. All packets in the buffer will be destroyed.
|
||||||
PacketBuffer::~PacketBuffer() {
|
PacketBuffer::~PacketBuffer() {
|
||||||
@@ -53,7 +47,6 @@ PacketBuffer::~PacketBuffer() {
|
|||||||
// Flush the buffer. All packets in the buffer will be destroyed.
|
// Flush the buffer. All packets in the buffer will be destroyed.
|
||||||
void PacketBuffer::Flush() {
|
void PacketBuffer::Flush() {
|
||||||
DeleteAllPackets(&buffer_);
|
DeleteAllPackets(&buffer_);
|
||||||
current_memory_bytes_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PacketBuffer::InsertPacket(Packet* packet) {
|
int PacketBuffer::InsertPacket(Packet* packet) {
|
||||||
@@ -66,22 +59,10 @@ int PacketBuffer::InsertPacket(Packet* packet) {
|
|||||||
|
|
||||||
int return_val = kOK;
|
int return_val = kOK;
|
||||||
|
|
||||||
if ((buffer_.size() >= max_number_of_packets_) ||
|
if (buffer_.size() >= max_number_of_packets_) {
|
||||||
(current_memory_bytes_ + packet->payload_length
|
|
||||||
> static_cast<int>(max_memory_bytes_))) {
|
|
||||||
// Buffer is full. Flush it.
|
// Buffer is full. Flush it.
|
||||||
Flush();
|
Flush();
|
||||||
return_val = kFlushed;
|
return_val = kFlushed;
|
||||||
if ((buffer_.size() >= max_number_of_packets_) ||
|
|
||||||
(current_memory_bytes_ + packet->payload_length
|
|
||||||
> static_cast<int>(max_memory_bytes_))) {
|
|
||||||
// Buffer is still too small for the packet. Either the buffer limits are
|
|
||||||
// really small, or the packet is really large. Delete the packet and
|
|
||||||
// return an error.
|
|
||||||
delete [] packet->payload;
|
|
||||||
delete packet;
|
|
||||||
return kOversizePacket;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an iterator pointing to the place in the buffer where the new packet
|
// Get an iterator pointing to the place in the buffer where the new packet
|
||||||
@@ -91,7 +72,6 @@ int PacketBuffer::InsertPacket(Packet* packet) {
|
|||||||
buffer_.rbegin(), buffer_.rend(),
|
buffer_.rbegin(), buffer_.rend(),
|
||||||
NewTimestampIsLarger(packet));
|
NewTimestampIsLarger(packet));
|
||||||
buffer_.insert(rit.base(), packet); // Insert the packet at that position.
|
buffer_.insert(rit.base(), packet); // Insert the packet at that position.
|
||||||
current_memory_bytes_ += packet->payload_length;
|
|
||||||
|
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
@@ -183,8 +163,6 @@ Packet* PacketBuffer::GetNextPacket(int* discard_count) {
|
|||||||
// Assert that the packet sanity checks in InsertPacket method works.
|
// Assert that the packet sanity checks in InsertPacket method works.
|
||||||
assert(packet && packet->payload);
|
assert(packet && packet->payload);
|
||||||
buffer_.pop_front();
|
buffer_.pop_front();
|
||||||
current_memory_bytes_ -= packet->payload_length;
|
|
||||||
assert(current_memory_bytes_ >= 0); // Assert bookkeeping is correct.
|
|
||||||
// Discard other packets with the same timestamp. These are duplicates or
|
// Discard other packets with the same timestamp. These are duplicates or
|
||||||
// redundant payloads that should not be used.
|
// redundant payloads that should not be used.
|
||||||
if (discard_count) {
|
if (discard_count) {
|
||||||
@@ -209,8 +187,6 @@ int PacketBuffer::DiscardNextPacket() {
|
|||||||
Packet* temp_packet = buffer_.front();
|
Packet* temp_packet = buffer_.front();
|
||||||
// Assert that the packet sanity checks in InsertPacket method works.
|
// Assert that the packet sanity checks in InsertPacket method works.
|
||||||
assert(temp_packet && temp_packet->payload);
|
assert(temp_packet && temp_packet->payload);
|
||||||
current_memory_bytes_ -= temp_packet->payload_length;
|
|
||||||
assert(current_memory_bytes_ >= 0); // Assert bookkeeping is correct.
|
|
||||||
DeleteFirstPacket(&buffer_);
|
DeleteFirstPacket(&buffer_);
|
||||||
return kOK;
|
return kOK;
|
||||||
}
|
}
|
||||||
@@ -280,14 +256,9 @@ void PacketBuffer::DeleteAllPackets(PacketList* packet_list) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacketBuffer::BufferStat(int* num_packets,
|
void PacketBuffer::BufferStat(int* num_packets, int* max_num_packets) const {
|
||||||
int* max_num_packets,
|
|
||||||
int* current_memory_bytes,
|
|
||||||
int* max_memory_bytes) const {
|
|
||||||
*num_packets = static_cast<int>(buffer_.size());
|
*num_packets = static_cast<int>(buffer_.size());
|
||||||
*max_num_packets = static_cast<int>(max_number_of_packets_);
|
*max_num_packets = static_cast<int>(max_number_of_packets_);
|
||||||
*current_memory_bytes = current_memory_bytes_;
|
|
||||||
*max_memory_bytes = static_cast<int>(max_memory_bytes_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@@ -29,14 +29,12 @@ class PacketBuffer {
|
|||||||
kNotFound,
|
kNotFound,
|
||||||
kBufferEmpty,
|
kBufferEmpty,
|
||||||
kInvalidPacket,
|
kInvalidPacket,
|
||||||
kInvalidPointer,
|
kInvalidPointer
|
||||||
kOversizePacket
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructor creates a buffer which can hold a maximum of
|
// Constructor creates a buffer which can hold a maximum of
|
||||||
// |max_number_of_packets| packets and |max_payload_memory| bytes of payload,
|
// |max_number_of_packets| packets.
|
||||||
// excluding RTP headers.
|
PacketBuffer(size_t max_number_of_packets);
|
||||||
PacketBuffer(size_t max_number_of_packets, size_t max_payload_memory);
|
|
||||||
|
|
||||||
// Deletes all packets in the buffer before destroying the buffer.
|
// Deletes all packets in the buffer before destroying the buffer.
|
||||||
virtual ~PacketBuffer();
|
virtual ~PacketBuffer();
|
||||||
@@ -116,12 +114,7 @@ class PacketBuffer {
|
|||||||
// The default value for |inc| is 1.
|
// The default value for |inc| is 1.
|
||||||
virtual void IncrementWaitingTimes(int inc = 1);
|
virtual void IncrementWaitingTimes(int inc = 1);
|
||||||
|
|
||||||
virtual void BufferStat(int* num_packets,
|
virtual void BufferStat(int* num_packets, int* max_num_packets) const;
|
||||||
int* max_num_packets,
|
|
||||||
int* current_memory_bytes,
|
|
||||||
int* max_memory_bytes) const;
|
|
||||||
|
|
||||||
virtual int current_memory_bytes() const { return current_memory_bytes_; }
|
|
||||||
|
|
||||||
// Static method that properly deletes the first packet, and its payload
|
// Static method that properly deletes the first packet, and its payload
|
||||||
// array, in |packet_list|. Returns false if |packet_list| already was empty,
|
// array, in |packet_list|. Returns false if |packet_list| already was empty,
|
||||||
@@ -134,8 +127,6 @@ class PacketBuffer {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
size_t max_number_of_packets_;
|
size_t max_number_of_packets_;
|
||||||
size_t max_memory_bytes_;
|
|
||||||
int current_memory_bytes_;
|
|
||||||
PacketList buffer_;
|
PacketList buffer_;
|
||||||
DISALLOW_COPY_AND_ASSIGN(PacketBuffer);
|
DISALLOW_COPY_AND_ASSIGN(PacketBuffer);
|
||||||
};
|
};
|
||||||
|
@@ -70,13 +70,13 @@ void PacketGenerator::SkipPacket() {
|
|||||||
// Start of test definitions.
|
// Start of test definitions.
|
||||||
|
|
||||||
TEST(PacketBuffer, CreateAndDestroy) {
|
TEST(PacketBuffer, CreateAndDestroy) {
|
||||||
PacketBuffer* buffer = new PacketBuffer(10, 1000); // 10 packets, 1000 bytes.
|
PacketBuffer* buffer = new PacketBuffer(10); // 10 packets.
|
||||||
EXPECT_TRUE(buffer->Empty());
|
EXPECT_TRUE(buffer->Empty());
|
||||||
delete buffer;
|
delete buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketBuffer, InsertPacket) {
|
TEST(PacketBuffer, InsertPacket) {
|
||||||
PacketBuffer buffer(10, 1000); // 10 packets, 1000 bytes.
|
PacketBuffer buffer(10); // 10 packets.
|
||||||
PacketGenerator gen(17u, 4711u, 0, 10);
|
PacketGenerator gen(17u, 4711u, 0, 10);
|
||||||
|
|
||||||
const int payload_len = 100;
|
const int payload_len = 100;
|
||||||
@@ -88,7 +88,6 @@ TEST(PacketBuffer, InsertPacket) {
|
|||||||
EXPECT_EQ(4711u, next_ts);
|
EXPECT_EQ(4711u, next_ts);
|
||||||
EXPECT_FALSE(buffer.Empty());
|
EXPECT_FALSE(buffer.Empty());
|
||||||
EXPECT_EQ(1, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(1, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_EQ(payload_len, buffer.current_memory_bytes());
|
|
||||||
const RTPHeader* hdr = buffer.NextRtpHeader();
|
const RTPHeader* hdr = buffer.NextRtpHeader();
|
||||||
EXPECT_EQ(&(packet->header), hdr); // Compare pointer addresses.
|
EXPECT_EQ(&(packet->header), hdr); // Compare pointer addresses.
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ TEST(PacketBuffer, InsertPacket) {
|
|||||||
|
|
||||||
// Test to flush buffer.
|
// Test to flush buffer.
|
||||||
TEST(PacketBuffer, FlushBuffer) {
|
TEST(PacketBuffer, FlushBuffer) {
|
||||||
PacketBuffer buffer(10, 1000); // 10 packets, 1000 bytes.
|
PacketBuffer buffer(10); // 10 packets.
|
||||||
PacketGenerator gen(0, 0, 0, 10);
|
PacketGenerator gen(0, 0, 0, 10);
|
||||||
const int payload_len = 10;
|
const int payload_len = 10;
|
||||||
|
|
||||||
@@ -109,18 +108,16 @@ TEST(PacketBuffer, FlushBuffer) {
|
|||||||
}
|
}
|
||||||
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_FALSE(buffer.Empty());
|
EXPECT_FALSE(buffer.Empty());
|
||||||
EXPECT_EQ(10 * payload_len, buffer.current_memory_bytes());
|
|
||||||
|
|
||||||
buffer.Flush();
|
buffer.Flush();
|
||||||
// Buffer should delete the payloads itself.
|
// Buffer should delete the payloads itself.
|
||||||
EXPECT_EQ(0, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(0, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_TRUE(buffer.Empty());
|
EXPECT_TRUE(buffer.Empty());
|
||||||
EXPECT_EQ(0, buffer.current_memory_bytes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test to fill the buffer over the limits, and verify that it flushes.
|
// Test to fill the buffer over the limits, and verify that it flushes.
|
||||||
TEST(PacketBuffer, OverfillBuffer) {
|
TEST(PacketBuffer, OverfillBuffer) {
|
||||||
PacketBuffer buffer(10, 1000); // 10 packets, 1000 bytes.
|
PacketBuffer buffer(10); // 10 packets.
|
||||||
PacketGenerator gen(0, 0, 0, 10);
|
PacketGenerator gen(0, 0, 0, 10);
|
||||||
|
|
||||||
// Insert 10 small packets; should be ok.
|
// Insert 10 small packets; should be ok.
|
||||||
@@ -131,7 +128,6 @@ TEST(PacketBuffer, OverfillBuffer) {
|
|||||||
EXPECT_EQ(PacketBuffer::kOK, buffer.InsertPacket(packet));
|
EXPECT_EQ(PacketBuffer::kOK, buffer.InsertPacket(packet));
|
||||||
}
|
}
|
||||||
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_EQ(10 * payload_len, buffer.current_memory_bytes());
|
|
||||||
uint32_t next_ts;
|
uint32_t next_ts;
|
||||||
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
|
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
|
||||||
EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
|
EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
|
||||||
@@ -140,30 +136,17 @@ TEST(PacketBuffer, OverfillBuffer) {
|
|||||||
Packet* packet = gen.NextPacket(payload_len);
|
Packet* packet = gen.NextPacket(payload_len);
|
||||||
EXPECT_EQ(PacketBuffer::kFlushed, buffer.InsertPacket(packet));
|
EXPECT_EQ(PacketBuffer::kFlushed, buffer.InsertPacket(packet));
|
||||||
EXPECT_EQ(1, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(1, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_EQ(payload_len, buffer.current_memory_bytes());
|
|
||||||
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
|
EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
|
||||||
// Expect last inserted packet to be first in line.
|
// Expect last inserted packet to be first in line.
|
||||||
EXPECT_EQ(packet->header.timestamp, next_ts);
|
EXPECT_EQ(packet->header.timestamp, next_ts);
|
||||||
|
|
||||||
// Insert 2 large packets; expect to flush when inserting the second one.
|
// Flush buffer to delete all packets.
|
||||||
const int large_payload_len = 500;
|
|
||||||
packet = gen.NextPacket(large_payload_len);
|
|
||||||
EXPECT_EQ(PacketBuffer::kOK, buffer.InsertPacket(packet));
|
|
||||||
EXPECT_EQ(2, buffer.NumPacketsInBuffer());
|
|
||||||
EXPECT_EQ(payload_len + large_payload_len, buffer.current_memory_bytes());
|
|
||||||
|
|
||||||
packet = gen.NextPacket(large_payload_len);
|
|
||||||
EXPECT_EQ(PacketBuffer::kFlushed, buffer.InsertPacket(packet));
|
|
||||||
EXPECT_EQ(1, buffer.NumPacketsInBuffer());
|
|
||||||
EXPECT_EQ(large_payload_len, buffer.current_memory_bytes());
|
|
||||||
|
|
||||||
// Flush buffer to delete remaining packets.
|
|
||||||
buffer.Flush();
|
buffer.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test inserting a list of packets.
|
// Test inserting a list of packets.
|
||||||
TEST(PacketBuffer, InsertPacketList) {
|
TEST(PacketBuffer, InsertPacketList) {
|
||||||
PacketBuffer buffer(10, 1000); // 10 packets, 1000 bytes.
|
PacketBuffer buffer(10); // 10 packets.
|
||||||
PacketGenerator gen(0, 0, 0, 10);
|
PacketGenerator gen(0, 0, 0, 10);
|
||||||
PacketList list;
|
PacketList list;
|
||||||
const int payload_len = 10;
|
const int payload_len = 10;
|
||||||
@@ -187,7 +170,6 @@ TEST(PacketBuffer, InsertPacketList) {
|
|||||||
¤t_cng_pt));
|
¤t_cng_pt));
|
||||||
EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
|
EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
|
||||||
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_EQ(10 * payload_len, buffer.current_memory_bytes());
|
|
||||||
EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
|
EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
|
||||||
EXPECT_EQ(0xFF, current_cng_pt); // CNG payload type not changed.
|
EXPECT_EQ(0xFF, current_cng_pt); // CNG payload type not changed.
|
||||||
|
|
||||||
@@ -200,7 +182,7 @@ TEST(PacketBuffer, InsertPacketList) {
|
|||||||
// Expecting the buffer to flush.
|
// Expecting the buffer to flush.
|
||||||
// TODO(hlundin): Remove this test when legacy operation is no longer needed.
|
// TODO(hlundin): Remove this test when legacy operation is no longer needed.
|
||||||
TEST(PacketBuffer, InsertPacketListChangePayloadType) {
|
TEST(PacketBuffer, InsertPacketListChangePayloadType) {
|
||||||
PacketBuffer buffer(10, 1000); // 10 packets, 1000 bytes.
|
PacketBuffer buffer(10); // 10 packets.
|
||||||
PacketGenerator gen(0, 0, 0, 10);
|
PacketGenerator gen(0, 0, 0, 10);
|
||||||
PacketList list;
|
PacketList list;
|
||||||
const int payload_len = 10;
|
const int payload_len = 10;
|
||||||
@@ -229,7 +211,6 @@ TEST(PacketBuffer, InsertPacketListChangePayloadType) {
|
|||||||
¤t_cng_pt));
|
¤t_cng_pt));
|
||||||
EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
|
EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
|
||||||
EXPECT_EQ(1, buffer.NumPacketsInBuffer()); // Only the last packet.
|
EXPECT_EQ(1, buffer.NumPacketsInBuffer()); // Only the last packet.
|
||||||
EXPECT_EQ(1 * payload_len, buffer.current_memory_bytes());
|
|
||||||
EXPECT_EQ(1, current_pt); // Current payload type changed to 0.
|
EXPECT_EQ(1, current_pt); // Current payload type changed to 0.
|
||||||
EXPECT_EQ(0xFF, current_cng_pt); // CNG payload type not changed.
|
EXPECT_EQ(0xFF, current_cng_pt); // CNG payload type not changed.
|
||||||
|
|
||||||
@@ -252,7 +233,7 @@ TEST(PacketBuffer, InsertPacketListChangePayloadType) {
|
|||||||
// 8 0x0005 0x00000028 0x0000001E
|
// 8 0x0005 0x00000028 0x0000001E
|
||||||
// 9 0x0006 0x00000032 0x00000028
|
// 9 0x0006 0x00000032 0x00000028
|
||||||
TEST(PacketBuffer, ExtractOrderRedundancy) {
|
TEST(PacketBuffer, ExtractOrderRedundancy) {
|
||||||
PacketBuffer buffer(100, 1000); // 100 packets, 1000 bytes.
|
PacketBuffer buffer(100); // 100 packets.
|
||||||
const uint32_t ts_increment = 10; // Samples per packet.
|
const uint32_t ts_increment = 10; // Samples per packet.
|
||||||
const uint16_t start_seq_no = 0xFFFF - 2; // Wraps after 3 packets.
|
const uint16_t start_seq_no = 0xFFFF - 2; // Wraps after 3 packets.
|
||||||
const uint32_t start_ts = 0xFFFFFFFF -
|
const uint32_t start_ts = 0xFFFFFFFF -
|
||||||
@@ -321,7 +302,7 @@ TEST(PacketBuffer, ExtractOrderRedundancy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketBuffer, DiscardPackets) {
|
TEST(PacketBuffer, DiscardPackets) {
|
||||||
PacketBuffer buffer(100, 1000); // 100 packets, 1000 bytes.
|
PacketBuffer buffer(100); // 100 packets.
|
||||||
const uint16_t start_seq_no = 17;
|
const uint16_t start_seq_no = 17;
|
||||||
const uint32_t start_ts = 4711;
|
const uint32_t start_ts = 4711;
|
||||||
const uint32_t ts_increment = 10;
|
const uint32_t ts_increment = 10;
|
||||||
@@ -335,7 +316,6 @@ TEST(PacketBuffer, DiscardPackets) {
|
|||||||
buffer.InsertPacket(packet);
|
buffer.InsertPacket(packet);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_EQ(10 * payload_len, buffer.current_memory_bytes());
|
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -351,7 +331,7 @@ TEST(PacketBuffer, DiscardPackets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketBuffer, Reordering) {
|
TEST(PacketBuffer, Reordering) {
|
||||||
PacketBuffer buffer(100, 1000); // 100 packets, 1000 bytes.
|
PacketBuffer buffer(100); // 100 packets.
|
||||||
const uint16_t start_seq_no = 17;
|
const uint16_t start_seq_no = 17;
|
||||||
const uint32_t start_ts = 4711;
|
const uint32_t start_ts = 4711;
|
||||||
const uint32_t ts_increment = 10;
|
const uint32_t ts_increment = 10;
|
||||||
@@ -384,7 +364,6 @@ TEST(PacketBuffer, Reordering) {
|
|||||||
¤t_pt,
|
¤t_pt,
|
||||||
¤t_cng_pt));
|
¤t_cng_pt));
|
||||||
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
EXPECT_EQ(10, buffer.NumPacketsInBuffer());
|
||||||
EXPECT_EQ(10 * payload_len, buffer.current_memory_bytes());
|
|
||||||
|
|
||||||
// Extract them and make sure that come out in the right order.
|
// Extract them and make sure that come out in the right order.
|
||||||
uint32_t current_ts = start_ts;
|
uint32_t current_ts = start_ts;
|
||||||
@@ -408,18 +387,8 @@ TEST(PacketBuffer, Failures) {
|
|||||||
int payload_len = 100;
|
int payload_len = 100;
|
||||||
PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
|
PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
|
||||||
|
|
||||||
PacketBuffer* buffer = new PacketBuffer(0, 1000); // 0 packets, 1000 bytes.
|
PacketBuffer* buffer = new PacketBuffer(100); // 100 packets.
|
||||||
Packet* packet = gen.NextPacket(payload_len);
|
Packet* packet = NULL;
|
||||||
EXPECT_EQ(PacketBuffer::kOversizePacket, buffer->InsertPacket(packet));
|
|
||||||
delete buffer;
|
|
||||||
|
|
||||||
buffer = new PacketBuffer(100, 10); // 100 packets, 10 bytes.
|
|
||||||
packet = gen.NextPacket(payload_len);
|
|
||||||
EXPECT_EQ(PacketBuffer::kOversizePacket, buffer->InsertPacket(packet));
|
|
||||||
delete buffer;
|
|
||||||
|
|
||||||
buffer = new PacketBuffer(100, 10000); // 100 packets, 10000 bytes.
|
|
||||||
packet = NULL;
|
|
||||||
EXPECT_EQ(PacketBuffer::kInvalidPacket, buffer->InsertPacket(packet));
|
EXPECT_EQ(PacketBuffer::kInvalidPacket, buffer->InsertPacket(packet));
|
||||||
packet = gen.NextPacket(payload_len);
|
packet = gen.NextPacket(payload_len);
|
||||||
delete [] packet->payload;
|
delete [] packet->payload;
|
||||||
@@ -448,7 +417,7 @@ TEST(PacketBuffer, Failures) {
|
|||||||
// Insert packet list of three packets, where the second packet has an invalid
|
// Insert packet list of three packets, where the second packet has an invalid
|
||||||
// payload. Expect first packet to be inserted, and the remaining two to be
|
// payload. Expect first packet to be inserted, and the remaining two to be
|
||||||
// discarded.
|
// discarded.
|
||||||
buffer = new PacketBuffer(100, 1000); // 100 packets, 1000 bytes.
|
buffer = new PacketBuffer(100); // 100 packets.
|
||||||
PacketList list;
|
PacketList list;
|
||||||
list.push_back(gen.NextPacket(payload_len)); // Valid packet.
|
list.push_back(gen.NextPacket(payload_len)); // Valid packet.
|
||||||
packet = gen.NextPacket(payload_len);
|
packet = gen.NextPacket(payload_len);
|
||||||
|
Reference in New Issue
Block a user