Fix wraparound issue in FrameInstrumentationGenerator.

This prevents an RTC_CHECK from triggering if the sequence index
wraparound happens on a delta frame.

Bug: webrtc:440978611, chromium:440989756
Change-Id: I4d893687391e87a0d2a8476d0db70153b0e8a768
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/406100
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Fanny Linderborg <linderborg@webrtc.org>
Auto-Submit: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45426}
diff --git a/video/corruption_detection/frame_instrumentation_generator.cc b/video/corruption_detection/frame_instrumentation_generator.cc
index be02930..160f9fb 100644
--- a/video/corruption_detection/frame_instrumentation_generator.cc
+++ b/video/corruption_detection/frame_instrumentation_generator.cc
@@ -140,17 +140,17 @@
     }
 
     int sequence_index = contexts_[layer_id].frame_sampler.GetCurrentIndex();
-    if (is_key_frame) {
+    if (is_key_frame && ((sequence_index & 0b0111'1111) != 0)) {
       // Increase until all the last 7 bits are zeroes.
-      // If this would overflow to 15 bits, reset to 0.
-      if (sequence_index > 0b0011'1111'1000'0000) {
-        sequence_index = 0;
-      } else if ((sequence_index & 0b0111'1111) != 0) {
-        // Last 7 bits are not all zeroes.
-        sequence_index >>= 7;
-        sequence_index += 1;
-        sequence_index <<= 7;
-      }
+      sequence_index >>= 7;
+      sequence_index += 1;
+      sequence_index <<= 7;
+      contexts_[layer_id].frame_sampler.SetCurrentIndex(sequence_index);
+    }
+
+    if (sequence_index >= (1 << 14)) {
+      // Overflow of 14 bit counter, reset to 0.
+      sequence_index = 0;
       contexts_[layer_id].frame_sampler.SetCurrentIndex(sequence_index);
     }
 
diff --git a/video/corruption_detection/frame_instrumentation_generator_unittest.cc b/video/corruption_detection/frame_instrumentation_generator_unittest.cc
index 0cf2975..264c801 100644
--- a/video/corruption_detection/frame_instrumentation_generator_unittest.cc
+++ b/video/corruption_detection/frame_instrumentation_generator_unittest.cc
@@ -581,6 +581,54 @@
   EXPECT_EQ(data1->sequence_index(), 0b0000'1000'0000);
   EXPECT_EQ(data2->sequence_index(), 0b0001'0000'0000);
 }
+TEST(FrameInstrumentationGeneratorTest,
+     SequenceIndexThatWouldOverflowTo15BitsIncreasesCorrectlyAtNewDeltaFrame) {
+  FrameInstrumentationGenerator generator(VideoCodecType::kVideoCodecVP8);
+  generator.OnCapturedFrame(
+      VideoFrame::Builder()
+          .set_video_frame_buffer(MakeI420FrameBufferWithDifferentPixelValues())
+          .set_rtp_timestamp(1)
+          .build());
+  EncodedImage encoded_image;
+  encoded_image.SetRtpTimestamp(1);
+  encoded_image.SetFrameType(VideoFrameType::kVideoFrameDelta);
+  encoded_image.qp_ = 10;
+  encoded_image._encodedWidth = kDefaultScaledWidth;
+  encoded_image._encodedHeight = kDefaultScaledHeight;
+  encoded_image.SetSimulcastIndex(0);
+
+  constexpr int kMaxSequenceIndex = 0b11'1111'1111'1111;
+
+  generator.SetHaltonSequenceIndex(kMaxSequenceIndex,
+                                   generator.GetLayerId(encoded_image));
+  std::optional<FrameInstrumentationData> data =
+      generator.OnEncodedImage(encoded_image);
+
+  ASSERT_TRUE(data.has_value());
+  EXPECT_EQ(data->sequence_index(), kMaxSequenceIndex);
+
+  // Loop until we get a new delta frame.
+  bool has_found_delta_frame = false;
+  for (int i = 0; i < 34; ++i) {
+    generator.OnCapturedFrame(
+        VideoFrame::Builder()
+            .set_video_frame_buffer(
+                MakeI420FrameBufferWithDifferentPixelValues())
+            .set_rtp_timestamp(i + 2)
+            .build());
+
+    encoded_image.SetRtpTimestamp(i + 2);
+
+    std::optional<FrameInstrumentationData> frame_instrumentation_data =
+        generator.OnEncodedImage(encoded_image);
+    if (frame_instrumentation_data.has_value()) {
+      has_found_delta_frame = true;
+      EXPECT_EQ(frame_instrumentation_data->sequence_index(), 0);
+      break;
+    }
+  }
+  EXPECT_TRUE(has_found_delta_frame);
+}
 
 TEST(FrameInstrumentationGeneratorTest, GetterAndSetterOperatesAsExpected) {
   FrameInstrumentationGenerator generator(VideoCodecType::kVideoCodecVP8);