Request keyframe if too many packets are missing and NACK is disabled.

This allows enabling "EndToEndTest.ReceivesPliAndRecoversWithoutNack".

BUG=webrtc:2250

Review URL: https://codereview.webrtc.org/1211873004

Cr-Commit-Position: refs/heads/master@{#10747}
This commit is contained in:
jbauch
2015-11-23 03:59:02 -08:00
committed by Commit bot
parent fa8ae9a535
commit db81ffd6f5
3 changed files with 44 additions and 13 deletions

View File

@ -38,6 +38,10 @@ static const uint32_t kSsCleanupIntervalSec = 60;
// Use this rtt if no value has been reported. // Use this rtt if no value has been reported.
static const int64_t kDefaultRtt = 200; static const int64_t kDefaultRtt = 200;
// Request a keyframe if no continuous frame has been received for this
// number of milliseconds and NACKs are disabled.
static const int64_t kMaxDiscontinuousFramesTime = 1000;
typedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair; typedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair;
bool IsKeyFrame(FrameListPair pair) { bool IsKeyFrame(FrameListPair pair) {
@ -528,16 +532,25 @@ bool VCMJitterBuffer::NextMaybeIncompleteTimestamp(uint32_t* timestamp) {
CleanUpOldOrEmptyFrames(); CleanUpOldOrEmptyFrames();
VCMFrameBuffer* oldest_frame;
if (decodable_frames_.empty()) { if (decodable_frames_.empty()) {
return false; if (nack_mode_ != kNoNack || incomplete_frames_.size() <= 1) {
} return false;
VCMFrameBuffer* oldest_frame = decodable_frames_.Front(); }
// If we have exactly one frame in the buffer, release it only if it is oldest_frame = incomplete_frames_.Front();
// complete. We know decodable_frames_ is not empty due to the previous // Frame will only be removed from buffer if it is complete (or decodable).
// check. if (oldest_frame->GetState() < kStateComplete) {
if (decodable_frames_.size() == 1 && incomplete_frames_.empty() return false;
&& oldest_frame->GetState() != kStateComplete) { }
return false; } else {
oldest_frame = decodable_frames_.Front();
// If we have exactly one frame in the buffer, release it only if it is
// complete. We know decodable_frames_ is not empty due to the previous
// check.
if (decodable_frames_.size() == 1 && incomplete_frames_.empty()
&& oldest_frame->GetState() != kStateComplete) {
return false;
}
} }
*timestamp = oldest_frame->TimeStamp(); *timestamp = oldest_frame->TimeStamp();
@ -779,6 +792,11 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
FindAndInsertContinuousFrames(*frame); FindAndInsertContinuousFrames(*frame);
} else { } else {
incomplete_frames_.InsertFrame(frame); incomplete_frames_.InsertFrame(frame);
// If NACKs are enabled, keyframes are triggered by |GetNackList|.
if (nack_mode_ == kNoNack && NonContinuousOrIncompleteDuration() >
90 * kMaxDiscontinuousFramesTime) {
return kFlushIndicator;
}
} }
break; break;
} }
@ -789,6 +807,11 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
return kNoError; return kNoError;
} else { } else {
incomplete_frames_.InsertFrame(frame); incomplete_frames_.InsertFrame(frame);
// If NACKs are enabled, keyframes are triggered by |GetNackList|.
if (nack_mode_ == kNoNack && NonContinuousOrIncompleteDuration() >
90 * kMaxDiscontinuousFramesTime) {
return kFlushIndicator;
}
} }
break; break;
} }
@ -814,8 +837,6 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame,
const VCMDecodingState& decoding_state) const { const VCMDecodingState& decoding_state) const {
if (decode_error_mode_ == kWithErrors)
return true;
// Is this frame (complete or decodable) and continuous? // Is this frame (complete or decodable) and continuous?
// kStateDecodable will never be set when decode_error_mode_ is false // kStateDecodable will never be set when decode_error_mode_ is false
// as SessionInfo determines this state based on the error mode (and frame // as SessionInfo determines this state based on the error mode (and frame

View File

@ -1834,6 +1834,12 @@ TEST_F(TestBasicJitterBuffer, ExceedNumOfFrameWithSeqNumWrap) {
// -------------------------------------------------------------- // --------------------------------------------------------------
// |<-----------delta frames------------->|<------key frames----->| // |<-----------delta frames------------->|<------key frames----->|
// Make sure the jitter doesn't request a keyframe after too much non-
// decodable frames.
jitter_buffer_->SetNackMode(kNack, -1, -1);
jitter_buffer_->SetNackSettings(kMaxNumberOfFrames,
kMaxNumberOfFrames, 0);
int loop = 0; int loop = 0;
seq_num_ = 65485; seq_num_ = 65485;
uint32_t first_key_frame_timestamp = 0; uint32_t first_key_frame_timestamp = 0;
@ -2131,6 +2137,11 @@ TEST_F(TestBasicJitterBuffer, NextFrameWhenIncomplete) {
} }
TEST_F(TestRunningJitterBuffer, Full) { TEST_F(TestRunningJitterBuffer, Full) {
// Make sure the jitter doesn't request a keyframe after too much non-
// decodable frames.
jitter_buffer_->SetNackMode(kNack, -1, -1);
jitter_buffer_->SetNackSettings(kMaxNumberOfFrames,
kMaxNumberOfFrames, 0);
// Insert a key frame and decode it. // Insert a key frame and decode it.
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError); EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
EXPECT_TRUE(DecodeCompleteFrame()); EXPECT_TRUE(DecodeCompleteFrame());

View File

@ -1002,8 +1002,7 @@ TEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) {
ReceivesPliAndRecovers(1000); ReceivesPliAndRecovers(1000);
} }
// TODO(pbos): Enable this when 2250 is resolved. TEST_F(EndToEndTest, ReceivesPliAndRecoversWithoutNack) {
TEST_F(EndToEndTest, DISABLED_ReceivesPliAndRecoversWithoutNack) {
ReceivesPliAndRecovers(0); ReceivesPliAndRecovers(0);
} }