RtpFrameReferenceFinder return frames directly instead of via callback.

Bug: webrtc:12579
Change-Id: I41263f70a6f3dc60167e41f8b015a7d3b0dc3dd7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219633
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@google.com>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34136}
diff --git a/modules/video_coding/rtp_frame_reference_finder.cc b/modules/video_coding/rtp_frame_reference_finder.cc
index a060f84..a44b76b 100644
--- a/modules/video_coding/rtp_frame_reference_finder.cc
+++ b/modules/video_coding/rtp_frame_reference_finder.cc
@@ -142,31 +142,34 @@
 
 }  // namespace internal
 
-RtpFrameReferenceFinder::RtpFrameReferenceFinder(
-    OnCompleteFrameCallback* frame_callback)
-    : RtpFrameReferenceFinder(frame_callback, 0) {}
+RtpFrameReferenceFinder::RtpFrameReferenceFinder()
+    : RtpFrameReferenceFinder(0) {}
 
 RtpFrameReferenceFinder::RtpFrameReferenceFinder(
-    OnCompleteFrameCallback* frame_callback,
     int64_t picture_id_offset)
     : picture_id_offset_(picture_id_offset),
-      frame_callback_(frame_callback),
       impl_(std::make_unique<internal::RtpFrameReferenceFinderImpl>()) {}
 
 RtpFrameReferenceFinder::~RtpFrameReferenceFinder() = default;
 
-void RtpFrameReferenceFinder::ManageFrame(
+RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinder::ManageFrame(
     std::unique_ptr<RtpFrameObject> frame) {
   // If we have cleared past this frame, drop it.
   if (cleared_to_seq_num_ != -1 &&
       AheadOf<uint16_t>(cleared_to_seq_num_, frame->first_seq_num())) {
-    return;
+    return {};
   }
-  HandOffFrames(impl_->ManageFrame(std::move(frame)));
+
+  auto frames = impl_->ManageFrame(std::move(frame));
+  AddPictureIdOffset(frames);
+  return frames;
 }
 
-void RtpFrameReferenceFinder::PaddingReceived(uint16_t seq_num) {
-  HandOffFrames(impl_->PaddingReceived(seq_num));
+RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinder::PaddingReceived(
+    uint16_t seq_num) {
+  auto frames = impl_->PaddingReceived(seq_num);
+  AddPictureIdOffset(frames);
+  return frames;
 }
 
 void RtpFrameReferenceFinder::ClearTo(uint16_t seq_num) {
@@ -174,14 +177,12 @@
   impl_->ClearTo(seq_num);
 }
 
-void RtpFrameReferenceFinder::HandOffFrames(ReturnVector frames) {
+void RtpFrameReferenceFinder::AddPictureIdOffset(ReturnVector& frames) {
   for (auto& frame : frames) {
     frame->SetId(frame->Id() + picture_id_offset_);
     for (size_t i = 0; i < frame->num_references; ++i) {
       frame->references[i] += picture_id_offset_;
     }
-
-    frame_callback_->OnCompleteFrame(std::move(frame));
   }
 }
 
diff --git a/modules/video_coding/rtp_frame_reference_finder.h b/modules/video_coding/rtp_frame_reference_finder.h
index 3577ea8..d244777 100644
--- a/modules/video_coding/rtp_frame_reference_finder.h
+++ b/modules/video_coding/rtp_frame_reference_finder.h
@@ -20,47 +20,38 @@
 class RtpFrameReferenceFinderImpl;
 }  // namespace internal
 
-// A complete frame is a frame which has received all its packets and all its
-// references are known.
-class OnCompleteFrameCallback {
- public:
-  virtual ~OnCompleteFrameCallback() {}
-  virtual void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) = 0;
-};
-
 class RtpFrameReferenceFinder {
  public:
   using ReturnVector = absl::InlinedVector<std::unique_ptr<RtpFrameObject>, 3>;
 
-  explicit RtpFrameReferenceFinder(OnCompleteFrameCallback* frame_callback);
-  explicit RtpFrameReferenceFinder(OnCompleteFrameCallback* frame_callback,
-                                   int64_t picture_id_offset);
+  RtpFrameReferenceFinder();
+  explicit RtpFrameReferenceFinder(int64_t picture_id_offset);
   ~RtpFrameReferenceFinder();
 
-  // Manage this frame until:
-  //  - We have all information needed to determine its references, after
-  //    which |frame_callback_| is called with the completed frame, or
-  //  - We have too many stashed frames (determined by |kMaxStashedFrames|)
-  //    so we drop this frame, or
-  //  - It gets cleared by ClearTo, which also means we drop it.
-  void ManageFrame(std::unique_ptr<RtpFrameObject> frame);
+  // The RtpFrameReferenceFinder will hold onto the frame until:
+  //  - the required information to determine its references has been received,
+  //    in which case it (and possibly other) frames are returned, or
+  //  - There are too many stashed frames (determined by |kMaxStashedFrames|),
+  //    in which case it gets dropped, or
+  //  - It gets cleared by ClearTo, in which case its dropped.
+  //  - The frame is old, in which case it also gets dropped.
+  ReturnVector ManageFrame(std::unique_ptr<RtpFrameObject> frame);
 
   // Notifies that padding has been received, which the reference finder
   // might need to calculate the references of a frame.
-  void PaddingReceived(uint16_t seq_num);
+  ReturnVector PaddingReceived(uint16_t seq_num);
 
   // Clear all stashed frames that include packets older than |seq_num|.
   void ClearTo(uint16_t seq_num);
 
  private:
-  void HandOffFrames(ReturnVector frames);
+  void AddPictureIdOffset(ReturnVector& frames);
 
   // How far frames have been cleared out of the buffer by RTP sequence number.
   // A frame will be cleared if it contains a packet with a sequence number
   // older than |cleared_to_seq_num_|.
   int cleared_to_seq_num_ = -1;
   const int64_t picture_id_offset_;
-  OnCompleteFrameCallback* frame_callback_;
   std::unique_ptr<internal::RtpFrameReferenceFinderImpl> impl_;
 };
 
diff --git a/modules/video_coding/rtp_frame_reference_finder_unittest.cc b/modules/video_coding/rtp_frame_reference_finder_unittest.cc
index 5141b49..a5b0fc4 100644
--- a/modules/video_coding/rtp_frame_reference_finder_unittest.cc
+++ b/modules/video_coding/rtp_frame_reference_finder_unittest.cc
@@ -60,28 +60,29 @@
 }
 }  // namespace
 
