Implementing APIs to set maximum and minimum for latency.
cpplint warnning fixed Ready for review BUG= R=minyue@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1971004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4563 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -34,7 +34,9 @@ DelayManager::DelayManager(int max_packets_in_buffer,
|
|||||||
streaming_mode_(false),
|
streaming_mode_(false),
|
||||||
last_seq_no_(0),
|
last_seq_no_(0),
|
||||||
last_timestamp_(0),
|
last_timestamp_(0),
|
||||||
extra_delay_ms_(0),
|
minimum_delay_ms_(0),
|
||||||
|
least_required_delay_ms_(target_level_),
|
||||||
|
maximum_delay_ms_(target_level_),
|
||||||
iat_cumulative_sum_(0),
|
iat_cumulative_sum_(0),
|
||||||
max_iat_cumulative_sum_(0),
|
max_iat_cumulative_sum_(0),
|
||||||
max_timer_ms_(0),
|
max_timer_ms_(0),
|
||||||
@@ -218,21 +220,34 @@ void DelayManager::UpdateHistogram(size_t iat_packets) {
|
|||||||
iat_factor_ += (kIatFactor_ - iat_factor_ + 3) >> 2;
|
iat_factor_ += (kIatFactor_ - iat_factor_ + 3) >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforces upper limit for |target_level_|. The limit is chosen to be
|
// Enforces upper and lower limits for |target_level_|. The upper limit is
|
||||||
// 75% of |max_packets_in_buffer_|, to leave some headroom for natural
|
// chosen to be minimum of i) 75% of |max_packets_in_buffer_|, to leave some
|
||||||
// fluctuations around the target. If an extra delay is requested, the
|
// headroom for natural fluctuations around the target, and ii) equivalent of
|
||||||
// cap is lowered even further. Note that in practice, this does not have
|
// |maximum_delay_ms_| in packets. Note that in practice, if no
|
||||||
// any impact, since the target level is far below the buffer capacity in
|
// |maximum_delay_ms_| is specified, this does not have any impact, since the
|
||||||
// all reasonable cases.
|
// target level is far below the buffer capacity in all reasonable cases.
|
||||||
|
// The lower limit is equivalent of |minimum_delay_ms_| in packets. We update
|
||||||
|
// |least_required_level_| while the above limits are applied.
|
||||||
// TODO(hlundin): Move this check to the buffer logistics class.
|
// TODO(hlundin): Move this check to the buffer logistics class.
|
||||||
void DelayManager::LimitTargetLevel() {
|
void DelayManager::LimitTargetLevel() {
|
||||||
int max_buffer_len = max_packets_in_buffer_;
|
least_required_delay_ms_ = (target_level_ * packet_len_ms_) >> 8;
|
||||||
if (extra_delay_ms_ > 0 && packet_len_ms_ > 0) {
|
|
||||||
max_buffer_len -= extra_delay_ms_ / packet_len_ms_;
|
if (packet_len_ms_ > 0 && minimum_delay_ms_ > 0) {
|
||||||
max_buffer_len = std::max(max_buffer_len, 1); // Sanity check.
|
int minimum_delay_packet_q8 = (minimum_delay_ms_ << 8) / packet_len_ms_;
|
||||||
|
target_level_ = std::max(target_level_, minimum_delay_packet_q8);
|
||||||
}
|
}
|
||||||
max_buffer_len = (3 * (max_buffer_len << 8)) / 4; // Shift to Q8, then 75%.
|
|
||||||
target_level_ = std::min(target_level_, max_buffer_len);
|
if (maximum_delay_ms_ > 0 && packet_len_ms_ > 0) {
|
||||||
|
int maximum_delay_packet_q8 = (maximum_delay_ms_ << 8) / packet_len_ms_;
|
||||||
|
target_level_ = std::min(target_level_, maximum_delay_packet_q8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift to Q8, then 75%.;
|
||||||
|
int max_buffer_packets_q8 = (3 * (max_packets_in_buffer_ << 8)) / 4;
|
||||||
|
target_level_ = std::min(target_level_, max_buffer_packets_q8);
|
||||||
|
|
||||||
|
// Sanity check, at least 1 packet (in Q8).
|
||||||
|
target_level_ = std::max(target_level_, 1 << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DelayManager::CalculateTargetLevel(int iat_packets) {
|
int DelayManager::CalculateTargetLevel(int iat_packets) {
|
||||||
@@ -331,6 +346,9 @@ void DelayManager::UpdateCounters(int elapsed_time_ms) {
|
|||||||
|
|
||||||
void DelayManager::ResetPacketIatCount() { packet_iat_count_ms_ = 0; }
|
void DelayManager::ResetPacketIatCount() { packet_iat_count_ms_ = 0; }
|
||||||
|
|
||||||
|
// Note that |low_limit| and |higher_limit| are not assigned to
|
||||||
|
// |minimum_delay_ms_| and |maximum_delay_ms_| defined by the client of this
|
||||||
|
// class. They are computed from |target_level_| and used for decision making.
|
||||||
void DelayManager::BufferLimits(int* lower_limit, int* higher_limit) const {
|
void DelayManager::BufferLimits(int* lower_limit, int* higher_limit) const {
|
||||||
if (!lower_limit || !higher_limit) {
|
if (!lower_limit || !higher_limit) {
|
||||||
LOG_F(LS_ERROR) << "NULL pointers supplied as input";
|
LOG_F(LS_ERROR) << "NULL pointers supplied as input";
|
||||||
@@ -338,29 +356,20 @@ void DelayManager::BufferLimits(int* lower_limit, int* higher_limit) const {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int extra_delay_packets_q8 = 0;
|
|
||||||
int window_20ms = 0x7FFF; // Default large value for legacy bit-exactness.
|
int window_20ms = 0x7FFF; // Default large value for legacy bit-exactness.
|
||||||
if (packet_len_ms_ > 0) {
|
if (packet_len_ms_ > 0) {
|
||||||
extra_delay_packets_q8 = (extra_delay_ms_ << 8) / packet_len_ms_;
|
|
||||||
window_20ms = (20 << 8) / packet_len_ms_;
|
window_20ms = (20 << 8) / packet_len_ms_;
|
||||||
}
|
}
|
||||||
// |lower_limit| is 75% of |target_level_| + extra delay.
|
|
||||||
// |target_level_| is in Q8 already.
|
// |target_level_| is in Q8 already.
|
||||||
*lower_limit = (target_level_ * 3) / 4 + extra_delay_packets_q8;
|
*lower_limit = (target_level_ * 3) / 4;
|
||||||
// |higher_limit| is equal to |target_level_| + extra delay, but should at
|
// |higher_limit| is equal to |target_level_|, but should at
|
||||||
// least be 20 ms higher than |lower_limit_|.
|
// least be 20 ms higher than |lower_limit_|.
|
||||||
*higher_limit = std::max(target_level_ + extra_delay_packets_q8,
|
*higher_limit = std::max(target_level_, *lower_limit + window_20ms);
|
||||||
*lower_limit + window_20ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DelayManager::TargetLevel() const {
|
int DelayManager::TargetLevel() const {
|
||||||
if (packet_len_ms_ > 0) {
|
|
||||||
// Add |extra_delay_ms_| converted to packets in Q8.
|
|
||||||
return target_level_ + (extra_delay_ms_ << 8) / packet_len_ms_;
|
|
||||||
} else {
|
|
||||||
// Cannot convert |extra_delay_ms_|; simply return |target_level_|.
|
|
||||||
return target_level_;
|
return target_level_;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelayManager::LastDecoderType(NetEqDecoder decoder_type) {
|
void DelayManager::LastDecoderType(NetEqDecoder decoder_type) {
|
||||||
@@ -375,8 +384,34 @@ void DelayManager::LastDecoderType(NetEqDecoder decoder_type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelayManager::set_extra_delay_ms(int16_t delay) {
|
bool DelayManager::SetMinimumDelay(int delay_ms) {
|
||||||
extra_delay_ms_ = delay;
|
// Minimum delay shouldn't be more than maximum delay, if any maximum is set.
|
||||||
|
// Also, if possible check |delay| to less than 75% of
|
||||||
|
// |max_packets_in_buffer_|.
|
||||||
|
if ((maximum_delay_ms_ > 0 && delay_ms > maximum_delay_ms_) ||
|
||||||
|
(packet_len_ms_ > 0 &&
|
||||||
|
delay_ms > 3 * max_packets_in_buffer_ * packet_len_ms_ / 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
minimum_delay_ms_ = delay_ms;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DelayManager::SetMaximumDelay(int delay_ms) {
|
||||||
|
if (delay_ms == 0) {
|
||||||
|
// Zero input unsets the maximum delay.
|
||||||
|
maximum_delay_ms_ = 0;
|
||||||
|
return true;
|
||||||
|
} else if (delay_ms < minimum_delay_ms_ || delay_ms < packet_len_ms_) {
|
||||||
|
// Maximum delay shouldn't be less than minimum delay or less than a packet.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
maximum_delay_ms_ = delay_ms;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DelayManager::least_required_delay_ms() const {
|
||||||
|
return least_required_delay_ms_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DelayManager::base_target_level() const { return base_target_level_; }
|
int DelayManager::base_target_level() const { return base_target_level_; }
|
||||||
|
|||||||
@@ -94,7 +94,10 @@ class DelayManager {
|
|||||||
virtual void LastDecoderType(NetEqDecoder decoder_type);
|
virtual void LastDecoderType(NetEqDecoder decoder_type);
|
||||||
|
|
||||||
// Accessors and mutators.
|
// Accessors and mutators.
|
||||||
virtual void set_extra_delay_ms(int16_t delay);
|
// Assuming |delay| is in valid range.
|
||||||
|
virtual bool SetMinimumDelay(int delay_ms);
|
||||||
|
virtual bool SetMaximumDelay(int delay_ms);
|
||||||
|
virtual int least_required_delay_ms() const;
|
||||||
virtual int base_target_level() const;
|
virtual int base_target_level() const;
|
||||||
virtual void set_streaming_mode(bool value);
|
virtual void set_streaming_mode(bool value);
|
||||||
virtual int last_pack_cng_or_dtmf() const;
|
virtual int last_pack_cng_or_dtmf() const;
|
||||||
@@ -135,13 +138,19 @@ class DelayManager {
|
|||||||
int packet_iat_count_ms_; // Milliseconds elapsed since last packet.
|
int packet_iat_count_ms_; // Milliseconds elapsed since last packet.
|
||||||
int base_target_level_; // Currently preferred buffer level before peak
|
int base_target_level_; // Currently preferred buffer level before peak
|
||||||
// detection and streaming mode (Q0).
|
// detection and streaming mode (Q0).
|
||||||
|
// TODO(turajs) change the comment according to the implementation of
|
||||||
|
// minimum-delay.
|
||||||
int target_level_; // Currently preferred buffer level in (fractions)
|
int target_level_; // Currently preferred buffer level in (fractions)
|
||||||
// of packets (Q8), before adding any extra delay.
|
// of packets (Q8), before adding any extra delay.
|
||||||
int packet_len_ms_; // Length of audio in each incoming packet [ms].
|
int packet_len_ms_; // Length of audio in each incoming packet [ms].
|
||||||
bool streaming_mode_;
|
bool streaming_mode_;
|
||||||
uint16_t last_seq_no_; // Sequence number for last received packet.
|
uint16_t last_seq_no_; // Sequence number for last received packet.
|
||||||
uint32_t last_timestamp_; // Timestamp for the last received packet.
|
uint32_t last_timestamp_; // Timestamp for the last received packet.
|
||||||
int extra_delay_ms_; // Externally set extra delay.
|
int minimum_delay_ms_; // Externally set minimum delay.
|
||||||
|
int least_required_delay_ms_; // Smallest preferred buffer level (same unit
|
||||||
|
// as |target_level_|), before applying
|
||||||
|
// |minimum_delay_ms_| and/or |maximum_delay_ms_|.
|
||||||
|
int maximum_delay_ms_; // Externally set maximum allowed delay.
|
||||||
int iat_cumulative_sum_; // Cumulative sum of delta inter-arrival times.
|
int iat_cumulative_sum_; // Cumulative sum of delta inter-arrival times.
|
||||||
int max_iat_cumulative_sum_; // Max of |iat_cumulative_sum_|.
|
int max_iat_cumulative_sum_; // Max of |iat_cumulative_sum_|.
|
||||||
int max_timer_ms_; // Time elapsed since maximum was observed.
|
int max_timer_ms_; // Time elapsed since maximum was observed.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
|
using ::testing::_;
|
||||||
|
|
||||||
class DelayManagerTest : public ::testing::Test {
|
class DelayManagerTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
@@ -193,9 +194,7 @@ TEST_F(DelayManagerTest, UpdatePeakFound) {
|
|||||||
EXPECT_EQ(5 << 8, higher);
|
EXPECT_EQ(5 << 8, higher);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DelayManagerTest, ExtraDelay) {
|
TEST_F(DelayManagerTest, TargetDelay) {
|
||||||
const int kExtraDelayMs = 200;
|
|
||||||
dm_->set_extra_delay_ms(kExtraDelayMs);
|
|
||||||
SetPacketAudioLength(kFrameSizeMs);
|
SetPacketAudioLength(kFrameSizeMs);
|
||||||
// First packet arrival.
|
// First packet arrival.
|
||||||
InsertNextPacket();
|
InsertNextPacket();
|
||||||
@@ -208,24 +207,91 @@ TEST_F(DelayManagerTest, ExtraDelay) {
|
|||||||
EXPECT_CALL(detector_, Update(1, 1))
|
EXPECT_CALL(detector_, Update(1, 1))
|
||||||
.WillOnce(Return(false));
|
.WillOnce(Return(false));
|
||||||
InsertNextPacket();
|
InsertNextPacket();
|
||||||
const int kExpectedTarget = 1 + kExtraDelayMs / kFrameSizeMs;
|
const int kExpectedTarget = 1;
|
||||||
EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel()); // In Q8.
|
EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel()); // In Q8.
|
||||||
EXPECT_EQ(1, dm_->base_target_level());
|
EXPECT_EQ(1, dm_->base_target_level());
|
||||||
int lower, higher;
|
int lower, higher;
|
||||||
dm_->BufferLimits(&lower, &higher);
|
dm_->BufferLimits(&lower, &higher);
|
||||||
// Expect |lower| to be 75% of base target level + extra delay, and |higher|
|
// Expect |lower| to be 75% of base target level, and |higher| to be
|
||||||
// to be target level + extra delay, but at least leave 20 ms headroom from
|
// lower + 20 ms headroom.
|
||||||
// lower.
|
EXPECT_EQ((1 << 8) * 3 / 4, lower);
|
||||||
EXPECT_EQ((1 << 8) * 3 / 4 + (kExtraDelayMs << 8) / kFrameSizeMs, lower);
|
|
||||||
EXPECT_EQ(lower + (20 << 8) / kFrameSizeMs, higher);
|
EXPECT_EQ(lower + (20 << 8) / kFrameSizeMs, higher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DelayManagerTest, MaxAndRequiredDelay) {
|
||||||
|
const int kExpectedTarget = 5;
|
||||||
|
const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
|
||||||
|
SetPacketAudioLength(kFrameSizeMs);
|
||||||
|
// First packet arrival.
|
||||||
|
InsertNextPacket();
|
||||||
|
// Second packet arrival.
|
||||||
|
// Expect detector update method to be called once with inter-arrival time
|
||||||
|
// equal to |kExpectedTarget| packet. Return true to indicate peaks found.
|
||||||
|
EXPECT_CALL(detector_, Update(kExpectedTarget, _))
|
||||||
|
.WillRepeatedly(Return(true));
|
||||||
|
EXPECT_CALL(detector_, MaxPeakHeight())
|
||||||
|
.WillRepeatedly(Return(kExpectedTarget));
|
||||||
|
IncreaseTime(kTimeIncrement);
|
||||||
|
InsertNextPacket();
|
||||||
|
|
||||||
|
// No limit is set.
|
||||||
|
EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel());
|
||||||
|
|
||||||
|
int kMaxDelayPackets = kExpectedTarget - 2;
|
||||||
|
int kMaxDelayMs = kMaxDelayPackets * kFrameSizeMs;
|
||||||
|
EXPECT_TRUE(dm_->SetMaximumDelay(kMaxDelayMs));
|
||||||
|
IncreaseTime(kTimeIncrement);
|
||||||
|
InsertNextPacket();
|
||||||
|
EXPECT_EQ(kExpectedTarget * kFrameSizeMs, dm_->least_required_delay_ms());
|
||||||
|
EXPECT_EQ(kMaxDelayPackets << 8, dm_->TargetLevel());
|
||||||
|
|
||||||
|
// Target level at least should be one packet.
|
||||||
|
EXPECT_FALSE(dm_->SetMaximumDelay(kFrameSizeMs - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DelayManagerTest, MinAndRequiredDelay) {
|
||||||
|
const int kExpectedTarget = 5;
|
||||||
|
const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
|
||||||
|
SetPacketAudioLength(kFrameSizeMs);
|
||||||
|
// First packet arrival.
|
||||||
|
InsertNextPacket();
|
||||||
|
// Second packet arrival.
|
||||||
|
// Expect detector update method to be called once with inter-arrival time
|
||||||
|
// equal to |kExpectedTarget| packet. Return true to indicate peaks found.
|
||||||
|
EXPECT_CALL(detector_, Update(kExpectedTarget, _))
|
||||||
|
.WillRepeatedly(Return(true));
|
||||||
|
EXPECT_CALL(detector_, MaxPeakHeight())
|
||||||
|
.WillRepeatedly(Return(kExpectedTarget));
|
||||||
|
IncreaseTime(kTimeIncrement);
|
||||||
|
InsertNextPacket();
|
||||||
|
|
||||||
|
// No limit is applied.
|
||||||
|
EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel());
|
||||||
|
|
||||||
|
int kMinDelayPackets = kExpectedTarget + 2;
|
||||||
|
int kMinDelayMs = kMinDelayPackets * kFrameSizeMs;
|
||||||
|
dm_->SetMinimumDelay(kMinDelayMs);
|
||||||
|
IncreaseTime(kTimeIncrement);
|
||||||
|
InsertNextPacket();
|
||||||
|
EXPECT_EQ(kExpectedTarget * kFrameSizeMs, dm_->least_required_delay_ms());
|
||||||
|
EXPECT_EQ(kMinDelayPackets << 8, dm_->TargetLevel());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(DelayManagerTest, Failures) {
|
TEST_F(DelayManagerTest, Failures) {
|
||||||
// Wrong sample rate.
|
// Wrong sample rate.
|
||||||
EXPECT_EQ(-1, dm_->Update(0, 0, -1));
|
EXPECT_EQ(-1, dm_->Update(0, 0, -1));
|
||||||
// Wrong packet size.
|
// Wrong packet size.
|
||||||
EXPECT_EQ(-1, dm_->SetPacketAudioLength(0));
|
EXPECT_EQ(-1, dm_->SetPacketAudioLength(0));
|
||||||
EXPECT_EQ(-1, dm_->SetPacketAudioLength(-1));
|
EXPECT_EQ(-1, dm_->SetPacketAudioLength(-1));
|
||||||
|
|
||||||
|
// Minimum delay higher than a maximum delay is not accepted.
|
||||||
|
EXPECT_TRUE(dm_->SetMaximumDelay(10));
|
||||||
|
EXPECT_FALSE(dm_->SetMinimumDelay(20));
|
||||||
|
|
||||||
|
// Maximum delay less than minimum delay is not accepted.
|
||||||
|
EXPECT_TRUE(dm_->SetMaximumDelay(100));
|
||||||
|
EXPECT_TRUE(dm_->SetMinimumDelay(80));
|
||||||
|
EXPECT_FALSE(dm_->SetMaximumDelay(60));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@@ -151,10 +151,22 @@ class NetEq {
|
|||||||
// -1 on failure.
|
// -1 on failure.
|
||||||
virtual int RemovePayloadType(uint8_t rtp_payload_type) = 0;
|
virtual int RemovePayloadType(uint8_t rtp_payload_type) = 0;
|
||||||
|
|
||||||
// Sets the desired extra delay on top of what NetEq already applies due to
|
// Sets a minimum delay in millisecond for packet buffer. The minimum is
|
||||||
// current network situation. Used for synchronization with video. Returns
|
// maintained unless a higher latency is dictated by channel condition.
|
||||||
// true if successful, otherwise false.
|
// Returns true if the minimum is successfully applied, otherwise false is
|
||||||
virtual bool SetExtraDelay(int extra_delay_ms) = 0;
|
// returned.
|
||||||
|
virtual bool SetMinimumDelay(int delay_ms) = 0;
|
||||||
|
|
||||||
|
// Sets a maximum delay in milliseconds for packet buffer. The latency will
|
||||||
|
// not exceed the given value, even required delay (given the channel
|
||||||
|
// conditions) is higher.
|
||||||
|
virtual bool SetMaximumDelay(int delay_ms) = 0;
|
||||||
|
|
||||||
|
// The smallest latency required. This is computed bases on inter-arrival
|
||||||
|
// time and internal NetEq logic. Note that in computing this latency none of
|
||||||
|
// the user defined limits (applied by calling setMinimumDelay() and/or
|
||||||
|
// SetMaximumDelay()) are applied.
|
||||||
|
virtual int LeastRequiredDelayMs() const = 0;
|
||||||
|
|
||||||
// Not implemented.
|
// Not implemented.
|
||||||
virtual int SetTargetDelay() = 0;
|
virtual int SetTargetDelay() = 0;
|
||||||
|
|||||||
@@ -236,16 +236,30 @@ int NetEqImpl::RemovePayloadType(uint8_t rtp_payload_type) {
|
|||||||
return kFail;
|
return kFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEqImpl::SetExtraDelay(int extra_delay_ms) {
|
bool NetEqImpl::SetMinimumDelay(int delay_ms) {
|
||||||
CriticalSectionScoped lock(crit_sect_);
|
CriticalSectionScoped lock(crit_sect_);
|
||||||
if (extra_delay_ms >= 0 && extra_delay_ms < 10000) {
|
if (delay_ms >= 0 && delay_ms < 10000) {
|
||||||
assert(delay_manager_.get());
|
assert(delay_manager_.get());
|
||||||
delay_manager_->set_extra_delay_ms(extra_delay_ms);
|
return delay_manager_->SetMinimumDelay(delay_ms);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NetEqImpl::SetMaximumDelay(int delay_ms) {
|
||||||
|
CriticalSectionScoped lock(crit_sect_);
|
||||||
|
if (delay_ms >= 0 && delay_ms < 10000) {
|
||||||
|
assert(delay_manager_.get());
|
||||||
|
return delay_manager_->SetMaximumDelay(delay_ms);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetEqImpl::LeastRequiredDelayMs() const {
|
||||||
|
CriticalSectionScoped lock(crit_sect_);
|
||||||
|
assert(delay_manager_.get());
|
||||||
|
return delay_manager_->least_required_delay_ms();
|
||||||
|
}
|
||||||
|
|
||||||
void NetEqImpl::SetPlayoutMode(NetEqPlayoutMode mode) {
|
void NetEqImpl::SetPlayoutMode(NetEqPlayoutMode mode) {
|
||||||
CriticalSectionScoped lock(crit_sect_);
|
CriticalSectionScoped lock(crit_sect_);
|
||||||
if (!decision_logic_.get() || mode != decision_logic_->playout_mode()) {
|
if (!decision_logic_.get() || mode != decision_logic_->playout_mode()) {
|
||||||
|
|||||||
@@ -102,10 +102,11 @@ class NetEqImpl : public webrtc::NetEq {
|
|||||||
// -1 on failure.
|
// -1 on failure.
|
||||||
virtual int RemovePayloadType(uint8_t rtp_payload_type);
|
virtual int RemovePayloadType(uint8_t rtp_payload_type);
|
||||||
|
|
||||||
// Sets the desired extra delay on top of what NetEq already applies due to
|
virtual bool SetMinimumDelay(int delay_ms);
|
||||||
// current network situation. Used for synchronization with video. Returns
|
|
||||||
// true if successful, otherwise false.
|
virtual bool SetMaximumDelay(int delay_ms);
|
||||||
virtual bool SetExtraDelay(int extra_delay_ms);
|
|
||||||
|
virtual int LeastRequiredDelayMs() const;
|
||||||
|
|
||||||
virtual int SetTargetDelay() { return kNotImplemented; }
|
virtual int SetTargetDelay() { return kNotImplemented; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user