1 /* 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * 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. 9 */ 10 11 // This file contains structures used for retrieving statistics from an ongoing 12 // libjingle session. 13 14 #ifndef API_STATSTYPES_H_ 15 #define API_STATSTYPES_H_ 16 17 #include <algorithm> 18 #include <list> 19 #include <map> 20 #include <string> 21 #include <vector> 22 23 #include "rtc_base/basictypes.h" 24 #include "rtc_base/constructormagic.h" 25 #include "rtc_base/refcount.h" 26 #include "rtc_base/scoped_ref_ptr.h" 27 #include "rtc_base/stringencode.h" 28 #include "rtc_base/thread_checker.h" 29 30 namespace webrtc { 31 32 class StatsReport { 33 public: 34 // Indicates whether a track is for sending or receiving. 35 // Used in reports for audio/video tracks. 36 enum Direction { 37 kSend = 0, 38 kReceive, 39 }; 40 41 enum StatsType { 42 // StatsReport types. 43 // A StatsReport of |type| = "googSession" contains overall information 44 // about the thing libjingle calls a session (which may contain one 45 // or more RTP sessions. 46 kStatsReportTypeSession, 47 48 // A StatsReport of |type| = "googTransport" contains information 49 // about a libjingle "transport". 50 kStatsReportTypeTransport, 51 52 // A StatsReport of |type| = "googComponent" contains information 53 // about a libjingle "channel" (typically, RTP or RTCP for a transport). 54 // This is intended to be the same thing as an ICE "Component". 55 kStatsReportTypeComponent, 56 57 // A StatsReport of |type| = "googCandidatePair" contains information 58 // about a libjingle "connection" - a single source/destination port pair. 59 // This is intended to be the same thing as an ICE "candidate pair". 60 kStatsReportTypeCandidatePair, 61 62 // A StatsReport of |type| = "VideoBWE" is statistics for video Bandwidth 63 // Estimation, which is global per-session. The |id| field is "bweforvideo" 64 // (will probably change in the future). 65 kStatsReportTypeBwe, 66 67 // A StatsReport of |type| = "ssrc" is statistics for a specific rtp stream. 68 // The |id| field is the SSRC in decimal form of the rtp stream. 69 kStatsReportTypeSsrc, 70 71 // A StatsReport of |type| = "remoteSsrc" is statistics for a specific 72 // rtp stream, generated by the remote end of the connection. 73 kStatsReportTypeRemoteSsrc, 74 75 // A StatsReport of |type| = "googTrack" is statistics for a specific media 76 // track. The |id| field is the track id. 77 kStatsReportTypeTrack, 78 79 // A StatsReport of |type| = "localcandidate" or "remotecandidate" is 80 // attributes on a specific ICE Candidate. It links to its connection pair 81 // by candidate id. The string value is taken from 82 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*. 83 kStatsReportTypeIceLocalCandidate, 84 kStatsReportTypeIceRemoteCandidate, 85 86 // A StatsReport of |type| = "googCertificate" contains an SSL certificate 87 // transmitted by one of the endpoints of this connection. The |id| is 88 // controlled by the fingerprint, and is used to identify the certificate in 89 // the Channel stats (as "googLocalCertificateId" or 90 // "googRemoteCertificateId") and in any child certificates (as 91 // "googIssuerId"). 92 kStatsReportTypeCertificate, 93 94 // A StatsReport of |type| = "datachannel" with statistics for a 95 // particular DataChannel. 96 kStatsReportTypeDataChannel, 97 }; 98 99 enum StatsValueName { 100 kStatsValueNameActiveConnection, 101 kStatsValueNameAecDivergentFilterFraction, 102 kStatsValueNameAudioInputLevel, 103 kStatsValueNameAudioOutputLevel, 104 kStatsValueNameBytesReceived, 105 kStatsValueNameBytesSent, 106 kStatsValueNameCodecImplementationName, 107 kStatsValueNameConcealedSamples, 108 kStatsValueNameConcealmentEvents, 109 kStatsValueNameDataChannelId, 110 kStatsValueNameFramesDecoded, 111 kStatsValueNameFramesEncoded, 112 kStatsValueNameJitterBufferDelay, 113 kStatsValueNameMediaType, 114 kStatsValueNamePacketsLost, 115 kStatsValueNamePacketsReceived, 116 kStatsValueNamePacketsSent, 117 kStatsValueNameProtocol, 118 kStatsValueNameQpSum, 119 kStatsValueNameReceiving, 120 kStatsValueNameSelectedCandidatePairId, 121 kStatsValueNameSsrc, 122 kStatsValueNameState, 123 kStatsValueNameTotalAudioEnergy, 124 kStatsValueNameTotalSamplesDuration, 125 kStatsValueNameTotalSamplesReceived, 126 kStatsValueNameTransportId, 127 kStatsValueNameSentPingRequestsTotal, 128 kStatsValueNameSentPingRequestsBeforeFirstResponse, 129 kStatsValueNameSentPingResponses, 130 kStatsValueNameRecvPingRequests, 131 kStatsValueNameRecvPingResponses, 132 133 // Internal StatsValue names. 134 kStatsValueNameAccelerateRate, 135 kStatsValueNameActualEncBitrate, 136 kStatsValueNameAdaptationChanges, 137 kStatsValueNameAvailableReceiveBandwidth, 138 kStatsValueNameAvailableSendBandwidth, 139 kStatsValueNameAvgEncodeMs, 140 kStatsValueNameBandwidthLimitedResolution, 141 kStatsValueNameBucketDelay, 142 kStatsValueNameCaptureStartNtpTimeMs, 143 kStatsValueNameCandidateIPAddress, 144 kStatsValueNameCandidateNetworkType, 145 kStatsValueNameCandidatePortNumber, 146 kStatsValueNameCandidatePriority, 147 kStatsValueNameCandidateTransportType, 148 kStatsValueNameCandidateType, 149 kStatsValueNameChannelId, 150 kStatsValueNameCodecName, 151 kStatsValueNameComponent, 152 kStatsValueNameContentName, 153 kStatsValueNameContentType, 154 kStatsValueNameCpuLimitedResolution, 155 kStatsValueNameCurrentDelayMs, 156 kStatsValueNameDecodeMs, 157 kStatsValueNameDecodingCNG, 158 kStatsValueNameDecodingCTN, 159 kStatsValueNameDecodingCTSG, 160 kStatsValueNameDecodingMutedOutput, 161 kStatsValueNameDecodingNormal, 162 kStatsValueNameDecodingPLC, 163 kStatsValueNameDecodingPLCCNG, 164 kStatsValueNameDer, 165 kStatsValueNameDtlsCipher, 166 kStatsValueNameEchoCancellationQualityMin, 167 kStatsValueNameEchoDelayMedian, 168 kStatsValueNameEchoDelayStdDev, 169 kStatsValueNameEchoReturnLoss, 170 kStatsValueNameEchoReturnLossEnhancement, 171 kStatsValueNameEncodeUsagePercent, 172 kStatsValueNameExpandRate, 173 kStatsValueNameFingerprint, 174 kStatsValueNameFingerprintAlgorithm, 175 kStatsValueNameFirsReceived, 176 kStatsValueNameFirsSent, 177 kStatsValueNameFrameHeightInput, 178 kStatsValueNameFrameHeightReceived, 179 kStatsValueNameFrameHeightSent, 180 kStatsValueNameFrameRateDecoded, 181 kStatsValueNameFrameRateInput, 182 kStatsValueNameFrameRateOutput, 183 kStatsValueNameFrameRateReceived, 184 kStatsValueNameFrameRateSent, 185 kStatsValueNameFrameWidthInput, 186 kStatsValueNameFrameWidthReceived, 187 kStatsValueNameFrameWidthSent, 188 kStatsValueNameHasEnteredLowResolution, 189 kStatsValueNameInitiator, 190 kStatsValueNameInterframeDelayMaxMs, // Max over last 10 seconds. 191 kStatsValueNameIssuerId, 192 kStatsValueNameJitterBufferMs, 193 kStatsValueNameJitterReceived, 194 kStatsValueNameLabel, 195 kStatsValueNameLocalAddress, 196 kStatsValueNameLocalCandidateId, 197 kStatsValueNameLocalCandidateType, 198 kStatsValueNameLocalCertificateId, 199 kStatsValueNameMaxDecodeMs, 200 kStatsValueNameMinPlayoutDelayMs, 201 kStatsValueNameNacksReceived, 202 kStatsValueNameNacksSent, 203 kStatsValueNamePlisReceived, 204 kStatsValueNamePlisSent, 205 kStatsValueNamePreemptiveExpandRate, 206 kStatsValueNamePreferredJitterBufferMs, 207 kStatsValueNameRemoteAddress, 208 kStatsValueNameRemoteCandidateId, 209 kStatsValueNameRemoteCandidateType, 210 kStatsValueNameRemoteCertificateId, 211 kStatsValueNameRenderDelayMs, 212 kStatsValueNameResidualEchoLikelihood, 213 kStatsValueNameResidualEchoLikelihoodRecentMax, 214 kStatsValueNameAnaBitrateActionCounter, 215 kStatsValueNameAnaChannelActionCounter, 216 kStatsValueNameAnaDtxActionCounter, 217 kStatsValueNameAnaFecActionCounter, 218 kStatsValueNameAnaFrameLengthIncreaseCounter, 219 kStatsValueNameAnaFrameLengthDecreaseCounter, 220 kStatsValueNameAnaUplinkPacketLossFraction, 221 kStatsValueNameRetransmitBitrate, 222 kStatsValueNameRtt, 223 kStatsValueNameSecondaryDecodedRate, 224 kStatsValueNameSecondaryDiscardedRate, 225 kStatsValueNameSendPacketsDiscarded, 226 kStatsValueNameSpeechExpandRate, 227 kStatsValueNameSrtpCipher, 228 kStatsValueNameTargetDelayMs, 229 kStatsValueNameTargetEncBitrate, 230 kStatsValueNameTimingFrameInfo, // Result of |TimingFrameInfo::ToString| 231 kStatsValueNameTrackId, 232 kStatsValueNameTransmitBitrate, 233 kStatsValueNameTransportType, 234 kStatsValueNameTypingNoiseState, 235 kStatsValueNameWritable, 236 }; 237 238 class IdBase : public rtc::RefCountInterface { 239 public: 240 ~IdBase() override; 241 StatsType type() const; 242 243 // Users of IdBase will be using the Id typedef, which is compatible with 244 // this Equals() function. It simply calls the protected (and overridden) 245 // Equals() method. Equals(const rtc::scoped_refptr<IdBase> & other)246 bool Equals(const rtc::scoped_refptr<IdBase>& other) const { 247 return Equals(*other.get()); 248 } 249 250 virtual std::string ToString() const = 0; 251 252 protected: 253 // Protected since users of the IdBase type will be using the Id typedef. 254 virtual bool Equals(const IdBase& other) const; 255 256 explicit IdBase(StatsType type); // Only meant for derived classes. 257 const StatsType type_; 258 259 static const char kSeparator = '_'; 260 }; 261 262 typedef rtc::scoped_refptr<IdBase> Id; 263 264 struct Value { 265 enum Type { 266 kInt, // int. 267 kInt64, // int64_t. 268 kFloat, // float. 269 kString, // std::string 270 kStaticString, // const char*. 271 kBool, // bool. 272 kId, // Id. 273 }; 274 275 Value(StatsValueName name, int64_t value, Type int_type); 276 Value(StatsValueName name, float f); 277 Value(StatsValueName name, const std::string& value); 278 Value(StatsValueName name, const char* value); 279 Value(StatsValueName name, bool b); 280 Value(StatsValueName name, const Id& value); 281 282 ~Value(); 283 284 // Support ref counting. Note that for performance reasons, we 285 // don't use thread safe operations. Therefore, all operations 286 // affecting the ref count (in practice, creation and copying of 287 // the Values mapping) must occur on webrtc's signalling thread. AddRefValue288 int AddRef() const { 289 RTC_DCHECK_RUN_ON(&thread_checker_); 290 return ++ref_count_; 291 } ReleaseValue292 int Release() const { 293 RTC_DCHECK_RUN_ON(&thread_checker_); 294 int count = --ref_count_; 295 if (!count) 296 delete this; 297 return count; 298 } 299 300 // TODO(tommi): This compares name as well as value... 301 // I think we should only need to compare the value part and 302 // move the name part into a hash map. 303 bool Equals(const Value& other) const; 304 305 // Comparison operators. Return true iff the current instance is of the 306 // correct type and holds the same value. No conversion is performed so 307 // a string value of "123" is not equal to an int value of 123 and an int 308 // value of 123 is not equal to a float value of 123.0f. 309 // One exception to this is that types kInt and kInt64 can be compared and 310 // kString and kStaticString too. 311 bool operator==(const std::string& value) const; 312 bool operator==(const char* value) const; 313 bool operator==(int64_t value) const; 314 bool operator==(bool value) const; 315 bool operator==(float value) const; 316 bool operator==(const Id& value) const; 317 318 // Getters that allow getting the native value directly. 319 // The caller must know the type beforehand or else hit a check. 320 int int_val() const; 321 int64_t int64_val() const; 322 float float_val() const; 323 const char* static_string_val() const; 324 const std::string& string_val() const; 325 bool bool_val() const; 326 const Id& id_val() const; 327 328 // Returns the string representation of |name|. 329 const char* display_name() const; 330 331 // Converts the native value to a string representation of the value. 332 std::string ToString() const; 333 typeValue334 Type type() const { return type_; } 335 336 // TODO(tommi): Move |name| and |display_name| out of the Value struct. 337 const StatsValueName name; 338 339 private: 340 rtc::ThreadChecker thread_checker_; 341 mutable int ref_count_ RTC_ACCESS_ON(thread_checker_) = 0; 342 343 const Type type_; 344 // TODO(tommi): Use C++ 11 union and make value_ const. 345 union InternalType { 346 int int_; 347 int64_t int64_; 348 float float_; 349 bool bool_; 350 std::string* string_; 351 const char* static_string_; 352 Id* id_; 353 } value_; 354 355 RTC_DISALLOW_COPY_AND_ASSIGN(Value); 356 }; 357 358 typedef rtc::scoped_refptr<Value> ValuePtr; 359 typedef std::map<StatsValueName, ValuePtr> Values; 360 361 // Ownership of |id| is passed to |this|. 362 explicit StatsReport(const Id& id); 363 ~StatsReport(); 364 365 // Factory functions for various types of stats IDs. 366 static Id NewBandwidthEstimationId(); 367 static Id NewTypedId(StatsType type, const std::string& id); 368 static Id NewTypedIntId(StatsType type, int id); 369 static Id NewIdWithDirection( 370 StatsType type, const std::string& id, Direction direction); 371 static Id NewCandidateId(bool local, const std::string& id); 372 static Id NewComponentId( 373 const std::string& content_name, int component); 374 static Id NewCandidatePairId( 375 const std::string& content_name, int component, int index); 376 id()377 const Id& id() const { return id_; } type()378 StatsType type() const { return id_->type(); } timestamp()379 double timestamp() const { return timestamp_; } set_timestamp(double t)380 void set_timestamp(double t) { timestamp_ = t; } empty()381 bool empty() const { return values_.empty(); } values()382 const Values& values() const { return values_; } 383 384 const char* TypeToString() const; 385 386 void AddString(StatsValueName name, const std::string& value); 387 void AddString(StatsValueName name, const char* value); 388 void AddInt64(StatsValueName name, int64_t value); 389 void AddInt(StatsValueName name, int value); 390 void AddFloat(StatsValueName name, float value); 391 void AddBoolean(StatsValueName name, bool value); 392 void AddId(StatsValueName name, const Id& value); 393 394 const Value* FindValue(StatsValueName name) const; 395 396 private: 397 // The unique identifier for this object. 398 // This is used as a key for this report in ordered containers, 399 // so it must never be changed. 400 const Id id_; 401 double timestamp_; // Time since 1970-01-01T00:00:00Z in milliseconds. 402 Values values_; 403 404 RTC_DISALLOW_COPY_AND_ASSIGN(StatsReport); 405 }; 406 407 // Typedef for an array of const StatsReport pointers. 408 // Ownership of the pointers held by this implementation is assumed to lie 409 // elsewhere and lifetime guarantees are made by the implementation that uses 410 // this type. In the StatsCollector, object ownership lies with the 411 // StatsCollection class. 412 typedef std::vector<const StatsReport*> StatsReports; 413 414 // A map from the report id to the report. 415 // This class wraps an STL container and provides a limited set of 416 // functionality in order to keep things simple. 417 class StatsCollection { 418 public: 419 StatsCollection(); 420 ~StatsCollection(); 421 422 typedef std::list<StatsReport*> Container; 423 typedef Container::iterator iterator; 424 typedef Container::const_iterator const_iterator; 425 426 const_iterator begin() const; 427 const_iterator end() const; 428 size_t size() const; 429 430 // Creates a new report object with |id| that does not already 431 // exist in the list of reports. 432 StatsReport* InsertNew(const StatsReport::Id& id); 433 StatsReport* FindOrAddNew(const StatsReport::Id& id); 434 StatsReport* ReplaceOrAddNew(const StatsReport::Id& id); 435 436 // Looks for a report with the given |id|. If one is not found, null 437 // will be returned. 438 StatsReport* Find(const StatsReport::Id& id); 439 440 private: 441 Container list_; 442 rtc::ThreadChecker thread_checker_; 443 }; 444 445 } // namespace webrtc 446 447 #endif // API_STATSTYPES_H_ 448