From 146a48b0fabef7e74f2a2b62fb5cb45f9b393408 Mon Sep 17 00:00:00 2001 From: philipel Date: Thu, 20 Apr 2017 04:04:38 -0700 Subject: [PATCH] Check if the order of frames becomes ambiguous if we were to insert the incoming frame, and if so, clear the FrameBuffer. BUG=chromium:679306 Review-Url: https://codereview.webrtc.org/2830723002 Cr-Commit-Position: refs/heads/master@{#17785} --- webrtc/modules/video_coding/frame_buffer2.cc | 14 +++++++++++++- .../video_coding/frame_buffer2_unittest.cc | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/webrtc/modules/video_coding/frame_buffer2.cc b/webrtc/modules/video_coding/frame_buffer2.cc index fcd523820f..acc1bb83c5 100644 --- a/webrtc/modules/video_coding/frame_buffer2.cc +++ b/webrtc/modules/video_coding/frame_buffer2.cc @@ -93,7 +93,8 @@ FrameBuffer::ReturnReason FrameBuffer::NextFrame( if (continuous_end_it != frames_.end()) ++continuous_end_it; - for (; frame_it != continuous_end_it; ++frame_it) { + for (; frame_it != continuous_end_it && frame_it != frames_.end(); + ++frame_it) { if (!frame_it->second.continuous || frame_it->second.num_missing_decodable > 0) { continue; @@ -233,6 +234,17 @@ int FrameBuffer::InsertFrame(std::unique_ptr frame) { } } + // Test if inserting this frame would cause the order of the frames to become + // ambiguous (covering more than half the interval of 2^16). This can happen + // when the picture id make large jumps mid stream. + if (!frames_.empty() && + key < frames_.begin()->first && + frames_.rbegin()->first < key) { + LOG(LS_WARNING) << "A jump in picture id was detected, clearing buffer."; + ClearFramesAndHistory(); + last_continuous_picture_id = -1; + } + auto info = frames_.insert(std::make_pair(key, FrameInfo())).first; if (info->second.frame) { diff --git a/webrtc/modules/video_coding/frame_buffer2_unittest.cc b/webrtc/modules/video_coding/frame_buffer2_unittest.cc index b67d99376f..04ce5595a5 100644 --- a/webrtc/modules/video_coding/frame_buffer2_unittest.cc +++ b/webrtc/modules/video_coding/frame_buffer2_unittest.cc @@ -497,5 +497,24 @@ TEST_F(TestFrameBuffer2, StatsCallback) { CheckFrame(0, pid, 0); } +TEST_F(TestFrameBuffer2, ForwardJumps) { + EXPECT_EQ(5453, InsertFrame(5453, 0, 1, false)); + ExtractFrame(); + EXPECT_EQ(5454, InsertFrame(5454, 0, 1, false, 5453)); + ExtractFrame(); + EXPECT_EQ(15670, InsertFrame(15670, 0, 1, false)); + ExtractFrame(); + EXPECT_EQ(29804, InsertFrame(29804, 0, 1, false)); + ExtractFrame(); + EXPECT_EQ(29805, InsertFrame(29805, 0, 1, false, 29804)); + ExtractFrame(); + EXPECT_EQ(29806, InsertFrame(29806, 0, 1, false, 29805)); + ExtractFrame(); + EXPECT_EQ(33819, InsertFrame(33819, 0, 1, false)); + ExtractFrame(); + EXPECT_EQ(41248, InsertFrame(41248, 0, 1, false)); + ExtractFrame(); +} + } // namespace video_coding } // namespace webrtc