blob: d1637e3ffd14f5be62fada0c691719a6993793ae [file] [log] [blame]
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2014 The WebRTC project authors. All Rights Reserved.
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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:01 +00009 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "api/statstypes.h"
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +000012
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000013#include <string.h>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/checks.h"
Niels Möller84255bb2017-10-06 13:43:23 +020016#include "rtc_base/refcountedobject.h"
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000017
18// TODO(tommi): Could we have a static map of value name -> expected type
henrikg91d6ede2015-09-17 00:24:34 -070019// and use this to RTC_DCHECK on correct usage (somewhat strongly typed values)?
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000020// Alternatively, we could define the names+type in a separate document and
21// generate strongly typed inline C++ code that forces the correct type to be
22// used for a given name at compile time.
23
tommi@webrtc.org4b89aa02015-03-16 09:52:30 +000024using rtc::RefCountedObject;
tommi@webrtc.org8e327c42015-01-19 20:41:26 +000025
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +000026namespace webrtc {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000027namespace {
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +000028
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000029// The id of StatsReport of type kStatsReportTypeBwe.
30const char kStatsReportVideoBweId[] = "bweforvideo";
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000031
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000032// NOTE: These names need to be consistent with an external
33// specification (W3C Stats Identifiers).
34const char* InternalTypeToString(StatsReport::StatsType type) {
35 switch (type) {
36 case StatsReport::kStatsReportTypeSession:
37 return "googLibjingleSession";
38 case StatsReport::kStatsReportTypeBwe:
39 return "VideoBwe";
40 case StatsReport::kStatsReportTypeRemoteSsrc:
41 return "remoteSsrc";
42 case StatsReport::kStatsReportTypeSsrc:
43 return "ssrc";
44 case StatsReport::kStatsReportTypeTrack:
45 return "googTrack";
46 case StatsReport::kStatsReportTypeIceLocalCandidate:
47 return "localcandidate";
48 case StatsReport::kStatsReportTypeIceRemoteCandidate:
49 return "remotecandidate";
50 case StatsReport::kStatsReportTypeTransport:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +000051 return "transport";
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000052 case StatsReport::kStatsReportTypeComponent:
53 return "googComponent";
54 case StatsReport::kStatsReportTypeCandidatePair:
55 return "googCandidatePair";
56 case StatsReport::kStatsReportTypeCertificate:
57 return "googCertificate";
58 case StatsReport::kStatsReportTypeDataChannel:
59 return "datachannel";
60 }
nisseeb4ca4e2017-01-12 02:24:27 -080061 RTC_NOTREACHED();
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000062 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000063}
64
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000065class BandwidthEstimationId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000066 public:
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000067 BandwidthEstimationId()
68 : StatsReport::IdBase(StatsReport::kStatsReportTypeBwe) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000069 std::string ToString() const override { return kStatsReportVideoBweId; }
70};
tommi@webrtc.org8e327c42015-01-19 20:41:26 +000071
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000072class TypedId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000073 public:
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000074 TypedId(StatsReport::StatsType type, const std::string& id)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000075 : StatsReport::IdBase(type), id_(id) {}
tommi@webrtc.org8e327c42015-01-19 20:41:26 +000076
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000077 bool Equals(const IdBase& other) const override {
78 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000079 static_cast<const TypedId&>(other).id_ == id_;
80 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000081
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000082 std::string ToString() const override {
83 return std::string(InternalTypeToString(type_)) + kSeparator + id_;
84 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000085
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000086 protected:
87 const std::string id_;
88};
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000089
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000090class TypedIntId : public StatsReport::IdBase {
decurtis@webrtc.org322a5642015-02-03 22:09:37 +000091 public:
92 TypedIntId(StatsReport::StatsType type, int id)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000093 : StatsReport::IdBase(type), id_(id) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +000094
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000095 bool Equals(const IdBase& other) const override {
96 return IdBase::Equals(other) &&
decurtis@webrtc.org322a5642015-02-03 22:09:37 +000097 static_cast<const TypedIntId&>(other).id_ == id_;
98 }
99
100 std::string ToString() const override {
101 return std::string(InternalTypeToString(type_)) +
102 kSeparator +
103 rtc::ToString<int>(id_);
104 }
105
106 protected:
107 const int id_;
108};
109
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000110class IdWithDirection : public TypedId {
111 public:
112 IdWithDirection(StatsReport::StatsType type, const std::string& id,
113 StatsReport::Direction direction)
114 : TypedId(type, id), direction_(direction) {}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000115
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000116 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000117 return TypedId::Equals(other) &&
118 static_cast<const IdWithDirection&>(other).direction_ == direction_;
119 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000120
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000121 std::string ToString() const override {
122 std::string ret(TypedId::ToString());
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000123 ret += kSeparator;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000124 ret += direction_ == StatsReport::kSend ? "send" : "recv";
125 return ret;
126 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000127
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000128 private:
129 const StatsReport::Direction direction_;
130};
131
132class CandidateId : public TypedId {
133 public:
134 CandidateId(bool local, const std::string& id)
135 : TypedId(local ?
136 StatsReport::kStatsReportTypeIceLocalCandidate :
137 StatsReport::kStatsReportTypeIceRemoteCandidate,
138 id) {
139 }
140
141 std::string ToString() const override {
142 return "Cand-" + id_;
143 }
144};
145
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000146class ComponentId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000147 public:
148 ComponentId(const std::string& content_name, int component)
149 : ComponentId(StatsReport::kStatsReportTypeComponent, content_name,
150 component) {}
151
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000152 bool Equals(const IdBase& other) const override {
153 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000154 static_cast<const ComponentId&>(other).component_ == component_ &&
155 static_cast<const ComponentId&>(other).content_name_ == content_name_;
156 }
157
158 std::string ToString() const override {
159 return ToString("Channel-");
160 }
161
162 protected:
163 ComponentId(StatsReport::StatsType type, const std::string& content_name,
164 int component)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000165 : IdBase(type),
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000166 content_name_(content_name),
167 component_(component) {}
168
169 std::string ToString(const char* prefix) const {
170 std::string ret(prefix);
171 ret += content_name_;
172 ret += '-';
173 ret += rtc::ToString<>(component_);
174 return ret;
175 }
176
177 private:
178 const std::string content_name_;
179 const int component_;
180};
181
182class CandidatePairId : public ComponentId {
183 public:
184 CandidatePairId(const std::string& content_name, int component, int index)
185 : ComponentId(StatsReport::kStatsReportTypeCandidatePair, content_name,
186 component),
187 index_(index) {}
188
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000189 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000190 return ComponentId::Equals(other) &&
191 static_cast<const CandidatePairId&>(other).index_ == index_;
192 }
193
194 std::string ToString() const override {
195 std::string ret(ComponentId::ToString("Conn-"));
196 ret += '-';
197 ret += rtc::ToString<>(index_);
198 return ret;
199 }
200
201 private:
202 const int index_;
203};
204
205} // namespace
206
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000207StatsReport::IdBase::IdBase(StatsType type) : type_(type) {}
208StatsReport::IdBase::~IdBase() {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000209
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000210StatsReport::StatsType StatsReport::IdBase::type() const { return type_; }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000211
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000212bool StatsReport::IdBase::Equals(const IdBase& other) const {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000213 return other.type_ == type_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000214}
215
Peter Boström0c4e06b2015-10-07 12:23:21 +0200216StatsReport::Value::Value(StatsValueName name, int64_t value, Type int_type)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000217 : name(name), type_(int_type) {
henrikg91d6ede2015-09-17 00:24:34 -0700218 RTC_DCHECK(type_ == kInt || type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000219 type_ == kInt ? value_.int_ = static_cast<int>(value) : value_.int64_ = value;
220}
221
222StatsReport::Value::Value(StatsValueName name, float f)
223 : name(name), type_(kFloat) {
224 value_.float_ = f;
225}
226
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000227StatsReport::Value::Value(StatsValueName name, const std::string& value)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000228 : name(name), type_(kString) {
229 value_.string_ = new std::string(value);
230}
231
232StatsReport::Value::Value(StatsValueName name, const char* value)
233 : name(name), type_(kStaticString) {
234 value_.static_string_ = value;
235}
236
237StatsReport::Value::Value(StatsValueName name, bool b)
238 : name(name), type_(kBool) {
239 value_.bool_ = b;
240}
241
242StatsReport::Value::Value(StatsValueName name, const Id& value)
243 : name(name), type_(kId) {
244 value_.id_ = new Id(value);
245}
246
247StatsReport::Value::~Value() {
248 switch (type_) {
249 case kInt:
250 case kInt64:
251 case kFloat:
252 case kBool:
253 case kStaticString:
254 break;
255 case kString:
256 delete value_.string_;
257 break;
258 case kId:
259 delete value_.id_;
260 break;
261 }
262}
263
264bool StatsReport::Value::Equals(const Value& other) const {
265 if (name != other.name)
266 return false;
267
268 // There's a 1:1 relation between a name and a type, so we don't have to
269 // check that.
henrikg91d6ede2015-09-17 00:24:34 -0700270 RTC_DCHECK_EQ(type_, other.type_);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000271
272 switch (type_) {
273 case kInt:
274 return value_.int_ == other.value_.int_;
275 case kInt64:
276 return value_.int64_ == other.value_.int64_;
277 case kFloat:
278 return value_.float_ == other.value_.float_;
279 case kStaticString: {
kwiberg5377bc72016-10-04 13:46:56 -0700280#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000281 if (value_.static_string_ != other.value_.static_string_) {
henrikg91d6ede2015-09-17 00:24:34 -0700282 RTC_DCHECK(strcmp(value_.static_string_, other.value_.static_string_) !=
283 0)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000284 << "Duplicate global?";
285 }
286#endif
287 return value_.static_string_ == other.value_.static_string_;
288 }
289 case kString:
290 return *value_.string_ == *other.value_.string_;
291 case kBool:
292 return value_.bool_ == other.value_.bool_;
293 case kId:
294 return (*value_.id_)->Equals(*other.value_.id_);
295 }
296 RTC_NOTREACHED();
297 return false;
298}
299
300bool StatsReport::Value::operator==(const std::string& value) const {
301 return (type_ == kString && value_.string_->compare(value) == 0) ||
302 (type_ == kStaticString && value.compare(value_.static_string_) == 0);
303}
304
305bool StatsReport::Value::operator==(const char* value) const {
306 if (type_ == kString)
307 return value_.string_->compare(value) == 0;
308 if (type_ != kStaticString)
309 return false;
kwiberg5377bc72016-10-04 13:46:56 -0700310#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000311 if (value_.static_string_ != value)
henrikg91d6ede2015-09-17 00:24:34 -0700312 RTC_DCHECK(strcmp(value_.static_string_, value) != 0)
313 << "Duplicate global?";
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000314#endif
315 return value == value_.static_string_;
316}
317
Peter Boström0c4e06b2015-10-07 12:23:21 +0200318bool StatsReport::Value::operator==(int64_t value) const {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000319 return type_ == kInt ? value_.int_ == static_cast<int>(value) :
320 (type_ == kInt64 ? value_.int64_ == value : false);
321}
322
323bool StatsReport::Value::operator==(bool value) const {
324 return type_ == kBool && value_.bool_ == value;
325}
326
327bool StatsReport::Value::operator==(float value) const {
328 return type_ == kFloat && value_.float_ == value;
329}
330
331bool StatsReport::Value::operator==(const Id& value) const {
332 return type_ == kId && (*value_.id_)->Equals(value);
333}
334
335int StatsReport::Value::int_val() const {
henrikg91d6ede2015-09-17 00:24:34 -0700336 RTC_DCHECK(type_ == kInt);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000337 return value_.int_;
338}
339
Peter Boström0c4e06b2015-10-07 12:23:21 +0200340int64_t StatsReport::Value::int64_val() const {
henrikg91d6ede2015-09-17 00:24:34 -0700341 RTC_DCHECK(type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000342 return value_.int64_;
343}
344
345float StatsReport::Value::float_val() const {
henrikg91d6ede2015-09-17 00:24:34 -0700346 RTC_DCHECK(type_ == kFloat);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000347 return value_.float_;
348}
349
350const char* StatsReport::Value::static_string_val() const {
henrikg91d6ede2015-09-17 00:24:34 -0700351 RTC_DCHECK(type_ == kStaticString);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000352 return value_.static_string_;
353}
354
355const std::string& StatsReport::Value::string_val() const {
henrikg91d6ede2015-09-17 00:24:34 -0700356 RTC_DCHECK(type_ == kString);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000357 return *value_.string_;
358}
359
360bool StatsReport::Value::bool_val() const {
henrikg91d6ede2015-09-17 00:24:34 -0700361 RTC_DCHECK(type_ == kBool);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000362 return value_.bool_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000363}
364
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000365const char* StatsReport::Value::display_name() const {
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000366 switch (name) {
Minyue2a8a78c2016-04-07 16:48:15 +0200367 case kStatsValueNameAecDivergentFilterFraction:
368 return "aecDivergentFilterFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000369 case kStatsValueNameAudioOutputLevel:
370 return "audioOutputLevel";
371 case kStatsValueNameAudioInputLevel:
372 return "audioInputLevel";
373 case kStatsValueNameBytesSent:
374 return "bytesSent";
Steve Anton2dbc69f2017-08-24 17:15:13 -0700375 case kStatsValueNameConcealedSamples:
376 return "concealedSamples";
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200377 case kStatsValueNameConcealmentEvents:
378 return "concealmentEvents";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000379 case kStatsValueNamePacketsSent:
380 return "packetsSent";
381 case kStatsValueNameBytesReceived:
382 return "bytesReceived";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000383 case kStatsValueNameLabel:
384 return "label";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000385 case kStatsValueNamePacketsReceived:
386 return "packetsReceived";
387 case kStatsValueNamePacketsLost:
388 return "packetsLost";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000389 case kStatsValueNameProtocol:
390 return "protocol";
Steve Anton2dbc69f2017-08-24 17:15:13 -0700391 case kStatsValueNameTotalSamplesReceived:
392 return "totalSamplesReceived";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000393 case kStatsValueNameTransportId:
394 return "transportId";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000395 case kStatsValueNameSelectedCandidatePairId:
396 return "selectedCandidatePairId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000397 case kStatsValueNameSsrc:
398 return "ssrc";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000399 case kStatsValueNameState:
400 return "state";
401 case kStatsValueNameDataChannelId:
402 return "datachannelid";
sakale5ba44e2016-10-26 07:09:24 -0700403 case kStatsValueNameFramesDecoded:
404 return "framesDecoded";
sakal43536c32016-10-24 01:46:43 -0700405 case kStatsValueNameFramesEncoded:
406 return "framesEncoded";
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200407 case kStatsValueNameJitterBufferDelay:
408 return "jitterBufferDelay";
Peter Boströmb7d9a972015-12-18 16:01:11 +0100409 case kStatsValueNameCodecImplementationName:
410 return "codecImplementationName";
fippobec70ab2016-01-28 01:27:15 -0800411 case kStatsValueNameMediaType:
412 return "mediaType";
sakal87da4042016-10-31 06:53:47 -0700413 case kStatsValueNameQpSum:
414 return "qpSum";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000415 // 'goog' prefixed constants.
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200416 case kStatsValueNameAccelerateRate:
417 return "googAccelerateRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000418 case kStatsValueNameActiveConnection:
419 return "googActiveConnection";
420 case kStatsValueNameActualEncBitrate:
421 return "googActualEncBitrate";
422 case kStatsValueNameAvailableReceiveBandwidth:
423 return "googAvailableReceiveBandwidth";
424 case kStatsValueNameAvailableSendBandwidth:
425 return "googAvailableSendBandwidth";
426 case kStatsValueNameAvgEncodeMs:
427 return "googAvgEncodeMs";
428 case kStatsValueNameBucketDelay:
429 return "googBucketDelay";
430 case kStatsValueNameBandwidthLimitedResolution:
431 return "googBandwidthLimitedResolution";
zhihuang5ecf16c2016-06-01 17:09:15 -0700432 // STUN ping related attributes.
433 // TODO(zhihuang) Rename these stats to follow the standards.
434 case kStatsValueNameSentPingRequestsTotal:
435 return "requestsSent";
436 case kStatsValueNameSentPingRequestsBeforeFirstResponse:
437 return "consentRequestsSent";
438 case kStatsValueNameSentPingResponses:
439 return "responsesSent";
440 case kStatsValueNameRecvPingRequests:
441 return "requestsReceived";
442 case kStatsValueNameRecvPingResponses:
443 return "responsesReceived";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000444
445 // Candidate related attributes. Values are taken from
446 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
447 case kStatsValueNameCandidateIPAddress:
448 return "ipAddress";
449 case kStatsValueNameCandidateNetworkType:
450 return "networkType";
451 case kStatsValueNameCandidatePortNumber:
452 return "portNumber";
453 case kStatsValueNameCandidatePriority:
454 return "priority";
455 case kStatsValueNameCandidateTransportType:
456 return "transport";
457 case kStatsValueNameCandidateType:
458 return "candidateType";
459
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000460 case kStatsValueNameChannelId:
461 return "googChannelId";
462 case kStatsValueNameCodecName:
463 return "googCodecName";
464 case kStatsValueNameComponent:
465 return "googComponent";
466 case kStatsValueNameContentName:
467 return "googContentName";
ilnik2e1b40b2017-09-04 07:57:17 -0700468 case kStatsValueNameContentType:
469 return "googContentType";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000470 case kStatsValueNameCpuLimitedResolution:
471 return "googCpuLimitedResolution";
472 case kStatsValueNameDecodingCTSG:
473 return "googDecodingCTSG";
474 case kStatsValueNameDecodingCTN:
475 return "googDecodingCTN";
henrik.lundin63489782016-09-20 01:47:12 -0700476 case kStatsValueNameDecodingMutedOutput:
477 return "googDecodingMuted";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000478 case kStatsValueNameDecodingNormal:
479 return "googDecodingNormal";
480 case kStatsValueNameDecodingPLC:
481 return "googDecodingPLC";
482 case kStatsValueNameDecodingCNG:
483 return "googDecodingCNG";
484 case kStatsValueNameDecodingPLCCNG:
485 return "googDecodingPLCCNG";
486 case kStatsValueNameDer:
487 return "googDerBase64";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000488 case kStatsValueNameDtlsCipher:
489 return "dtlsCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000490 case kStatsValueNameEchoDelayMedian:
491 return "googEchoCancellationEchoDelayMedian";
492 case kStatsValueNameEchoDelayStdDev:
493 return "googEchoCancellationEchoDelayStdDev";
494 case kStatsValueNameEchoReturnLoss:
495 return "googEchoCancellationReturnLoss";
496 case kStatsValueNameEchoReturnLossEnhancement:
497 return "googEchoCancellationReturnLossEnhancement";
498 case kStatsValueNameEncodeUsagePercent:
499 return "googEncodeUsagePercent";
500 case kStatsValueNameExpandRate:
501 return "googExpandRate";
502 case kStatsValueNameFingerprint:
503 return "googFingerprint";
504 case kStatsValueNameFingerprintAlgorithm:
505 return "googFingerprintAlgorithm";
506 case kStatsValueNameFirsReceived:
507 return "googFirsReceived";
508 case kStatsValueNameFirsSent:
509 return "googFirsSent";
510 case kStatsValueNameFrameHeightInput:
511 return "googFrameHeightInput";
512 case kStatsValueNameFrameHeightReceived:
513 return "googFrameHeightReceived";
514 case kStatsValueNameFrameHeightSent:
515 return "googFrameHeightSent";
516 case kStatsValueNameFrameRateReceived:
517 return "googFrameRateReceived";
518 case kStatsValueNameFrameRateDecoded:
519 return "googFrameRateDecoded";
520 case kStatsValueNameFrameRateOutput:
521 return "googFrameRateOutput";
522 case kStatsValueNameDecodeMs:
523 return "googDecodeMs";
524 case kStatsValueNameMaxDecodeMs:
525 return "googMaxDecodeMs";
526 case kStatsValueNameCurrentDelayMs:
527 return "googCurrentDelayMs";
528 case kStatsValueNameTargetDelayMs:
529 return "googTargetDelayMs";
530 case kStatsValueNameJitterBufferMs:
531 return "googJitterBufferMs";
532 case kStatsValueNameMinPlayoutDelayMs:
533 return "googMinPlayoutDelayMs";
534 case kStatsValueNameRenderDelayMs:
535 return "googRenderDelayMs";
536 case kStatsValueNameCaptureStartNtpTimeMs:
537 return "googCaptureStartNtpTimeMs";
538 case kStatsValueNameFrameRateInput:
539 return "googFrameRateInput";
540 case kStatsValueNameFrameRateSent:
541 return "googFrameRateSent";
542 case kStatsValueNameFrameWidthInput:
543 return "googFrameWidthInput";
544 case kStatsValueNameFrameWidthReceived:
545 return "googFrameWidthReceived";
546 case kStatsValueNameFrameWidthSent:
547 return "googFrameWidthSent";
Ã…sa Perssonc3ed6302017-11-16 14:04:52 +0100548 case kStatsValueNameHasEnteredLowResolution:
549 return "googHasEnteredLowResolution";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000550 case kStatsValueNameInitiator:
551 return "googInitiator";
ilnika79cc282017-08-23 05:24:10 -0700552 case kStatsValueNameInterframeDelayMaxMs:
553 return "googInterframeDelayMax";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000554 case kStatsValueNameIssuerId:
555 return "googIssuerId";
556 case kStatsValueNameJitterReceived:
557 return "googJitterReceived";
558 case kStatsValueNameLocalAddress:
559 return "googLocalAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000560 case kStatsValueNameLocalCandidateId:
561 return "localCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000562 case kStatsValueNameLocalCandidateType:
563 return "googLocalCandidateType";
564 case kStatsValueNameLocalCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000565 return "localCertificateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000566 case kStatsValueNameAdaptationChanges:
567 return "googAdaptationChanges";
568 case kStatsValueNameNacksReceived:
569 return "googNacksReceived";
570 case kStatsValueNameNacksSent:
571 return "googNacksSent";
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200572 case kStatsValueNamePreemptiveExpandRate:
573 return "googPreemptiveExpandRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000574 case kStatsValueNamePlisReceived:
575 return "googPlisReceived";
576 case kStatsValueNamePlisSent:
577 return "googPlisSent";
578 case kStatsValueNamePreferredJitterBufferMs:
579 return "googPreferredJitterBufferMs";
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700580 case kStatsValueNameReceiving:
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000581 return "googReadable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000582 case kStatsValueNameRemoteAddress:
583 return "googRemoteAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000584 case kStatsValueNameRemoteCandidateId:
585 return "remoteCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000586 case kStatsValueNameRemoteCandidateType:
587 return "googRemoteCandidateType";
588 case kStatsValueNameRemoteCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000589 return "remoteCertificateId";
ivoc8c63a822016-10-21 04:10:03 -0700590 case kStatsValueNameResidualEchoLikelihood:
591 return "googResidualEchoLikelihood";
ivoc4e477a12017-01-15 08:29:46 -0800592 case kStatsValueNameResidualEchoLikelihoodRecentMax:
593 return "googResidualEchoLikelihoodRecentMax";
ivoce1198e02017-09-08 08:13:19 -0700594 case kStatsValueNameAnaBitrateActionCounter:
595 return "googAnaBitrateActionCounter";
596 case kStatsValueNameAnaChannelActionCounter:
597 return "googAnaChannelActionCounter";
598 case kStatsValueNameAnaDtxActionCounter:
599 return "googAnaDtxActionCounter";
600 case kStatsValueNameAnaFecActionCounter:
601 return "googAnaFecActionCounter";
ivoc0d0b9122017-09-08 13:24:21 -0700602 case kStatsValueNameAnaFrameLengthIncreaseCounter:
603 return "googAnaFrameLengthIncreaseCounter";
604 case kStatsValueNameAnaFrameLengthDecreaseCounter:
605 return "googAnaFrameLengthDecreaseCounter";
606 case kStatsValueNameAnaUplinkPacketLossFraction:
607 return "googAnaUplinkPacketLossFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000608 case kStatsValueNameRetransmitBitrate:
609 return "googRetransmitBitrate";
610 case kStatsValueNameRtt:
611 return "googRtt";
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000612 case kStatsValueNameSecondaryDecodedRate:
613 return "googSecondaryDecodedRate";
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200614 case kStatsValueNameSecondaryDiscardedRate:
615 return "googSecondaryDiscardedRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000616 case kStatsValueNameSendPacketsDiscarded:
617 return "packetsDiscardedOnSend";
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000618 case kStatsValueNameSpeechExpandRate:
619 return "googSpeechExpandRate";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000620 case kStatsValueNameSrtpCipher:
621 return "srtpCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000622 case kStatsValueNameTargetEncBitrate:
623 return "googTargetEncBitrate";
zsteine76bd3a2017-07-14 12:17:49 -0700624 case kStatsValueNameTotalAudioEnergy:
625 return "totalAudioEnergy";
626 case kStatsValueNameTotalSamplesDuration:
627 return "totalSamplesDuration";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000628 case kStatsValueNameTransmitBitrate:
629 return "googTransmitBitrate";
630 case kStatsValueNameTransportType:
631 return "googTransportType";
632 case kStatsValueNameTrackId:
633 return "googTrackId";
ilnik2edc6842017-07-06 03:06:50 -0700634 case kStatsValueNameTimingFrameInfo:
635 return "googTimingFrameInfo";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000636 case kStatsValueNameTypingNoiseState:
637 return "googTypingNoiseState";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000638 case kStatsValueNameWritable:
639 return "googWritable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000640 }
641
642 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000643}
644
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000645std::string StatsReport::Value::ToString() const {
646 switch (type_) {
647 case kInt:
648 return rtc::ToString(value_.int_);
649 case kInt64:
650 return rtc::ToString(value_.int64_);
651 case kFloat:
652 return rtc::ToString(value_.float_);
653 case kStaticString:
654 return std::string(value_.static_string_);
655 case kString:
656 return *value_.string_;
657 case kBool:
658 return value_.bool_ ? "true" : "false";
659 case kId:
660 return (*value_.id_)->ToString();
661 }
662 RTC_NOTREACHED();
663 return std::string();
tommi@webrtc.orgafa6d162015-03-02 11:27:48 +0000664}
665
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000666StatsReport::StatsReport(const Id& id) : id_(id), timestamp_(0.0) {
henrikg91d6ede2015-09-17 00:24:34 -0700667 RTC_DCHECK(id_.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000668}
669
ossu7bb87ee2017-01-23 04:56:25 -0800670StatsReport::~StatsReport() = default;
671
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000672// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000673StatsReport::Id StatsReport::NewBandwidthEstimationId() {
674 return Id(new RefCountedObject<BandwidthEstimationId>());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000675}
676
677// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000678StatsReport::Id StatsReport::NewTypedId(StatsType type, const std::string& id) {
679 return Id(new RefCountedObject<TypedId>(type, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000680}
681
682// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000683StatsReport::Id StatsReport::NewTypedIntId(StatsType type, int id) {
684 return Id(new RefCountedObject<TypedIntId>(type, id));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000685}
686
687// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000688StatsReport::Id StatsReport::NewIdWithDirection(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000689 StatsType type, const std::string& id, StatsReport::Direction direction) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000690 return Id(new RefCountedObject<IdWithDirection>(type, id, direction));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000691}
692
693// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000694StatsReport::Id StatsReport::NewCandidateId(bool local, const std::string& id) {
695 return Id(new RefCountedObject<CandidateId>(local, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000696}
697
698// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000699StatsReport::Id StatsReport::NewComponentId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000700 const std::string& content_name, int component) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000701 return Id(new RefCountedObject<ComponentId>(content_name, component));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000702}
703
704// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000705StatsReport::Id StatsReport::NewCandidatePairId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000706 const std::string& content_name, int component, int index) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000707 return Id(new RefCountedObject<CandidatePairId>(
708 content_name, component, index));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000709}
710
711const char* StatsReport::TypeToString() const {
712 return InternalTypeToString(id_->type());
713}
714
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000715void StatsReport::AddString(StatsReport::StatsValueName name,
716 const std::string& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000717 const Value* found = FindValue(name);
718 if (!found || !(*found == value))
719 values_[name] = ValuePtr(new Value(name, value));
720}
721
722void StatsReport::AddString(StatsReport::StatsValueName name,
723 const char* value) {
724 const Value* found = FindValue(name);
725 if (!found || !(*found == value))
726 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000727}
728
Peter Boström0c4e06b2015-10-07 12:23:21 +0200729void StatsReport::AddInt64(StatsReport::StatsValueName name, int64_t value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000730 const Value* found = FindValue(name);
731 if (!found || !(*found == value))
732 values_[name] = ValuePtr(new Value(name, value, Value::kInt64));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000733}
734
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000735void StatsReport::AddInt(StatsReport::StatsValueName name, int value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000736 const Value* found = FindValue(name);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200737 if (!found || !(*found == static_cast<int64_t>(value)))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000738 values_[name] = ValuePtr(new Value(name, value, Value::kInt));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000739}
740
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000741void StatsReport::AddFloat(StatsReport::StatsValueName name, float value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000742 const Value* found = FindValue(name);
743 if (!found || !(*found == value))
744 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000745}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000746
747void StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000748 const Value* found = FindValue(name);
749 if (!found || !(*found == value))
750 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000751}
752
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000753void StatsReport::AddId(StatsReport::StatsValueName name,
754 const Id& value) {
755 const Value* found = FindValue(name);
756 if (!found || !(*found == value))
757 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000758}
759
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000760const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000761 Values::const_iterator it = values_.find(name);
762 return it == values_.end() ? nullptr : it->second.get();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000763}
764
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000765StatsCollection::StatsCollection() {
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000766}
767
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000768StatsCollection::~StatsCollection() {
henrikg91d6ede2015-09-17 00:24:34 -0700769 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000770 for (auto* r : list_)
771 delete r;
772}
773
774StatsCollection::const_iterator StatsCollection::begin() const {
henrikg91d6ede2015-09-17 00:24:34 -0700775 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000776 return list_.begin();
777}
778
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000779StatsCollection::const_iterator StatsCollection::end() const {
henrikg91d6ede2015-09-17 00:24:34 -0700780 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000781 return list_.end();
782}
783
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000784size_t StatsCollection::size() const {
henrikg91d6ede2015-09-17 00:24:34 -0700785 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000786 return list_.size();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000787}
788
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000789StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700790 RTC_DCHECK(thread_checker_.CalledOnValidThread());
791 RTC_DCHECK(Find(id) == nullptr);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000792 StatsReport* report = new StatsReport(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000793 list_.push_back(report);
794 return report;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000795}
796
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000797StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700798 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000799 StatsReport* ret = Find(id);
800 return ret ? ret : InsertNew(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000801}
802
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000803StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700804 RTC_DCHECK(thread_checker_.CalledOnValidThread());
805 RTC_DCHECK(id.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000806 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000807 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000808 if (it != end()) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000809 StatsReport* report = new StatsReport((*it)->id());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000810 delete *it;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000811 *it = report;
812 return report;
813 }
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000814 return InsertNew(id);
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000815}
816
deadbeef8d60a942017-02-27 14:47:33 -0800817// Looks for a report with the given |id|. If one is not found, null
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000818// will be returned.
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000819StatsReport* StatsCollection::Find(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700820 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000821 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000822 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000823 return it == list_.end() ? nullptr : *it;
824}
825
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +0000826} // namespace webrtc