blob: f1a11304a8837eb10a52d9e5433f5be117f6bfbb [file] [log] [blame]
tommi@webrtc.org5c3ee4b2014-12-09 10:47:011/*
kjellanderb24317b2016-02-10 15:54:432 * Copyright 2014 The WebRTC project authors. All Rights Reserved.
tommi@webrtc.org5c3ee4b2014-12-09 10:47:013 *
kjellanderb24317b2016-02-10 15:54:434 * 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.
tommi@webrtc.org5c3ee4b2014-12-09 10:47:019 */
10
Mirko Bonadei92ea95e2017-09-15 04:47:3111#include "api/statstypes.h"
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0112
tommi@webrtc.orgd3900292015-03-12 16:35:5513#include <string.h>
14
Mirko Bonadei92ea95e2017-09-15 04:47:3115#include "rtc_base/checks.h"
tommi@webrtc.orgd3900292015-03-12 16:35:5516
17// TODO(tommi): Could we have a static map of value name -> expected type
henrikg91d6ede2015-09-17 07:24:3418// and use this to RTC_DCHECK on correct usage (somewhat strongly typed values)?
tommi@webrtc.orgd3900292015-03-12 16:35:5519// Alternatively, we could define the names+type in a separate document and
20// generate strongly typed inline C++ code that forces the correct type to be
21// used for a given name at compile time.
22
tommi@webrtc.org4b89aa02015-03-16 09:52:3023using rtc::RefCountedObject;
tommi@webrtc.org8e327c42015-01-19 20:41:2624
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0125namespace webrtc {
tommi@webrtc.org4fb7e252015-01-21 11:36:1826namespace {
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0127
tommi@webrtc.org4fb7e252015-01-21 11:36:1828// The id of StatsReport of type kStatsReportTypeBwe.
29const char kStatsReportVideoBweId[] = "bweforvideo";
tommi@webrtc.orgc9d155f2014-12-09 18:18:0630
tommi@webrtc.org4fb7e252015-01-21 11:36:1831// NOTE: These names need to be consistent with an external
32// specification (W3C Stats Identifiers).
33const char* InternalTypeToString(StatsReport::StatsType type) {
34 switch (type) {
35 case StatsReport::kStatsReportTypeSession:
36 return "googLibjingleSession";
37 case StatsReport::kStatsReportTypeBwe:
38 return "VideoBwe";
39 case StatsReport::kStatsReportTypeRemoteSsrc:
40 return "remoteSsrc";
41 case StatsReport::kStatsReportTypeSsrc:
42 return "ssrc";
43 case StatsReport::kStatsReportTypeTrack:
44 return "googTrack";
45 case StatsReport::kStatsReportTypeIceLocalCandidate:
46 return "localcandidate";
47 case StatsReport::kStatsReportTypeIceRemoteCandidate:
48 return "remotecandidate";
49 case StatsReport::kStatsReportTypeTransport:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:3050 return "transport";
tommi@webrtc.org4fb7e252015-01-21 11:36:1851 case StatsReport::kStatsReportTypeComponent:
52 return "googComponent";
53 case StatsReport::kStatsReportTypeCandidatePair:
54 return "googCandidatePair";
55 case StatsReport::kStatsReportTypeCertificate:
56 return "googCertificate";
57 case StatsReport::kStatsReportTypeDataChannel:
58 return "datachannel";
59 }
nisseeb4ca4e2017-01-12 10:24:2760 RTC_NOTREACHED();
tommi@webrtc.org4fb7e252015-01-21 11:36:1861 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:0662}
63
tommi@webrtc.orgd3900292015-03-12 16:35:5564class BandwidthEstimationId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:1865 public:
tommi@webrtc.orgd3900292015-03-12 16:35:5566 BandwidthEstimationId()
67 : StatsReport::IdBase(StatsReport::kStatsReportTypeBwe) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:1868 std::string ToString() const override { return kStatsReportVideoBweId; }
69};
tommi@webrtc.org8e327c42015-01-19 20:41:2670
tommi@webrtc.orgd3900292015-03-12 16:35:5571class TypedId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:1872 public:
tommi@webrtc.org4fb7e252015-01-21 11:36:1873 TypedId(StatsReport::StatsType type, const std::string& id)
tommi@webrtc.orgd3900292015-03-12 16:35:5574 : StatsReport::IdBase(type), id_(id) {}
tommi@webrtc.org8e327c42015-01-19 20:41:2675
tommi@webrtc.orgd3900292015-03-12 16:35:5576 bool Equals(const IdBase& other) const override {
77 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:1878 static_cast<const TypedId&>(other).id_ == id_;
79 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:0680
tommi@webrtc.org4fb7e252015-01-21 11:36:1881 std::string ToString() const override {
82 return std::string(InternalTypeToString(type_)) + kSeparator + id_;
83 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:0684
tommi@webrtc.org4fb7e252015-01-21 11:36:1885 protected:
86 const std::string id_;
87};
tommi@webrtc.orgc9d155f2014-12-09 18:18:0688
tommi@webrtc.orgd3900292015-03-12 16:35:5589class TypedIntId : public StatsReport::IdBase {
decurtis@webrtc.org322a5642015-02-03 22:09:3790 public:
91 TypedIntId(StatsReport::StatsType type, int id)
tommi@webrtc.orgd3900292015-03-12 16:35:5592 : StatsReport::IdBase(type), id_(id) {}
decurtis@webrtc.org322a5642015-02-03 22:09:3793
tommi@webrtc.orgd3900292015-03-12 16:35:5594 bool Equals(const IdBase& other) const override {
95 return IdBase::Equals(other) &&
decurtis@webrtc.org322a5642015-02-03 22:09:3796 static_cast<const TypedIntId&>(other).id_ == id_;
97 }
98
99 std::string ToString() const override {
100 return std::string(InternalTypeToString(type_)) +
101 kSeparator +
102 rtc::ToString<int>(id_);
103 }
104
105 protected:
106 const int id_;
107};
108
tommi@webrtc.org4fb7e252015-01-21 11:36:18109class IdWithDirection : public TypedId {
110 public:
111 IdWithDirection(StatsReport::StatsType type, const std::string& id,
112 StatsReport::Direction direction)
113 : TypedId(type, id), direction_(direction) {}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06114
tommi@webrtc.orgd3900292015-03-12 16:35:55115 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18116 return TypedId::Equals(other) &&
117 static_cast<const IdWithDirection&>(other).direction_ == direction_;
118 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06119
tommi@webrtc.org4fb7e252015-01-21 11:36:18120 std::string ToString() const override {
121 std::string ret(TypedId::ToString());
decurtis@webrtc.org322a5642015-02-03 22:09:37122 ret += kSeparator;
tommi@webrtc.org4fb7e252015-01-21 11:36:18123 ret += direction_ == StatsReport::kSend ? "send" : "recv";
124 return ret;
125 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06126
tommi@webrtc.org4fb7e252015-01-21 11:36:18127 private:
128 const StatsReport::Direction direction_;
129};
130
131class CandidateId : public TypedId {
132 public:
133 CandidateId(bool local, const std::string& id)
134 : TypedId(local ?
135 StatsReport::kStatsReportTypeIceLocalCandidate :
136 StatsReport::kStatsReportTypeIceRemoteCandidate,
137 id) {
138 }
139
140 std::string ToString() const override {
141 return "Cand-" + id_;
142 }
143};
144
tommi@webrtc.orgd3900292015-03-12 16:35:55145class ComponentId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18146 public:
147 ComponentId(const std::string& content_name, int component)
148 : ComponentId(StatsReport::kStatsReportTypeComponent, content_name,
149 component) {}
150
tommi@webrtc.orgd3900292015-03-12 16:35:55151 bool Equals(const IdBase& other) const override {
152 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:18153 static_cast<const ComponentId&>(other).component_ == component_ &&
154 static_cast<const ComponentId&>(other).content_name_ == content_name_;
155 }
156
157 std::string ToString() const override {
158 return ToString("Channel-");
159 }
160
161 protected:
162 ComponentId(StatsReport::StatsType type, const std::string& content_name,
163 int component)
tommi@webrtc.orgd3900292015-03-12 16:35:55164 : IdBase(type),
tommi@webrtc.org4fb7e252015-01-21 11:36:18165 content_name_(content_name),
166 component_(component) {}
167
168 std::string ToString(const char* prefix) const {
169 std::string ret(prefix);
170 ret += content_name_;
171 ret += '-';
172 ret += rtc::ToString<>(component_);
173 return ret;
174 }
175
176 private:
177 const std::string content_name_;
178 const int component_;
179};
180
181class CandidatePairId : public ComponentId {
182 public:
183 CandidatePairId(const std::string& content_name, int component, int index)
184 : ComponentId(StatsReport::kStatsReportTypeCandidatePair, content_name,
185 component),
186 index_(index) {}
187
tommi@webrtc.orgd3900292015-03-12 16:35:55188 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18189 return ComponentId::Equals(other) &&
190 static_cast<const CandidatePairId&>(other).index_ == index_;
191 }
192
193 std::string ToString() const override {
194 std::string ret(ComponentId::ToString("Conn-"));
195 ret += '-';
196 ret += rtc::ToString<>(index_);
197 return ret;
198 }
199
200 private:
201 const int index_;
202};
203
204} // namespace
205
tommi@webrtc.orgd3900292015-03-12 16:35:55206StatsReport::IdBase::IdBase(StatsType type) : type_(type) {}
207StatsReport::IdBase::~IdBase() {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18208
tommi@webrtc.orgd3900292015-03-12 16:35:55209StatsReport::StatsType StatsReport::IdBase::type() const { return type_; }
tommi@webrtc.org4fb7e252015-01-21 11:36:18210
tommi@webrtc.orgd3900292015-03-12 16:35:55211bool StatsReport::IdBase::Equals(const IdBase& other) const {
tommi@webrtc.org4fb7e252015-01-21 11:36:18212 return other.type_ == type_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06213}
214
Peter Boström0c4e06b2015-10-07 10:23:21215StatsReport::Value::Value(StatsValueName name, int64_t value, Type int_type)
tommi@webrtc.orgd3900292015-03-12 16:35:55216 : name(name), type_(int_type) {
henrikg91d6ede2015-09-17 07:24:34217 RTC_DCHECK(type_ == kInt || type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55218 type_ == kInt ? value_.int_ = static_cast<int>(value) : value_.int64_ = value;
219}
220
221StatsReport::Value::Value(StatsValueName name, float f)
222 : name(name), type_(kFloat) {
223 value_.float_ = f;
224}
225
tommi@webrtc.orgc9d155f2014-12-09 18:18:06226StatsReport::Value::Value(StatsValueName name, const std::string& value)
tommi@webrtc.orgd3900292015-03-12 16:35:55227 : name(name), type_(kString) {
228 value_.string_ = new std::string(value);
229}
230
231StatsReport::Value::Value(StatsValueName name, const char* value)
232 : name(name), type_(kStaticString) {
233 value_.static_string_ = value;
234}
235
236StatsReport::Value::Value(StatsValueName name, bool b)
237 : name(name), type_(kBool) {
238 value_.bool_ = b;
239}
240
241StatsReport::Value::Value(StatsValueName name, const Id& value)
242 : name(name), type_(kId) {
243 value_.id_ = new Id(value);
244}
245
246StatsReport::Value::~Value() {
247 switch (type_) {
248 case kInt:
249 case kInt64:
250 case kFloat:
251 case kBool:
252 case kStaticString:
253 break;
254 case kString:
255 delete value_.string_;
256 break;
257 case kId:
258 delete value_.id_;
259 break;
260 }
261}
262
263bool StatsReport::Value::Equals(const Value& other) const {
264 if (name != other.name)
265 return false;
266
267 // There's a 1:1 relation between a name and a type, so we don't have to
268 // check that.
henrikg91d6ede2015-09-17 07:24:34269 RTC_DCHECK_EQ(type_, other.type_);
tommi@webrtc.orgd3900292015-03-12 16:35:55270
271 switch (type_) {
272 case kInt:
273 return value_.int_ == other.value_.int_;
274 case kInt64:
275 return value_.int64_ == other.value_.int64_;
276 case kFloat:
277 return value_.float_ == other.value_.float_;
278 case kStaticString: {
kwiberg5377bc72016-10-04 20:46:56279#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55280 if (value_.static_string_ != other.value_.static_string_) {
henrikg91d6ede2015-09-17 07:24:34281 RTC_DCHECK(strcmp(value_.static_string_, other.value_.static_string_) !=
282 0)
tommi@webrtc.orgd3900292015-03-12 16:35:55283 << "Duplicate global?";
284 }
285#endif
286 return value_.static_string_ == other.value_.static_string_;
287 }
288 case kString:
289 return *value_.string_ == *other.value_.string_;
290 case kBool:
291 return value_.bool_ == other.value_.bool_;
292 case kId:
293 return (*value_.id_)->Equals(*other.value_.id_);
294 }
295 RTC_NOTREACHED();
296 return false;
297}
298
299bool StatsReport::Value::operator==(const std::string& value) const {
300 return (type_ == kString && value_.string_->compare(value) == 0) ||
301 (type_ == kStaticString && value.compare(value_.static_string_) == 0);
302}
303
304bool StatsReport::Value::operator==(const char* value) const {
305 if (type_ == kString)
306 return value_.string_->compare(value) == 0;
307 if (type_ != kStaticString)
308 return false;
kwiberg5377bc72016-10-04 20:46:56309#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55310 if (value_.static_string_ != value)
henrikg91d6ede2015-09-17 07:24:34311 RTC_DCHECK(strcmp(value_.static_string_, value) != 0)
312 << "Duplicate global?";
tommi@webrtc.orgd3900292015-03-12 16:35:55313#endif
314 return value == value_.static_string_;
315}
316
Peter Boström0c4e06b2015-10-07 10:23:21317bool StatsReport::Value::operator==(int64_t value) const {
tommi@webrtc.orgd3900292015-03-12 16:35:55318 return type_ == kInt ? value_.int_ == static_cast<int>(value) :
319 (type_ == kInt64 ? value_.int64_ == value : false);
320}
321
322bool StatsReport::Value::operator==(bool value) const {
323 return type_ == kBool && value_.bool_ == value;
324}
325
326bool StatsReport::Value::operator==(float value) const {
327 return type_ == kFloat && value_.float_ == value;
328}
329
330bool StatsReport::Value::operator==(const Id& value) const {
331 return type_ == kId && (*value_.id_)->Equals(value);
332}
333
334int StatsReport::Value::int_val() const {
henrikg91d6ede2015-09-17 07:24:34335 RTC_DCHECK(type_ == kInt);
tommi@webrtc.orgd3900292015-03-12 16:35:55336 return value_.int_;
337}
338
Peter Boström0c4e06b2015-10-07 10:23:21339int64_t StatsReport::Value::int64_val() const {
henrikg91d6ede2015-09-17 07:24:34340 RTC_DCHECK(type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55341 return value_.int64_;
342}
343
344float StatsReport::Value::float_val() const {
henrikg91d6ede2015-09-17 07:24:34345 RTC_DCHECK(type_ == kFloat);
tommi@webrtc.orgd3900292015-03-12 16:35:55346 return value_.float_;
347}
348
349const char* StatsReport::Value::static_string_val() const {
henrikg91d6ede2015-09-17 07:24:34350 RTC_DCHECK(type_ == kStaticString);
tommi@webrtc.orgd3900292015-03-12 16:35:55351 return value_.static_string_;
352}
353
354const std::string& StatsReport::Value::string_val() const {
henrikg91d6ede2015-09-17 07:24:34355 RTC_DCHECK(type_ == kString);
tommi@webrtc.orgd3900292015-03-12 16:35:55356 return *value_.string_;
357}
358
359bool StatsReport::Value::bool_val() const {
henrikg91d6ede2015-09-17 07:24:34360 RTC_DCHECK(type_ == kBool);
tommi@webrtc.orgd3900292015-03-12 16:35:55361 return value_.bool_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06362}
363
tommi@webrtc.orgc9d155f2014-12-09 18:18:06364const char* StatsReport::Value::display_name() const {
tommi@webrtc.orgc57310b2014-12-12 17:41:28365 switch (name) {
Minyue2a8a78c2016-04-07 14:48:15366 case kStatsValueNameAecDivergentFilterFraction:
367 return "aecDivergentFilterFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28368 case kStatsValueNameAudioOutputLevel:
369 return "audioOutputLevel";
370 case kStatsValueNameAudioInputLevel:
371 return "audioInputLevel";
372 case kStatsValueNameBytesSent:
373 return "bytesSent";
Steve Anton2dbc69f2017-08-25 00:15:13374 case kStatsValueNameConcealedSamples:
375 return "concealedSamples";
Gustaf Ullberg9a2e9062017-09-18 07:28:20376 case kStatsValueNameConcealmentEvents:
377 return "concealmentEvents";
tommi@webrtc.orgc57310b2014-12-12 17:41:28378 case kStatsValueNamePacketsSent:
379 return "packetsSent";
380 case kStatsValueNameBytesReceived:
381 return "bytesReceived";
decurtis@webrtc.org487a4442015-01-15 22:55:07382 case kStatsValueNameLabel:
383 return "label";
tommi@webrtc.orgc57310b2014-12-12 17:41:28384 case kStatsValueNamePacketsReceived:
385 return "packetsReceived";
386 case kStatsValueNamePacketsLost:
387 return "packetsLost";
decurtis@webrtc.org487a4442015-01-15 22:55:07388 case kStatsValueNameProtocol:
389 return "protocol";
Steve Anton2dbc69f2017-08-25 00:15:13390 case kStatsValueNameTotalSamplesReceived:
391 return "totalSamplesReceived";
tommi@webrtc.orgc57310b2014-12-12 17:41:28392 case kStatsValueNameTransportId:
393 return "transportId";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30394 case kStatsValueNameSelectedCandidatePairId:
395 return "selectedCandidatePairId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28396 case kStatsValueNameSsrc:
397 return "ssrc";
decurtis@webrtc.org487a4442015-01-15 22:55:07398 case kStatsValueNameState:
399 return "state";
400 case kStatsValueNameDataChannelId:
401 return "datachannelid";
sakale5ba44e2016-10-26 14:09:24402 case kStatsValueNameFramesDecoded:
403 return "framesDecoded";
sakal43536c32016-10-24 08:46:43404 case kStatsValueNameFramesEncoded:
405 return "framesEncoded";
Gustaf Ullbergb0a02072017-10-02 10:00:34406 case kStatsValueNameJitterBufferDelay:
407 return "jitterBufferDelay";
Peter Boströmb7d9a972015-12-18 15:01:11408 case kStatsValueNameCodecImplementationName:
409 return "codecImplementationName";
fippobec70ab2016-01-28 09:27:15410 case kStatsValueNameMediaType:
411 return "mediaType";
sakal87da4042016-10-31 13:53:47412 case kStatsValueNameQpSum:
413 return "qpSum";
tommi@webrtc.orgc57310b2014-12-12 17:41:28414 // 'goog' prefixed constants.
Henrik Lundin8e6fd462015-06-02 07:24:52415 case kStatsValueNameAccelerateRate:
416 return "googAccelerateRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28417 case kStatsValueNameActiveConnection:
418 return "googActiveConnection";
419 case kStatsValueNameActualEncBitrate:
420 return "googActualEncBitrate";
421 case kStatsValueNameAvailableReceiveBandwidth:
422 return "googAvailableReceiveBandwidth";
423 case kStatsValueNameAvailableSendBandwidth:
424 return "googAvailableSendBandwidth";
425 case kStatsValueNameAvgEncodeMs:
426 return "googAvgEncodeMs";
427 case kStatsValueNameBucketDelay:
428 return "googBucketDelay";
429 case kStatsValueNameBandwidthLimitedResolution:
430 return "googBandwidthLimitedResolution";
zhihuang5ecf16c2016-06-02 00:09:15431 // STUN ping related attributes.
432 // TODO(zhihuang) Rename these stats to follow the standards.
433 case kStatsValueNameSentPingRequestsTotal:
434 return "requestsSent";
435 case kStatsValueNameSentPingRequestsBeforeFirstResponse:
436 return "consentRequestsSent";
437 case kStatsValueNameSentPingResponses:
438 return "responsesSent";
439 case kStatsValueNameRecvPingRequests:
440 return "requestsReceived";
441 case kStatsValueNameRecvPingResponses:
442 return "responsesReceived";
guoweis@webrtc.org950c5182014-12-16 23:01:31443
444 // Candidate related attributes. Values are taken from
445 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
446 case kStatsValueNameCandidateIPAddress:
447 return "ipAddress";
448 case kStatsValueNameCandidateNetworkType:
449 return "networkType";
450 case kStatsValueNameCandidatePortNumber:
451 return "portNumber";
452 case kStatsValueNameCandidatePriority:
453 return "priority";
454 case kStatsValueNameCandidateTransportType:
455 return "transport";
456 case kStatsValueNameCandidateType:
457 return "candidateType";
458
tommi@webrtc.orgc57310b2014-12-12 17:41:28459 case kStatsValueNameChannelId:
460 return "googChannelId";
461 case kStatsValueNameCodecName:
462 return "googCodecName";
463 case kStatsValueNameComponent:
464 return "googComponent";
465 case kStatsValueNameContentName:
466 return "googContentName";
ilnik2e1b40b2017-09-04 14:57:17467 case kStatsValueNameContentType:
468 return "googContentType";
tommi@webrtc.orgc57310b2014-12-12 17:41:28469 case kStatsValueNameCpuLimitedResolution:
470 return "googCpuLimitedResolution";
471 case kStatsValueNameDecodingCTSG:
472 return "googDecodingCTSG";
473 case kStatsValueNameDecodingCTN:
474 return "googDecodingCTN";
henrik.lundin63489782016-09-20 08:47:12475 case kStatsValueNameDecodingMutedOutput:
476 return "googDecodingMuted";
tommi@webrtc.orgc57310b2014-12-12 17:41:28477 case kStatsValueNameDecodingNormal:
478 return "googDecodingNormal";
479 case kStatsValueNameDecodingPLC:
480 return "googDecodingPLC";
481 case kStatsValueNameDecodingCNG:
482 return "googDecodingCNG";
483 case kStatsValueNameDecodingPLCCNG:
484 return "googDecodingPLCCNG";
485 case kStatsValueNameDer:
486 return "googDerBase64";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30487 case kStatsValueNameDtlsCipher:
488 return "dtlsCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28489 case kStatsValueNameEchoCancellationQualityMin:
490 return "googEchoCancellationQualityMin";
491 case kStatsValueNameEchoDelayMedian:
492 return "googEchoCancellationEchoDelayMedian";
493 case kStatsValueNameEchoDelayStdDev:
494 return "googEchoCancellationEchoDelayStdDev";
495 case kStatsValueNameEchoReturnLoss:
496 return "googEchoCancellationReturnLoss";
497 case kStatsValueNameEchoReturnLossEnhancement:
498 return "googEchoCancellationReturnLossEnhancement";
499 case kStatsValueNameEncodeUsagePercent:
500 return "googEncodeUsagePercent";
501 case kStatsValueNameExpandRate:
502 return "googExpandRate";
503 case kStatsValueNameFingerprint:
504 return "googFingerprint";
505 case kStatsValueNameFingerprintAlgorithm:
506 return "googFingerprintAlgorithm";
507 case kStatsValueNameFirsReceived:
508 return "googFirsReceived";
509 case kStatsValueNameFirsSent:
510 return "googFirsSent";
511 case kStatsValueNameFrameHeightInput:
512 return "googFrameHeightInput";
513 case kStatsValueNameFrameHeightReceived:
514 return "googFrameHeightReceived";
515 case kStatsValueNameFrameHeightSent:
516 return "googFrameHeightSent";
517 case kStatsValueNameFrameRateReceived:
518 return "googFrameRateReceived";
519 case kStatsValueNameFrameRateDecoded:
520 return "googFrameRateDecoded";
521 case kStatsValueNameFrameRateOutput:
522 return "googFrameRateOutput";
523 case kStatsValueNameDecodeMs:
524 return "googDecodeMs";
525 case kStatsValueNameMaxDecodeMs:
526 return "googMaxDecodeMs";
527 case kStatsValueNameCurrentDelayMs:
528 return "googCurrentDelayMs";
529 case kStatsValueNameTargetDelayMs:
530 return "googTargetDelayMs";
531 case kStatsValueNameJitterBufferMs:
532 return "googJitterBufferMs";
533 case kStatsValueNameMinPlayoutDelayMs:
534 return "googMinPlayoutDelayMs";
535 case kStatsValueNameRenderDelayMs:
536 return "googRenderDelayMs";
537 case kStatsValueNameCaptureStartNtpTimeMs:
538 return "googCaptureStartNtpTimeMs";
539 case kStatsValueNameFrameRateInput:
540 return "googFrameRateInput";
541 case kStatsValueNameFrameRateSent:
542 return "googFrameRateSent";
543 case kStatsValueNameFrameWidthInput:
544 return "googFrameWidthInput";
545 case kStatsValueNameFrameWidthReceived:
546 return "googFrameWidthReceived";
547 case kStatsValueNameFrameWidthSent:
548 return "googFrameWidthSent";
549 case kStatsValueNameInitiator:
550 return "googInitiator";
ilnika79cc282017-08-23 12:24:10551 case kStatsValueNameInterframeDelayMaxMs:
552 return "googInterframeDelayMax";
tommi@webrtc.orgc57310b2014-12-12 17:41:28553 case kStatsValueNameIssuerId:
554 return "googIssuerId";
555 case kStatsValueNameJitterReceived:
556 return "googJitterReceived";
557 case kStatsValueNameLocalAddress:
558 return "googLocalAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31559 case kStatsValueNameLocalCandidateId:
560 return "localCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28561 case kStatsValueNameLocalCandidateType:
562 return "googLocalCandidateType";
563 case kStatsValueNameLocalCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30564 return "localCertificateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28565 case kStatsValueNameAdaptationChanges:
566 return "googAdaptationChanges";
567 case kStatsValueNameNacksReceived:
568 return "googNacksReceived";
569 case kStatsValueNameNacksSent:
570 return "googNacksSent";
Henrik Lundin8e6fd462015-06-02 07:24:52571 case kStatsValueNamePreemptiveExpandRate:
572 return "googPreemptiveExpandRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28573 case kStatsValueNamePlisReceived:
574 return "googPlisReceived";
575 case kStatsValueNamePlisSent:
576 return "googPlisSent";
577 case kStatsValueNamePreferredJitterBufferMs:
578 return "googPreferredJitterBufferMs";
Peter Thatcher04ac81f2015-09-21 18:48:28579 case kStatsValueNameReceiving:
tommi@webrtc.orgc57310b2014-12-12 17:41:28580 return "googReadable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28581 case kStatsValueNameRemoteAddress:
582 return "googRemoteAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31583 case kStatsValueNameRemoteCandidateId:
584 return "remoteCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28585 case kStatsValueNameRemoteCandidateType:
586 return "googRemoteCandidateType";
587 case kStatsValueNameRemoteCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30588 return "remoteCertificateId";
ivoc8c63a822016-10-21 11:10:03589 case kStatsValueNameResidualEchoLikelihood:
590 return "googResidualEchoLikelihood";
ivoc4e477a12017-01-15 16:29:46591 case kStatsValueNameResidualEchoLikelihoodRecentMax:
592 return "googResidualEchoLikelihoodRecentMax";
ivoce1198e02017-09-08 15:13:19593 case kStatsValueNameAnaBitrateActionCounter:
594 return "googAnaBitrateActionCounter";
595 case kStatsValueNameAnaChannelActionCounter:
596 return "googAnaChannelActionCounter";
597 case kStatsValueNameAnaDtxActionCounter:
598 return "googAnaDtxActionCounter";
599 case kStatsValueNameAnaFecActionCounter:
600 return "googAnaFecActionCounter";
ivoc0d0b9122017-09-08 20:24:21601 case kStatsValueNameAnaFrameLengthIncreaseCounter:
602 return "googAnaFrameLengthIncreaseCounter";
603 case kStatsValueNameAnaFrameLengthDecreaseCounter:
604 return "googAnaFrameLengthDecreaseCounter";
605 case kStatsValueNameAnaUplinkPacketLossFraction:
606 return "googAnaUplinkPacketLossFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28607 case kStatsValueNameRetransmitBitrate:
608 return "googRetransmitBitrate";
609 case kStatsValueNameRtt:
610 return "googRtt";
minyue@webrtc.org652bc372015-02-18 23:50:46611 case kStatsValueNameSecondaryDecodedRate:
612 return "googSecondaryDecodedRate";
minyue-webrtc0e320ec2017-08-28 11:51:27613 case kStatsValueNameSecondaryDiscardedRate:
614 return "googSecondaryDiscardedRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28615 case kStatsValueNameSendPacketsDiscarded:
616 return "packetsDiscardedOnSend";
minyue@webrtc.org652bc372015-02-18 23:50:46617 case kStatsValueNameSpeechExpandRate:
618 return "googSpeechExpandRate";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30619 case kStatsValueNameSrtpCipher:
620 return "srtpCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28621 case kStatsValueNameTargetEncBitrate:
622 return "googTargetEncBitrate";
zsteine76bd3a2017-07-14 19:17:49623 case kStatsValueNameTotalAudioEnergy:
624 return "totalAudioEnergy";
625 case kStatsValueNameTotalSamplesDuration:
626 return "totalSamplesDuration";
tommi@webrtc.orgc57310b2014-12-12 17:41:28627 case kStatsValueNameTransmitBitrate:
628 return "googTransmitBitrate";
629 case kStatsValueNameTransportType:
630 return "googTransportType";
631 case kStatsValueNameTrackId:
632 return "googTrackId";
ilnik2edc6842017-07-06 10:06:50633 case kStatsValueNameTimingFrameInfo:
634 return "googTimingFrameInfo";
tommi@webrtc.orgc57310b2014-12-12 17:41:28635 case kStatsValueNameTypingNoiseState:
636 return "googTypingNoiseState";
tommi@webrtc.orgc57310b2014-12-12 17:41:28637 case kStatsValueNameWritable:
638 return "googWritable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28639 }
640
641 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06642}
643
tommi@webrtc.orgd3900292015-03-12 16:35:55644std::string StatsReport::Value::ToString() const {
645 switch (type_) {
646 case kInt:
647 return rtc::ToString(value_.int_);
648 case kInt64:
649 return rtc::ToString(value_.int64_);
650 case kFloat:
651 return rtc::ToString(value_.float_);
652 case kStaticString:
653 return std::string(value_.static_string_);
654 case kString:
655 return *value_.string_;
656 case kBool:
657 return value_.bool_ ? "true" : "false";
658 case kId:
659 return (*value_.id_)->ToString();
660 }
661 RTC_NOTREACHED();
662 return std::string();
tommi@webrtc.orgafa6d162015-03-02 11:27:48663}
664
tommi@webrtc.orgd3900292015-03-12 16:35:55665StatsReport::StatsReport(const Id& id) : id_(id), timestamp_(0.0) {
henrikg91d6ede2015-09-17 07:24:34666 RTC_DCHECK(id_.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18667}
668
ossu7bb87ee2017-01-23 12:56:25669StatsReport::~StatsReport() = default;
670
tommi@webrtc.org4fb7e252015-01-21 11:36:18671// static
tommi@webrtc.orgd3900292015-03-12 16:35:55672StatsReport::Id StatsReport::NewBandwidthEstimationId() {
673 return Id(new RefCountedObject<BandwidthEstimationId>());
tommi@webrtc.org4fb7e252015-01-21 11:36:18674}
675
676// static
tommi@webrtc.orgd3900292015-03-12 16:35:55677StatsReport::Id StatsReport::NewTypedId(StatsType type, const std::string& id) {
678 return Id(new RefCountedObject<TypedId>(type, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18679}
680
681// static
tommi@webrtc.orgd3900292015-03-12 16:35:55682StatsReport::Id StatsReport::NewTypedIntId(StatsType type, int id) {
683 return Id(new RefCountedObject<TypedIntId>(type, id));
decurtis@webrtc.org322a5642015-02-03 22:09:37684}
685
686// static
tommi@webrtc.orgd3900292015-03-12 16:35:55687StatsReport::Id StatsReport::NewIdWithDirection(
tommi@webrtc.org4fb7e252015-01-21 11:36:18688 StatsType type, const std::string& id, StatsReport::Direction direction) {
tommi@webrtc.orgd3900292015-03-12 16:35:55689 return Id(new RefCountedObject<IdWithDirection>(type, id, direction));
tommi@webrtc.org4fb7e252015-01-21 11:36:18690}
691
692// static
tommi@webrtc.orgd3900292015-03-12 16:35:55693StatsReport::Id StatsReport::NewCandidateId(bool local, const std::string& id) {
694 return Id(new RefCountedObject<CandidateId>(local, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18695}
696
697// static
tommi@webrtc.orgd3900292015-03-12 16:35:55698StatsReport::Id StatsReport::NewComponentId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18699 const std::string& content_name, int component) {
tommi@webrtc.orgd3900292015-03-12 16:35:55700 return Id(new RefCountedObject<ComponentId>(content_name, component));
tommi@webrtc.org4fb7e252015-01-21 11:36:18701}
702
703// static
tommi@webrtc.orgd3900292015-03-12 16:35:55704StatsReport::Id StatsReport::NewCandidatePairId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18705 const std::string& content_name, int component, int index) {
tommi@webrtc.orgd3900292015-03-12 16:35:55706 return Id(new RefCountedObject<CandidatePairId>(
707 content_name, component, index));
tommi@webrtc.org4fb7e252015-01-21 11:36:18708}
709
710const char* StatsReport::TypeToString() const {
711 return InternalTypeToString(id_->type());
712}
713
tommi@webrtc.org92f40182015-03-04 15:25:19714void StatsReport::AddString(StatsReport::StatsValueName name,
715 const std::string& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55716 const Value* found = FindValue(name);
717 if (!found || !(*found == value))
718 values_[name] = ValuePtr(new Value(name, value));
719}
720
721void StatsReport::AddString(StatsReport::StatsValueName name,
722 const char* value) {
723 const Value* found = FindValue(name);
724 if (!found || !(*found == value))
725 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06726}
727
Peter Boström0c4e06b2015-10-07 10:23:21728void StatsReport::AddInt64(StatsReport::StatsValueName name, int64_t value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55729 const Value* found = FindValue(name);
730 if (!found || !(*found == value))
731 values_[name] = ValuePtr(new Value(name, value, Value::kInt64));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06732}
733
tommi@webrtc.org92f40182015-03-04 15:25:19734void StatsReport::AddInt(StatsReport::StatsValueName name, int value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55735 const Value* found = FindValue(name);
Peter Boström0c4e06b2015-10-07 10:23:21736 if (!found || !(*found == static_cast<int64_t>(value)))
tommi@webrtc.orgd3900292015-03-12 16:35:55737 values_[name] = ValuePtr(new Value(name, value, Value::kInt));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06738}
739
tommi@webrtc.org92f40182015-03-04 15:25:19740void StatsReport::AddFloat(StatsReport::StatsValueName name, float value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55741 const Value* found = FindValue(name);
742 if (!found || !(*found == value))
743 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org92f40182015-03-04 15:25:19744}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06745
746void StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55747 const Value* found = FindValue(name);
748 if (!found || !(*found == value))
749 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org8e327c42015-01-19 20:41:26750}
751
tommi@webrtc.orgd3900292015-03-12 16:35:55752void StatsReport::AddId(StatsReport::StatsValueName name,
753 const Id& value) {
754 const Value* found = FindValue(name);
755 if (!found || !(*found == value))
756 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06757}
758
tommi@webrtc.org4fb7e252015-01-21 11:36:18759const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const {
tommi@webrtc.org92f40182015-03-04 15:25:19760 Values::const_iterator it = values_.find(name);
761 return it == values_.end() ? nullptr : it->second.get();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06762}
763
tommi@webrtc.org4fb7e252015-01-21 11:36:18764StatsCollection::StatsCollection() {
tommi@webrtc.orgc9d155f2014-12-09 18:18:06765}
766
tommi@webrtc.org4fb7e252015-01-21 11:36:18767StatsCollection::~StatsCollection() {
henrikg91d6ede2015-09-17 07:24:34768 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18769 for (auto* r : list_)
770 delete r;
771}
772
773StatsCollection::const_iterator StatsCollection::begin() const {
henrikg91d6ede2015-09-17 07:24:34774 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06775 return list_.begin();
776}
777
tommi@webrtc.org4fb7e252015-01-21 11:36:18778StatsCollection::const_iterator StatsCollection::end() const {
henrikg91d6ede2015-09-17 07:24:34779 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06780 return list_.end();
781}
782
tommi@webrtc.org4fb7e252015-01-21 11:36:18783size_t StatsCollection::size() const {
henrikg91d6ede2015-09-17 07:24:34784 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18785 return list_.size();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06786}
787
tommi@webrtc.orgd3900292015-03-12 16:35:55788StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34789 RTC_DCHECK(thread_checker_.CalledOnValidThread());
790 RTC_DCHECK(Find(id) == nullptr);
tommi@webrtc.orgd3900292015-03-12 16:35:55791 StatsReport* report = new StatsReport(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18792 list_.push_back(report);
793 return report;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06794}
795
tommi@webrtc.orgd3900292015-03-12 16:35:55796StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34797 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgd3900292015-03-12 16:35:55798 StatsReport* ret = Find(id);
799 return ret ? ret : InsertNew(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18800}
801
tommi@webrtc.orgd3900292015-03-12 16:35:55802StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34803 RTC_DCHECK(thread_checker_.CalledOnValidThread());
804 RTC_DCHECK(id.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18805 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55806 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18807 if (it != end()) {
tommi@webrtc.orgd3900292015-03-12 16:35:55808 StatsReport* report = new StatsReport((*it)->id());
tommi@webrtc.org4fb7e252015-01-21 11:36:18809 delete *it;
tommi@webrtc.org4fb7e252015-01-21 11:36:18810 *it = report;
811 return report;
812 }
tommi@webrtc.orgd3900292015-03-12 16:35:55813 return InsertNew(id);
tommi@webrtc.orgc9d155f2014-12-09 18:18:06814}
815
deadbeef8d60a942017-02-27 22:47:33816// Looks for a report with the given |id|. If one is not found, null
tommi@webrtc.orgc9d155f2014-12-09 18:18:06817// will be returned.
tommi@webrtc.org4fb7e252015-01-21 11:36:18818StatsReport* StatsCollection::Find(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34819 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18820 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55821 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18822 return it == list_.end() ? nullptr : *it;
823}
824
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01825} // namespace webrtc