Use flat_map/flat_set in RtpDemuxer

Except for a use of std::multimap (for which there currently is no
drop-in replacement), use webrtc::flat_map and flat_set for increased
performance.

The number of ssrcs/mids/payload types/etc is likely to be small and is
generally updated very rarely, but looked up a lot.

RtpDemuxer::ResolveSink's use of std::map represents about 0.6% CPU in
heavily loaded media servers. It does quite a few map lookups, and by
taking advantage of the increased cache locality of the flat_map and
flat_set containers, performance should be increased.

A previous attempt to use std::unordered_map failed in change 216243,
which was reverted. This is the second attempt.

Bug: webrtc:12689
Change-Id: Ifdbec63b2fd8f2f52e45ebaf12834b11dd7a41c5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/224662
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34429}
This commit is contained in:
Victor Boivie 2021-07-01 21:42:02 +02:00 committed by WebRTC LUCI CQ
parent 9e89c76301
commit ac5f2e7203
3 changed files with 15 additions and 20 deletions

View File

@ -147,6 +147,8 @@ rtc_library("rtp_receiver") {
"../modules/rtp_rtcp:rtp_rtcp_format",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
"../rtc_base/containers:flat_map",
"../rtc_base/containers:flat_set",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}

View File

@ -36,16 +36,7 @@ size_t RemoveFromMultimapByValue(Container* multimap, const Value& value) {
template <typename Map, typename Value>
size_t RemoveFromMapByValue(Map* map, const Value& value) {
size_t count = 0;
for (auto it = map->begin(); it != map->end();) {
if (it->second == value) {
it = map->erase(it);
++count;
} else {
++it;
}
}
return count;
return EraseIf(*map, [&](const auto& elem) { return elem.second == value; });
}
} // namespace

View File

@ -12,11 +12,13 @@
#define CALL_RTP_DEMUXER_H_
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "rtc_base/containers/flat_map.h"
#include "rtc_base/containers/flat_set.h"
namespace webrtc {
class RtpPacketReceived;
@ -42,10 +44,10 @@ struct RtpDemuxerCriteria {
std::string rsid;
// Will match packets with any of these SSRCs.
std::set<uint32_t> ssrcs;
flat_set<uint32_t> ssrcs;
// Will match packets with any of these payload types.
std::set<uint8_t> payload_types;
flat_set<uint8_t> payload_types;
// Return string representation of demux criteria to facilitate logging
std::string ToString() const;
@ -168,24 +170,24 @@ class RtpDemuxer {
// Note: Mappings are only modified by AddSink/RemoveSink (except for
// SSRC mapping which receives all MID, payload type, or RSID to SSRC bindings
// discovered when demuxing packets).
std::map<std::string, RtpPacketSinkInterface*> sink_by_mid_;
std::map<uint32_t, RtpPacketSinkInterface*> sink_by_ssrc_;
flat_map<std::string, RtpPacketSinkInterface*> sink_by_mid_;
flat_map<uint32_t, RtpPacketSinkInterface*> sink_by_ssrc_;
std::multimap<uint8_t, RtpPacketSinkInterface*> sinks_by_pt_;
std::map<std::pair<std::string, std::string>, RtpPacketSinkInterface*>
flat_map<std::pair<std::string, std::string>, RtpPacketSinkInterface*>
sink_by_mid_and_rsid_;
std::map<std::string, RtpPacketSinkInterface*> sink_by_rsid_;
flat_map<std::string, RtpPacketSinkInterface*> sink_by_rsid_;
// Tracks all the MIDs that have been identified in added criteria. Used to
// determine if a packet should be dropped right away because the MID is
// unknown.
std::set<std::string> known_mids_;
flat_set<std::string> known_mids_;
// Records learned mappings of MID --> SSRC and RSID --> SSRC as packets are
// received.
// This is stored separately from the sink mappings because if a sink is
// removed we want to still remember these associations.
std::map<uint32_t, std::string> mid_by_ssrc_;
std::map<uint32_t, std::string> rsid_by_ssrc_;
flat_map<uint32_t, std::string> mid_by_ssrc_;
flat_map<uint32_t, std::string> rsid_by_ssrc_;
// Adds a binding from the SSRC to the given sink.
void AddSsrcSinkBinding(uint32_t ssrc, RtpPacketSinkInterface* sink);