blob: ff70bac442b27edc6e4633b74eed101114b73c42 [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 kStatsValueNameEchoCancellationQualityMin:
491 return "googEchoCancellationQualityMin";
492 case kStatsValueNameEchoDelayMedian:
493 return "googEchoCancellationEchoDelayMedian";
494 case kStatsValueNameEchoDelayStdDev:
495 return "googEchoCancellationEchoDelayStdDev";
496 case kStatsValueNameEchoReturnLoss:
497 return "googEchoCancellationReturnLoss";
498 case kStatsValueNameEchoReturnLossEnhancement:
499 return "googEchoCancellationReturnLossEnhancement";
500 case kStatsValueNameEncodeUsagePercent:
501 return "googEncodeUsagePercent";
502 case kStatsValueNameExpandRate:
503 return "googExpandRate";
504 case kStatsValueNameFingerprint:
505 return "googFingerprint";
506 case kStatsValueNameFingerprintAlgorithm:
507 return "googFingerprintAlgorithm";
508 case kStatsValueNameFirsReceived:
509 return "googFirsReceived";
510 case kStatsValueNameFirsSent:
511 return "googFirsSent";
512 case kStatsValueNameFrameHeightInput:
513 return "googFrameHeightInput";
514 case kStatsValueNameFrameHeightReceived:
515 return "googFrameHeightReceived";
516 case kStatsValueNameFrameHeightSent:
517 return "googFrameHeightSent";
518 case kStatsValueNameFrameRateReceived:
519 return "googFrameRateReceived";
520 case kStatsValueNameFrameRateDecoded:
521 return "googFrameRateDecoded";
522 case kStatsValueNameFrameRateOutput:
523 return "googFrameRateOutput";
524 case kStatsValueNameDecodeMs:
525 return "googDecodeMs";
526 case kStatsValueNameMaxDecodeMs:
527 return "googMaxDecodeMs";
528 case kStatsValueNameCurrentDelayMs:
529 return "googCurrentDelayMs";
530 case kStatsValueNameTargetDelayMs:
531 return "googTargetDelayMs";
532 case kStatsValueNameJitterBufferMs:
533 return "googJitterBufferMs";
534 case kStatsValueNameMinPlayoutDelayMs:
535 return "googMinPlayoutDelayMs";
536 case kStatsValueNameRenderDelayMs:
537 return "googRenderDelayMs";
538 case kStatsValueNameCaptureStartNtpTimeMs:
539 return "googCaptureStartNtpTimeMs";
540 case kStatsValueNameFrameRateInput:
541 return "googFrameRateInput";
542 case kStatsValueNameFrameRateSent:
543 return "googFrameRateSent";
544 case kStatsValueNameFrameWidthInput:
545 return "googFrameWidthInput";
546 case kStatsValueNameFrameWidthReceived:
547 return "googFrameWidthReceived";
548 case kStatsValueNameFrameWidthSent:
549 return "googFrameWidthSent";
Ã…sa Perssonc3ed6302017-11-16 14:04:52 +0100550 case kStatsValueNameHasEnteredLowResolution:
551 return "googHasEnteredLowResolution";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000552 case kStatsValueNameInitiator:
553 return "googInitiator";
ilnika79cc282017-08-23 05:24:10 -0700554 case kStatsValueNameInterframeDelayMaxMs:
555 return "googInterframeDelayMax";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000556 case kStatsValueNameIssuerId:
557 return "googIssuerId";
558 case kStatsValueNameJitterReceived:
559 return "googJitterReceived";
560 case kStatsValueNameLocalAddress:
561 return "googLocalAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000562 case kStatsValueNameLocalCandidateId:
563 return "localCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000564 case kStatsValueNameLocalCandidateType:
565 return "googLocalCandidateType";
566 case kStatsValueNameLocalCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000567 return "localCertificateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000568 case kStatsValueNameAdaptationChanges:
569 return "googAdaptationChanges";
570 case kStatsValueNameNacksReceived:
571 return "googNacksReceived";
572 case kStatsValueNameNacksSent:
573 return "googNacksSent";
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200574 case kStatsValueNamePreemptiveExpandRate:
575 return "googPreemptiveExpandRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000576 case kStatsValueNamePlisReceived:
577 return "googPlisReceived";
578 case kStatsValueNamePlisSent:
579 return "googPlisSent";
580 case kStatsValueNamePreferredJitterBufferMs:
581 return "googPreferredJitterBufferMs";
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700582 case kStatsValueNameReceiving:
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000583 return "googReadable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000584 case kStatsValueNameRemoteAddress:
585 return "googRemoteAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000586 case kStatsValueNameRemoteCandidateId:
587 return "remoteCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000588 case kStatsValueNameRemoteCandidateType:
589 return "googRemoteCandidateType";
590 case kStatsValueNameRemoteCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000591 return "remoteCertificateId";
ivoc8c63a822016-10-21 04:10:03 -0700592 case kStatsValueNameResidualEchoLikelihood:
593 return "googResidualEchoLikelihood";
ivoc4e477a12017-01-15 08:29:46 -0800594 case kStatsValueNameResidualEchoLikelihoodRecentMax:
595 return "googResidualEchoLikelihoodRecentMax";
ivoce1198e02017-09-08 08:13:19 -0700596 case kStatsValueNameAnaBitrateActionCounter:
597 return "googAnaBitrateActionCounter";
598 case kStatsValueNameAnaChannelActionCounter:
599 return "googAnaChannelActionCounter";
600 case kStatsValueNameAnaDtxActionCounter:
601 return "googAnaDtxActionCounter";
602 case kStatsValueNameAnaFecActionCounter:
603 return "googAnaFecActionCounter";
ivoc0d0b9122017-09-08 13:24:21 -0700604 case kStatsValueNameAnaFrameLengthIncreaseCounter:
605 return "googAnaFrameLengthIncreaseCounter";
606 case kStatsValueNameAnaFrameLengthDecreaseCounter:
607 return "googAnaFrameLengthDecreaseCounter";
608 case kStatsValueNameAnaUplinkPacketLossFraction:
609 return "googAnaUplinkPacketLossFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000610 case kStatsValueNameRetransmitBitrate:
611 return "googRetransmitBitrate";
612 case kStatsValueNameRtt:
613 return "googRtt";
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000614 case kStatsValueNameSecondaryDecodedRate:
615 return "googSecondaryDecodedRate";
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200616 case kStatsValueNameSecondaryDiscardedRate:
617 return "googSecondaryDiscardedRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000618 case kStatsValueNameSendPacketsDiscarded:
619 return "packetsDiscardedOnSend";
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000620 case kStatsValueNameSpeechExpandRate:
621 return "googSpeechExpandRate";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000622 case kStatsValueNameSrtpCipher:
623 return "srtpCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000624 case kStatsValueNameTargetEncBitrate:
625 return "googTargetEncBitrate";
zsteine76bd3a2017-07-14 12:17:49 -0700626 case kStatsValueNameTotalAudioEnergy:
627 return "totalAudioEnergy";
628 case kStatsValueNameTotalSamplesDuration:
629 return "totalSamplesDuration";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000630 case kStatsValueNameTransmitBitrate:
631 return "googTransmitBitrate";
632 case kStatsValueNameTransportType:
633 return "googTransportType";
634 case kStatsValueNameTrackId:
635 return "googTrackId";
ilnik2edc6842017-07-06 03:06:50 -0700636 case kStatsValueNameTimingFrameInfo:
637 return "googTimingFrameInfo";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000638 case kStatsValueNameTypingNoiseState:
639 return "googTypingNoiseState";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000640 case kStatsValueNameWritable:
641 return "googWritable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000642 }
643
644 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000645}
646
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000647std::string StatsReport::Value::ToString() const {
648 switch (type_) {
649 case kInt:
650 return rtc::ToString(value_.int_);
651 case kInt64:
652 return rtc::ToString(value_.int64_);
653 case kFloat:
654 return rtc::ToString(value_.float_);
655 case kStaticString:
656 return std::string(value_.static_string_);
657 case kString:
658 return *value_.string_;
659 case kBool:
660 return value_.bool_ ? "true" : "false";
661 case kId:
662 return (*value_.id_)->ToString();
663 }
664 RTC_NOTREACHED();
665 return std::string();
tommi@webrtc.orgafa6d162015-03-02 11:27:48 +0000666}
667
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000668StatsReport::StatsReport(const Id& id) : id_(id), timestamp_(0.0) {
henrikg91d6ede2015-09-17 00:24:34 -0700669 RTC_DCHECK(id_.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000670}
671
ossu7bb87ee2017-01-23 04:56:25 -0800672StatsReport::~StatsReport() = default;
673
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000674// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000675StatsReport::Id StatsReport::NewBandwidthEstimationId() {
676 return Id(new RefCountedObject<BandwidthEstimationId>());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000677}
678
679// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000680StatsReport::Id StatsReport::NewTypedId(StatsType type, const std::string& id) {
681 return Id(new RefCountedObject<TypedId>(type, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000682}
683
684// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000685StatsReport::Id StatsReport::NewTypedIntId(StatsType type, int id) {
686 return Id(new RefCountedObject<TypedIntId>(type, id));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000687}
688
689// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000690StatsReport::Id StatsReport::NewIdWithDirection(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000691 StatsType type, const std::string& id, StatsReport::Direction direction) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000692 return Id(new RefCountedObject<IdWithDirection>(type, id, direction));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000693}
694
695// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000696StatsReport::Id StatsReport::NewCandidateId(bool local, const std::string& id) {
697 return Id(new RefCountedObject<CandidateId>(local, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000698}
699
700// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000701StatsReport::Id StatsReport::NewComponentId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000702 const std::string& content_name, int component) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000703 return Id(new RefCountedObject<ComponentId>(content_name, component));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000704}
705
706// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000707StatsReport::Id StatsReport::NewCandidatePairId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000708 const std::string& content_name, int component, int index) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000709 return Id(new RefCountedObject<CandidatePairId>(
710 content_name, component, index));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000711}
712
713const char* StatsReport::TypeToString() const {
714 return InternalTypeToString(id_->type());
715}
716
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000717void StatsReport::AddString(StatsReport::StatsValueName name,
718 const std::string& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000719 const Value* found = FindValue(name);
720 if (!found || !(*found == value))
721 values_[name] = ValuePtr(new Value(name, value));
722}
723
724void StatsReport::AddString(StatsReport::StatsValueName name,
725 const char* value) {
726 const Value* found = FindValue(name);
727 if (!found || !(*found == value))
728 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000729}
730
Peter Boström0c4e06b2015-10-07 12:23:21 +0200731void StatsReport::AddInt64(StatsReport::StatsValueName name, int64_t value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000732 const Value* found = FindValue(name);
733 if (!found || !(*found == value))
734 values_[name] = ValuePtr(new Value(name, value, Value::kInt64));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000735}
736
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000737void StatsReport::AddInt(StatsReport::StatsValueName name, int value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000738 const Value* found = FindValue(name);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200739 if (!found || !(*found == static_cast<int64_t>(value)))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000740 values_[name] = ValuePtr(new Value(name, value, Value::kInt));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000741}
742
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000743void StatsReport::AddFloat(StatsReport::StatsValueName name, float value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000744 const Value* found = FindValue(name);
745 if (!found || !(*found == value))
746 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000747}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000748
749void StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000750 const Value* found = FindValue(name);
751 if (!found || !(*found == value))
752 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000753}
754
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000755void StatsReport::AddId(StatsReport::StatsValueName name,
756 const Id& value) {
757 const Value* found = FindValue(name);
758 if (!found || !(*found == value))
759 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000760}
761
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000762const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000763 Values::const_iterator it = values_.find(name);
764 return it == values_.end() ? nullptr : it->second.get();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000765}
766
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000767StatsCollection::StatsCollection() {
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000768}
769
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000770StatsCollection::~StatsCollection() {
henrikg91d6ede2015-09-17 00:24:34 -0700771 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000772 for (auto* r : list_)
773 delete r;
774}
775
776StatsCollection::const_iterator StatsCollection::begin() const {
henrikg91d6ede2015-09-17 00:24:34 -0700777 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000778 return list_.begin();
779}
780
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000781StatsCollection::const_iterator StatsCollection::end() const {
henrikg91d6ede2015-09-17 00:24:34 -0700782 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000783 return list_.end();
784}
785
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000786size_t StatsCollection::size() const {
henrikg91d6ede2015-09-17 00:24:34 -0700787 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000788 return list_.size();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000789}
790
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000791StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700792 RTC_DCHECK(thread_checker_.CalledOnValidThread());
793 RTC_DCHECK(Find(id) == nullptr);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000794 StatsReport* report = new StatsReport(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000795 list_.push_back(report);
796 return report;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000797}
798
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000799StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700800 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000801 StatsReport* ret = Find(id);
802 return ret ? ret : InsertNew(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000803}
804
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000805StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700806 RTC_DCHECK(thread_checker_.CalledOnValidThread());
807 RTC_DCHECK(id.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000808 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000809 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000810 if (it != end()) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000811 StatsReport* report = new StatsReport((*it)->id());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000812 delete *it;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000813 *it = report;
814 return report;
815 }
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000816 return InsertNew(id);
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000817}
818
deadbeef8d60a942017-02-27 14:47:33 -0800819// Looks for a report with the given |id|. If one is not found, null
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000820// will be returned.
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000821StatsReport* StatsCollection::Find(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 00:24:34 -0700822 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000823 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000824 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000825 return it == list_.end() ? nullptr : *it;
826}
827
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +0000828} // namespace webrtc