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 kDefaultVideoReportInterval = TimeDelta::Seconds(1);
|
||||||
constexpr TimeDelta kDefaultAudioReportInterval = TimeDelta::Seconds(5);
|
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 *
|
// Returns true if the |timestamp| has exceeded the |interval *
|
||||||
// kRrTimeoutIntervals| period and was reset (set to PlusInfinity()). Returns
|
// kRrTimeoutIntervals| period and was reset (set to PlusInfinity()). Returns
|
||||||
// false if the timer was either already reset or if it has not expired.
|
// false if the timer was either already reset or if it has not expired.
|
||||||
@ -100,6 +84,22 @@ bool ResetTimestampIfExpired(const Timestamp now,
|
|||||||
|
|
||||||
} // namespace
|
} // 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 {
|
struct RTCPReceiver::PacketInformation {
|
||||||
uint32_t packet_type_flags = 0; // RTCPPacketTypeFlags bit field.
|
uint32_t packet_type_flags = 0; // RTCPPacketTypeFlags bit field.
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ RTCPReceiver::RTCPReceiver(const RtpRtcpInterface::Configuration& config,
|
|||||||
receiver_only_(config.receiver_only),
|
receiver_only_(config.receiver_only),
|
||||||
rtp_rtcp_(owner),
|
rtp_rtcp_(owner),
|
||||||
main_ssrc_(config.local_media_ssrc),
|
main_ssrc_(config.local_media_ssrc),
|
||||||
registered_ssrcs_(GetRegisteredSsrcs(config)),
|
registered_ssrcs_(config),
|
||||||
rtcp_bandwidth_observer_(config.bandwidth_callback),
|
rtcp_bandwidth_observer_(config.bandwidth_callback),
|
||||||
rtcp_intra_frame_observer_(config.intra_frame_callback),
|
rtcp_intra_frame_observer_(config.intra_frame_callback),
|
||||||
rtcp_loss_notification_observer_(config.rtcp_loss_notification_observer),
|
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.
|
// which the information in this reception report block pertains.
|
||||||
|
|
||||||
// Filter out all report blocks that are not for us.
|
// 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;
|
return;
|
||||||
|
|
||||||
last_received_rb_ = clock_->CurrentTime();
|
last_received_rb_ = clock_->CurrentTime();
|
||||||
@ -833,7 +833,7 @@ void RTCPReceiver::HandleXrReceiveReferenceTime(uint32_t sender_ssrc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RTCPReceiver::HandleXrDlrrReportBlock(const rtcp::ReceiveTimeInfo& rti) {
|
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;
|
return;
|
||||||
|
|
||||||
// Caller should explicitly enable rtt calculation using extended reports.
|
// Caller should explicitly enable rtt calculation using extended reports.
|
||||||
@ -1056,14 +1056,7 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
|
|||||||
// Might trigger a OnReceivedBandwidthEstimateUpdate.
|
// Might trigger a OnReceivedBandwidthEstimateUpdate.
|
||||||
NotifyTmmbrUpdated();
|
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)) {
|
if (!receiver_only_ && (packet_information.packet_type_flags & kRtcpSrReq)) {
|
||||||
rtp_rtcp_->OnRequestSendReport();
|
rtp_rtcp_->OnRequestSendReport();
|
||||||
}
|
}
|
||||||
@ -1090,7 +1083,7 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
|
|||||||
RTC_LOG(LS_VERBOSE)
|
RTC_LOG(LS_VERBOSE)
|
||||||
<< "Incoming FIR from SSRC " << packet_information.remote_ssrc;
|
<< "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_ &&
|
if (rtcp_loss_notification_observer_ &&
|
||||||
@ -1098,7 +1091,7 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
|
|||||||
rtcp::LossNotification* loss_notification =
|
rtcp::LossNotification* loss_notification =
|
||||||
packet_information.loss_notification.get();
|
packet_information.loss_notification.get();
|
||||||
RTC_DCHECK(loss_notification);
|
RTC_DCHECK(loss_notification);
|
||||||
if (loss_notification->media_ssrc() == local_ssrc) {
|
if (loss_notification->media_ssrc() == main_ssrc_) {
|
||||||
rtcp_loss_notification_observer_->OnReceivedLossNotification(
|
rtcp_loss_notification_observer_->OnReceivedLossNotification(
|
||||||
loss_notification->media_ssrc(), loss_notification->last_decoded(),
|
loss_notification->media_ssrc(), loss_notification->last_decoded(),
|
||||||
loss_notification->last_received(),
|
loss_notification->last_received(),
|
||||||
@ -1130,8 +1123,8 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
|
|||||||
(packet_information.packet_type_flags & kRtcpTransportFeedback)) {
|
(packet_information.packet_type_flags & kRtcpTransportFeedback)) {
|
||||||
uint32_t media_source_ssrc =
|
uint32_t media_source_ssrc =
|
||||||
packet_information.transport_feedback->media_ssrc();
|
packet_information.transport_feedback->media_ssrc();
|
||||||
if (media_source_ssrc == local_ssrc ||
|
if (media_source_ssrc == main_ssrc_ ||
|
||||||
registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
|
registered_ssrcs_.contains(media_source_ssrc)) {
|
||||||
transport_feedback_observer_->OnTransportFeedback(
|
transport_feedback_observer_->OnTransportFeedback(
|
||||||
*packet_information.transport_feedback);
|
*packet_information.transport_feedback);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,23 @@ class RTCPReceiver final {
|
|||||||
void NotifyTmmbrUpdated();
|
void NotifyTmmbrUpdated();
|
||||||
|
|
||||||
private:
|
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 PacketInformation;
|
||||||
struct TmmbrInformation;
|
struct TmmbrInformation;
|
||||||
struct RrtrInformation;
|
struct RrtrInformation;
|
||||||
@ -229,7 +246,8 @@ class RTCPReceiver final {
|
|||||||
const bool receiver_only_;
|
const bool receiver_only_;
|
||||||
ModuleRtpRtcp* const rtp_rtcp_;
|
ModuleRtpRtcp* const rtp_rtcp_;
|
||||||
const uint32_t main_ssrc_;
|
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_;
|
RtcpBandwidthObserver* const rtcp_bandwidth_observer_;
|
||||||
RtcpIntraFrameObserver* const rtcp_intra_frame_observer_;
|
RtcpIntraFrameObserver* const rtcp_intra_frame_observer_;
|
||||||
|
Reference in New Issue
Block a user