diff --git a/modules/video_coding/rtp_frame_reference_finder.cc b/modules/video_coding/rtp_frame_reference_finder.cc index 79f11cd8a4..d24bc112c9 100644 --- a/modules/video_coding/rtp_frame_reference_finder.cc +++ b/modules/video_coding/rtp_frame_reference_finder.cc @@ -554,6 +554,7 @@ bool RtpFrameReferenceFinder::MissingRequiredFrameVp9(uint16_t picture_id, void RtpFrameReferenceFinder::FrameReceivedVp9(uint16_t picture_id, GofInfo* info) { int last_picture_id = info->last_picture_id; + size_t gof_size = std::min(info->gof->num_frames_in_gof, kMaxVp9FramesInGof); // If there is a gap, find which temporal layer the missing frames // belong to and add the frame as missing for that temporal layer. @@ -561,22 +562,38 @@ void RtpFrameReferenceFinder::FrameReceivedVp9(uint16_t picture_id, if (AheadOf(picture_id, last_picture_id)) { size_t diff = ForwardDiff(info->gof->pid_start, last_picture_id); - size_t gof_idx = diff % info->gof->num_frames_in_gof; + size_t gof_idx = diff % gof_size; last_picture_id = Add(last_picture_id, 1); while (last_picture_id != picture_id) { - ++gof_idx; - RTC_DCHECK_NE(0ul, gof_idx % info->gof->num_frames_in_gof); + gof_idx = (gof_idx + 1) % gof_size; + RTC_CHECK(gof_idx < kMaxVp9FramesInGof); + size_t temporal_idx = info->gof->temporal_idx[gof_idx]; + if (temporal_idx >= kMaxTemporalLayers) { + RTC_LOG(LS_WARNING) << "At most " << kMaxTemporalLayers << " temporal " + << "layers are supported."; + return; + } + missing_frames_for_layer_[temporal_idx].insert(last_picture_id); last_picture_id = Add(last_picture_id, 1); } + info->last_picture_id = last_picture_id; } else { size_t diff = ForwardDiff(info->gof->pid_start, picture_id); - size_t gof_idx = diff % info->gof->num_frames_in_gof; + size_t gof_idx = diff % gof_size; + RTC_CHECK(gof_idx < kMaxVp9FramesInGof); + size_t temporal_idx = info->gof->temporal_idx[gof_idx]; + if (temporal_idx >= kMaxTemporalLayers) { + RTC_LOG(LS_WARNING) << "At most " << kMaxTemporalLayers << " temporal " + << "layers are supported."; + return; + } + missing_frames_for_layer_[temporal_idx].erase(picture_id); } } diff --git a/modules/video_coding/rtp_frame_reference_finder_unittest.cc b/modules/video_coding/rtp_frame_reference_finder_unittest.cc index de02a43c36..0d150ed4d8 100644 --- a/modules/video_coding/rtp_frame_reference_finder_unittest.cc +++ b/modules/video_coding/rtp_frame_reference_finder_unittest.cc @@ -1321,5 +1321,15 @@ TEST_F(TestRtpFrameReferenceFinder, WrappingFlexReference) { CheckReferencesVp9(1, 0, 0); } +TEST_F(TestRtpFrameReferenceFinder, Vp9GofPidJump) { + uint16_t pid = Rand(); + uint16_t sn = Rand(); + GofInfoVP9 ss; + ss.SetGofInfoVP9(kTemporalStructureMode3); + + InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss); + InsertVp9Gof(sn + 1, sn + 1, false, pid + 1000, 0, 0, 1); +} + } // namespace video_coding } // namespace webrtc