Clear the FrameBuffer in case of a backward jump in the picture id.
Even though this is against the spec we allow a stream to continue if
a backwards jump in the picture id occurs on a keyframe.
BUG=webrtc:7001, webrtc:5514
Review-Url: https://codereview.webrtc.org/2640793003
Cr-Original-Commit-Position: refs/heads/master@{#16146}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: fcc600651dfe50e2d6e27fc77e5acbf04f5a63cd
diff --git a/modules/video_coding/frame_buffer2.cc b/modules/video_coding/frame_buffer2.cc
index 279c613..58c41bf 100644
--- a/modules/video_coding/frame_buffer2.cc
+++ b/modules/video_coding/frame_buffer2.cc
@@ -135,6 +135,7 @@
PropagateDecodability(next_frame_it->second);
AdvanceLastDecodedFrame(next_frame_it);
+ last_decoded_frame_timestamp_ = frame->timestamp;
*frame_out = std::move(frame);
return kFrameFound;
} else {
@@ -189,14 +190,27 @@
if (last_decoded_frame_it_ != frames_.end() &&
key < last_decoded_frame_it_->first) {
- LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id
- << ":" << static_cast<int>(key.spatial_layer)
- << ") inserted after frame ("
- << last_decoded_frame_it_->first.picture_id << ":"
- << static_cast<int>(
- last_decoded_frame_it_->first.spatial_layer)
- << ") was handed off for decoding, dropping frame.";
- return last_continuous_picture_id;
+ if (AheadOf(frame->timestamp, last_decoded_frame_timestamp_) &&
+ frame->num_references == 0) {
+ // If this frame has a newer timestamp but an earlier picture id then we
+ // assume there has been a jump in the picture id due to some encoder
+ // reconfiguration or some other reason. Even though this is not according
+ // to spec we can still continue to decode from this frame if it is a
+ // keyframe.
+ LOG(LS_WARNING) << "A jump in picture id was detected, clearing buffer.";
+ ClearFramesAndHistory();
+ last_continuous_picture_id = -1;
+ } else {
+ LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) ("
+ << key.picture_id << ":"
+ << static_cast<int>(key.spatial_layer)
+ << ") inserted after frame ("
+ << last_decoded_frame_it_->first.picture_id << ":"
+ << static_cast<int>(
+ last_decoded_frame_it_->first.spatial_layer)
+ << ") was handed off for decoding, dropping frame.";
+ return last_continuous_picture_id;
+ }
}
auto info = frames_.insert(std::make_pair(key, FrameInfo())).first;
@@ -390,5 +404,13 @@
}
}
+void FrameBuffer::ClearFramesAndHistory() {
+ frames_.clear();
+ last_decoded_frame_it_ = frames_.end();
+ last_continuous_frame_it_ = frames_.end();
+ num_frames_history_ = 0;
+ num_frames_buffered_ = 0;
+}
+
} // namespace video_coding
} // namespace webrtc