1 /* 2 * libjingle 3 * Copyright 2012 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 // This file contains structures used for retrieving statistics from an ongoing 29 // libjingle session. 30 31 #ifndef TALK_APP_WEBRTC_STATSTYPES_H_ 32 #define TALK_APP_WEBRTC_STATSTYPES_H_ 33 34 #include <algorithm> 35 #include <list> 36 #include <map> 37 #include <string> 38 39 #include "webrtc/base/basictypes.h" 40 #include "webrtc/base/common.h" 41 #include "webrtc/base/refcount.h" 42 #include "webrtc/base/scoped_ptr.h" 43 #include "webrtc/base/linked_ptr.h" 44 #include "webrtc/base/scoped_ref_ptr.h" 45 #include "webrtc/base/stringencode.h" 46 #include "webrtc/base/thread_checker.h" 47 48 namespace webrtc { 49 50 class StatsReport { 51 public: 52 // Indicates whether a track is for sending or receiving. 53 // Used in reports for audio/video tracks. 54 enum Direction { 55 kSend = 0, 56 kReceive, 57 }; 58 59 enum StatsType { 60 // StatsReport types. 61 // A StatsReport of |type| = "googSession" contains overall information 62 // about the thing libjingle calls a session (which may contain one 63 // or more RTP sessions. 64 kStatsReportTypeSession, 65 66 // A StatsReport of |type| = "googTransport" contains information 67 // about a libjingle "transport". 68 kStatsReportTypeTransport, 69 70 // A StatsReport of |type| = "googComponent" contains information 71 // about a libjingle "channel" (typically, RTP or RTCP for a transport). 72 // This is intended to be the same thing as an ICE "Component". 73 kStatsReportTypeComponent, 74 75 // A StatsReport of |type| = "googCandidatePair" contains information 76 // about a libjingle "connection" - a single source/destination port pair. 77 // This is intended to be the same thing as an ICE "candidate pair". 78 kStatsReportTypeCandidatePair, 79 80 // A StatsReport of |type| = "VideoBWE" is statistics for video Bandwidth 81 // Estimation, which is global per-session. The |id| field is "bweforvideo" 82 // (will probably change in the future). 83 kStatsReportTypeBwe, 84 85 // A StatsReport of |type| = "ssrc" is statistics for a specific rtp stream. 86 // The |id| field is the SSRC in decimal form of the rtp stream. 87 kStatsReportTypeSsrc, 88 89 // A StatsReport of |type| = "remoteSsrc" is statistics for a specific 90 // rtp stream, generated by the remote end of the connection. 91 kStatsReportTypeRemoteSsrc, 92 93 // A StatsReport of |type| = "googTrack" is statistics for a specific media 94 // track. The |id| field is the track id. 95 kStatsReportTypeTrack, 96 97 // A StatsReport of |type| = "localcandidate" or "remotecandidate" is 98 // attributes on a specific ICE Candidate. It links to its connection pair 99 // by candidate id. The string value is taken from 100 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*. 101 kStatsReportTypeIceLocalCandidate, 102 kStatsReportTypeIceRemoteCandidate, 103 104 // A StatsReport of |type| = "googCertificate" contains an SSL certificate 105 // transmitted by one of the endpoints of this connection. The |id| is 106 // controlled by the fingerprint, and is used to identify the certificate in 107 // the Channel stats (as "googLocalCertificateId" or 108 // "googRemoteCertificateId") and in any child certificates (as 109 // "googIssuerId"). 110 kStatsReportTypeCertificate, 111 112 // A StatsReport of |type| = "datachannel" with statistics for a 113 // particular DataChannel. 114 kStatsReportTypeDataChannel, 115 }; 116 117 enum StatsValueName { 118 kStatsValueNameActiveConnection, 119 kStatsValueNameAudioInputLevel, 120 kStatsValueNameAudioOutputLevel, 121 kStatsValueNameBytesReceived, 122 kStatsValueNameBytesSent, 123 kStatsValueNameCodecImplementationName, 124 kStatsValueNameDataChannelId, 125 kStatsValueNamePacketsLost, 126 kStatsValueNamePacketsReceived, 127 kStatsValueNamePacketsSent, 128 kStatsValueNameProtocol, 129 kStatsValueNameReceiving, 130 kStatsValueNameSelectedCandidatePairId, 131 kStatsValueNameSsrc, 132 kStatsValueNameState, 133 kStatsValueNameTransportId, 134 135 // Internal StatsValue names. 136 kStatsValueNameAccelerateRate, 137 kStatsValueNameActualEncBitrate, 138 kStatsValueNameAdaptationChanges, 139 kStatsValueNameAvailableReceiveBandwidth, 140 kStatsValueNameAvailableSendBandwidth, 141 kStatsValueNameAvgEncodeMs, 142 kStatsValueNameBandwidthLimitedResolution, 143 kStatsValueNameBucketDelay, 144 kStatsValueNameCaptureStartNtpTimeMs, 145 kStatsValueNameCandidateIPAddress, 146 kStatsValueNameCandidateNetworkType, 147 kStatsValueNameCandidatePortNumber, 148 kStatsValueNameCandidatePriority, 149 kStatsValueNameCandidateTransportType, 150 kStatsValueNameCandidateType, 151 kStatsValueNameChannelId, 152 kStatsValueNameCodecName, 153 kStatsValueNameComponent, 154 kStatsValueNameContentName, 155 kStatsValueNameCpuLimitedResolution, 156 kStatsValueNameCurrentDelayMs, 157 kStatsValueNameDecodeMs, 158 kStatsValueNameDecodingCNG, 159 kStatsValueNameDecodingCTN, 160 kStatsValueNameDecodingCTSG, 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 kStatsValueNameInitiator, 189 kStatsValueNameIssuerId, 190 kStatsValueNameJitterBufferMs, 191 kStatsValueNameJitterReceived, 192 kStatsValueNameLabel, 193 kStatsValueNameLocalAddress, 194 kStatsValueNameLocalCandidateId, 195 kStatsValueNameLocalCandidateType, 196 kStatsValueNameLocalCertificateId, 197 kStatsValueNameMaxDecodeMs, 198 kStatsValueNameMinPlayoutDelayMs, 199 kStatsValueNameNacksReceived, 200 kStatsValueNameNacksSent, 201 kStatsValueNamePlisReceived, 202 kStatsValueNamePlisSent, 203 kStatsValueNamePreemptiveExpandRate, 204 kStatsValueNamePreferredJitterBufferMs, 205 kStatsValueNameRemoteAddress, 206 kStatsValueNameRemoteCandidateId, 207 kStatsValueNameRemoteCandidateType, 208 kStatsValueNameRemoteCertificateId, 209 kStatsValueNameRenderDelayMs, 210 kStatsValueNameRetransmitBitrate, 211 kStatsValueNameRtt, 212 kStatsValueNameSecondaryDecodedRate, 213 kStatsValueNameSendPacketsDiscarded, 214 kStatsValueNameSpeechExpandRate, 215 kStatsValueNameSrtpCipher, 216 kStatsValueNameTargetDelayMs, 217 kStatsValueNameTargetEncBitrate, 218 kStatsValueNameTrackId, 219 kStatsValueNameTransmitBitrate, 220 kStatsValueNameTransportType, 221 kStatsValueNameTypingNoiseState, 222 kStatsValueNameViewLimitedResolution, 223 kStatsValueNameWritable, 224 }; 225 226 class IdBase : public rtc::RefCountInterface { 227 public: 228 ~IdBase() override; 229 StatsType type() const; 230 231 // Users of IdBase will be using the Id typedef, which is compatible with 232 // this Equals() function. It simply calls the protected (and overridden) 233 // Equals() method. 234 bool Equals(const rtc::scoped_refptr<IdBase>& other) const { 235 return Equals(*other.get()); 236 } 237 238 virtual std::string ToString() const = 0; 239 240 protected: 241 // Protected since users of the IdBase type will be using the Id typedef. 242 virtual bool Equals(const IdBase& other) const; 243 244 IdBase(StatsType type); // Only meant for derived classes. 245 const StatsType type_; 246 247 static const char kSeparator = '_'; 248 }; 249 250 typedef rtc::scoped_refptr<IdBase> Id; 251 252 struct Value { 253 enum Type { 254 kInt, // int. 255 kInt64, // int64_t. 256 kFloat, // float. 257 kString, // std::string 258 kStaticString, // const char*. 259 kBool, // bool. 260 kId, // Id. 261 }; 262 263 Value(StatsValueName name, int64_t value, Type int_type); 264 Value(StatsValueName name, float f); 265 Value(StatsValueName name, const std::string& value); 266 Value(StatsValueName name, const char* value); 267 Value(StatsValueName name, bool b); 268 Value(StatsValueName name, const Id& value); 269 270 ~Value(); 271 272 // TODO(tommi): This compares name as well as value... 273 // I think we should only need to compare the value part and 274 // move the name part into a hash map. 275 bool Equals(const Value& other) const; 276 277 // Comparison operators. Return true iff the current instance is of the 278 // correct type and holds the same value. No conversion is performed so 279 // a string value of "123" is not equal to an int value of 123 and an int 280 // value of 123 is not equal to a float value of 123.0f. 281 // One exception to this is that types kInt and kInt64 can be compared and 282 // kString and kStaticString too. 283 bool operator==(const std::string& value) const; 284 bool operator==(const char* value) const; 285 bool operator==(int64_t value) const; 286 bool operator==(bool value) const; 287 bool operator==(float value) const; 288 bool operator==(const Id& value) const; 289 290 // Getters that allow getting the native value directly. 291 // The caller must know the type beforehand or else hit a check. 292 int int_val() const; 293 int64_t int64_val() const; 294 float float_val() const; 295 const char* static_string_val() const; 296 const std::string& string_val() const; 297 bool bool_val() const; 298 const Id& id_val() const; 299 300 // Returns the string representation of |name|. 301 const char* display_name() const; 302 303 // Converts the native value to a string representation of the value. 304 std::string ToString() const; 305 306 Type type() const { return type_; } 307 308 // TODO(tommi): Move |name| and |display_name| out of the Value struct. 309 const StatsValueName name; 310 311 private: 312 const Type type_; 313 // TODO(tommi): Use C++ 11 union and make value_ const. 314 union InternalType { 315 int int_; 316 int64_t int64_; 317 float float_; 318 bool bool_; 319 std::string* string_; 320 const char* static_string_; 321 Id* id_; 322 } value_; 323 324 private: 325 RTC_DISALLOW_COPY_AND_ASSIGN(Value); 326 }; 327 328 // TODO(tommi): Consider using a similar approach to how we store Ids using 329 // scoped_refptr for values. 330 typedef rtc::linked_ptr<Value> ValuePtr; 331 typedef std::map<StatsValueName, ValuePtr> Values; 332 333 // Ownership of |id| is passed to |this|. 334 explicit StatsReport(const Id& id); 335 336 // Factory functions for various types of stats IDs. 337 static Id NewBandwidthEstimationId(); 338 static Id NewTypedId(StatsType type, const std::string& id); 339 static Id NewTypedIntId(StatsType type, int id); 340 static Id NewIdWithDirection( 341 StatsType type, const std::string& id, Direction direction); 342 static Id NewCandidateId(bool local, const std::string& id); 343 static Id NewComponentId( 344 const std::string& content_name, int component); 345 static Id NewCandidatePairId( 346 const std::string& content_name, int component, int index); 347 348 const Id& id() const { return id_; } 349 StatsType type() const { return id_->type(); } 350 double timestamp() const { return timestamp_; } 351 void set_timestamp(double t) { timestamp_ = t; } 352 bool empty() const { return values_.empty(); } 353 const Values& values() const { return values_; } 354 355 const char* TypeToString() const; 356 357 void AddString(StatsValueName name, const std::string& value); 358 void AddString(StatsValueName name, const char* value); 359 void AddInt64(StatsValueName name, int64_t value); 360 void AddInt(StatsValueName name, int value); 361 void AddFloat(StatsValueName name, float value); 362 void AddBoolean(StatsValueName name, bool value); 363 void AddId(StatsValueName name, const Id& value); 364 365 const Value* FindValue(StatsValueName name) const; 366 367 private: 368 // The unique identifier for this object. 369 // This is used as a key for this report in ordered containers, 370 // so it must never be changed. 371 const Id id_; 372 double timestamp_; // Time since 1970-01-01T00:00:00Z in milliseconds. 373 Values values_; 374 375 RTC_DISALLOW_COPY_AND_ASSIGN(StatsReport); 376 }; 377 378 // Typedef for an array of const StatsReport pointers. 379 // Ownership of the pointers held by this implementation is assumed to lie 380 // elsewhere and lifetime guarantees are made by the implementation that uses 381 // this type. In the StatsCollector, object ownership lies with the 382 // StatsCollection class. 383 typedef std::vector<const StatsReport*> StatsReports; 384 385 // A map from the report id to the report. 386 // This class wraps an STL container and provides a limited set of 387 // functionality in order to keep things simple. 388 class StatsCollection { 389 public: 390 StatsCollection(); 391 ~StatsCollection(); 392 393 typedef std::list<StatsReport*> Container; 394 typedef Container::iterator iterator; 395 typedef Container::const_iterator const_iterator; 396 397 const_iterator begin() const; 398 const_iterator end() const; 399 size_t size() const; 400 401 // Creates a new report object with |id| that does not already 402 // exist in the list of reports. 403 StatsReport* InsertNew(const StatsReport::Id& id); 404 StatsReport* FindOrAddNew(const StatsReport::Id& id); 405 StatsReport* ReplaceOrAddNew(const StatsReport::Id& id); 406 407 // Looks for a report with the given |id|. If one is not found, NULL 408 // will be returned. 409 StatsReport* Find(const StatsReport::Id& id); 410 411 private: 412 Container list_; 413 rtc::ThreadChecker thread_checker_; 414 }; 415 416 } // namespace webrtc 417 418 #endif // TALK_APP_WEBRTC_STATSTYPES_H_ 419