rtc_stats_collector.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * Copyright 2016 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef PC_RTC_STATS_COLLECTOR_H_
  11. #define PC_RTC_STATS_COLLECTOR_H_
  12. #include <map>
  13. #include <memory>
  14. #include <set>
  15. #include <string>
  16. #include <vector>
  17. #include "absl/types/optional.h"
  18. #include "api/scoped_refptr.h"
  19. #include "api/stats/rtc_stats_collector_callback.h"
  20. #include "api/stats/rtc_stats_report.h"
  21. #include "api/stats/rtcstats_objects.h"
  22. #include "call/call.h"
  23. #include "media/base/media_channel.h"
  24. #include "pc/data_channel_utils.h"
  25. #include "pc/peer_connection_internal.h"
  26. #include "pc/track_media_info_map.h"
  27. #include "rtc_base/event.h"
  28. #include "rtc_base/ref_count.h"
  29. #include "rtc_base/ssl_identity.h"
  30. #include "rtc_base/third_party/sigslot/sigslot.h"
  31. #include "rtc_base/time_utils.h"
  32. namespace webrtc {
  33. class RtpSenderInternal;
  34. class RtpReceiverInternal;
  35. // All public methods of the collector are to be called on the signaling thread.
  36. // Stats are gathered on the signaling, worker and network threads
  37. // asynchronously. The callback is invoked on the signaling thread. Resulting
  38. // reports are cached for |cache_lifetime_| ms.
  39. class RTCStatsCollector : public virtual rtc::RefCountInterface,
  40. public sigslot::has_slots<> {
  41. public:
  42. static rtc::scoped_refptr<RTCStatsCollector> Create(
  43. PeerConnectionInternal* pc,
  44. int64_t cache_lifetime_us = 50 * rtc::kNumMicrosecsPerMillisec);
  45. // Gets a recent stats report. If there is a report cached that is still fresh
  46. // it is returned, otherwise new stats are gathered and returned. A report is
  47. // considered fresh for |cache_lifetime_| ms. const RTCStatsReports are safe
  48. // to use across multiple threads and may be destructed on any thread.
  49. // If the optional selector argument is used, stats are filtered according to
  50. // stats selection algorithm before delivery.
  51. // https://w3c.github.io/webrtc-pc/#dfn-stats-selection-algorithm
  52. void GetStatsReport(rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
  53. // If |selector| is null the selection algorithm is still applied (interpreted
  54. // as: no RTP streams are sent by selector). The result is empty.
  55. void GetStatsReport(rtc::scoped_refptr<RtpSenderInternal> selector,
  56. rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
  57. // If |selector| is null the selection algorithm is still applied (interpreted
  58. // as: no RTP streams are received by selector). The result is empty.
  59. void GetStatsReport(rtc::scoped_refptr<RtpReceiverInternal> selector,
  60. rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
  61. // Clears the cache's reference to the most recent stats report. Subsequently
  62. // calling |GetStatsReport| guarantees fresh stats.
  63. void ClearCachedStatsReport();
  64. // If there is a |GetStatsReport| requests in-flight, waits until it has been
  65. // completed. Must be called on the signaling thread.
  66. void WaitForPendingRequest();
  67. protected:
  68. RTCStatsCollector(PeerConnectionInternal* pc, int64_t cache_lifetime_us);
  69. ~RTCStatsCollector();
  70. struct CertificateStatsPair {
  71. std::unique_ptr<rtc::SSLCertificateStats> local;
  72. std::unique_ptr<rtc::SSLCertificateStats> remote;
  73. };
  74. // Stats gathering on a particular thread. Virtual for the sake of testing.
  75. virtual void ProducePartialResultsOnSignalingThreadImpl(
  76. int64_t timestamp_us,
  77. RTCStatsReport* partial_report);
  78. virtual void ProducePartialResultsOnNetworkThreadImpl(
  79. int64_t timestamp_us,
  80. const std::map<std::string, cricket::TransportStats>&
  81. transport_stats_by_name,
  82. const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
  83. RTCStatsReport* partial_report);
  84. private:
  85. class RequestInfo {
  86. public:
  87. enum class FilterMode { kAll, kSenderSelector, kReceiverSelector };
  88. // Constructs with FilterMode::kAll.
  89. explicit RequestInfo(
  90. rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
  91. // Constructs with FilterMode::kSenderSelector. The selection algorithm is
  92. // applied even if |selector| is null, resulting in an empty report.
  93. RequestInfo(rtc::scoped_refptr<RtpSenderInternal> selector,
  94. rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
  95. // Constructs with FilterMode::kReceiverSelector. The selection algorithm is
  96. // applied even if |selector| is null, resulting in an empty report.
  97. RequestInfo(rtc::scoped_refptr<RtpReceiverInternal> selector,
  98. rtc::scoped_refptr<RTCStatsCollectorCallback> callback);
  99. FilterMode filter_mode() const { return filter_mode_; }
  100. rtc::scoped_refptr<RTCStatsCollectorCallback> callback() const {
  101. return callback_;
  102. }
  103. rtc::scoped_refptr<RtpSenderInternal> sender_selector() const {
  104. RTC_DCHECK(filter_mode_ == FilterMode::kSenderSelector);
  105. return sender_selector_;
  106. }
  107. rtc::scoped_refptr<RtpReceiverInternal> receiver_selector() const {
  108. RTC_DCHECK(filter_mode_ == FilterMode::kReceiverSelector);
  109. return receiver_selector_;
  110. }
  111. private:
  112. RequestInfo(FilterMode filter_mode,
  113. rtc::scoped_refptr<RTCStatsCollectorCallback> callback,
  114. rtc::scoped_refptr<RtpSenderInternal> sender_selector,
  115. rtc::scoped_refptr<RtpReceiverInternal> receiver_selector);
  116. FilterMode filter_mode_;
  117. rtc::scoped_refptr<RTCStatsCollectorCallback> callback_;
  118. rtc::scoped_refptr<RtpSenderInternal> sender_selector_;
  119. rtc::scoped_refptr<RtpReceiverInternal> receiver_selector_;
  120. };
  121. void GetStatsReportInternal(RequestInfo request);
  122. // Structure for tracking stats about each RtpTransceiver managed by the
  123. // PeerConnection. This can either by a Plan B style or Unified Plan style
  124. // transceiver (i.e., can have 0 or many senders and receivers).
  125. // Some fields are copied from the RtpTransceiver/BaseChannel object so that
  126. // they can be accessed safely on threads other than the signaling thread.
  127. // If a BaseChannel is not available (e.g., if signaling has not started),
  128. // then |mid| and |transport_name| will be null.
  129. struct RtpTransceiverStatsInfo {
  130. rtc::scoped_refptr<RtpTransceiver> transceiver;
  131. cricket::MediaType media_type;
  132. absl::optional<std::string> mid;
  133. absl::optional<std::string> transport_name;
  134. std::unique_ptr<TrackMediaInfoMap> track_media_info_map;
  135. };
  136. void DeliverCachedReport(
  137. rtc::scoped_refptr<const RTCStatsReport> cached_report,
  138. std::vector<RequestInfo> requests);
  139. // Produces |RTCCertificateStats|.
  140. void ProduceCertificateStats_n(
  141. int64_t timestamp_us,
  142. const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
  143. RTCStatsReport* report) const;
  144. // Produces |RTCCodecStats|.
  145. void ProduceCodecStats_n(
  146. int64_t timestamp_us,
  147. const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
  148. RTCStatsReport* report) const;
  149. // Produces |RTCDataChannelStats|.
  150. void ProduceDataChannelStats_s(int64_t timestamp_us,
  151. RTCStatsReport* report) const;
  152. // Produces |RTCIceCandidatePairStats| and |RTCIceCandidateStats|.
  153. void ProduceIceCandidateAndPairStats_n(
  154. int64_t timestamp_us,
  155. const std::map<std::string, cricket::TransportStats>&
  156. transport_stats_by_name,
  157. const Call::Stats& call_stats,
  158. RTCStatsReport* report) const;
  159. // Produces |RTCMediaStreamStats|.
  160. void ProduceMediaStreamStats_s(int64_t timestamp_us,
  161. RTCStatsReport* report) const;
  162. // Produces |RTCMediaStreamTrackStats|.
  163. void ProduceMediaStreamTrackStats_s(int64_t timestamp_us,
  164. RTCStatsReport* report) const;
  165. // Produces RTCMediaSourceStats, including RTCAudioSourceStats and
  166. // RTCVideoSourceStats.
  167. void ProduceMediaSourceStats_s(int64_t timestamp_us,
  168. RTCStatsReport* report) const;
  169. // Produces |RTCPeerConnectionStats|.
  170. void ProducePeerConnectionStats_s(int64_t timestamp_us,
  171. RTCStatsReport* report) const;
  172. // Produces |RTCInboundRTPStreamStats| and |RTCOutboundRTPStreamStats|.
  173. // This has to be invoked after codecs and transport stats have been created
  174. // because some metrics are calculated through lookup of other metrics.
  175. void ProduceRTPStreamStats_n(
  176. int64_t timestamp_us,
  177. const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
  178. RTCStatsReport* report) const;
  179. void ProduceAudioRTPStreamStats_n(int64_t timestamp_us,
  180. const RtpTransceiverStatsInfo& stats,
  181. RTCStatsReport* report) const;
  182. void ProduceVideoRTPStreamStats_n(int64_t timestamp_us,
  183. const RtpTransceiverStatsInfo& stats,
  184. RTCStatsReport* report) const;
  185. // Produces |RTCTransportStats|.
  186. void ProduceTransportStats_n(
  187. int64_t timestamp_us,
  188. const std::map<std::string, cricket::TransportStats>&
  189. transport_stats_by_name,
  190. const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
  191. RTCStatsReport* report) const;
  192. // Helper function to stats-producing functions.
  193. std::map<std::string, CertificateStatsPair>
  194. PrepareTransportCertificateStats_n(
  195. const std::map<std::string, cricket::TransportStats>&
  196. transport_stats_by_name) const;
  197. std::vector<RtpTransceiverStatsInfo> PrepareTransceiverStatsInfos_s_w() const;
  198. std::set<std::string> PrepareTransportNames_s() const;
  199. // Stats gathering on a particular thread.
  200. void ProducePartialResultsOnSignalingThread(int64_t timestamp_us);
  201. void ProducePartialResultsOnNetworkThread(int64_t timestamp_us);
  202. // Merges |network_report_| into |partial_report_| and completes the request.
  203. // This is a NO-OP if |network_report_| is null.
  204. void MergeNetworkReport_s();
  205. // Slots for signals (sigslot) that are wired up to |pc_|.
  206. void OnRtpDataChannelCreated(RtpDataChannel* channel);
  207. void OnSctpDataChannelCreated(SctpDataChannel* channel);
  208. // Slots for signals (sigslot) that are wired up to |channel|.
  209. void OnDataChannelOpened(DataChannelInterface* channel);
  210. void OnDataChannelClosed(DataChannelInterface* channel);
  211. PeerConnectionInternal* const pc_;
  212. rtc::Thread* const signaling_thread_;
  213. rtc::Thread* const worker_thread_;
  214. rtc::Thread* const network_thread_;
  215. int num_pending_partial_reports_;
  216. int64_t partial_report_timestamp_us_;
  217. // Reports that are produced on the signaling thread or the network thread are
  218. // merged into this report. It is only touched on the signaling thread. Once
  219. // all partial reports are merged this is the result of a request.
  220. rtc::scoped_refptr<RTCStatsReport> partial_report_;
  221. std::vector<RequestInfo> requests_;
  222. // Holds the result of ProducePartialResultsOnNetworkThread(). It is merged
  223. // into |partial_report_| on the signaling thread and then nulled by
  224. // MergeNetworkReport_s(). Thread-safety is ensured by using
  225. // |network_report_event_|.
  226. rtc::scoped_refptr<RTCStatsReport> network_report_;
  227. // If set, it is safe to touch the |network_report_| on the signaling thread.
  228. // This is reset before async-invoking ProducePartialResultsOnNetworkThread()
  229. // and set when ProducePartialResultsOnNetworkThread() is complete, after it
  230. // has updated the value of |network_report_|.
  231. rtc::Event network_report_event_;
  232. // Set in |GetStatsReport|, read in |ProducePartialResultsOnNetworkThread| and
  233. // |ProducePartialResultsOnSignalingThread|, reset after work is complete. Not
  234. // passed as arguments to avoid copies. This is thread safe - when we
  235. // set/reset we know there are no pending stats requests in progress.
  236. std::vector<RtpTransceiverStatsInfo> transceiver_stats_infos_;
  237. std::set<std::string> transport_names_;
  238. Call::Stats call_stats_;
  239. // A timestamp, in microseconds, that is based on a timer that is
  240. // monotonically increasing. That is, even if the system clock is modified the
  241. // difference between the timer and this timestamp is how fresh the cached
  242. // report is.
  243. int64_t cache_timestamp_us_;
  244. int64_t cache_lifetime_us_;
  245. rtc::scoped_refptr<const RTCStatsReport> cached_report_;
  246. // Data recorded and maintained by the stats collector during its lifetime.
  247. // Some stats are produced from this record instead of other components.
  248. struct InternalRecord {
  249. InternalRecord() : data_channels_opened(0), data_channels_closed(0) {}
  250. // The opened count goes up when a channel is fully opened and the closed
  251. // count goes up if a previously opened channel has fully closed. The opened
  252. // count does not go down when a channel closes, meaning (opened - closed)
  253. // is the number of channels currently opened. A channel that is closed
  254. // before reaching the open state does not affect these counters.
  255. uint32_t data_channels_opened;
  256. uint32_t data_channels_closed;
  257. // Identifies by address channels that have been opened, which remain in the
  258. // set until they have been fully closed.
  259. std::set<uintptr_t> opened_data_channels;
  260. };
  261. InternalRecord internal_record_;
  262. };
  263. const char* CandidateTypeToRTCIceCandidateTypeForTesting(
  264. const std::string& type);
  265. const char* DataStateToRTCDataChannelStateForTesting(
  266. DataChannelInterface::DataState state);
  267. } // namespace webrtc
  268. #endif // PC_RTC_STATS_COLLECTOR_H_