blob: f6f26899e9226c88baa73ad6e5d5206b73e01045 [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
Henrik Kjellander15583c12016-02-10 09:53:1211#include "webrtc/api/statstypes.h"
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0112
tommi@webrtc.orgd3900292015-03-12 16:35:5513#include <string.h>
14
15#include "webrtc/base/checks.h"
16
17// TODO(tommi): Could we have a static map of value name -> expected type
henrikg91d6ede2015-09-17 07:24:3418// and use this to RTC_DCHECK on correct usage (somewhat strongly typed values)?
tommi@webrtc.orgd3900292015-03-12 16:35:5519// Alternatively, we could define the names+type in a separate document and
20// generate strongly typed inline C++ code that forces the correct type to be
21// used for a given name at compile time.
22
tommi@webrtc.org4b89aa02015-03-16 09:52:3023using rtc::RefCountedObject;
tommi@webrtc.org8e327c42015-01-19 20:41:2624
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0125namespace webrtc {
tommi@webrtc.org4fb7e252015-01-21 11:36:1826namespace {
tommi@webrtc.org5c3ee4b2014-12-09 10:47:0127
tommi@webrtc.org4fb7e252015-01-21 11:36:1828// The id of StatsReport of type kStatsReportTypeBwe.
29const char kStatsReportVideoBweId[] = "bweforvideo";
tommi@webrtc.orgc9d155f2014-12-09 18:18:0630
tommi@webrtc.org4fb7e252015-01-21 11:36:1831// NOTE: These names need to be consistent with an external
32// specification (W3C Stats Identifiers).
33const char* InternalTypeToString(StatsReport::StatsType type) {
34 switch (type) {
35 case StatsReport::kStatsReportTypeSession:
36 return "googLibjingleSession";
37 case StatsReport::kStatsReportTypeBwe:
38 return "VideoBwe";
39 case StatsReport::kStatsReportTypeRemoteSsrc:
40 return "remoteSsrc";
41 case StatsReport::kStatsReportTypeSsrc:
42 return "ssrc";
43 case StatsReport::kStatsReportTypeTrack:
44 return "googTrack";
45 case StatsReport::kStatsReportTypeIceLocalCandidate:
46 return "localcandidate";
47 case StatsReport::kStatsReportTypeIceRemoteCandidate:
48 return "remotecandidate";
49 case StatsReport::kStatsReportTypeTransport:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:3050 return "transport";
tommi@webrtc.org4fb7e252015-01-21 11:36:1851 case StatsReport::kStatsReportTypeComponent:
52 return "googComponent";
53 case StatsReport::kStatsReportTypeCandidatePair:
54 return "googCandidatePair";
55 case StatsReport::kStatsReportTypeCertificate:
56 return "googCertificate";
57 case StatsReport::kStatsReportTypeDataChannel:
58 return "datachannel";
59 }
nisseeb4ca4e2017-01-12 10:24:2760 RTC_NOTREACHED();
tommi@webrtc.org4fb7e252015-01-21 11:36:1861 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:0662}
63
tommi@webrtc.orgd3900292015-03-12 16:35:5564class BandwidthEstimationId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:1865 public:
tommi@webrtc.orgd3900292015-03-12 16:35:5566 BandwidthEstimationId()
67 : StatsReport::IdBase(StatsReport::kStatsReportTypeBwe) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:1868 std::string ToString() const override { return kStatsReportVideoBweId; }
69};
tommi@webrtc.org8e327c42015-01-19 20:41:2670
tommi@webrtc.orgd3900292015-03-12 16:35:5571class TypedId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:1872 public:
tommi@webrtc.org4fb7e252015-01-21 11:36:1873 TypedId(StatsReport::StatsType type, const std::string& id)
tommi@webrtc.orgd3900292015-03-12 16:35:5574 : StatsReport::IdBase(type), id_(id) {}
tommi@webrtc.org8e327c42015-01-19 20:41:2675
tommi@webrtc.orgd3900292015-03-12 16:35:5576 bool Equals(const IdBase& other) const override {
77 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:1878 static_cast<const TypedId&>(other).id_ == id_;
79 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:0680
tommi@webrtc.org4fb7e252015-01-21 11:36:1881 std::string ToString() const override {
82 return std::string(InternalTypeToString(type_)) + kSeparator + id_;
83 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:0684
tommi@webrtc.org4fb7e252015-01-21 11:36:1885 protected:
86 const std::string id_;
87};
tommi@webrtc.orgc9d155f2014-12-09 18:18:0688
tommi@webrtc.orgd3900292015-03-12 16:35:5589class TypedIntId : public StatsReport::IdBase {
decurtis@webrtc.org322a5642015-02-03 22:09:3790 public:
91 TypedIntId(StatsReport::StatsType type, int id)
tommi@webrtc.orgd3900292015-03-12 16:35:5592 : StatsReport::IdBase(type), id_(id) {}
decurtis@webrtc.org322a5642015-02-03 22:09:3793
tommi@webrtc.orgd3900292015-03-12 16:35:5594 bool Equals(const IdBase& other) const override {
95 return IdBase::Equals(other) &&
decurtis@webrtc.org322a5642015-02-03 22:09:3796 static_cast<const TypedIntId&>(other).id_ == id_;
97 }
98
99 std::string ToString() const override {
100 return std::string(InternalTypeToString(type_)) +
101 kSeparator +
102 rtc::ToString<int>(id_);
103 }
104
105 protected:
106 const int id_;
107};
108
tommi@webrtc.org4fb7e252015-01-21 11:36:18109class IdWithDirection : public TypedId {
110 public:
111 IdWithDirection(StatsReport::StatsType type, const std::string& id,
112 StatsReport::Direction direction)
113 : TypedId(type, id), direction_(direction) {}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06114
tommi@webrtc.orgd3900292015-03-12 16:35:55115 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18116 return TypedId::Equals(other) &&
117 static_cast<const IdWithDirection&>(other).direction_ == direction_;
118 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06119
tommi@webrtc.org4fb7e252015-01-21 11:36:18120 std::string ToString() const override {
121 std::string ret(TypedId::ToString());
decurtis@webrtc.org322a5642015-02-03 22:09:37122 ret += kSeparator;
tommi@webrtc.org4fb7e252015-01-21 11:36:18123 ret += direction_ == StatsReport::kSend ? "send" : "recv";
124 return ret;
125 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06126
tommi@webrtc.org4fb7e252015-01-21 11:36:18127 private:
128 const StatsReport::Direction direction_;
129};
130
131class CandidateId : public TypedId {
132 public:
133 CandidateId(bool local, const std::string& id)
134 : TypedId(local ?
135 StatsReport::kStatsReportTypeIceLocalCandidate :
136 StatsReport::kStatsReportTypeIceRemoteCandidate,
137 id) {
138 }
139
140 std::string ToString() const override {
141 return "Cand-" + id_;
142 }
143};
144
tommi@webrtc.orgd3900292015-03-12 16:35:55145class ComponentId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18146 public:
147 ComponentId(const std::string& content_name, int component)
148 : ComponentId(StatsReport::kStatsReportTypeComponent, content_name,
149 component) {}
150
tommi@webrtc.orgd3900292015-03-12 16:35:55151 bool Equals(const IdBase& other) const override {
152 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:18153 static_cast<const ComponentId&>(other).component_ == component_ &&
154 static_cast<const ComponentId&>(other).content_name_ == content_name_;
155 }
156
157 std::string ToString() const override {
158 return ToString("Channel-");
159 }
160
161 protected:
162 ComponentId(StatsReport::StatsType type, const std::string& content_name,
163 int component)
tommi@webrtc.orgd3900292015-03-12 16:35:55164 : IdBase(type),
tommi@webrtc.org4fb7e252015-01-21 11:36:18165 content_name_(content_name),
166 component_(component) {}
167
168 std::string ToString(const char* prefix) const {
169 std::string ret(prefix);
170 ret += content_name_;
171 ret += '-';
172 ret += rtc::ToString<>(component_);
173 return ret;
174 }
175
176 private:
177 const std::string content_name_;
178 const int component_;
179};
180
181class CandidatePairId : public ComponentId {
182 public:
183 CandidatePairId(const std::string& content_name, int component, int index)
184 : ComponentId(StatsReport::kStatsReportTypeCandidatePair, content_name,
185 component),
186 index_(index) {}
187
tommi@webrtc.orgd3900292015-03-12 16:35:55188 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18189 return ComponentId::Equals(other) &&
190 static_cast<const CandidatePairId&>(other).index_ == index_;
191 }
192
193 std::string ToString() const override {
194 std::string ret(ComponentId::ToString("Conn-"));
195 ret += '-';
196 ret += rtc::ToString<>(index_);
197 return ret;
198 }
199
200 private:
201 const int index_;
202};
203
204} // namespace
205
tommi@webrtc.orgd3900292015-03-12 16:35:55206StatsReport::IdBase::IdBase(StatsType type) : type_(type) {}
207StatsReport::IdBase::~IdBase() {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18208
tommi@webrtc.orgd3900292015-03-12 16:35:55209StatsReport::StatsType StatsReport::IdBase::type() const { return type_; }
tommi@webrtc.org4fb7e252015-01-21 11:36:18210
tommi@webrtc.orgd3900292015-03-12 16:35:55211bool StatsReport::IdBase::Equals(const IdBase& other) const {
tommi@webrtc.org4fb7e252015-01-21 11:36:18212 return other.type_ == type_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06213}
214
Peter Boström0c4e06b2015-10-07 10:23:21215StatsReport::Value::Value(StatsValueName name, int64_t value, Type int_type)
tommi@webrtc.orgd3900292015-03-12 16:35:55216 : name(name), type_(int_type) {
henrikg91d6ede2015-09-17 07:24:34217 RTC_DCHECK(type_ == kInt || type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55218 type_ == kInt ? value_.int_ = static_cast<int>(value) : value_.int64_ = value;
219}
220
221StatsReport::Value::Value(StatsValueName name, float f)
222 : name(name), type_(kFloat) {
223 value_.float_ = f;
224}
225
tommi@webrtc.orgc9d155f2014-12-09 18:18:06226StatsReport::Value::Value(StatsValueName name, const std::string& value)
tommi@webrtc.orgd3900292015-03-12 16:35:55227 : name(name), type_(kString) {
228 value_.string_ = new std::string(value);
229}
230
231StatsReport::Value::Value(StatsValueName name, const char* value)
232 : name(name), type_(kStaticString) {
233 value_.static_string_ = value;
234}
235
236StatsReport::Value::Value(StatsValueName name, bool b)
237 : name(name), type_(kBool) {
238 value_.bool_ = b;
239}
240
241StatsReport::Value::Value(StatsValueName name, const Id& value)
242 : name(name), type_(kId) {
243 value_.id_ = new Id(value);
244}
245
246StatsReport::Value::~Value() {
247 switch (type_) {
248 case kInt:
249 case kInt64:
250 case kFloat:
251 case kBool:
252 case kStaticString:
253 break;
254 case kString:
255 delete value_.string_;
256 break;
257 case kId:
258 delete value_.id_;
259 break;
260 }
261}
262
263bool StatsReport::Value::Equals(const Value& other) const {
264 if (name != other.name)
265 return false;
266
267 // There's a 1:1 relation between a name and a type, so we don't have to
268 // check that.
henrikg91d6ede2015-09-17 07:24:34269 RTC_DCHECK_EQ(type_, other.type_);
tommi@webrtc.orgd3900292015-03-12 16:35:55270
271 switch (type_) {
272 case kInt:
273 return value_.int_ == other.value_.int_;
274 case kInt64:
275 return value_.int64_ == other.value_.int64_;
276 case kFloat:
277 return value_.float_ == other.value_.float_;
278 case kStaticString: {
kwiberg5377bc72016-10-04 20:46:56279#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55280 if (value_.static_string_ != other.value_.static_string_) {
henrikg91d6ede2015-09-17 07:24:34281 RTC_DCHECK(strcmp(value_.static_string_, other.value_.static_string_) !=
282 0)
tommi@webrtc.orgd3900292015-03-12 16:35:55283 << "Duplicate global?";
284 }
285#endif
286 return value_.static_string_ == other.value_.static_string_;
287 }
288 case kString:
289 return *value_.string_ == *other.value_.string_;
290 case kBool:
291 return value_.bool_ == other.value_.bool_;
292 case kId:
293 return (*value_.id_)->Equals(*other.value_.id_);
294 }
295 RTC_NOTREACHED();
296 return false;
297}
298
299bool StatsReport::Value::operator==(const std::string& value) const {
300 return (type_ == kString && value_.string_->compare(value) == 0) ||
301 (type_ == kStaticString && value.compare(value_.static_string_) == 0);
302}
303
304bool StatsReport::Value::operator==(const char* value) const {
305 if (type_ == kString)
306 return value_.string_->compare(value) == 0;
307 if (type_ != kStaticString)
308 return false;
kwiberg5377bc72016-10-04 20:46:56309#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55310 if (value_.static_string_ != value)
henrikg91d6ede2015-09-17 07:24:34311 RTC_DCHECK(strcmp(value_.static_string_, value) != 0)
312 << "Duplicate global?";
tommi@webrtc.orgd3900292015-03-12 16:35:55313#endif
314 return value == value_.static_string_;
315}
316
Peter Boström0c4e06b2015-10-07 10:23:21317bool StatsReport::Value::operator==(int64_t value) const {
tommi@webrtc.orgd3900292015-03-12 16:35:55318 return type_ == kInt ? value_.int_ == static_cast<int>(value) :
319 (type_ == kInt64 ? value_.int64_ == value : false);
320}
321
322bool StatsReport::Value::operator==(bool value) const {
323 return type_ == kBool && value_.bool_ == value;
324}
325
326bool StatsReport::Value::operator==(float value) const {
327 return type_ == kFloat && value_.float_ == value;
328}
329
330bool StatsReport::Value::operator==(const Id& value) const {
331 return type_ == kId && (*value_.id_)->Equals(value);
332}
333
334int StatsReport::Value::int_val() const {
henrikg91d6ede2015-09-17 07:24:34335 RTC_DCHECK(type_ == kInt);
tommi@webrtc.orgd3900292015-03-12 16:35:55336 return value_.int_;
337}
338
Peter Boström0c4e06b2015-10-07 10:23:21339int64_t StatsReport::Value::int64_val() const {
henrikg91d6ede2015-09-17 07:24:34340 RTC_DCHECK(type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55341 return value_.int64_;
342}
343
344float StatsReport::Value::float_val() const {
henrikg91d6ede2015-09-17 07:24:34345 RTC_DCHECK(type_ == kFloat);
tommi@webrtc.orgd3900292015-03-12 16:35:55346 return value_.float_;
347}
348
349const char* StatsReport::Value::static_string_val() const {
henrikg91d6ede2015-09-17 07:24:34350 RTC_DCHECK(type_ == kStaticString);
tommi@webrtc.orgd3900292015-03-12 16:35:55351 return value_.static_string_;
352}
353
354const std::string& StatsReport::Value::string_val() const {
henrikg91d6ede2015-09-17 07:24:34355 RTC_DCHECK(type_ == kString);
tommi@webrtc.orgd3900292015-03-12 16:35:55356 return *value_.string_;
357}
358
359bool StatsReport::Value::bool_val() const {
henrikg91d6ede2015-09-17 07:24:34360 RTC_DCHECK(type_ == kBool);
tommi@webrtc.orgd3900292015-03-12 16:35:55361 return value_.bool_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06362}
363
tommi@webrtc.orgc9d155f2014-12-09 18:18:06364const char* StatsReport::Value::display_name() const {
tommi@webrtc.orgc57310b2014-12-12 17:41:28365 switch (name) {
Minyue2a8a78c2016-04-07 14:48:15366 case kStatsValueNameAecDivergentFilterFraction:
367 return "aecDivergentFilterFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28368 case kStatsValueNameAudioOutputLevel:
369 return "audioOutputLevel";
370 case kStatsValueNameAudioInputLevel:
371 return "audioInputLevel";
372 case kStatsValueNameBytesSent:
373 return "bytesSent";
374 case kStatsValueNamePacketsSent:
375 return "packetsSent";
376 case kStatsValueNameBytesReceived:
377 return "bytesReceived";
decurtis@webrtc.org487a4442015-01-15 22:55:07378 case kStatsValueNameLabel:
379 return "label";
tommi@webrtc.orgc57310b2014-12-12 17:41:28380 case kStatsValueNamePacketsReceived:
381 return "packetsReceived";
382 case kStatsValueNamePacketsLost:
383 return "packetsLost";
decurtis@webrtc.org487a4442015-01-15 22:55:07384 case kStatsValueNameProtocol:
385 return "protocol";
tommi@webrtc.orgc57310b2014-12-12 17:41:28386 case kStatsValueNameTransportId:
387 return "transportId";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30388 case kStatsValueNameSelectedCandidatePairId:
389 return "selectedCandidatePairId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28390 case kStatsValueNameSsrc:
391 return "ssrc";
decurtis@webrtc.org487a4442015-01-15 22:55:07392 case kStatsValueNameState:
393 return "state";
394 case kStatsValueNameDataChannelId:
395 return "datachannelid";
sakale5ba44e2016-10-26 14:09:24396 case kStatsValueNameFramesDecoded:
397 return "framesDecoded";
sakal43536c32016-10-24 08:46:43398 case kStatsValueNameFramesEncoded:
399 return "framesEncoded";
Peter Boströmb7d9a972015-12-18 15:01:11400 case kStatsValueNameCodecImplementationName:
401 return "codecImplementationName";
fippobec70ab2016-01-28 09:27:15402 case kStatsValueNameMediaType:
403 return "mediaType";
sakal87da4042016-10-31 13:53:47404 case kStatsValueNameQpSum:
405 return "qpSum";
tommi@webrtc.orgc57310b2014-12-12 17:41:28406 // 'goog' prefixed constants.
Henrik Lundin8e6fd462015-06-02 07:24:52407 case kStatsValueNameAccelerateRate:
408 return "googAccelerateRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28409 case kStatsValueNameActiveConnection:
410 return "googActiveConnection";
411 case kStatsValueNameActualEncBitrate:
412 return "googActualEncBitrate";
413 case kStatsValueNameAvailableReceiveBandwidth:
414 return "googAvailableReceiveBandwidth";
415 case kStatsValueNameAvailableSendBandwidth:
416 return "googAvailableSendBandwidth";
417 case kStatsValueNameAvgEncodeMs:
418 return "googAvgEncodeMs";
419 case kStatsValueNameBucketDelay:
420 return "googBucketDelay";
421 case kStatsValueNameBandwidthLimitedResolution:
422 return "googBandwidthLimitedResolution";
zhihuang5ecf16c2016-06-02 00:09:15423 // STUN ping related attributes.
424 // TODO(zhihuang) Rename these stats to follow the standards.
425 case kStatsValueNameSentPingRequestsTotal:
426 return "requestsSent";
427 case kStatsValueNameSentPingRequestsBeforeFirstResponse:
428 return "consentRequestsSent";
429 case kStatsValueNameSentPingResponses:
430 return "responsesSent";
431 case kStatsValueNameRecvPingRequests:
432 return "requestsReceived";
433 case kStatsValueNameRecvPingResponses:
434 return "responsesReceived";
guoweis@webrtc.org950c5182014-12-16 23:01:31435
436 // Candidate related attributes. Values are taken from
437 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
438 case kStatsValueNameCandidateIPAddress:
439 return "ipAddress";
440 case kStatsValueNameCandidateNetworkType:
441 return "networkType";
442 case kStatsValueNameCandidatePortNumber:
443 return "portNumber";
444 case kStatsValueNameCandidatePriority:
445 return "priority";
446 case kStatsValueNameCandidateTransportType:
447 return "transport";
448 case kStatsValueNameCandidateType:
449 return "candidateType";
450
tommi@webrtc.orgc57310b2014-12-12 17:41:28451 case kStatsValueNameChannelId:
452 return "googChannelId";
453 case kStatsValueNameCodecName:
454 return "googCodecName";
455 case kStatsValueNameComponent:
456 return "googComponent";
457 case kStatsValueNameContentName:
458 return "googContentName";
459 case kStatsValueNameCpuLimitedResolution:
460 return "googCpuLimitedResolution";
461 case kStatsValueNameDecodingCTSG:
462 return "googDecodingCTSG";
463 case kStatsValueNameDecodingCTN:
464 return "googDecodingCTN";
henrik.lundin63489782016-09-20 08:47:12465 case kStatsValueNameDecodingMutedOutput:
466 return "googDecodingMuted";
tommi@webrtc.orgc57310b2014-12-12 17:41:28467 case kStatsValueNameDecodingNormal:
468 return "googDecodingNormal";
469 case kStatsValueNameDecodingPLC:
470 return "googDecodingPLC";
471 case kStatsValueNameDecodingCNG:
472 return "googDecodingCNG";
473 case kStatsValueNameDecodingPLCCNG:
474 return "googDecodingPLCCNG";
475 case kStatsValueNameDer:
476 return "googDerBase64";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30477 case kStatsValueNameDtlsCipher:
478 return "dtlsCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28479 case kStatsValueNameEchoCancellationQualityMin:
480 return "googEchoCancellationQualityMin";
481 case kStatsValueNameEchoDelayMedian:
482 return "googEchoCancellationEchoDelayMedian";
483 case kStatsValueNameEchoDelayStdDev:
484 return "googEchoCancellationEchoDelayStdDev";
485 case kStatsValueNameEchoReturnLoss:
486 return "googEchoCancellationReturnLoss";
487 case kStatsValueNameEchoReturnLossEnhancement:
488 return "googEchoCancellationReturnLossEnhancement";
489 case kStatsValueNameEncodeUsagePercent:
490 return "googEncodeUsagePercent";
491 case kStatsValueNameExpandRate:
492 return "googExpandRate";
493 case kStatsValueNameFingerprint:
494 return "googFingerprint";
495 case kStatsValueNameFingerprintAlgorithm:
496 return "googFingerprintAlgorithm";
497 case kStatsValueNameFirsReceived:
498 return "googFirsReceived";
499 case kStatsValueNameFirsSent:
500 return "googFirsSent";
501 case kStatsValueNameFrameHeightInput:
502 return "googFrameHeightInput";
503 case kStatsValueNameFrameHeightReceived:
504 return "googFrameHeightReceived";
505 case kStatsValueNameFrameHeightSent:
506 return "googFrameHeightSent";
507 case kStatsValueNameFrameRateReceived:
508 return "googFrameRateReceived";
509 case kStatsValueNameFrameRateDecoded:
510 return "googFrameRateDecoded";
511 case kStatsValueNameFrameRateOutput:
512 return "googFrameRateOutput";
513 case kStatsValueNameDecodeMs:
514 return "googDecodeMs";
515 case kStatsValueNameMaxDecodeMs:
516 return "googMaxDecodeMs";
517 case kStatsValueNameCurrentDelayMs:
518 return "googCurrentDelayMs";
519 case kStatsValueNameTargetDelayMs:
520 return "googTargetDelayMs";
521 case kStatsValueNameJitterBufferMs:
522 return "googJitterBufferMs";
523 case kStatsValueNameMinPlayoutDelayMs:
524 return "googMinPlayoutDelayMs";
525 case kStatsValueNameRenderDelayMs:
526 return "googRenderDelayMs";
527 case kStatsValueNameCaptureStartNtpTimeMs:
528 return "googCaptureStartNtpTimeMs";
529 case kStatsValueNameFrameRateInput:
530 return "googFrameRateInput";
531 case kStatsValueNameFrameRateSent:
532 return "googFrameRateSent";
533 case kStatsValueNameFrameWidthInput:
534 return "googFrameWidthInput";
535 case kStatsValueNameFrameWidthReceived:
536 return "googFrameWidthReceived";
537 case kStatsValueNameFrameWidthSent:
538 return "googFrameWidthSent";
539 case kStatsValueNameInitiator:
540 return "googInitiator";
541 case kStatsValueNameIssuerId:
542 return "googIssuerId";
543 case kStatsValueNameJitterReceived:
544 return "googJitterReceived";
545 case kStatsValueNameLocalAddress:
546 return "googLocalAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31547 case kStatsValueNameLocalCandidateId:
548 return "localCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28549 case kStatsValueNameLocalCandidateType:
550 return "googLocalCandidateType";
551 case kStatsValueNameLocalCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30552 return "localCertificateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28553 case kStatsValueNameAdaptationChanges:
554 return "googAdaptationChanges";
555 case kStatsValueNameNacksReceived:
556 return "googNacksReceived";
557 case kStatsValueNameNacksSent:
558 return "googNacksSent";
Henrik Lundin8e6fd462015-06-02 07:24:52559 case kStatsValueNamePreemptiveExpandRate:
560 return "googPreemptiveExpandRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28561 case kStatsValueNamePlisReceived:
562 return "googPlisReceived";
563 case kStatsValueNamePlisSent:
564 return "googPlisSent";
565 case kStatsValueNamePreferredJitterBufferMs:
566 return "googPreferredJitterBufferMs";
Peter Thatcher04ac81f2015-09-21 18:48:28567 case kStatsValueNameReceiving:
tommi@webrtc.orgc57310b2014-12-12 17:41:28568 return "googReadable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28569 case kStatsValueNameRemoteAddress:
570 return "googRemoteAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31571 case kStatsValueNameRemoteCandidateId:
572 return "remoteCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28573 case kStatsValueNameRemoteCandidateType:
574 return "googRemoteCandidateType";
575 case kStatsValueNameRemoteCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30576 return "remoteCertificateId";
ivoc8c63a822016-10-21 11:10:03577 case kStatsValueNameResidualEchoLikelihood:
578 return "googResidualEchoLikelihood";
ivoc4e477a12017-01-15 16:29:46579 case kStatsValueNameResidualEchoLikelihoodRecentMax:
580 return "googResidualEchoLikelihoodRecentMax";
tommi@webrtc.orgc57310b2014-12-12 17:41:28581 case kStatsValueNameRetransmitBitrate:
582 return "googRetransmitBitrate";
583 case kStatsValueNameRtt:
584 return "googRtt";
minyue@webrtc.org652bc372015-02-18 23:50:46585 case kStatsValueNameSecondaryDecodedRate:
586 return "googSecondaryDecodedRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28587 case kStatsValueNameSendPacketsDiscarded:
588 return "packetsDiscardedOnSend";
minyue@webrtc.org652bc372015-02-18 23:50:46589 case kStatsValueNameSpeechExpandRate:
590 return "googSpeechExpandRate";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30591 case kStatsValueNameSrtpCipher:
592 return "srtpCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28593 case kStatsValueNameTargetEncBitrate:
594 return "googTargetEncBitrate";
595 case kStatsValueNameTransmitBitrate:
596 return "googTransmitBitrate";
597 case kStatsValueNameTransportType:
598 return "googTransportType";
599 case kStatsValueNameTrackId:
600 return "googTrackId";
ilnik2edc6842017-07-06 10:06:50601 case kStatsValueNameTimingFrameInfo:
602 return "googTimingFrameInfo";
tommi@webrtc.orgc57310b2014-12-12 17:41:28603 case kStatsValueNameTypingNoiseState:
604 return "googTypingNoiseState";
tommi@webrtc.orgc57310b2014-12-12 17:41:28605 case kStatsValueNameWritable:
606 return "googWritable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28607 }
608
609 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06610}
611
tommi@webrtc.orgd3900292015-03-12 16:35:55612std::string StatsReport::Value::ToString() const {
613 switch (type_) {
614 case kInt:
615 return rtc::ToString(value_.int_);
616 case kInt64:
617 return rtc::ToString(value_.int64_);
618 case kFloat:
619 return rtc::ToString(value_.float_);
620 case kStaticString:
621 return std::string(value_.static_string_);
622 case kString:
623 return *value_.string_;
624 case kBool:
625 return value_.bool_ ? "true" : "false";
626 case kId:
627 return (*value_.id_)->ToString();
628 }
629 RTC_NOTREACHED();
630 return std::string();
tommi@webrtc.orgafa6d162015-03-02 11:27:48631}
632
tommi@webrtc.orgd3900292015-03-12 16:35:55633StatsReport::StatsReport(const Id& id) : id_(id), timestamp_(0.0) {
henrikg91d6ede2015-09-17 07:24:34634 RTC_DCHECK(id_.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18635}
636
ossu7bb87ee2017-01-23 12:56:25637StatsReport::~StatsReport() = default;
638
tommi@webrtc.org4fb7e252015-01-21 11:36:18639// static
tommi@webrtc.orgd3900292015-03-12 16:35:55640StatsReport::Id StatsReport::NewBandwidthEstimationId() {
641 return Id(new RefCountedObject<BandwidthEstimationId>());
tommi@webrtc.org4fb7e252015-01-21 11:36:18642}
643
644// static
tommi@webrtc.orgd3900292015-03-12 16:35:55645StatsReport::Id StatsReport::NewTypedId(StatsType type, const std::string& id) {
646 return Id(new RefCountedObject<TypedId>(type, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18647}
648
649// static
tommi@webrtc.orgd3900292015-03-12 16:35:55650StatsReport::Id StatsReport::NewTypedIntId(StatsType type, int id) {
651 return Id(new RefCountedObject<TypedIntId>(type, id));
decurtis@webrtc.org322a5642015-02-03 22:09:37652}
653
654// static
tommi@webrtc.orgd3900292015-03-12 16:35:55655StatsReport::Id StatsReport::NewIdWithDirection(
tommi@webrtc.org4fb7e252015-01-21 11:36:18656 StatsType type, const std::string& id, StatsReport::Direction direction) {
tommi@webrtc.orgd3900292015-03-12 16:35:55657 return Id(new RefCountedObject<IdWithDirection>(type, id, direction));
tommi@webrtc.org4fb7e252015-01-21 11:36:18658}
659
660// static
tommi@webrtc.orgd3900292015-03-12 16:35:55661StatsReport::Id StatsReport::NewCandidateId(bool local, const std::string& id) {
662 return Id(new RefCountedObject<CandidateId>(local, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18663}
664
665// static
tommi@webrtc.orgd3900292015-03-12 16:35:55666StatsReport::Id StatsReport::NewComponentId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18667 const std::string& content_name, int component) {
tommi@webrtc.orgd3900292015-03-12 16:35:55668 return Id(new RefCountedObject<ComponentId>(content_name, component));
tommi@webrtc.org4fb7e252015-01-21 11:36:18669}
670
671// static
tommi@webrtc.orgd3900292015-03-12 16:35:55672StatsReport::Id StatsReport::NewCandidatePairId(
tommi@webrtc.org4fb7e252015-01-21 11:36:18673 const std::string& content_name, int component, int index) {
tommi@webrtc.orgd3900292015-03-12 16:35:55674 return Id(new RefCountedObject<CandidatePairId>(
675 content_name, component, index));
tommi@webrtc.org4fb7e252015-01-21 11:36:18676}
677
678const char* StatsReport::TypeToString() const {
679 return InternalTypeToString(id_->type());
680}
681
tommi@webrtc.org92f40182015-03-04 15:25:19682void StatsReport::AddString(StatsReport::StatsValueName name,
683 const std::string& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55684 const Value* found = FindValue(name);
685 if (!found || !(*found == value))
686 values_[name] = ValuePtr(new Value(name, value));
687}
688
689void StatsReport::AddString(StatsReport::StatsValueName name,
690 const char* value) {
691 const Value* found = FindValue(name);
692 if (!found || !(*found == value))
693 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06694}
695
Peter Boström0c4e06b2015-10-07 10:23:21696void StatsReport::AddInt64(StatsReport::StatsValueName name, int64_t value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55697 const Value* found = FindValue(name);
698 if (!found || !(*found == value))
699 values_[name] = ValuePtr(new Value(name, value, Value::kInt64));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06700}
701
tommi@webrtc.org92f40182015-03-04 15:25:19702void StatsReport::AddInt(StatsReport::StatsValueName name, int value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55703 const Value* found = FindValue(name);
Peter Boström0c4e06b2015-10-07 10:23:21704 if (!found || !(*found == static_cast<int64_t>(value)))
tommi@webrtc.orgd3900292015-03-12 16:35:55705 values_[name] = ValuePtr(new Value(name, value, Value::kInt));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06706}
707
tommi@webrtc.org92f40182015-03-04 15:25:19708void StatsReport::AddFloat(StatsReport::StatsValueName name, float value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55709 const Value* found = FindValue(name);
710 if (!found || !(*found == value))
711 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org92f40182015-03-04 15:25:19712}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06713
714void StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55715 const Value* found = FindValue(name);
716 if (!found || !(*found == value))
717 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org8e327c42015-01-19 20:41:26718}
719
tommi@webrtc.orgd3900292015-03-12 16:35:55720void StatsReport::AddId(StatsReport::StatsValueName name,
721 const Id& value) {
722 const Value* found = FindValue(name);
723 if (!found || !(*found == value))
724 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06725}
726
tommi@webrtc.org4fb7e252015-01-21 11:36:18727const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const {
tommi@webrtc.org92f40182015-03-04 15:25:19728 Values::const_iterator it = values_.find(name);
729 return it == values_.end() ? nullptr : it->second.get();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06730}
731
tommi@webrtc.org4fb7e252015-01-21 11:36:18732StatsCollection::StatsCollection() {
tommi@webrtc.orgc9d155f2014-12-09 18:18:06733}
734
tommi@webrtc.org4fb7e252015-01-21 11:36:18735StatsCollection::~StatsCollection() {
henrikg91d6ede2015-09-17 07:24:34736 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18737 for (auto* r : list_)
738 delete r;
739}
740
741StatsCollection::const_iterator StatsCollection::begin() const {
henrikg91d6ede2015-09-17 07:24:34742 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06743 return list_.begin();
744}
745
tommi@webrtc.org4fb7e252015-01-21 11:36:18746StatsCollection::const_iterator StatsCollection::end() const {
henrikg91d6ede2015-09-17 07:24:34747 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06748 return list_.end();
749}
750
tommi@webrtc.org4fb7e252015-01-21 11:36:18751size_t StatsCollection::size() const {
henrikg91d6ede2015-09-17 07:24:34752 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18753 return list_.size();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06754}
755
tommi@webrtc.orgd3900292015-03-12 16:35:55756StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34757 RTC_DCHECK(thread_checker_.CalledOnValidThread());
758 RTC_DCHECK(Find(id) == nullptr);
tommi@webrtc.orgd3900292015-03-12 16:35:55759 StatsReport* report = new StatsReport(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18760 list_.push_back(report);
761 return report;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06762}
763
tommi@webrtc.orgd3900292015-03-12 16:35:55764StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34765 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.orgd3900292015-03-12 16:35:55766 StatsReport* ret = Find(id);
767 return ret ? ret : InsertNew(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18768}
769
tommi@webrtc.orgd3900292015-03-12 16:35:55770StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34771 RTC_DCHECK(thread_checker_.CalledOnValidThread());
772 RTC_DCHECK(id.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18773 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55774 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18775 if (it != end()) {
tommi@webrtc.orgd3900292015-03-12 16:35:55776 StatsReport* report = new StatsReport((*it)->id());
tommi@webrtc.org4fb7e252015-01-21 11:36:18777 delete *it;
tommi@webrtc.org4fb7e252015-01-21 11:36:18778 *it = report;
779 return report;
780 }
tommi@webrtc.orgd3900292015-03-12 16:35:55781 return InsertNew(id);
tommi@webrtc.orgc9d155f2014-12-09 18:18:06782}
783
deadbeef8d60a942017-02-27 22:47:33784// Looks for a report with the given |id|. If one is not found, null
tommi@webrtc.orgc9d155f2014-12-09 18:18:06785// will be returned.
tommi@webrtc.org4fb7e252015-01-21 11:36:18786StatsReport* StatsCollection::Find(const StatsReport::Id& id) {
henrikg91d6ede2015-09-17 07:24:34787 RTC_DCHECK(thread_checker_.CalledOnValidThread());
tommi@webrtc.org4fb7e252015-01-21 11:36:18788 Container::iterator it = std::find_if(list_.begin(), list_.end(),
tommi@webrtc.orgd3900292015-03-12 16:35:55789 [&id](const StatsReport* r)->bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18790 return it == list_.end() ? nullptr : *it;
791}
792
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01793} // namespace webrtc