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:

committed by
WebRTC LUCI CQ

parent
723873b841
commit
306b1393cb
@ -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);
|
||||
}
|
||||
|
@ -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_;
|
||||
|
Reference in New Issue
Block a user