blob: 2b54614b3acfc7c319b26b532dde61523968b604 [file] [log] [blame]
Henrik Boström3e6931b2022-11-11 09:07:341/*
2 * Copyright 2012 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
11// This file contains structures used for retrieving statistics from an ongoing
12// libjingle session.
13
14#ifndef API_LEGACY_STATS_TYPES_H_
15#define API_LEGACY_STATS_TYPES_H_
16
Dor Henaefed552024-06-18 13:20:3517#include <stddef.h>
18#include <stdint.h>
19
Henrik Boström3e6931b2022-11-11 09:07:3420#include <list>
21#include <map>
22#include <string>
23#include <vector>
24
Harald Alvestrande8a2b3c2023-10-31 13:30:3025#include "api/ref_count.h"
Henrik Boström3e6931b2022-11-11 09:07:3426#include "api/scoped_refptr.h"
27#include "api/sequence_checker.h"
Dor Henaefed552024-06-18 13:20:3528#include "rtc_base/checks.h"
Henrik Boström3e6931b2022-11-11 09:07:3429#include "rtc_base/system/rtc_export.h"
Dor Henaefed552024-06-18 13:20:3530#include "rtc_base/thread_annotations.h"
Henrik Boström3e6931b2022-11-11 09:07:3431
32namespace webrtc {
33
34class RTC_EXPORT StatsReport {
35 public:
36 // Indicates whether a track is for sending or receiving.
37 // Used in reports for audio/video tracks.
38 enum Direction {
39 kSend = 0,
40 kReceive,
41 };
42
43 enum StatsType {
44 // StatsReport types.
45 // A StatsReport of `type` = "googSession" contains overall information
46 // about the thing libjingle calls a session (which may contain one
47 // or more RTP sessions.
48 kStatsReportTypeSession,
49
50 // A StatsReport of `type` = "googTransport" contains information
51 // about a libjingle "transport".
52 kStatsReportTypeTransport,
53
54 // A StatsReport of `type` = "googComponent" contains information
55 // about a libjingle "channel" (typically, RTP or RTCP for a transport).
56 // This is intended to be the same thing as an ICE "Component".
57 kStatsReportTypeComponent,
58
59 // A StatsReport of `type` = "googCandidatePair" contains information
60 // about a libjingle "connection" - a single source/destination port pair.
61 // This is intended to be the same thing as an ICE "candidate pair".
62 kStatsReportTypeCandidatePair,
63
64 // A StatsReport of `type` = "VideoBWE" is statistics for video Bandwidth
65 // Estimation, which is global per-session. The `id` field is "bweforvideo"
66 // (will probably change in the future).
67 kStatsReportTypeBwe,
68
69 // A StatsReport of `type` = "ssrc" is statistics for a specific rtp stream.
70 // The `id` field is the SSRC in decimal form of the rtp stream.
71 kStatsReportTypeSsrc,
72
73 // A StatsReport of `type` = "remoteSsrc" is statistics for a specific
74 // rtp stream, generated by the remote end of the connection.
75 kStatsReportTypeRemoteSsrc,
76
77 // A StatsReport of `type` = "googTrack" is statistics for a specific media
78 // track. The `id` field is the track id.
79 kStatsReportTypeTrack,
80
81 // A StatsReport of `type` = "localcandidate" or "remotecandidate" is
82 // attributes on a specific ICE Candidate. It links to its connection pair
83 // by candidate id. The string value is taken from
84 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
85 kStatsReportTypeIceLocalCandidate,
86 kStatsReportTypeIceRemoteCandidate,
87
88 // A StatsReport of `type` = "googCertificate" contains an SSL certificate
89 // transmitted by one of the endpoints of this connection. The `id` is
90 // controlled by the fingerprint, and is used to identify the certificate in
91 // the Channel stats (as "googLocalCertificateId" or
92 // "googRemoteCertificateId") and in any child certificates (as
93 // "googIssuerId").
94 kStatsReportTypeCertificate,
95
96 // A StatsReport of `type` = "datachannel" with statistics for a
97 // particular DataChannel.
98 kStatsReportTypeDataChannel,
99 };
100
101 enum StatsValueName {
102 kStatsValueNameActiveConnection,
103 kStatsValueNameAecDivergentFilterFraction,
104 kStatsValueNameAudioInputLevel,
105 kStatsValueNameAudioOutputLevel,
106 kStatsValueNameBytesReceived,
107 kStatsValueNameBytesSent,
108 kStatsValueNameCodecImplementationName,
109 kStatsValueNameConcealedSamples,
110 kStatsValueNameConcealmentEvents,
111 kStatsValueNameDataChannelId,
112 kStatsValueNameFramesDecoded,
113 kStatsValueNameFramesEncoded,
114 kStatsValueNameJitterBufferDelay,
115 kStatsValueNameMediaType,
116 kStatsValueNamePacketsLost,
117 kStatsValueNamePacketsReceived,
118 kStatsValueNamePacketsSent,
119 kStatsValueNameProtocol,
120 kStatsValueNameQpSum,
121 kStatsValueNameReceiving,
122 kStatsValueNameSelectedCandidatePairId,
123 kStatsValueNameSsrc,
124 kStatsValueNameState,
125 kStatsValueNameTotalAudioEnergy,
126 kStatsValueNameTotalSamplesDuration,
127 kStatsValueNameTotalSamplesReceived,
128 kStatsValueNameTransportId,
129 kStatsValueNameSentPingRequestsTotal,
130 kStatsValueNameSentPingRequestsBeforeFirstResponse,
131 kStatsValueNameSentPingResponses,
132 kStatsValueNameRecvPingRequests,
133 kStatsValueNameRecvPingResponses,
134 kStatsValueNameSentStunKeepaliveRequests,
135 kStatsValueNameRecvStunKeepaliveResponses,
136 kStatsValueNameStunKeepaliveRttTotal,
137 kStatsValueNameStunKeepaliveRttSquaredTotal,
138
139 // Internal StatsValue names.
140 kStatsValueNameAccelerateRate,
141 kStatsValueNameActualEncBitrate,
142 kStatsValueNameAdaptationChanges,
143 kStatsValueNameAvailableReceiveBandwidth,
144 kStatsValueNameAvailableSendBandwidth,
145 kStatsValueNameAvgEncodeMs,
146 kStatsValueNameBandwidthLimitedResolution,
147 kStatsValueNameBucketDelay,
148 kStatsValueNameCaptureStartNtpTimeMs,
149 kStatsValueNameCandidateIPAddress,
150 kStatsValueNameCandidateNetworkType,
151 kStatsValueNameCandidatePortNumber,
152 kStatsValueNameCandidatePriority,
153 kStatsValueNameCandidateTransportType,
154 kStatsValueNameCandidateType,
155 kStatsValueNameChannelId,
156 kStatsValueNameCodecName,
157 kStatsValueNameComponent,
158 kStatsValueNameContentName,
159 kStatsValueNameContentType,
160 kStatsValueNameCpuLimitedResolution,
161 kStatsValueNameCurrentDelayMs,
162 kStatsValueNameDecodeMs,
163 kStatsValueNameDecodingCNG,
164 kStatsValueNameDecodingCTN,
165 kStatsValueNameDecodingCTSG,
166 kStatsValueNameDecodingMutedOutput,
167 kStatsValueNameDecodingNormal,
168 kStatsValueNameDecodingPLC,
169 kStatsValueNameDecodingCodecPLC,
170 kStatsValueNameDecodingPLCCNG,
171 kStatsValueNameDer,
172 kStatsValueNameDtlsCipher,
173 kStatsValueNameEchoDelayMedian,
174 kStatsValueNameEchoDelayStdDev,
175 kStatsValueNameEchoReturnLoss,
176 kStatsValueNameEchoReturnLossEnhancement,
177 kStatsValueNameEncodeUsagePercent,
178 kStatsValueNameExpandRate,
179 kStatsValueNameFingerprint,
180 kStatsValueNameFingerprintAlgorithm,
181 kStatsValueNameFirsReceived,
182 kStatsValueNameFirsSent,
183 kStatsValueNameFirstFrameReceivedToDecodedMs,
184 kStatsValueNameFrameHeightInput,
185 kStatsValueNameFrameHeightReceived,
186 kStatsValueNameFrameHeightSent,
187 kStatsValueNameFrameRateDecoded,
188 kStatsValueNameFrameRateInput,
189 kStatsValueNameFrameRateOutput,
190 kStatsValueNameFrameRateReceived,
191 kStatsValueNameFrameRateSent,
192 kStatsValueNameFrameWidthInput,
193 kStatsValueNameFrameWidthReceived,
194 kStatsValueNameFrameWidthSent,
195 kStatsValueNameHasEnteredLowResolution,
196 kStatsValueNameHugeFramesSent,
197 kStatsValueNameInitiator,
198 kStatsValueNameInterframeDelayMaxMs, // Max over last 10 seconds.
199 kStatsValueNameIssuerId,
200 kStatsValueNameJitterBufferMs,
201 kStatsValueNameJitterReceived,
202 kStatsValueNameLabel,
203 kStatsValueNameLocalAddress,
204 kStatsValueNameLocalCandidateId,
205 kStatsValueNameLocalCandidateType,
206 kStatsValueNameLocalCertificateId,
207 kStatsValueNameMaxDecodeMs,
208 kStatsValueNameMinPlayoutDelayMs,
209 kStatsValueNameNacksReceived,
210 kStatsValueNameNacksSent,
211 kStatsValueNamePlisReceived,
212 kStatsValueNamePlisSent,
213 kStatsValueNamePreemptiveExpandRate,
214 kStatsValueNamePreferredJitterBufferMs,
215 kStatsValueNameRemoteAddress,
216 kStatsValueNameRemoteCandidateId,
217 kStatsValueNameRemoteCandidateType,
218 kStatsValueNameRemoteCertificateId,
219 kStatsValueNameRenderDelayMs,
220 kStatsValueNameResidualEchoLikelihood,
221 kStatsValueNameResidualEchoLikelihoodRecentMax,
222 kStatsValueNameAnaBitrateActionCounter,
223 kStatsValueNameAnaChannelActionCounter,
224 kStatsValueNameAnaDtxActionCounter,
225 kStatsValueNameAnaFecActionCounter,
226 kStatsValueNameAnaFrameLengthIncreaseCounter,
227 kStatsValueNameAnaFrameLengthDecreaseCounter,
228 kStatsValueNameAnaUplinkPacketLossFraction,
229 kStatsValueNameRetransmitBitrate,
230 kStatsValueNameRtt,
231 kStatsValueNameSecondaryDecodedRate,
232 kStatsValueNameSecondaryDiscardedRate,
233 kStatsValueNameSendPacketsDiscarded,
234 kStatsValueNameSpeechExpandRate,
235 kStatsValueNameSrtpCipher,
236 kStatsValueNameTargetDelayMs,
237 kStatsValueNameTargetEncBitrate,
238 kStatsValueNameTimingFrameInfo, // Result of `TimingFrameInfo::ToString`
239 kStatsValueNameTrackId,
240 kStatsValueNameTransmitBitrate,
241 kStatsValueNameTransportType,
242 kStatsValueNameWritable,
243 kStatsValueNameAudioDeviceUnderrunCounter,
244 kStatsValueNameLocalCandidateRelayProtocol,
245 };
246
Harald Alvestrande8a2b3c2023-10-31 13:30:30247 class RTC_EXPORT IdBase : public webrtc::RefCountInterface {
Henrik Boström3e6931b2022-11-11 09:07:34248 public:
249 ~IdBase() override;
250 StatsType type() const;
251
252 // Users of IdBase will be using the Id typedef, which is compatible with
253 // this Equals() function. It simply calls the protected (and overridden)
254 // Equals() method.
255 bool Equals(const rtc::scoped_refptr<IdBase>& other) const {
256 return Equals(*other.get());
257 }
258
259 virtual std::string ToString() const = 0;
260
261 protected:
262 // Protected since users of the IdBase type will be using the Id typedef.
263 virtual bool Equals(const IdBase& other) const;
264
265 explicit IdBase(StatsType type); // Only meant for derived classes.
266 const StatsType type_;
267
268 static const char kSeparator = '_';
269 };
270
271 typedef rtc::scoped_refptr<IdBase> Id;
272
273 struct RTC_EXPORT Value {
274 enum Type {
275 kInt, // int.
276 kInt64, // int64_t.
277 kFloat, // float.
278 kString, // std::string
279 kStaticString, // const char*.
280 kBool, // bool.
281 kId, // Id.
282 };
283
284 Value(StatsValueName name, int64_t value, Type int_type);
285 Value(StatsValueName name, float f);
286 Value(StatsValueName name, const std::string& value);
287 Value(StatsValueName name, const char* value);
288 Value(StatsValueName name, bool b);
289 Value(StatsValueName name, const Id& value);
290
291 ~Value();
292
293 Value(const Value&) = delete;
294 Value& operator=(const Value&) = delete;
295
296 // Support ref counting. Note that for performance reasons, we
297 // don't use thread safe operations. Therefore, all operations
298 // affecting the ref count (in practice, creation and copying of
299 // the Values mapping) must occur on webrtc's signalling thread.
300 int AddRef() const {
301 RTC_DCHECK_RUN_ON(&thread_checker_);
302 return ++ref_count_;
303 }
304 int Release() const {
305 RTC_DCHECK_RUN_ON(&thread_checker_);
306 int count = --ref_count_;
307 if (!count)
308 delete this;
309 return count;
310 }
311
312 // TODO(tommi): This compares name as well as value...
313 // I think we should only need to compare the value part and
314 // move the name part into a hash map.
315 bool Equals(const Value& other) const;
316
317 // Comparison operators. Return true iff the current instance is of the
318 // correct type and holds the same value. No conversion is performed so
319 // a string value of "123" is not equal to an int value of 123 and an int
320 // value of 123 is not equal to a float value of 123.0f.
321 // One exception to this is that types kInt and kInt64 can be compared and
322 // kString and kStaticString too.
323 bool operator==(const std::string& value) const;
324 bool operator==(const char* value) const;
325 bool operator==(int64_t value) const;
326 bool operator==(bool value) const;
327 bool operator==(float value) const;
328 bool operator==(const Id& value) const;
329
330 // Getters that allow getting the native value directly.
331 // The caller must know the type beforehand or else hit a check.
332 int int_val() const;
333 int64_t int64_val() const;
334 float float_val() const;
335 const char* static_string_val() const;
336 const std::string& string_val() const;
337 bool bool_val() const;
338 const Id& id_val() const;
339
340 // Returns the string representation of `name`.
341 const char* display_name() const;
342
343 // Converts the native value to a string representation of the value.
344 std::string ToString() const;
345
346 Type type() const { return type_; }
347
348 // TODO(tommi): Move `name` and `display_name` out of the Value struct.
349 const StatsValueName name;
350
Tommi0fe65102023-03-31 10:09:30351 protected:
352#if RTC_DCHECK_IS_ON
353 friend class StatsReport;
354 void DetachSequenceChecker() { thread_checker_.Detach(); }
355 void AttachSequenceChecker() { RTC_DCHECK_RUN_ON(&thread_checker_); }
356#endif
357
Henrik Boström3e6931b2022-11-11 09:07:34358 private:
Tommi0fe65102023-03-31 10:09:30359 webrtc::SequenceChecker thread_checker_{webrtc::SequenceChecker::kDetached};
Henrik Boström3e6931b2022-11-11 09:07:34360 mutable int ref_count_ RTC_GUARDED_BY(thread_checker_) = 0;
361
362 const Type type_;
363 // TODO(tommi): Use C++ 11 union and make value_ const.
364 union InternalType {
365 int int_;
366 int64_t int64_;
367 float float_;
368 bool bool_;
369 std::string* string_;
370 const char* static_string_;
371 Id* id_;
372 } value_;
373 };
374
375 typedef rtc::scoped_refptr<Value> ValuePtr;
376 typedef std::map<StatsValueName, ValuePtr> Values;
377
378 // Ownership of `id` is passed to `this`.
379 explicit StatsReport(const Id& id);
380 ~StatsReport();
381
382 StatsReport(const StatsReport&) = delete;
383 StatsReport& operator=(const StatsReport&) = delete;
384
385 // Factory functions for various types of stats IDs.
386 static Id NewBandwidthEstimationId();
387 static Id NewTypedId(StatsType type, const std::string& id);
388 static Id NewTypedIntId(StatsType type, int id);
389 static Id NewIdWithDirection(StatsType type,
390 const std::string& id,
391 Direction direction);
392 static Id NewCandidateId(bool local, const std::string& id);
393 static Id NewComponentId(const std::string& content_name, int component);
394 static Id NewCandidatePairId(const std::string& content_name,
395 int component,
396 int index);
397
398 const Id& id() const { return id_; }
399 StatsType type() const { return id_->type(); }
400 double timestamp() const { return timestamp_; }
401 void set_timestamp(double t) { timestamp_ = t; }
402 bool empty() const { return values_.empty(); }
403 const Values& values() const { return values_; }
404
405 const char* TypeToString() const;
406
407 void AddString(StatsValueName name, const std::string& value);
408 void AddString(StatsValueName name, const char* value);
409 void AddInt64(StatsValueName name, int64_t value);
410 void AddInt(StatsValueName name, int value);
411 void AddFloat(StatsValueName name, float value);
412 void AddBoolean(StatsValueName name, bool value);
413 void AddId(StatsValueName name, const Id& value);
414
415 const Value* FindValue(StatsValueName name) const;
416
Tommi0fe65102023-03-31 10:09:30417#if RTC_DCHECK_IS_ON
418 void DetachSequenceCheckers() {
419 for (auto& v : values_) {
420 v.second->DetachSequenceChecker();
421 }
422 }
423 void AttachSequenceCheckers() {
424 for (auto& v : values_) {
425 v.second->AttachSequenceChecker();
426 }
427 }
428#endif
429
Henrik Boström3e6931b2022-11-11 09:07:34430 private:
431 // The unique identifier for this object.
432 // This is used as a key for this report in ordered containers,
433 // so it must never be changed.
434 const Id id_;
435 double timestamp_; // Time since 1970-01-01T00:00:00Z in milliseconds.
436 Values values_;
437};
438
439// Typedef for an array of const StatsReport pointers.
440// Ownership of the pointers held by this implementation is assumed to lie
441// elsewhere and lifetime guarantees are made by the implementation that uses
442// this type. In the StatsCollector, object ownership lies with the
443// StatsCollection class.
444typedef std::vector<const StatsReport*> StatsReports;
445
446// A map from the report id to the report.
447// This class wraps an STL container and provides a limited set of
448// functionality in order to keep things simple.
449class StatsCollection {
450 public:
451 StatsCollection();
452 ~StatsCollection();
453
454 typedef std::list<StatsReport*> Container;
455 typedef Container::iterator iterator;
456 typedef Container::const_iterator const_iterator;
457
458 const_iterator begin() const;
459 const_iterator end() const;
460 size_t size() const;
461
462 // Creates a new report object with `id` that does not already
463 // exist in the list of reports.
464 StatsReport* InsertNew(const StatsReport::Id& id);
465 StatsReport* FindOrAddNew(const StatsReport::Id& id);
466 StatsReport* ReplaceOrAddNew(const StatsReport::Id& id);
467
Tommi0fe65102023-03-31 10:09:30468 Container DetachCollection();
469 void MergeCollection(Container collection);
470
Henrik Boström3e6931b2022-11-11 09:07:34471 // Looks for a report with the given `id`. If one is not found, null
472 // will be returned.
473 StatsReport* Find(const StatsReport::Id& id);
474
475 private:
476 Container list_;
Tommi0fe65102023-03-31 10:09:30477 webrtc::SequenceChecker thread_checker_{SequenceChecker::kDetached};
Henrik Boström3e6931b2022-11-11 09:07:34478};
479
480} // namespace webrtc
481
482#endif // API_LEGACY_STATS_TYPES_H_