Iterate over all VP9 GoF `pid_diff`s to determine frame references.

Currently `num_references` is decremented to skip a reference to a frame
prior to an upswitch point, but this also modified the loop condition in
such a way that we didn't end up looking at all the `pid_diff`s.

Bug: none
Change-Id: I89b9581ce86c09955723589851d3ce373c66a5b5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/475921
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#47816}
diff --git a/modules/video_coding/rtp_vp9_ref_finder.cc b/modules/video_coding/rtp_vp9_ref_finder.cc
index 4f5969a..ab2345f 100644
--- a/modules/video_coding/rtp_vp9_ref_finder.cc
+++ b/modules/video_coding/rtp_vp9_ref_finder.cc
@@ -205,18 +205,20 @@
     }
 
     // Populate references according to the scalability structure.
-    frame->num_references = info->gof->num_ref_pics[gof_idx];
-    for (size_t i = 0; i < frame->num_references; ++i) {
-      frame->references[i] = Subtract<kFrameIdLength>(
+    size_t num_references = 0;
+    for (size_t i = 0; i < info->gof->num_ref_pics[gof_idx]; ++i) {
+      int64_t reference = Subtract<kFrameIdLength>(
           frame->Id(), info->gof->pid_diff[gof_idx][i]);
 
       // If this is a reference to a frame earlier than the last up switch
       // point, then ignore this reference.
       if (UpSwitchInIntervalVp9(frame->Id(), codec_header.temporal_idx,
-                                frame->references[i])) {
-        --frame->num_references;
+                                reference)) {
+        continue;
       }
+      frame->references[num_references++] = reference;
     }
+    frame->num_references = num_references;
   } else {
     frame->num_references = 0;
   }
diff --git a/modules/video_coding/rtp_vp9_ref_finder_unittest.cc b/modules/video_coding/rtp_vp9_ref_finder_unittest.cc
index 0ca1a3b..17ca806 100644
--- a/modules/video_coding/rtp_vp9_ref_finder_unittest.cc
+++ b/modules/video_coding/rtp_vp9_ref_finder_unittest.cc
@@ -716,4 +716,35 @@
   EXPECT_THAT(frames_, SizeIs(0));
 }
 
+TEST_F(RtpVp9RefFinderTest, GofUpSwitchMultipleRefs) {
+  GofInfoVP9 ss;
+  ss.num_frames_in_gof = 3;
+
+  ss.temporal_idx[0] = 0;
+  ss.num_ref_pics[0] = 1;
+  ss.pid_diff[0][0] = 3;
+
+  ss.temporal_idx[1] = 1;
+  ss.num_ref_pics[1] = 1;
+  ss.pid_diff[1][0] = 1;
+
+  ss.temporal_idx[2] = 2;
+  ss.num_ref_pics[2] = 2;
+  ss.pid_diff[2][0] = 2;
+  ss.pid_diff[2][1] = 1;
+
+  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().Gof(&ss));
+  EXPECT_THAT(frames_, SizeIs(1));
+  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
+  Insert(Frame().Pid(1).SidAndTid(0, 1).Tl0(0).AsUpswitch());
+  EXPECT_THAT(frames_, SizeIs(2));
+  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
+
+  // Since PID0 was prior to the upswitch frame (PID1), the reference from PID2
+  // to PID0 should be removed.
+  Insert(Frame().Pid(2).SidAndTid(0, 2).Tl0(0));
+  EXPECT_THAT(frames_, SizeIs(3));
+  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {5}));
+}
+
 }  // namespace webrtc