VCM: Setting buffering delay in timing

Review URL: https://webrtc-codereview.appspot.com/1338004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3921 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mikhal@webrtc.org
2013-04-30 15:39:34 +00:00
parent dd807ac474
commit 6faba6edc9
7 changed files with 26 additions and 47 deletions

View File

@@ -793,9 +793,9 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(VCMEncodedFrame* encoded_frame,
return ret; return ret;
} }
void VCMJitterBuffer::SetMaxJitterEstimate(uint32_t initial_delay_ms) { void VCMJitterBuffer::SetMaxJitterEstimate(bool enable) {
CriticalSectionScoped cs(crit_sect_); CriticalSectionScoped cs(crit_sect_);
jitter_estimate_.SetMaxJitterEstimate(initial_delay_ms); jitter_estimate_.SetMaxJitterEstimate(enable);
} }
uint32_t VCMJitterBuffer::EstimatedJitterMs() { uint32_t VCMJitterBuffer::EstimatedJitterMs() {

View File

@@ -135,7 +135,7 @@ class VCMJitterBuffer {
// Enable a max filter on the jitter estimate by setting an initial // Enable a max filter on the jitter estimate by setting an initial
// non-zero delay. When set to zero (default), the last jitter // non-zero delay. When set to zero (default), the last jitter
// estimate will be used. // estimate will be used.
void SetMaxJitterEstimate(uint32_t initial_delay_ms); void SetMaxJitterEstimate(bool enable);
// Returns the estimated jitter in milliseconds. // Returns the estimated jitter in milliseconds.
uint32_t EstimatedJitterMs(); uint32_t EstimatedJitterMs();

View File

@@ -177,12 +177,9 @@ TEST_F(TestRunningJitterBuffer, JitterEstimateMode) {
InsertFrame(kVideoFrameDelta); InsertFrame(kVideoFrameDelta);
EXPECT_FALSE(request_key_frame); EXPECT_FALSE(request_key_frame);
EXPECT_GT(20u, jitter_buffer_->EstimatedJitterMs()); EXPECT_GT(20u, jitter_buffer_->EstimatedJitterMs());
// Set kMaxEstimate with a 2 seconds initial delay. jitter_buffer_->SetMaxJitterEstimate(true);
jitter_buffer_->SetMaxJitterEstimate(2000u);
EXPECT_EQ(2000u, jitter_buffer_->EstimatedJitterMs());
InsertFrame(kVideoFrameDelta); InsertFrame(kVideoFrameDelta);
EXPECT_FALSE(request_key_frame); EXPECT_FALSE(request_key_frame);
EXPECT_EQ(2000u, jitter_buffer_->EstimatedJitterMs());
// Jitter cannot decrease. // Jitter cannot decrease.
InsertFrames(2, kVideoFrameDelta); InsertFrames(2, kVideoFrameDelta);
EXPECT_FALSE(request_key_frame); EXPECT_FALSE(request_key_frame);

View File

@@ -20,8 +20,6 @@
namespace webrtc { namespace webrtc {
enum { kInitialMaxJitterEstimate = 0 };
VCMJitterEstimator::VCMJitterEstimator(int32_t vcmId, int32_t receiverId) : VCMJitterEstimator::VCMJitterEstimator(int32_t vcmId, int32_t receiverId) :
_vcmId(vcmId), _vcmId(vcmId),
_receiverId(receiverId), _receiverId(receiverId),
@@ -37,7 +35,7 @@ _noiseStdDevs(2.33), // ~Less than 1% chance
_noiseStdDevOffset(30.0), // ...of getting 30 ms freezes _noiseStdDevOffset(30.0), // ...of getting 30 ms freezes
_rttFilter(vcmId, receiverId), _rttFilter(vcmId, receiverId),
_jitterEstimateMode(kLastEstimate), _jitterEstimateMode(kLastEstimate),
_maxJitterEstimateMs(kInitialMaxJitterEstimate) _maxJitterEstimateMs(0)
{ {
Reset(); Reset();
} }
@@ -407,13 +405,10 @@ VCMJitterEstimator::UpdateMaxFrameSize(uint32_t frameSizeBytes)
} }
} }
void VCMJitterEstimator::SetMaxJitterEstimate(uint32_t initial_delay_ms) void VCMJitterEstimator::SetMaxJitterEstimate(bool enable) {
{ if (enable) {
if (initial_delay_ms > 0) {
_maxJitterEstimateMs = initial_delay_ms;
_jitterEstimateMode = kMaxEstimate; _jitterEstimateMode = kMaxEstimate;
} else { } else {
_maxJitterEstimateMs = kInitialMaxJitterEstimate;
_jitterEstimateMode = kLastEstimate; _jitterEstimateMode = kLastEstimate;
} }
} }

View File

@@ -64,10 +64,9 @@ public:
void UpdateMaxFrameSize(uint32_t frameSizeBytes); void UpdateMaxFrameSize(uint32_t frameSizeBytes);
// Set a max filter on the jitter estimate by setting an initial // Set a max filter on the jitter estimate. When disabled (default), the
// non-zero delay. When set to zero (default), the last jitter // last jitter estimate will be used.
// estimate will be used. void SetMaxJitterEstimate(bool enable);
void SetMaxJitterEstimate(uint32_t initial_delay_ms);
// A constant describing the delay from the jitter buffer // A constant describing the delay from the jitter buffer
// to the delay on the receiving side which is not accounted // to the delay on the receiving side which is not accounted

View File

@@ -430,11 +430,11 @@ int VCMReceiver::SetMinReceiverDelay(int desired_delay_ms) {
if (desired_delay_ms < 0 || desired_delay_ms > kMaxReceiverDelayMs) { if (desired_delay_ms < 0 || desired_delay_ms > kMaxReceiverDelayMs) {
return -1; return -1;
} }
jitter_buffer_.SetMaxJitterEstimate(desired_delay_ms); // Enable a max filter on the jitter estimate for non-zero delays.
jitter_buffer_.SetMaxJitterEstimate(desired_delay_ms > 0);
max_video_delay_ms_ = desired_delay_ms + kMaxVideoDelayMs; max_video_delay_ms_ = desired_delay_ms + kMaxVideoDelayMs;
timing_->SetMaxVideoDelay(max_video_delay_ms_);
// Initializing timing to the desired delay. // Initializing timing to the desired delay.
timing_->SetRequiredDelay(desired_delay_ms); timing_->SetMinimumTotalDelay(desired_delay_ms);
return 0; return 0;
} }

View File

@@ -120,12 +120,6 @@ void VCMTiming::UpdateCurrentDelay(uint32_t frameTimestamp)
CriticalSectionScoped cs(_critSect); CriticalSectionScoped cs(_critSect);
uint32_t targetDelayMs = TargetDelayInternal(); uint32_t targetDelayMs = TargetDelayInternal();
// Make sure we try to sync with audio
if (targetDelayMs < _minTotalDelayMs)
{
targetDelayMs = _minTotalDelayMs;
}
if (_currentDelayMs == 0) if (_currentDelayMs == 0)
{ {
// Not initialized, set current delay to target. // Not initialized, set current delay to target.
@@ -159,14 +153,9 @@ void VCMTiming::UpdateCurrentDelay(uint32_t frameTimestamp)
// to reordering and should be ignored. // to reordering and should be ignored.
return; return;
} }
else if (delayDiffMs < -maxChangeMs) delayDiffMs = std::max(delayDiffMs, -maxChangeMs);
{ delayDiffMs = std::min(delayDiffMs, maxChangeMs);
delayDiffMs = -maxChangeMs;
}
else if (delayDiffMs > maxChangeMs)
{
delayDiffMs = maxChangeMs;
}
_currentDelayMs = _currentDelayMs + static_cast<int32_t>(delayDiffMs); _currentDelayMs = _currentDelayMs + static_cast<int32_t>(delayDiffMs);
} }
_prevFrameTimestamp = frameTimestamp; _prevFrameTimestamp = frameTimestamp;
@@ -177,18 +166,14 @@ void VCMTiming::UpdateCurrentDelay(int64_t renderTimeMs,
{ {
CriticalSectionScoped cs(_critSect); CriticalSectionScoped cs(_critSect);
uint32_t targetDelayMs = TargetDelayInternal(); uint32_t targetDelayMs = TargetDelayInternal();
// Make sure we try to sync with audio
if (targetDelayMs < _minTotalDelayMs)
{
targetDelayMs = _minTotalDelayMs;
}
int64_t delayedMs = actualDecodeTimeMs - int64_t delayedMs = actualDecodeTimeMs -
(renderTimeMs - MaxDecodeTimeMs() - _renderDelayMs); (renderTimeMs - MaxDecodeTimeMs() - _renderDelayMs);
if (delayedMs < 0) if (delayedMs < 0)
{ {
return; return;
} }
else if (_currentDelayMs + delayedMs <= targetDelayMs) if (_currentDelayMs + delayedMs <= targetDelayMs)
{ {
_currentDelayMs += static_cast<uint32_t>(delayedMs); _currentDelayMs += static_cast<uint32_t>(delayedMs);
} }
@@ -274,7 +259,10 @@ VCMTiming::RenderTimeMsInternal(uint32_t frameTimestamp, int64_t nowMs) const
{ {
estimatedCompleteTimeMs = nowMs; estimatedCompleteTimeMs = nowMs;
} }
return estimatedCompleteTimeMs + _currentDelayMs;
// Make sure that we have at least the total minimum delay.
uint32_t actual_delay = std::max(_currentDelayMs, _minTotalDelayMs);
return estimatedCompleteTimeMs + actual_delay;
} }
// Must be called from inside a critical section // Must be called from inside a critical section