RTPSenderVideo::GetSentRtpPacketInfo() over a set of sequence numbers

Add a version of RTPSenderVideo::GetSentRtpPacketInfo() that operates
over a set of numbers, so as to only grab the lock once.

Bug: webrtc:10501
Change-Id: I9453b0cb44dcd6e2ce196390b2c5c9a7dd6d800a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132014
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27544}
diff --git a/call/BUILD.gn b/call/BUILD.gn
index 6ddaf6e..bcd3078 100644
--- a/call/BUILD.gn
+++ b/call/BUILD.gn
@@ -124,6 +124,7 @@
   deps = [
     ":bitrate_configurator",
     ":rtp_interfaces",
+    "../api:array_view",
     "../api:fec_controller_api",
     "../api:network_state_predictor_api",
     "../api:transport_api",
diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc
index 94a8fad..019f842 100644
--- a/call/rtp_video_sender.cc
+++ b/call/rtp_video_sender.cc
@@ -745,15 +745,15 @@
   return protection_bitrate_bps_;
 }
 
-absl::optional<RtpSequenceNumberMap::Info> RtpVideoSender::GetSentRtpPacketInfo(
+std::vector<RtpSequenceNumberMap::Info> RtpVideoSender::GetSentRtpPacketInfos(
     uint32_t ssrc,
-    uint16_t seq_num) const {
+    rtc::ArrayView<const uint16_t> sequence_numbers) const {
   for (const auto& rtp_stream : rtp_streams_) {
     if (ssrc == rtp_stream.rtp_rtcp->SSRC()) {
-      return rtp_stream.sender_video->GetSentRtpPacketInfo(seq_num);
+      return rtp_stream.sender_video->GetSentRtpPacketInfos(sequence_numbers);
     }
   }
-  return absl::nullopt;
+  return std::vector<RtpSequenceNumberMap::Info>();
 }
 
 int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params,
diff --git a/call/rtp_video_sender.h b/call/rtp_video_sender.h
index 8518c91..e17bb49 100644
--- a/call/rtp_video_sender.h
+++ b/call/rtp_video_sender.h
@@ -17,6 +17,7 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "api/call/transport.h"
 #include "api/fec_controller.h"
 #include "api/video_codecs/video_encoder.h"
@@ -140,9 +141,9 @@
                        size_t height,
                        size_t num_temporal_layers) override;
 
-  absl::optional<RtpSequenceNumberMap::Info> GetSentRtpPacketInfo(
+  std::vector<RtpSequenceNumberMap::Info> GetSentRtpPacketInfos(
       uint32_t ssrc,
-      uint16_t seq_num) const override;
+      rtc::ArrayView<const uint16_t> sequence_numbers) const override;
 
   // From PacketFeedbackObserver.
   void OnPacketAdded(uint32_t ssrc, uint16_t seq_num) override;
diff --git a/call/rtp_video_sender_interface.h b/call/rtp_video_sender_interface.h
index 51cf56b..3208e94 100644
--- a/call/rtp_video_sender_interface.h
+++ b/call/rtp_video_sender_interface.h
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "call/rtp_config.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtp_sequence_number_map.h"
@@ -57,9 +58,9 @@
   virtual void SetEncodingData(size_t width,
                                size_t height,
                                size_t num_temporal_layers) = 0;
-  virtual absl::optional<RtpSequenceNumberMap::Info> GetSentRtpPacketInfo(
+  virtual std::vector<RtpSequenceNumberMap::Info> GetSentRtpPacketInfos(
       uint32_t ssrc,
-      uint16_t seq_num) const = 0;
+      rtc::ArrayView<const uint16_t> sequence_numbers) const = 0;
 };
 }  // namespace webrtc
 #endif  // CALL_RTP_VIDEO_SENDER_INTERFACE_H_
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index a90afbf..a71a6e5 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -17,7 +17,6 @@
 #include <memory>
 #include <string>
 #include <utility>