-class TestRtpFrameReferenceFinder : public ::testing::Test,
-                                    public OnCompleteFrameCallback {
+class TestRtpFrameReferenceFinder : public ::testing::Test {
  protected:
   TestRtpFrameReferenceFinder()
       : rand_(0x8739211),
-        reference_finder_(new RtpFrameReferenceFinder(this)),
+        reference_finder_(std::make_unique<RtpFrameReferenceFinder>()),
         frames_from_callback_(FrameComp()) {}
 
   uint16_t Rand() { return rand_.Rand<uint16_t>(); }
 
-  void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) override {
-    int64_t pid = frame->Id();
-    uint16_t sidx = *frame->SpatialIndex();
-    auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
-    if (frame_it != frames_from_callback_.end()) {
-      ADD_FAILURE() << "Already received frame with (pid:sidx): (" << pid << ":"
-                    << sidx << ")";
-      return;
-    }
+  void OnCompleteFrames(RtpFrameReferenceFinder::ReturnVector frames) {
+    for (auto& frame : frames) {
+      int64_t pid = frame->Id();
+      uint16_t sidx = *frame->SpatialIndex();
+      auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
+      if (frame_it != frames_from_callback_.end()) {
+        ADD_FAILURE() << "Already received frame with (pid:sidx): (" << pid
+                      << ":" << sidx << ")";
+        return;
+      }
 
-    frames_from_callback_.insert(
-        std::make_pair(std::make_pair(pid, sidx), std::move(frame)));
+      frames_from_callback_.insert(
+          std::make_pair(std::make_pair(pid, sidx), std::move(frame)));
+    }
   }
 
   void InsertGeneric(uint16_t seq_num_start,
@@ -91,14 +92,18 @@
         CreateFrame(seq_num_start, seq_num_end, keyframe, kVideoCodecGeneric,
                     RTPVideoTypeHeader());
 
-    reference_finder_->ManageFrame(std::move(frame));
+    OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
   }
 
   void InsertH264(uint16_t seq_num_start, uint16_t seq_num_end, bool keyframe) {
     std::unique_ptr<RtpFrameObject> frame =
         CreateFrame(seq_num_start, seq_num_end, keyframe, kVideoCodecH264,
                     RTPVideoTypeHeader());
-    reference_finder_->ManageFrame(std::move(frame));
+    OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
+  }
+
+  void InsertPadding(uint16_t seq_num) {
+    OnCompleteFrames(reference_finder_->PaddingReceived(seq_num));
   }
 
   // Check if a frame with picture id |pid| and spatial index |sidx| has been
@@ -165,7 +170,7 @@
   InsertGeneric(sn, sn, true);
   InsertGeneric(sn + 2, sn + 2, false);
   EXPECT_EQ(1UL, frames_from_callback_.size());
-  reference_finder_->PaddingReceived(sn + 1);
+  InsertPadding(sn + 1);
   EXPECT_EQ(2UL, frames_from_callback_.size());
 }
 
@@ -173,8 +178,8 @@
   uint16_t sn = Rand();
 
   InsertGeneric(sn, sn, true);
-  reference_finder_->PaddingReceived(sn + 1);
-  reference_finder_->PaddingReceived(sn + 4);
+  InsertPadding(sn + 1);
+  InsertPadding(sn + 4);
   InsertGeneric(sn + 2, sn + 3, false);
 
   EXPECT_EQ(2UL, frames_from_callback_.size());
@@ -186,12 +191,12 @@
   uint16_t sn = Rand();
 
   InsertGeneric(sn, sn, true);
-  reference_finder_->PaddingReceived(sn + 1);
-  reference_finder_->PaddingReceived(sn + 4);
+  InsertPadding(sn + 1);
+  InsertPadding(sn + 4);
   InsertGeneric(sn + 2, sn + 3, false);
   InsertGeneric(sn + 5, sn + 5, true);
-  reference_finder_->PaddingReceived(sn + 6);
-  reference_finder_->PaddingReceived(sn + 9);
+  InsertPadding(sn + 6);
+  InsertPadding(sn + 9);
   InsertGeneric(sn + 7, sn + 8, false);
 
   EXPECT_EQ(4UL, frames_from_callback_.size());
@@ -308,7 +313,7 @@
       CreateFrame(/*seq_num_start=*/sn, /*seq_num_end=*/sn, /*keyframe=*/true,
                   kVideoCodecAV1, RTPVideoTypeHeader());
 
-  reference_finder_->ManageFrame(std::move(frame));
+  OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
 
   ASSERT_EQ(1UL, frames_from_callback_.size());
   CheckReferencesGeneric(sn);
diff --git a/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc b/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
index aeeb5c0..fdb4aa5 100644
--- a/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
+++ b/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
@@ -12,9 +12,7 @@
 
 #include "api/rtp_packet_infos.h"
 #include "modules/video_coding/frame_object.h"
-#include "modules/video_coding/packet_buffer.h"
 #include "modules/video_coding/rtp_frame_reference_finder.h"
-#include "system_wrappers/include/clock.h"
 
 namespace webrtc {
 
@@ -58,10 +56,6 @@
   size_t offset_ = 0;
 };
 
-class NullCallback : public OnCompleteFrameCallback {
-  void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) override {}
-};
-
 absl::optional<RTPVideoHeader::GenericDescriptorInfo>
 GenerateGenericFrameDependencies(DataReader* reader) {
   absl::optional<RTPVideoHeader::GenericDescriptorInfo> result;
@@ -91,8 +85,7 @@
 
 void FuzzOneInput(const uint8_t* data, size_t size) {
   DataReader reader(data, size);
-  NullCallback cb;
-  RtpFrameReferenceFinder reference_finder(&cb);
+  RtpFrameReferenceFinder reference_finder;
 
   auto codec = static_cast<VideoCodecType>(reader.GetNum<uint8_t>() % 5);
 
diff --git a/video/rtp_video_stream_receiver.cc b/video/rtp_video_stream_receiver.cc
index 7286a3b..a0520cd 100644
--- a/video/rtp_video_stream_receiver.cc
+++ b/video/rtp_video_stream_receiver.cc
@@ -272,6 +272,7 @@
       // directly with |rtp_rtcp_|.
       rtcp_feedback_buffer_(this, nack_sender, this),
       packet_buffer_(kPacketBufferStartSize, PacketBufferMaxSize()),
+      reference_finder_(std::make_unique<RtpFrameReferenceFinder>()),
       has_received_frame_(false),
       frames_decryptable_(false),
       absolute_capture_time_interpolator_(clock) {
@@ -321,8 +322,6 @@
     process_thread_->RegisterModule(nack_module_.get(), RTC_FROM_HERE);
   }
 
-  reference_finder_ = std::make_unique<RtpFrameReferenceFinder>(this);
-
   // Only construct the encrypted receiver if frame encryption is enabled.
   if (config_.crypto_options.sframe.require_frame_encryption) {
     buffered_frame_decryptor_ =
@@ -886,7 +885,6 @@
         // start from the |last_completed_picture_id_| and add an offset in
         // case of reordering.
         reference_finder_ = std::make_unique<RtpFrameReferenceFinder>(
-            this,
             last_completed_picture_id_ + std::numeric_limits<uint16_t>::max());
         current_codec_ = frame->codec_type();
       } else {
@@ -908,26 +906,30 @@
   } else if (frame_transformer_delegate_) {
     frame_transformer_delegate_->TransformFrame(std::move(frame));
   } else {
-    reference_finder_->ManageFrame(std::move(frame));
+    OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
   }
 }
 
-void RtpVideoStreamReceiver::OnCompleteFrame(
-    std::unique_ptr<EncodedFrame> frame) {
+void RtpVideoStreamReceiver::OnCompleteFrames(
+    RtpFrameReferenceFinder::ReturnVector frames) {
   {
     MutexLock lock(&last_seq_num_mutex_);
-    RtpFrameObject* rtp_frame = static_cast<RtpFrameObject*>(frame.get());
-    last_seq_num_for_pic_id_[rtp_frame->Id()] = rtp_frame->last_seq_num();
+    for (const auto& frame : frames) {
+      RtpFrameObject* rtp_frame = static_cast<RtpFrameObject*>(frame.get());
+      last_seq_num_for_pic_id_[rtp_frame->Id()] = rtp_frame->last_seq_num();
+    }
   }
-  last_completed_picture_id_ =
-      std::max(last_completed_picture_id_, frame->Id());
-  complete_frame_callback_->OnCompleteFrame(std::move(frame));
+  for (auto& frame : frames) {
+    last_completed_picture_id_ =
+        std::max(last_completed_picture_id_, frame->Id());
+    complete_frame_callback_->OnCompleteFrame(std::move(frame));
+  }
 }
 
 void RtpVideoStreamReceiver::OnDecryptedFrame(
     std::unique_ptr<RtpFrameObject> frame) {
   MutexLock lock(&reference_finder_lock_);
-  reference_finder_->ManageFrame(std::move(frame));
+  OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
 }
 
 void RtpVideoStreamReceiver::OnDecryptionStatusChange(
@@ -1003,7 +1005,7 @@
 void RtpVideoStreamReceiver::ManageFrame(
     std::unique_ptr<RtpFrameObject> frame) {
   MutexLock lock(&reference_finder_lock_);
-  reference_finder_->ManageFrame(std::move(frame));
+  OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
 }
 
 void RtpVideoStreamReceiver::ReceivePacket(const RtpPacketReceived& packet) {
@@ -1058,7 +1060,7 @@
 void RtpVideoStreamReceiver::NotifyReceiverOfEmptyPacket(uint16_t seq_num) {
   {
     MutexLock lock(&reference_finder_lock_);
-    reference_finder_->PaddingReceived(seq_num);
+    OnCompleteFrames(reference_finder_->PaddingReceived(seq_num));
   }
 
   video_coding::PacketBuffer::InsertResult insert_result;
diff --git a/video/rtp_video_stream_receiver.h b/video/rtp_video_stream_receiver.h
index a302e1e..b2abe42 100644
--- a/video/rtp_video_stream_receiver.h
+++ b/video/rtp_video_stream_receiver.h
@@ -69,11 +69,18 @@
                                public RecoveredPacketReceiver,
                                public RtpPacketSinkInterface,
                                public KeyFrameRequestSender,
-                               public OnCompleteFrameCallback,
                                public OnDecryptedFrameCallback,
                                public OnDecryptionStatusChangeCallback,
                                public RtpVideoFrameReceiver {
  public:
+  // A complete frame is a frame which has received all its packets and all its
+  // references are known.
+  class OnCompleteFrameCallback {
+   public:
+    virtual ~OnCompleteFrameCallback() {}
+    virtual void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) = 0;
+  };
+
   // DEPRECATED due to dependency on ReceiveStatisticsProxy.
   RtpVideoStreamReceiver(
       Clock* clock,
@@ -173,8 +180,7 @@
   // Don't use, still experimental.
   void RequestPacketRetransmit(const std::vector<uint16_t>& sequence_numbers);
 
-  // Implements OnCompleteFrameCallback.
-  void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) override;
+  void OnCompleteFrames(RtpFrameReferenceFinder::ReturnVector frames);
 
   // Implements OnDecryptedFrameCallback.
   void OnDecryptedFrame(std::unique_ptr<RtpFrameObject> frame) override;
@@ -419,6 +425,9 @@
       RTC_GUARDED_BY(packet_buffer_lock_);
 };
 
+// TODO(philipel): Remove when downstream has been updated.
+using OnCompleteFrameCallback = RtpVideoStreamReceiver::OnCompleteFrameCallback;
+
 }  // namespace webrtc
 
 #endif  // VIDEO_RTP_VIDEO_STREAM_RECEIVER_H_
diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc
index a45dbeb..8a71181 100644
--- a/video/rtp_video_stream_receiver2.cc
+++ b/video/rtp_video_stream_receiver2.cc
@@ -251,6 +251,7 @@
                                             &rtcp_feedback_buffer_,
                                             &rtcp_feedback_buffer_)),
       packet_buffer_(kPacketBufferStartSize, PacketBufferMaxSize()),
+      reference_finder_(std::make_unique<RtpFrameReferenceFinder>()),
       has_received_frame_(false),
       frames_decryptable_(false),
       absolute_capture_time_interpolator_(clock) {
@@ -295,8 +296,6 @@
                                                      &rtcp_feedback_buffer_);
   }
 
