diff --git a/call/BUILD.gn b/call/BUILD.gn index 6ddaf6e924..bcd30787b9 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -124,6 +124,7 @@ rtc_source_set("rtp_sender") { 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 94a8fad586..019f8422c8 100644 --- a/call/rtp_video_sender.cc +++ b/call/rtp_video_sender.cc @@ -745,15 +745,15 @@ uint32_t RtpVideoSender::GetProtectionBitrateBps() const { return protection_bitrate_bps_; } -absl::optional RtpVideoSender::GetSentRtpPacketInfo( +std::vector RtpVideoSender::GetSentRtpPacketInfos( uint32_t ssrc, - uint16_t seq_num) const { + rtc::ArrayView 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(); } int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params, diff --git a/call/rtp_video_sender.h b/call/rtp_video_sender.h index 8518c91dd2..e17bb49a36 100644 --- a/call/rtp_video_sender.h +++ b/call/rtp_video_sender.h @@ -17,6 +17,7 @@ #include #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 @@ class RtpVideoSender : public RtpVideoSenderInterface, size_t height, size_t num_temporal_layers) override; - absl::optional GetSentRtpPacketInfo( + std::vector GetSentRtpPacketInfos( uint32_t ssrc, - uint16_t seq_num) const override; + rtc::ArrayView 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 51cf56b609..3208e94e39 100644 --- a/call/rtp_video_sender_interface.h +++ b/call/rtp_video_sender_interface.h @@ -15,6 +15,7 @@ #include #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 @@ class RtpVideoSenderInterface : public EncodedImageCallback { virtual void SetEncodingData(size_t width, size_t height, size_t num_temporal_layers) = 0; - virtual absl::optional GetSentRtpPacketInfo( + virtual std::vector GetSentRtpPacketInfos( uint32_t ssrc, - uint16_t seq_num) const = 0; + rtc::ArrayView 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 a90afbf559..a71a6e5b05 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include "absl/memory/memory.h" #include "absl/strings/match.h" @@ -758,13 +757,35 @@ uint32_t RTPSenderVideo::PacketizationOverheadBps() const { .value_or(0); } -absl::optional RTPSenderVideo::GetSentRtpPacketInfo( - uint16_t sequence_number) const { +std::vector RTPSenderVideo::GetSentRtpPacketInfos( + rtc::ArrayView sequence_numbers) const { + RTC_DCHECK(!sequence_numbers.empty()); + + std::vector 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 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 814efcc4dd..cc7c1fa624 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.h +++ b/modules/rtp_rtcp/source/rtp_sender_video.h @@ -13,9 +13,11 @@ #include #include +#include #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 @@ class RTPSenderVideo { // 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 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 GetSentRtpPacketInfos( + rtc::ArrayView 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 a5e5cd43ff..cae3b86cc0 100644 --- a/video/video_send_stream_impl_unittest.cc +++ b/video/video_send_stream_impl_unittest.cc @@ -69,10 +69,10 @@ class MockRtpVideoSender : public RtpVideoSenderInterface { 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(uint32_t ssrc, - uint16_t seq_num)); + MOCK_CONST_METHOD2(GetSentRtpPacketInfos, + std::vector( + uint32_t ssrc, + rtc::ArrayView sequence_numbers)); }; BitrateAllocationUpdate CreateAllocation(int bitrate_bps) {