-#include <vector>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/match.h"
@@ -758,13 +757,35 @@
       .value_or(0);
 }
 
-absl::optional<RtpSequenceNumberMap::Info> RTPSenderVideo::GetSentRtpPacketInfo(
-    uint16_t sequence_number) const {
+std::vector<RtpSequenceNumberMap::Info> RTPSenderVideo::GetSentRtpPacketInfos(
+    rtc::ArrayView<const uint16_t> sequence_numbers) const {
+  RTC_DCHECK(!sequence_numbers.empty());
+
+  std::vector<RtpSequenceNumberMap::Info> results;
   if (!rtp_sequence_number_map_) {
-    return absl::nullopt;
+    return results;
   }
-  rtc::CritScope cs(&crit_);
-  return rtp_sequence_number_map_->Get(sequence_number);
+  results.reserve(sequence_numbers.size());
+
+  {
+    rtc::CritScope cs(&crit_);
+    for (uint16_t sequence_number : sequence_numbers) {
+      const absl::optional<RtpSequenceNumberMap::Info> info =
+          rtp_sequence_number_map_->Get(sequence_number);
+      if (!info) {
+        // The empty vector will be returned. We can delay the clearing
+        // of the vector until after we exit the critical section.
+        break;
+      }
+      results.push_back(*info);
+    }
+  }
+
+  if (results.size() != sequence_numbers.size()) {
+    results.clear();  // Some sequence number was not found.
+  }
+
+  return results;
 }
 
 StorageType RTPSenderVideo::GetStorageType(
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index 814efcc..cc7c1fa 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -13,9 +13,11 @@
 
 #include <map>
 #include <memory>
+#include <vector>
 
 #include "absl/strings/string_view.h"
 #include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "modules/rtp_rtcp/include/flexfec_sender.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/playout_delay_oracle.h"
@@ -94,13 +96,13 @@
   // or extension/
   uint32_t PacketizationOverheadBps() const;
 
-  // Recall the last RTP packet whose sequence number was |sequence_number|.
-  // Return the timestamp of the video frame that packet belonged too, as well
-  // as whether the packet was the first and/or last packet in the frame.
-  // absl::nullopt returned if no such packet can be recalled (e.g. it happened
-  // too long ago).
-  absl::optional<RtpSequenceNumberMap::Info> GetSentRtpPacketInfo(
-      uint16_t sequence_number) const;
+  // For each sequence number in |sequence_number|, recall the last RTP packet
+  // which bore it - its timestamp and whether it was the first and/or last
+  // packet in that frame. If all of the given sequence numbers could be
+  // recalled, return a vector with all of them (in corresponding order).
+  // If any could not be recalled, return an empty vector.
+  std::vector<RtpSequenceNumberMap::Info> GetSentRtpPacketInfos(
+      rtc::ArrayView<const uint16_t> sequence_numbers) const;
 
  protected:
   static uint8_t GetTemporalId(const RTPVideoHeader& header);
diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc
index a5e5cd4..cae3b86 100644
--- a/video/video_send_stream_impl_unittest.cc
+++ b/video/video_send_stream_impl_unittest.cc
@@ -69,10 +69,10 @@
   MOCK_CONST_METHOD0(GetPayloadBitrateBps, uint32_t());
   MOCK_CONST_METHOD0(GetProtectionBitrateBps, uint32_t());
   MOCK_METHOD3(SetEncodingData, void(size_t, size_t, size_t));
-  MOCK_CONST_METHOD2(
-      GetSentRtpPacketInfo,
-      absl::optional<RtpSequenceNumberMap::Info>(uint32_t ssrc,
-                                                 uint16_t seq_num));
+  MOCK_CONST_METHOD2(GetSentRtpPacketInfos,
+                     std::vector<RtpSequenceNumberMap::Info>(
+                         uint32_t ssrc,
+                         rtc::ArrayView<const uint16_t> sequence_numbers));
 };
 
 BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {