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}
diff --git a/webrtc/modules/video_coding/jitter_buffer.cc b/webrtc/modules/video_coding/jitter_buffer.cc
index 15195db..d44d2b6 100644
--- a/webrtc/modules/video_coding/jitter_buffer.cc
+++ b/webrtc/modules/video_coding/jitter_buffer.cc
@@ -38,6 +38,10 @@
// Use this rtt if no value has been reported.
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;
bool IsKeyFrame(FrameListPair pair) {
@@ -528,16 +532,25 @@
CleanUpOldOrEmptyFrames();
+ VCMFrameBuffer* oldest_frame;
if (decodable_frames_.empty()) {
- return false;
- }
- VCMFrameBuffer* 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;
+ if (nack_mode_ != kNoNack || incomplete_frames_.size() <= 1) {
+ return false;
+ }
+ oldest_frame = incomplete_frames_.Front();
+ // Frame will only be removed from buffer if it is complete (or decodable).
+ if (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();
@@ -779,6 +792,11 @@
FindAndInsertContinuousFrames(*frame);
} else {
incomplete_frames_.InsertFrame(frame);
+ // If NACKs are enabled, keyframes are triggered by |GetNackList|.
+ if (nack_mode_ == kNoNack && NonContinuousOrIncompleteDuration() >
+ 90 * kMaxDiscontinuousFramesTime) {
+ return kFlushIndicator;
+ }
}
break;
}
@@ -789,6 +807,11 @@
return kNoError;
} else {
incomplete_frames_.InsertFrame(frame);
+ // If NACKs are enabled, keyframes are triggered by |GetNackList|.
+ if (nack_mode_ == kNoNack && NonContinuousOrIncompleteDuration() >
+ 90 * kMaxDiscontinuousFramesTime) {
+ return kFlushIndicator;
+ }
}
break;
}
@@ -814,8 +837,6 @@
bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame,
const VCMDecodingState& decoding_state) const {
- if (decode_error_mode_ == kWithErrors)
- return true;
// Is this frame (complete or decodable) and continuous?
// kStateDecodable will never be set when decode_error_mode_ is false
// as SessionInfo determines this state based on the error mode (and frame
diff --git a/webrtc/modules/video_coding/jitter_buffer_unittest.cc b/webrtc/modules/video_coding/jitter_buffer_unittest.cc
index 52151ea..116bf08 100644
--- a/webrtc/modules/video_coding/jitter_buffer_unittest.cc
+++ b/webrtc/modules/video_coding/jitter_buffer_unittest.cc
@@ -1834,6 +1834,12 @@
// --------------------------------------------------------------
// |<-----------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;
seq_num_ = 65485;
uint32_t first_key_frame_timestamp = 0;
@@ -2131,6 +2137,11 @@
}
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.
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
EXPECT_TRUE(DecodeCompleteFrame());
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index e541d37..3659955 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -1002,8 +1002,7 @@
ReceivesPliAndRecovers(1000);
}
-// TODO(pbos): Enable this when 2250 is resolved.
-TEST_F(EndToEndTest, DISABLED_ReceivesPliAndRecoversWithoutNack) {
+TEST_F(EndToEndTest, ReceivesPliAndRecoversWithoutNack) {
ReceivesPliAndRecovers(0);
}