RTCStatsCollector::GetStatsReport() with optional selector argument.
This implements the stats selection algorithm[1] in RTCStatsCollector by
obtaining the selector's inbound-rtp/outbound-rtp stats and performing
the stats traversal algorithm (TakeReferencedStats)[2] on a copy of the
cached report with the rtps as starting point.
Changes:
- RTCStatsCollector.GetStatsReport() with selector arguments added.
- RequestInfo added, "callbacks_" is replaced by "requests_".
- RTCStatsReport.Copy() added.
- New test for sender selector and receiver selector,
RTCStatsCollectorTest.GetStatsWithSelector.
[1] https://w3c.github.io/webrtc-pc/#dfn-stats-selection-algorithm
[2] https://cs.chromium.org/chromium/src/third_party/webrtc/pc/rtcstatstraversal.h
Bug: chromium:680172
Change-Id: I9eff00738a1f24c94c9c8ecd13c1304452e962cf
Reviewed-on: https://webrtc-review.googlesource.com/62141
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22499}
diff --git a/pc/rtcstatscollector.h b/pc/rtcstatscollector.h
index be5980b..0018d60 100644
--- a/pc/rtcstatscollector.h
+++ b/pc/rtcstatscollector.h
@@ -35,6 +35,9 @@
namespace webrtc {
+class RtpSenderInternal;
+class RtpReceiverInternal;
+
// All public methods of the collector are to be called on the signaling thread.
// Stats are gathered on the signaling, worker and network threads
// asynchronously. The callback is invoked on the signaling thread. Resulting
@@ -50,7 +53,18 @@
// it is returned, otherwise new stats are gathered and returned. A report is
// considered fresh for |cache_lifetime_| ms. const RTCStatsReports are safe
// to use across multiple threads and may be destructed on any thread.
+ // If the optional selector argument is used, stats are filtered according to
+ // stats selection algorithm before delivery.
+ // https://w3c.github.io/webrtc-pc/#dfn-stats-selection-algorithm
void GetStatsReport(rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
+ // If |selector| is null the selection algorithm is still applied (interpreted
+ // as: no RTP streams are sent by selector). The result is empty.
+ void GetStatsReport(rtc::scoped_refptr<RtpSenderInternal> selector,
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
+ // If |selector| is null the selection algorithm is still applied (interpreted
+ // as: no RTP streams are received by selector). The result is empty.
+ void GetStatsReport(rtc::scoped_refptr<RtpReceiverInternal> selector,
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
// Clears the cache's reference to the most recent stats report. Subsequently
// calling |GetStatsReport| guarantees fresh stats.
void ClearCachedStatsReport();
@@ -73,6 +87,49 @@
const rtc::scoped_refptr<RTCStatsReport>& partial_report);
private:
+ class RequestInfo {
+ public:
+ enum class FilterMode { kAll, kSenderSelector, kReceiverSelector };
+
+ // Constructs with FilterMode::kAll.
+ explicit RequestInfo(
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
+ // Constructs with FilterMode::kSenderSelector. The selection algorithm is
+ // applied even if |selector| is null, resulting in an empty report.
+ RequestInfo(rtc::scoped_refptr<RtpSenderInternal> selector,
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
+ // Constructs with FilterMode::kReceiverSelector. The selection algorithm is
+ // applied even if |selector| is null, resulting in an empty report.
+ RequestInfo(rtc::scoped_refptr<RtpReceiverInternal> selector,
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
+
+ FilterMode filter_mode() const { return filter_mode_; }
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback() const {
+ return callback_;
+ }
+ rtc::scoped_refptr<RtpSenderInternal> sender_selector() const {
+ RTC_DCHECK(filter_mode_ == FilterMode::kSenderSelector);
+ return sender_selector_;
+ }
+ rtc::scoped_refptr<RtpReceiverInternal> receiver_selector() const {
+ RTC_DCHECK(filter_mode_ == FilterMode::kReceiverSelector);
+ return receiver_selector_;
+ }
+
+ private:
+ RequestInfo(FilterMode filter_mode,
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback,
+ rtc::scoped_refptr<RtpSenderInternal> sender_selector,
+ rtc::scoped_refptr<RtpReceiverInternal> receiver_selector);
+
+ FilterMode filter_mode_;
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback_;
+ rtc::scoped_refptr<RtpSenderInternal> sender_selector_;
+ rtc::scoped_refptr<RtpReceiverInternal> receiver_selector_;
+ };
+
+ void GetStatsReportInternal(RequestInfo request);
+
struct CertificateStatsPair {
std::unique_ptr<rtc::SSLCertificateStats> local;
std::unique_ptr<rtc::SSLCertificateStats> remote;
@@ -96,7 +153,7 @@
void AddPartialResults_s(rtc::scoped_refptr<RTCStatsReport> partial_report);
void DeliverCachedReport(
rtc::scoped_refptr<const RTCStatsReport> cached_report,
- std::vector<rtc::scoped_refptr<RTCStatsCollectorCallback>> callbacks);
+ std::vector<RequestInfo> requests);
// Produces |RTCCertificateStats|.
void ProduceCertificateStats_n(
@@ -168,7 +225,7 @@
int num_pending_partial_reports_;
int64_t partial_report_timestamp_us_;
rtc::scoped_refptr<RTCStatsReport> partial_report_;
- std::vector<rtc::scoped_refptr<RTCStatsCollectorCallback>> callbacks_;
+ std::vector<RequestInfo> requests_;
// Set in |GetStatsReport|, read in |ProducePartialResultsOnNetworkThread| and
// |ProducePartialResultsOnSignalingThread|, reset after work is complete. Not