Optimize set of registered SSRCs in RTCPReceiver

In highly loaded media servers, RTCPReceiver's use of std::set
attributes to ~0.87% CPU. It's mostly ::find and the [] operator and the
assignment operator.

 * Removed locking of a mutex in `TriggerCallbacksFromRtcpPacket``
   as it copied members that were already const.
 * Switched the use of std::set for the list of registered local SSRCs
   to an absl::InlinedVector, as the set is very small and it's not
   expected that any more complicated container would be faster than a
   linear search within a cache line.

Bug: webrtc:12689
Change-Id: I734578c22eeca2d9ba89fef77ecc689b72624567
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/216322
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33849}
This commit is contained in:
Victor Boivie
2021-04-27 10:33:58 +02:00
committed by WebRTC LUCI CQ
parent 723873b841
commit 306b1393cb
2 changed files with 43 additions and 32 deletions

View File

@ -67,22 +67,6 @@ const size_t kMaxNumberOfStoredRrtrs = 300;
constexpr TimeDelta kDefaultVideoReportInterval = TimeDelta::Seconds(1);
constexpr TimeDelta kDefaultAudioReportInterval = TimeDelta::Seconds(5);
std::set<uint32_t> GetRegisteredSsrcs(
const RtpRtcpInterface::Configuration& config) {
std::set<uint32_t> ssrcs;
ssrcs.insert(config.local_media_ssrc);
if (config.rtx_send_ssrc) {
ssrcs.insert(*config.rtx_send_ssrc);
}
if (config.fec_generator) {
absl::optional<uint32_t> flexfec_ssrc = config.fec_generator->FecSsrc();
if (flexfec_ssrc) {
ssrcs.insert(*flexfec_ssrc);
}
}
return ssrcs;
}
// Returns true if the |timestamp| has exceeded the |interval *
// kRrTimeoutIntervals| period and was reset (set to PlusInfinity()). Returns
// false if the timer was either already reset or if it has not expired.
@ -100,6 +84,22 @@ bool ResetTimestampIfExpired(const Timestamp now,
} // namespace
RTCPReceiver::RegisteredSsrcs::RegisteredSsrcs(
const RtpRtcpInterface::Configuration& config) {
ssrcs_.push_back(config.local_media_ssrc);
if (config.rtx_send_ssrc) {
ssrcs_.push_back(*config.rtx_send_ssrc);
}
if (config.fec_generator) {
absl::optional<uint32_t> flexfec_ssrc = config.fec_generator->FecSsrc();
if (flexfec_ssrc) {
ssrcs_.push_back(*flexfec_ssrc);
}
}
// Ensure that the RegisteredSsrcs can inline the SSRCs.
RTC_DCHECK_LE(ssrcs_.size(), RTCPReceiver::RegisteredSsrcs::kMaxSsrcs);
}
struct RTCPReceiver::PacketInformation {
uint32_t packet_type_flags = 0; // RTCPPacketTypeFlags bit field.
@ -160,7 +160,7 @@ RTCPReceiver::RTCPReceiver(const RtpRtcpInterface::Configuration& config,
receiver_only_(config.receiver_only),
rtp_rtcp_(owner),
main_ssrc_(config.local_media_ssrc),
registered_ssrcs_(GetRegisteredSsrcs(config)),
registered_ssrcs_(config),
rtcp_bandwidth_observer_(config.bandwidth_callback),
rtcp_intra_frame_observer_(config.intra_frame_callback),
rtcp_loss_notification_observer_(config.rtcp_loss_notification_observer),
@ -567,7 +567,7 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block,
// which the information in this reception report block pertains.
// Filter out all report blocks that are not for us.
if (registered_ssrcs_.count(report_block.source_ssrc()) == 0)
if (!registered_ssrcs_.contains(report_block.source_ssrc()))
return;
last_received_rb_ = clock_->CurrentTime();
@ -833,7 +833,7 @@ void RTCPReceiver::HandleXrReceiveReferenceTime(uint32_t sender_ssrc,
}
void RTCPReceiver::HandleXrDlrrReportBlock(const rtcp::ReceiveTimeInfo& rti) {
if (registered_ssrcs_.count(rti.ssrc) == 0) // Not to us.
if (!registered_ssrcs_.contains(rti.ssrc)) // Not to us.
return;
// Caller should explicitly enable rtt calculation using extended reports.
@ -1056,14 +1056,7 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
// Might trigger a OnReceivedBandwidthEstimateUpdate.
NotifyTmmbrUpdated();
}
uint32_t local_ssrc;
std::set<uint32_t> registered_ssrcs;
{
// We don't want to hold this critsect when triggering the callbacks below.
MutexLock lock(&rtcp_receiver_lock_);
local_ssrc = main_ssrc_;
registered_ssrcs = registered_ssrcs_;
}
if (!receiver_only_ && (packet_information.packet_type_flags & kRtcpSrReq)) {
rtp_rtcp_->OnRequestSendReport();
}
@ -1090,7 +1083,7 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
RTC_LOG(LS_VERBOSE)
<< "Incoming FIR from SSRC " << packet_information.remote_ssrc;
}
rtcp_intra_frame_observer_->OnReceivedIntraFrameRequest(local_ssrc);
rtcp_intra_frame_observer_->OnReceivedIntraFrameRequest(main_ssrc_);
}
}
if (rtcp_loss_notification_observer_ &&
@ -1098,7 +1091,7 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
rtcp::LossNotification* loss_notification =
packet_information.loss_notification.get();
RTC_DCHECK(loss_notification);
if (loss_notification->media_ssrc() == local_ssrc) {
if (loss_notification->media_ssrc() == main_ssrc_) {
rtcp_loss_notification_observer_->OnReceivedLossNotification(
loss_notification->media_ssrc(), loss_notification->last_decoded(),
loss_notification->last_received(),
@ -1130,8 +1123,8 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
(packet_information.packet_type_flags & kRtcpTransportFeedback)) {
uint32_t media_source_ssrc =
packet_information.transport_feedback->media_ssrc();
if (media_source_ssrc == local_ssrc ||
registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
if (media_source_ssrc == main_ssrc_ ||
registered_ssrcs_.contains(media_source_ssrc)) {
transport_feedback_observer_->OnTransportFeedback(
*packet_information.transport_feedback);
}

View File

@ -124,6 +124,23 @@ class RTCPReceiver final {
void NotifyTmmbrUpdated();
private:
// A lightweight inlined set of local SSRCs.
class RegisteredSsrcs {
public:
static constexpr size_t kMaxSsrcs = 3;
// Initializes the set of registered local SSRCS by extracting them from the
// provided `config`.
explicit RegisteredSsrcs(const RtpRtcpInterface::Configuration& config);
// Indicates if `ssrc` is in the set of registered local SSRCs.
bool contains(uint32_t ssrc) const {
return absl::c_linear_search(ssrcs_, ssrc);
}
private:
absl::InlinedVector<uint32_t, kMaxSsrcs> ssrcs_;
};
struct PacketInformation;
struct TmmbrInformation;
struct RrtrInformation;
@ -229,7 +246,8 @@ class RTCPReceiver final {
const bool receiver_only_;
ModuleRtpRtcp* const rtp_rtcp_;
const uint32_t main_ssrc_;
const std::set<uint32_t> registered_ssrcs_;
// The set of registered local SSRCs.
const RegisteredSsrcs registered_ssrcs_;
RtcpBandwidthObserver* const rtcp_bandwidth_observer_;
RtcpIntraFrameObserver* const rtcp_intra_frame_observer_;