-  reference_finder_ = std::make_unique<RtpFrameReferenceFinder>(this);
-
   // Only construct the encrypted receiver if frame encryption is enabled.
   if (config_.crypto_options.sframe.require_frame_encryption) {
     buffered_frame_decryptor_ =
@@ -832,7 +831,6 @@
         // start from the |last_completed_picture_id_| and add an offset in case
         // of reordering.
         reference_finder_ = std::make_unique<RtpFrameReferenceFinder>(
-            this,
             last_completed_picture_id_ + std::numeric_limits<uint16_t>::max());
         current_codec_ = frame->codec_type();
       } else {
@@ -854,25 +852,27 @@
   } else if (frame_transformer_delegate_) {
     frame_transformer_delegate_->TransformFrame(std::move(frame));
   } else {
-    reference_finder_->ManageFrame(std::move(frame));
+    OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
   }
 }
 
-void RtpVideoStreamReceiver2::OnCompleteFrame(
-    std::unique_ptr<EncodedFrame> frame) {
-  RTC_DCHECK_RUN_ON(&worker_task_checker_);
-  RtpFrameObject* rtp_frame = static_cast<RtpFrameObject*>(frame.get());
-  last_seq_num_for_pic_id_[rtp_frame->Id()] = rtp_frame->last_seq_num();
+void RtpVideoStreamReceiver2::OnCompleteFrames(
+    RtpFrameReferenceFinder::ReturnVector frames) {
+  for (auto& frame : frames) {
+    RTC_DCHECK_RUN_ON(&worker_task_checker_);
+    RtpFrameObject* rtp_frame = static_cast<RtpFrameObject*>(frame.get());
+    last_seq_num_for_pic_id_[rtp_frame->Id()] = rtp_frame->last_seq_num();
 
-  last_completed_picture_id_ =
-      std::max(last_completed_picture_id_, frame->Id());
-  complete_frame_callback_->OnCompleteFrame(std::move(frame));
+    last_completed_picture_id_ =
+        std::max(last_completed_picture_id_, frame->Id());
+    complete_frame_callback_->OnCompleteFrame(std::move(frame));
+  }
 }
 
 void RtpVideoStreamReceiver2::OnDecryptedFrame(
     std::unique_ptr<RtpFrameObject> frame) {
   RTC_DCHECK_RUN_ON(&worker_task_checker_);
-  reference_finder_->ManageFrame(std::move(frame));
+  OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
 }
 
 void RtpVideoStreamReceiver2::OnDecryptionStatusChange(
@@ -931,7 +931,7 @@
 void RtpVideoStreamReceiver2::ManageFrame(
     std::unique_ptr<RtpFrameObject> frame) {
   RTC_DCHECK_RUN_ON(&worker_task_checker_);
-  reference_finder_->ManageFrame(std::move(frame));
+  OnCompleteFrames(reference_finder_->ManageFrame(std::move(frame)));
 }
 
 void RtpVideoStreamReceiver2::ReceivePacket(const RtpPacketReceived& packet) {
@@ -987,7 +987,7 @@
 void RtpVideoStreamReceiver2::NotifyReceiverOfEmptyPacket(uint16_t seq_num) {
   RTC_DCHECK_RUN_ON(&worker_task_checker_);
 
-  reference_finder_->PaddingReceived(seq_num);
+  OnCompleteFrames(reference_finder_->PaddingReceived(seq_num));
 
   OnInsertedPacket(packet_buffer_.InsertPadding(seq_num));
   if (nack_module_) {
diff --git a/video/rtp_video_stream_receiver2.h b/video/rtp_video_stream_receiver2.h
index f8d5a26..ab14060 100644
--- a/video/rtp_video_stream_receiver2.h
+++ b/video/rtp_video_stream_receiver2.h
@@ -65,11 +65,18 @@
                                 public RecoveredPacketReceiver,
                                 public RtpPacketSinkInterface,
                                 public KeyFrameRequestSender,
-                                public OnCompleteFrameCallback,
                                 public OnDecryptedFrameCallback,
                                 public OnDecryptionStatusChangeCallback,
                                 public RtpVideoFrameReceiver {
  public:
+  // A complete frame is a frame which has received all its packets and all its
+  // references are known.
+  class OnCompleteFrameCallback {
+   public:
+    virtual ~OnCompleteFrameCallback() {}
+    virtual void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) = 0;
+  };
+
   RtpVideoStreamReceiver2(
       TaskQueueBase* current_queue,
       Clock* clock,
@@ -149,8 +156,7 @@
   // Don't use, still experimental.
   void RequestPacketRetransmit(const std::vector<uint16_t>& sequence_numbers);
 
-  // Implements OnCompleteFrameCallback.
-  void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) override;
+  void OnCompleteFrames(RtpFrameReferenceFinder::ReturnVector frame);
 
   // Implements OnDecryptedFrameCallback.
   void OnDecryptedFrame(std::unique_ptr<RtpFrameObject> frame) override;
diff --git a/video/rtp_video_stream_receiver2_unittest.cc b/video/rtp_video_stream_receiver2_unittest.cc
index 9ade57d..d22f12e 100644
--- a/video/rtp_video_stream_receiver2_unittest.cc
+++ b/video/rtp_video_stream_receiver2_unittest.cc
@@ -94,7 +94,8 @@
   MOCK_METHOD(void, RequestKeyFrame, (), (override));
 };
 
-class MockOnCompleteFrameCallback : public OnCompleteFrameCallback {
+class MockOnCompleteFrameCallback
+    : public RtpVideoStreamReceiver2::OnCompleteFrameCallback {
  public:
   MOCK_METHOD(void, DoOnCompleteFrame, (EncodedFrame*), ());
   MOCK_METHOD(void, DoOnCompleteFrameFailNullptr, (EncodedFrame*), ());
diff --git a/video/rtp_video_stream_receiver_unittest.cc b/video/rtp_video_stream_receiver_unittest.cc
index 5a79b2a..765e1e1 100644
--- a/video/rtp_video_stream_receiver_unittest.cc
+++ b/video/rtp_video_stream_receiver_unittest.cc
@@ -93,7 +93,8 @@
   MOCK_METHOD(void, RequestKeyFrame, (), (override));
 };
 
-class MockOnCompleteFrameCallback : public OnCompleteFrameCallback {
+class MockOnCompleteFrameCallback
+    : public RtpVideoStreamReceiver::OnCompleteFrameCallback {
  public:
   MOCK_METHOD(void, DoOnCompleteFrame, (EncodedFrame*), ());
   MOCK_METHOD(void, DoOnCompleteFrameFailNullptr, (EncodedFrame*), ());
diff --git a/video/video_receive_stream.h b/video/video_receive_stream.h
index f3b5189..9bea0b8f 100644
--- a/video/video_receive_stream.h
+++ b/video/video_receive_stream.h
@@ -45,12 +45,13 @@
 
 namespace internal {
 
-class VideoReceiveStream : public webrtc::DEPRECATED_VideoReceiveStream,
-                           public rtc::VideoSinkInterface<VideoFrame>,
-                           public NackSender,
-                           public OnCompleteFrameCallback,
-                           public Syncable,
-                           public CallStatsObserver {
+class VideoReceiveStream
+    : public webrtc::DEPRECATED_VideoReceiveStream,
+      public rtc::VideoSinkInterface<VideoFrame>,
+      public NackSender,
+      public RtpVideoStreamReceiver::OnCompleteFrameCallback,
+      public Syncable,
+      public CallStatsObserver {
  public:
   // The default number of milliseconds to pass before re-requesting a key frame
   // to be sent.
@@ -111,7 +112,7 @@
   void SendNack(const std::vector<uint16_t>& sequence_numbers,
                 bool buffering_allowed) override;
 
-  // Implements OnCompleteFrameCallback.
+  // Implements RtpVideoStreamReceiver::OnCompleteFrameCallback.
   void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) override;
 
   // Implements CallStatsObserver::OnRttUpdate
diff --git a/video/video_receive_stream2.h b/video/video_receive_stream2.h
index c22ce1c..f952de2 100644
--- a/video/video_receive_stream2.h
+++ b/video/video_receive_stream2.h
@@ -75,12 +75,13 @@
   const Timestamp decode_timestamp;
 };
 
-class VideoReceiveStream2 : public webrtc::VideoReceiveStream,
-                            public rtc::VideoSinkInterface<VideoFrame>,
-                            public NackSender,
-                            public OnCompleteFrameCallback,
-                            public Syncable,
-                            public CallStatsObserver {
+class VideoReceiveStream2
+    : public webrtc::VideoReceiveStream,
+      public rtc::VideoSinkInterface<VideoFrame>,
+      public NackSender,
+      public RtpVideoStreamReceiver2::OnCompleteFrameCallback,
+      public Syncable,
+      public CallStatsObserver {
  public:
   // The default number of milliseconds to pass before re-requesting a key frame
   // to be sent.
@@ -134,7 +135,7 @@
   void SendNack(const std::vector<uint16_t>& sequence_numbers,
                 bool buffering_allowed) override;
 
-  // Implements OnCompleteFrameCallback.
+  // Implements RtpVideoStreamReceiver2::OnCompleteFrameCallback.
   void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) override;
 
   // Implements CallStatsObserver::OnRttUpdate