blob: ceba28d20f0e0ca660101ab867b61ef8844cb6df [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"
Niels Möller84255bb2017-10-06 11:43:2316#include "rtc_base/refcountedobject.h"
tommi@webrtc.orgd3900292015-03-12 16:35:5517
18// TODO(tommi): Could we have a static map of value name -> expected type
henrikg91d6ede2015-09-17 07:24:3419// and use this to RTC_DCHECK on correct usage (somewhat strongly typed values)?
tommi@webrtc.orgd3900292015-03-12 16:35:5520// 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:3024using rtc::RefCountedObject;
tommi@webrtc.org8e327c42015-01-19 20:41:2625
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0126namespace webrtc {
tommi@webrtc.org4fb7e252015-01-21 11:36:1827namespace {
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0128
tommi@webrtc.org4fb7e252015-01-21 11:36:1829// The id of StatsReport of type kStatsReportTypeBwe.
30const char kStatsReportVideoBweId[] = "bweforvideo";
tommi@webrtc.orgc9d155f2014-12-09 18:18:0631
tommi@webrtc.org4fb7e252015-01-21 11:36:1832// 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:3051 return "transport";
tommi@webrtc.org4fb7e252015-01-21 11:36:1852 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 10:24:2761 RTC_NOTREACHED();
tommi@webrtc.org4fb7e252015-01-21 11:36:1862 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:0663}
64
tommi@webrtc.orgd3900292015-03-12 16:35:5565class BandwidthEstimationId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:1866 public:
tommi@webrtc.orgd3900292015-03-12 16:35:5567 BandwidthEstimationId()
68 : StatsReport::IdBase(StatsReport::kStatsReportTypeBwe) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:1869 std::string ToString() const override { return kStatsReportVideoBweId; }
70};
tommi@webrtc.org8e327c42015-01-19 20:41:2671
tommi@webrtc.orgd3900292015-03-12 16:35:5572class TypedId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:1873 public:
tommi@webrtc.org4fb7e252015-01-21 11:36:1874 TypedId(StatsReport::StatsType type, const std::string& id)
tommi@webrtc.orgd3900292015-03-12 16:35:5575 : StatsReport::IdBase(type), id_(id) {}
tommi@webrtc.org8e327c42015-01-19 20:41:2676
tommi@webrtc.orgd3900292015-03-12 16:35:5577 bool Equals(const IdBase& other) const override {
78 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:1879 static_cast<const TypedId&>(other).id_ == id_;
80 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:0681
tommi@webrtc.org4fb7e252015-01-21 11:36:1882 std::string ToString() const override {
83 return std::string(InternalTypeToString(type_)) + kSeparator + id_;
84 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:0685
tommi@webrtc.org4fb7e252015-01-21 11:36:1886 protected:
87 const std::string id_;
88};
tommi@webrtc.orgc9d155f2014-12-09 18:18:0689
tommi@webrtc.orgd3900292015-03-12 16:35:5590class TypedIntId : public StatsReport::IdBase {
decurtis@webrtc.org322a5642015-02-03 22:09:3791 public:
92 TypedIntId(StatsReport::StatsType type, int id)
tommi@webrtc.orgd3900292015-03-12 16:35:5593 : StatsReport::IdBase(type), id_(id) {}
decurtis@webrtc.org322a5642015-02-03 22:09:3794
tommi@webrtc.orgd3900292015-03-12 16:35:5595 bool Equals(const IdBase& other) const override {
96 return IdBase::Equals(other) &&
decurtis@webrtc.org322a5642015-02-03 22:09:3797 static_cast<const TypedIntId&>(other).id_ == id_;
98 }
99
100 std::string ToString() const override {
Yves Gerey665174f2018-06-19 13:03:05101 return std::string(InternalTypeToString(type_)) + kSeparator +
decurtis@webrtc.org322a5642015-02-03 22:09:37102 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:
Yves Gerey665174f2018-06-19 13:03:05111 IdWithDirection(StatsReport::StatsType type,
112 const std::string& id,
tommi@webrtc.org4fb7e252015-01-21 11:36:18113 StatsReport::Direction direction)
114 : TypedId(type, id), direction_(direction) {}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06115
tommi@webrtc.orgd3900292015-03-12 16:35:55116 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18117 return TypedId::Equals(other) &&
118 static_cast<const IdWithDirection&>(other).direction_ == direction_;
119 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06120
tommi@webrtc.org4fb7e252015-01-21 11:36:18121 std::string ToString() const override {
122 std::string ret(TypedId::ToString());
decurtis@webrtc.org322a5642015-02-03 22:09:37123 ret += kSeparator;
tommi@webrtc.org4fb7e252015-01-21 11:36:18124 ret += direction_ == StatsReport::kSend ? "send" : "recv";
125 return ret;
126 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06127
tommi@webrtc.org4fb7e252015-01-21 11:36:18128 private:
129 const StatsReport::Direction direction_;
130};
131
132class CandidateId : public TypedId {
133 public:
134 CandidateId(bool local, const std::string& id)
Yves Gerey665174f2018-06-19 13:03:05135 : TypedId(local ? StatsReport::kStatsReportTypeIceLocalCandidate
136 : StatsReport::kStatsReportTypeIceRemoteCandidate,
137 id) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18138
Yves Gerey665174f2018-06-19 13:03:05139 std::string ToString() const override { return "Cand-" + id_; }
tommi@webrtc.org4fb7e252015-01-21 11:36:18140};
141
tommi@webrtc.orgd3900292015-03-12 16:35:55142class ComponentId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18143 public:
144 ComponentId(const std::string& content_name, int component)
Yves Gerey665174f2018-06-19 13:03:05145 : ComponentId(StatsReport::kStatsReportTypeComponent,
146 content_name,
147 component) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18148
tommi@webrtc.orgd3900292015-03-12 16:35:55149 bool Equals(const IdBase& other) const override {
150 return IdBase::Equals(other) &&
Yves Gerey665174f2018-06-19 13:03:05151 static_cast<const ComponentId&>(other).component_ == component_ &&
152 static_cast<const ComponentId&>(other).content_name_ ==
153 content_name_;
tommi@webrtc.org4fb7e252015-01-21 11:36:18154 }
155
Yves Gerey665174f2018-06-19 13:03:05156 std::string ToString() const override { return ToString("Channel-"); }
tommi@webrtc.org4fb7e252015-01-21 11:36:18157
158 protected:
Yves Gerey665174f2018-06-19 13:03:05159 ComponentId(StatsReport::StatsType type,
160 const std::string& content_name,
tommi@webrtc.org4fb7e252015-01-21 11:36:18161 int component)
Yves Gerey665174f2018-06-19 13:03:05162 : IdBase(type), content_name_(content_name), component_(component) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18163
164 std::string ToString(const char* prefix) const {
165 std::string ret(prefix);
166 ret += content_name_;
167 ret += '-';
168 ret += rtc::ToString<>(component_);
169 return ret;
170 }
171
172 private:
173 const std::string content_name_;
174 const int component_;
175};
176
177class CandidatePairId : public ComponentId {
178 public:
179 CandidatePairId(const std::string& content_name, int component, int index)
Yves Gerey665174f2018-06-19 13:03:05180 : ComponentId(StatsReport::kStatsReportTypeCandidatePair,
181 content_name,
182 component),
tommi@webrtc.org4fb7e252015-01-21 11:36:18183 index_(index) {}
184
tommi@webrtc.orgd3900292015-03-12 16:35:55185 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18186 return ComponentId::Equals(other) &&
Yves Gerey665174f2018-06-19 13:03:05187 static_cast<const CandidatePairId&>(other).index_ == index_;
tommi@webrtc.org4fb7e252015-01-21 11:36:18188 }
189
190 std::string ToString() const override {
191 std::string ret(ComponentId::ToString("Conn-"));
192 ret += '-';
193 ret += rtc::ToString<>(index_);
194 return ret;
195 }
196
197 private:
198 const int index_;
199};
200
201} // namespace
202
tommi@webrtc.orgd3900292015-03-12 16:35:55203StatsReport::IdBase::IdBase(StatsType type) : type_(type) {}
204StatsReport::IdBase::~IdBase() {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18205
Yves Gerey665174f2018-06-19 13:03:05206StatsReport::StatsType StatsReport::IdBase::type() const {
207 return type_;
208}
tommi@webrtc.org4fb7e252015-01-21 11:36:18209
tommi@webrtc.orgd3900292015-03-12 16:35:55210bool StatsReport::IdBase::Equals(const IdBase& other) const {
tommi@webrtc.org4fb7e252015-01-21 11:36:18211 return other.type_ == type_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06212}
213
Peter Boström0c4e06b2015-10-07 10:23:21214StatsReport::Value::Value(StatsValueName name, int64_t value, Type int_type)
tommi@webrtc.orgd3900292015-03-12 16:35:55215 : name(name), type_(int_type) {
henrikg91d6ede2015-09-17 07:24:34216 RTC_DCHECK(type_ == kInt || type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55217 type_ == kInt ? value_.int_ = static_cast<int>(value) : value_.int64_ = value;
218}
219
220StatsReport::Value::Value(StatsValueName name, float f)
221 : name(name), type_(kFloat) {
222 value_.float_ = f;
223}
224
tommi@webrtc.orgc9d155f2014-12-09 18:18:06225StatsReport::Value::Value(StatsValueName name, const std::string& value)
tommi@webrtc.orgd3900292015-03-12 16:35:55226 : name(name), type_(kString) {
227 value_.string_ = new std::string(value);
228}
229
230StatsReport::Value::Value(StatsValueName name, const char* value)
231 : name(name), type_(kStaticString) {
232 value_.static_string_ = value;
233}
234
235StatsReport::Value::Value(StatsValueName name, bool b)
236 : name(name), type_(kBool) {
237 value_.bool_ = b;
238}
239
240StatsReport::Value::Value(StatsValueName name, const Id& value)
241 : name(name), type_(kId) {
242 value_.id_ = new Id(value);
243}
244
245StatsReport::Value::~Value() {
246 switch (type_) {
247 case kInt:
248 case kInt64:
249 case kFloat:
250 case kBool:
251 case kStaticString:
252 break;
253 case kString:
254 delete value_.string_;
255 break;
256 case kId:
257 delete value_.id_;
258 break;
259 }
260}
261
262bool StatsReport::Value::Equals(const Value& other) const {
263 if (name != other.name)
264 return false;
265
266 // There's a 1:1 relation between a name and a type, so we don't have to
267 // check that.
henrikg91d6ede2015-09-17 07:24:34268 RTC_DCHECK_EQ(type_, other.type_);
tommi@webrtc.orgd3900292015-03-12 16:35:55269
270 switch (type_) {
271 case kInt:
272 return value_.int_ == other.value_.int_;
273 case kInt64:
274 return value_.int64_ == other.value_.int64_;
275 case kFloat:
276 return value_.float_ == other.value_.float_;
277 case kStaticString: {
kwiberg5377bc72016-10-04 20:46:56278#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55279 if (value_.static_string_ != other.value_.static_string_) {
henrikg91d6ede2015-09-17 07:24:34280 RTC_DCHECK(strcmp(value_.static_string_, other.value_.static_string_) !=
281 0)
tommi@webrtc.orgd3900292015-03-12 16:35:55282 << "Duplicate global?";
283 }
284#endif
285 return value_.static_string_ == other.value_.static_string_;
286 }
287 case kString:
288 return *value_.string_ == *other.value_.string_;
289 case kBool:
290 return value_.bool_ == other.value_.bool_;
291 case kId:
292 return (*value_.id_)->Equals(*other.value_.id_);
293 }
294 RTC_NOTREACHED();
295 return false;
296}
297
298bool StatsReport::Value::operator==(const std::string& value) const {
299 return (type_ == kString && value_.string_->compare(value) == 0) ||
300 (type_ == kStaticString && value.compare(value_.static_string_) == 0);
301}
302
303bool StatsReport::Value::operator==(const char* value) const {
304 if (type_ == kString)
305 return value_.string_->compare(value) == 0;
306 if (type_ != kStaticString)
307 return false;
kwiberg5377bc72016-10-04 20:46:56308#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55309 if (value_.static_string_ != value)
henrikg91d6ede2015-09-17 07:24:34310 RTC_DCHECK(strcmp(value_.static_string_, value) != 0)
311 << "Duplicate global?";
tommi@webrtc.orgd3900292015-03-12 16:35:55312#endif
313 return value == value_.static_string_;
314}
315
Peter Boström0c4e06b2015-10-07 10:23:21316bool StatsReport::Value::operator==(int64_t value) const {
Yves Gerey665174f2018-06-19 13:03:05317 return type_ == kInt ? value_.int_ == static_cast<int>(value)
318 : (type_ == kInt64 ? value_.int64_ == value : false);
tommi@webrtc.orgd3900292015-03-12 16:35:55319}
320
321bool StatsReport::Value::operator==(bool value) const {
322 return type_ == kBool && value_.bool_ == value;
323}
324
325bool StatsReport::Value::operator==(float value) const {
326 return type_ == kFloat && value_.float_ == value;
327}
328
329bool StatsReport::Value::operator==(const Id& value) const {
330 return type_ == kId && (*value_.id_)->Equals(value);
331}
332
333int StatsReport::Value::int_val() const {
henrikg91d6ede2015-09-17 07:24:34334 RTC_DCHECK(type_ == kInt);
tommi@webrtc.orgd3900292015-03-12 16:35:55335 return value_.int_;
336}
337
Peter Boström0c4e06b2015-10-07 10:23:21338int64_t StatsReport::Value::int64_val() const {
henrikg91d6ede2015-09-17 07:24:34339 RTC_DCHECK(type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55340 return value_.int64_;
341}
342
343float StatsReport::Value::float_val() const {
henrikg91d6ede2015-09-17 07:24:34344 RTC_DCHECK(type_ == kFloat);
tommi@webrtc.orgd3900292015-03-12 16:35:55345 return value_.float_;
346}
347
348const char* StatsReport::Value::static_string_val() const {
henrikg91d6ede2015-09-17 07:24:34349 RTC_DCHECK(type_ == kStaticString);
tommi@webrtc.orgd3900292015-03-12 16:35:55350 return value_.static_string_;
351}
352
353const std::string& StatsReport::Value::string_val() const {
henrikg91d6ede2015-09-17 07:24:34354 RTC_DCHECK(type_ == kString);
tommi@webrtc.orgd3900292015-03-12 16:35:55355 return *value_.string_;
356}
357
358bool StatsReport::Value::bool_val() const {
henrikg91d6ede2015-09-17 07:24:34359 RTC_DCHECK(type_ == kBool);
tommi@webrtc.orgd3900292015-03-12 16:35:55360 return value_.bool_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06361}
362
tommi@webrtc.orgc9d155f2014-12-09 18:18:06363const char* StatsReport::Value::display_name() const {
tommi@webrtc.orgc57310b2014-12-12 17:41:28364 switch (name) {
Minyue2a8a78c2016-04-07 14:48:15365 case kStatsValueNameAecDivergentFilterFraction:
366 return "aecDivergentFilterFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28367 case kStatsValueNameAudioOutputLevel:
368 return "audioOutputLevel";
369 case kStatsValueNameAudioInputLevel:
370 return "audioInputLevel";
371 case kStatsValueNameBytesSent:
372 return "bytesSent";
Steve Anton2dbc69f2017-08-25 00:15:13373 case kStatsValueNameConcealedSamples:
374 return "concealedSamples";
Gustaf Ullberg9a2e9062017-09-18 07:28:20375 case kStatsValueNameConcealmentEvents:
376 return "concealmentEvents";
tommi@webrtc.orgc57310b2014-12-12 17:41:28377 case kStatsValueNamePacketsSent:
378 return "packetsSent";
379 case kStatsValueNameBytesReceived:
380 return "bytesReceived";
decurtis@webrtc.org487a4442015-01-15 22:55:07381 case kStatsValueNameLabel:
382 return "label";
tommi@webrtc.orgc57310b2014-12-12 17:41:28383 case kStatsValueNamePacketsReceived:
384 return "packetsReceived";
385 case kStatsValueNamePacketsLost:
386 return "packetsLost";
decurtis@webrtc.org487a4442015-01-15 22:55:07387 case kStatsValueNameProtocol:
388 return "protocol";
Steve Anton2dbc69f2017-08-25 00:15:13389 case kStatsValueNameTotalSamplesReceived:
390 return "totalSamplesReceived";
tommi@webrtc.orgc57310b2014-12-12 17:41:28391 case kStatsValueNameTransportId:
392 return "transportId";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30393 case kStatsValueNameSelectedCandidatePairId:
394 return "selectedCandidatePairId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28395 case kStatsValueNameSsrc:
396 return "ssrc";
decurtis@webrtc.org487a4442015-01-15 22:55:07397 case kStatsValueNameState:
398 return "state";
399 case kStatsValueNameDataChannelId:
400 return "datachannelid";
sakale5ba44e2016-10-26 14:09:24401 case kStatsValueNameFramesDecoded:
402 return "framesDecoded";
sakal43536c32016-10-24 08:46:43403 case kStatsValueNameFramesEncoded:
404 return "framesEncoded";
Gustaf Ullbergb0a02072017-10-02 10:00:34405 case kStatsValueNameJitterBufferDelay:
406 return "jitterBufferDelay";
Peter Boströmb7d9a972015-12-18 15:01:11407 case kStatsValueNameCodecImplementationName:
408 return "codecImplementationName";
fippobec70ab2016-01-28 09:27:15409 case kStatsValueNameMediaType:
410 return "mediaType";
sakal87da4042016-10-31 13:53:47411 case kStatsValueNameQpSum:
412 return "qpSum";
tommi@webrtc.orgc57310b2014-12-12 17:41:28413 // 'goog' prefixed constants.
Henrik Lundin8e6fd462015-06-02 07:24:52414 case kStatsValueNameAccelerateRate:
415 return "googAccelerateRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28416 case kStatsValueNameActiveConnection:
417 return "googActiveConnection";
418 case kStatsValueNameActualEncBitrate:
419 return "googActualEncBitrate";
420 case kStatsValueNameAvailableReceiveBandwidth:
421 return "googAvailableReceiveBandwidth";
422 case kStatsValueNameAvailableSendBandwidth:
423 return "googAvailableSendBandwidth";
424 case kStatsValueNameAvgEncodeMs:
425 return "googAvgEncodeMs";
426 case kStatsValueNameBucketDelay:
427 return "googBucketDelay";
428 case kStatsValueNameBandwidthLimitedResolution:
429 return "googBandwidthLimitedResolution";
zhihuang5ecf16c2016-06-02 00:09:15430 // STUN ping related attributes.
Qingsi Wang72a43a12018-02-21 00:03:18431 //
zhihuang5ecf16c2016-06-02 00:09:15432 // TODO(zhihuang) Rename these stats to follow the standards.
Qingsi Wang72a43a12018-02-21 00:03:18433 // Connectivity checks.
zhihuang5ecf16c2016-06-02 00:09:15434 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";
Qingsi Wang72a43a12018-02-21 00:03:18444 // STUN Keepalive pings.
445 case kStatsValueNameSentStunKeepaliveRequests:
446 return "stunKeepaliveRequestsSent";
447 case kStatsValueNameRecvStunKeepaliveResponses:
448 return "stunKeepaliveResponsesReceived";
449 case kStatsValueNameStunKeepaliveRttTotal:
450 return "stunKeepaliveRttTotal";
451 case kStatsValueNameStunKeepaliveRttSquaredTotal:
452 return "stunKeepaliveRttSquaredTotal";
guoweis@webrtc.org950c5182014-12-16 23:01:31453
454 // Candidate related attributes. Values are taken from
455 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
456 case kStatsValueNameCandidateIPAddress:
457 return "ipAddress";
458 case kStatsValueNameCandidateNetworkType:
459 return "networkType";
460 case kStatsValueNameCandidatePortNumber:
461 return "portNumber";
462 case kStatsValueNameCandidatePriority:
463 return "priority";
464 case kStatsValueNameCandidateTransportType:
465 return "transport";
466 case kStatsValueNameCandidateType:
467 return "candidateType";
468
tommi@webrtc.orgc57310b2014-12-12 17:41:28469 case kStatsValueNameChannelId:
470 return "googChannelId";
471 case kStatsValueNameCodecName:
472 return "googCodecName";
473 case kStatsValueNameComponent:
474 return "googComponent";
475 case kStatsValueNameContentName:
476 return "googContentName";
ilnik2e1b40b2017-09-04 14:57:17477 case kStatsValueNameContentType:
478 return "googContentType";
tommi@webrtc.orgc57310b2014-12-12 17:41:28479 case kStatsValueNameCpuLimitedResolution:
480 return "googCpuLimitedResolution";
481 case kStatsValueNameDecodingCTSG:
482 return "googDecodingCTSG";
483 case kStatsValueNameDecodingCTN:
484 return "googDecodingCTN";
henrik.lundin63489782016-09-20 08:47:12485 case kStatsValueNameDecodingMutedOutput:
486 return "googDecodingMuted";
tommi@webrtc.orgc57310b2014-12-12 17:41:28487 case kStatsValueNameDecodingNormal:
488 return "googDecodingNormal";
489 case kStatsValueNameDecodingPLC:
490 return "googDecodingPLC";
491 case kStatsValueNameDecodingCNG:
492 return "googDecodingCNG";
493 case kStatsValueNameDecodingPLCCNG:
494 return "googDecodingPLCCNG";
495 case kStatsValueNameDer:
496 return "googDerBase64";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30497 case kStatsValueNameDtlsCipher:
498 return "dtlsCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28499 case kStatsValueNameEchoDelayMedian:
500 return "googEchoCancellationEchoDelayMedian";
501 case kStatsValueNameEchoDelayStdDev:
502 return "googEchoCancellationEchoDelayStdDev";
503 case kStatsValueNameEchoReturnLoss:
504 return "googEchoCancellationReturnLoss";
505 case kStatsValueNameEchoReturnLossEnhancement:
506 return "googEchoCancellationReturnLossEnhancement";
507 case kStatsValueNameEncodeUsagePercent:
508 return "googEncodeUsagePercent";
509 case kStatsValueNameExpandRate:
510 return "googExpandRate";
511 case kStatsValueNameFingerprint:
512 return "googFingerprint";
513 case kStatsValueNameFingerprintAlgorithm:
514 return "googFingerprintAlgorithm";
515 case kStatsValueNameFirsReceived:
516 return "googFirsReceived";
517 case kStatsValueNameFirsSent:
518 return "googFirsSent";
519 case kStatsValueNameFrameHeightInput:
520 return "googFrameHeightInput";
521 case kStatsValueNameFrameHeightReceived:
522 return "googFrameHeightReceived";
523 case kStatsValueNameFrameHeightSent:
524 return "googFrameHeightSent";
525 case kStatsValueNameFrameRateReceived:
526 return "googFrameRateReceived";
527 case kStatsValueNameFrameRateDecoded:
528 return "googFrameRateDecoded";
529 case kStatsValueNameFrameRateOutput:
530 return "googFrameRateOutput";
531 case kStatsValueNameDecodeMs:
532 return "googDecodeMs";
533 case kStatsValueNameMaxDecodeMs:
534 return "googMaxDecodeMs";
535 case kStatsValueNameCurrentDelayMs:
536 return "googCurrentDelayMs";
537 case kStatsValueNameTargetDelayMs:
538 return "googTargetDelayMs";
539 case kStatsValueNameJitterBufferMs:
540 return "googJitterBufferMs";
541 case kStatsValueNameMinPlayoutDelayMs:
542 return "googMinPlayoutDelayMs";
543 case kStatsValueNameRenderDelayMs:
544 return "googRenderDelayMs";
545 case kStatsValueNameCaptureStartNtpTimeMs:
546 return "googCaptureStartNtpTimeMs";
547 case kStatsValueNameFrameRateInput:
548 return "googFrameRateInput";
549 case kStatsValueNameFrameRateSent:
550 return "googFrameRateSent";
551 case kStatsValueNameFrameWidthInput:
552 return "googFrameWidthInput";
553 case kStatsValueNameFrameWidthReceived:
554 return "googFrameWidthReceived";
555 case kStatsValueNameFrameWidthSent:
556 return "googFrameWidthSent";
Åsa Perssonc3ed6302017-11-16 13:04:52557 case kStatsValueNameHasEnteredLowResolution:
558 return "googHasEnteredLowResolution";
Ilya Nikolaevskiy70473fc2018-02-28 15:35:03559 case kStatsValueNameHugeFramesSent:
560 return "hugeFramesSent";
tommi@webrtc.orgc57310b2014-12-12 17:41:28561 case kStatsValueNameInitiator:
562 return "googInitiator";
ilnika79cc282017-08-23 12:24:10563 case kStatsValueNameInterframeDelayMaxMs:
564 return "googInterframeDelayMax";
tommi@webrtc.orgc57310b2014-12-12 17:41:28565 case kStatsValueNameIssuerId:
566 return "googIssuerId";
567 case kStatsValueNameJitterReceived:
568 return "googJitterReceived";
569 case kStatsValueNameLocalAddress:
570 return "googLocalAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31571 case kStatsValueNameLocalCandidateId:
572 return "localCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28573 case kStatsValueNameLocalCandidateType:
574 return "googLocalCandidateType";
575 case kStatsValueNameLocalCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30576 return "localCertificateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28577 case kStatsValueNameAdaptationChanges:
578 return "googAdaptationChanges";
579 case kStatsValueNameNacksReceived:
580 return "googNacksReceived";
581 case kStatsValueNameNacksSent:
582 return "googNacksSent";
Henrik Lundin8e6fd462015-06-02 07:24:52583 case kStatsValueNamePreemptiveExpandRate:
584 return "googPreemptiveExpandRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28585 case kStatsValueNamePlisReceived:
586 return "googPlisReceived";
587 case kStatsValueNamePlisSent:
588 return "googPlisSent";
589 case kStatsValueNamePreferredJitterBufferMs:
590 return "googPreferredJitterBufferMs";
Peter Thatcher04ac81f2015-09-21 18:48:28591 case kStatsValueNameReceiving:
tommi@webrtc.orgc57310b2014-12-12 17:41:28592 return "googReadable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28593 case kStatsValueNameRemoteAddress:
594 return "googRemoteAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31595 case kStatsValueNameRemoteCandidateId:
596 return "remoteCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28597 case kStatsValueNameRemoteCandidateType:
598 return "googRemoteCandidateType";
599 case kStatsValueNameRemoteCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30600 return "remoteCertificateId";
ivoc8c63a822016-10-21 11:10:03601 case kStatsValueNameResidualEchoLikelihood:
602 return "googResidualEchoLikelihood";
ivoc4e477a12017-01-15 16:29:46603 case kStatsValueNameResidualEchoLikelihoodRecentMax:
604 return "googResidualEchoLikelihoodRecentMax";
ivoce1198e02017-09-08 15:13:19605 case kStatsValueNameAnaBitrateActionCounter:
606 return "googAnaBitrateActionCounter";
607 case kStatsValueNameAnaChannelActionCounter:
608 return "googAnaChannelActionCounter";
609 case kStatsValueNameAnaDtxActionCounter:
610 return "googAnaDtxActionCounter";
611 case kStatsValueNameAnaFecActionCounter:
612 return "googAnaFecActionCounter";
ivoc0d0b9122017-09-08 20:24:21613 case kStatsValueNameAnaFrameLengthIncreaseCounter:
614 return "googAnaFrameLengthIncreaseCounter";
615 case kStatsValueNameAnaFrameLengthDecreaseCounter:
616 return "googAnaFrameLengthDecreaseCounter";
617 case kStatsValueNameAnaUplinkPacketLossFraction:
618 return "googAnaUplinkPacketLossFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28619 case kStatsValueNameRetransmitBitrate:
620 return "googRetransmitBitrate";
621 case kStatsValueNameRtt:
622 return "googRtt";
minyue@webrtc.org652bc372015-02-18 23:50:46623 case kStatsValueNameSecondaryDecodedRate:
624 return "googSecondaryDecodedRate";
minyue-webrtc0e320ec2017-08-28 11:51:27625 case kStatsValueNameSecondaryDiscardedRate:
626 return "googSecondaryDiscardedRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28627 case kStatsValueNameSendPacketsDiscarded:
628 return "packetsDiscardedOnSend";
minyue@webrtc.org652bc372015-02-18 23:50:46629 case kStatsValueNameSpeechExpandRate:
630 return "googSpeechExpandRate";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30631 case kStatsValueNameSrtpCipher:
632 return "srtpCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28633 case kStatsValueNameTargetEncBitrate:
634 return "googTargetEncBitrate";
zsteine76bd3a2017-07-14 19:17:49635 case kStatsValueNameTotalAudioEnergy:
636 return "totalAudioEnergy";
637 case kStatsValueNameTotalSamplesDuration:
638 return "totalSamplesDuration";
tommi@webrtc.orgc57310b2014-12-12 17:41:28639 case kStatsValueNameTransmitBitrate:
640 return "googTransmitBitrate";
641 case kStatsValueNameTransportType:
642 return "googTransportType";
643 case kStatsValueNameTrackId:
644 return "googTrackId";
ilnik2edc6842017-07-06 10:06:50645 case kStatsValueNameTimingFrameInfo:
646 return "googTimingFrameInfo";
tommi@webrtc.orgc57310b2014-12-12 17:41:28647 case kStatsValueNameTypingNoiseState:
648 return "googTypingNoiseState";
tommi@webrtc.orgc57310b2014-12-12 17:41:28649 case kStatsValueNameWritable:
650 return "googWritable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28651 }
652
653 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06654}
655
tommi@webrtc.orgd3900292015-03-12 16:35:55656std::string StatsReport::Value::ToString() const {
657 switch (type_) {
658 case kInt:
659 return rtc::ToString(value_.int_);
660 case kInt64:
661 return rtc::ToString(value_.int64_);
662 case kFloat:
663 return rtc::ToString(value_.float_);
664 case kStaticString:
665 return std::string(value_.static_string_);
666 case kString:
667 return *value_.string_;
668 case kBool:
669 return value_.bool_ ? "true" : "false";
670 case kId:
671 return (*value_.id_)->ToString();
672 }
673 RTC_NOTREACHED();
674 return std::string();
tommi@webrtc.orgafa6d162015-03-02 11:27:48675}
676
tommi@webrtc.orgd3900292015-03-12 16:35:55677StatsReport::StatsReport(const Id& id) : id_(id), timestamp_(0.0) {
henrikg91d6ede2015-09-17 07:24:34678 RTC_DCHECK(id_.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18679}
680
ossu7bb87ee2017-01-23 12:56:25681StatsReport::~StatsReport() = default;
682
tommi@webrtc.org4fb7e252015-01-21 11:36:18683// static
tommi@webrtc.orgd3900292015-03-12 16:35:55684StatsReport::Id StatsReport::NewBandwidthEstimationId() {
685 return Id(new RefCountedObject<BandwidthEstimationId>());
tommi@webrtc.org4fb7e252015-01-21 11:36:18686}
687
688// static
tommi@webrtc.orgd3900292015-03-12 16:35:55689StatsReport::Id StatsReport::NewTypedId(StatsType type, const std::string& id) {
690 return Id(new RefCountedObject<TypedId>(type, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18691}
692
693// static
tommi@webrtc.orgd3900292015-03-12 16:35:55694StatsReport::Id StatsReport::NewTypedIntId(StatsType type, int id) {
695 return Id(new RefCountedObject<TypedIntId>(type, id));
decurtis@webrtc.org322a5642015-02-03 22:09:37696}
697
698// static
tommi@webrtc.orgd3900292015-03-12 16:35:55699StatsReport::Id StatsReport::NewIdWithDirection(
Yves Gerey665174f2018-06-19 13:03:05700 StatsType type,
701 const std::string& id,
702 StatsReport::Direction direction) {
tommi@webrtc.orgd3900292015-03-12 16:35:55703 return Id(new RefCountedObject<IdWithDirection>(type, id, direction));
tommi@webrtc.org4fb7e252015-01-21 11:36:18704}
705
706// static
tommi@webrtc.orgd3900292015-03-12 16:35:55707StatsReport::Id StatsReport::NewCandidateId(bool local, const std::string& id) {
708 return Id(new RefCountedObject<CandidateId>(local, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18709}
710
711// static
Yves Gerey665174f2018-06-19 13:03:05712StatsReport::Id StatsReport::NewComponentId(const std::string& content_name,
713 int component) {
tommi@webrtc.orgd3900292015-03-12 16:35:55714 return Id(new RefCountedObject<ComponentId>(content_name, component));
tommi@webrtc.org4fb7e252015-01-21 11:36:18715}
716
717// static
Yves Gerey665174f2018-06-19 13:03:05718StatsReport::Id StatsReport::NewCandidatePairId(const std::string& content_name,
719 int component,
720 int index) {
721 return Id(
722 new RefCountedObject<CandidatePairId>(content_name, component, index));
tommi@webrtc.org4fb7e252015-01-21 11:36:18723}
724
725const char* StatsReport::TypeToString() const {
726 return InternalTypeToString(id_->type());
727}
728
tommi@webrtc.org92f40182015-03-04 15:25:19729void StatsReport::AddString(StatsReport::StatsValueName name,
730 const std::string& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55731 const Value* found = FindValue(name);
732 if (!found || !(*found == value))
733 values_[name] = ValuePtr(new Value(name, value));
734}
735
736void StatsReport::AddString(StatsReport::StatsValueName name,
737 const char* value) {
738 const Value* found = FindValue(name);
739 if (!found || !(*found == value))
740 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06741}
742
Peter Boström0c4e06b2015-10-07 10:23:21743void StatsReport::AddInt64(StatsReport::StatsValueName name, int64_t value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55744 const Value* found = FindValue(name);
745 if (!found || !(*found == value))
746 values_[name] = ValuePtr(new Value(name, value, Value::kInt64));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06747}
748
tommi@webrtc.org92f40182015-03-04 15:25:19749void StatsReport::AddInt(StatsReport::StatsValueName name, int value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55750 const Value* found = FindValue(name);
Peter Boström0c4e06b2015-10-07 10:23:21751 if (!found || !(*found == static_cast<int64_t>(value)))
tommi@webrtc.orgd3900292015-03-12 16:35:55752 values_[name] = ValuePtr(new Value(name, value, Value::kInt));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06753}
754
tommi@webrtc.org92f40182015-03-04 15:25:19755void StatsReport::AddFloat(StatsReport::StatsValueName name, float value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55756 const Value* found = FindValue(name);
757 if (!found || !(*found == value))
758 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org92f40182015-03-04 15:25:19759}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06760
761void StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55762 const Value* found = FindValue(name);
763 if (!found || !(*found == value))
764 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org8e327c42015-01-19 20:41:26765}
766
Yves Gerey665174f2018-06-19 13:03:05767void StatsReport::AddId(StatsReport::StatsValueName name, const Id& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55768 const Value* found = FindValue(name);
769 if (!found || !(*found == value))
770 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06771}
772
tommi@webrtc.org4fb7e252015-01-21 11:36:18773const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const {
tommi@webrtc.org92f40182015-03-04 15:25:19774 Values::const_iterator it = values_.find(name);
775 return it == values_.end() ? nullptr : it->second.get();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06776}
777
Yves Gerey665174f2018-06-19 13:03:05778StatsCollection::StatsCollection() {}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06779
tommi@webrtc.org4fb7e252015-01-21 11:36:18780StatsCollection::~StatsCollection() {
henrikg91d6ede2015-09-17 07:24:34781 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18782 for (auto* r : list_)
783 delete r;
784}
785
786StatsCollection::const_iterator StatsCollection::begin() const {
henrikg91d6ede2015-09-17 07:24:34787 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06788 return list_.begin();
789}
790
tommi@webrtc.org4fb7e252015-01-21 11:36:18791StatsCollection::const_iterator StatsCollection::end() const {
henrikg91d6ede2015-09-17 07:24:34792 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06793 return list_.end();
794}
795
tommi@webrtc.org4fb7e252015-01-21 11:36:18796size_t StatsCollection::size() const {
henrikg91d6ede2015-09-17 07:24:34797 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18798 return list_.size();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06799}
800
tommi@webrtc.orgd3900292015-03-12 16:35:55801StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34802 RTC_DCHECK(thread_checker_.CalledOnValidThread());
803 RTC_DCHECK(Find(id) == nullptr);
tommi@webrtc.orgd3900292015-03-12 16:35:55804 StatsReport* report = new StatsReport(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18805 list_.push_back(report);
806 return report;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06807}
808
tommi@webrtc.orgd3900292015-03-12 16:35:55809StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34810 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgd3900292015-03-12 16:35:55811 StatsReport* ret = Find(id);
812 return ret ? ret : InsertNew(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18813}
814
tommi@webrtc.orgd3900292015-03-12 16:35:55815StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34816 RTC_DCHECK(thread_checker_.CalledOnValidThread());
817 RTC_DCHECK(id.get());
Yves Gerey665174f2018-06-19 13:03:05818 Container::iterator it = std::find_if(
819 list_.begin(), list_.end(),
820 [&id](const StatsReport* r) -> bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18821 if (it != end()) {
tommi@webrtc.orgd3900292015-03-12 16:35:55822 StatsReport* report = new StatsReport((*it)->id());
tommi@webrtc.org4fb7e252015-01-21 11:36:18823 delete *it;
tommi@webrtc.org4fb7e252015-01-21 11:36:18824 *it = report;
825 return report;
826 }
tommi@webrtc.orgd3900292015-03-12 16:35:55827 return InsertNew(id);
tommi@webrtc.orgc9d155f2014-12-09 18:18:06828}
829
deadbeef8d60a942017-02-27 22:47:33830// Looks for a report with the given |id|. If one is not found, null
tommi@webrtc.orgc9d155f2014-12-09 18:18:06831// will be returned.
tommi@webrtc.org4fb7e252015-01-21 11:36:18832StatsReport* StatsCollection::Find(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34833 RTC_DCHECK(thread_checker_.CalledOnValidThread());
Yves Gerey665174f2018-06-19 13:03:05834 Container::iterator it = std::find_if(
835 list_.begin(), list_.end(),
836 [&id](const StatsReport* r) -> bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18837 return it == list_.end() ? nullptr : *it;
838}
839
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01840} // namespace webrtc