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_STATS_TYPES_H_
15 #define API_STATS_TYPES_H_
16 
17 #include <algorithm>
18 #include <list>
19 #include <map>
20 #include <string>
21 #include <vector>
22 
23 #include "api/scoped_refptr.h"
24 #include "rtc_base/constructor_magic.h"
25 #include "rtc_base/ref_count.h"
26 #include "rtc_base/string_encode.h"
27 #include "rtc_base/system/rtc_export.h"
28 #include "rtc_base/thread_checker.h"
29 
30 namespace webrtc {
31 
32 class RTC_EXPORT 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     kStatsValueNameSentStunKeepaliveRequests,
133     kStatsValueNameRecvStunKeepaliveResponses,
134     kStatsValueNameStunKeepaliveRttTotal,
135     kStatsValueNameStunKeepaliveRttSquaredTotal,
136 
137     // Internal StatsValue names.
138     kStatsValueNameAccelerateRate,
139     kStatsValueNameActualEncBitrate,
140     kStatsValueNameAdaptationChanges,
141     kStatsValueNameAvailableReceiveBandwidth,
142     kStatsValueNameAvailableSendBandwidth,
143     kStatsValueNameAvgEncodeMs,
144     kStatsValueNameBandwidthLimitedResolution,
145     kStatsValueNameBucketDelay,
146     kStatsValueNameCaptureStartNtpTimeMs,
147     kStatsValueNameCandidateIPAddress,
148     kStatsValueNameCandidateNetworkType,
149     kStatsValueNameCandidatePortNumber,
150     kStatsValueNameCandidatePriority,
151     kStatsValueNameCandidateTransportType,
152     kStatsValueNameCandidateType,
153     kStatsValueNameChannelId,
154     kStatsValueNameCodecName,
155     kStatsValueNameComponent,
156     kStatsValueNameContentName,
157     kStatsValueNameContentType,
158     kStatsValueNameCpuLimitedResolution,
159     kStatsValueNameCurrentDelayMs,
160     kStatsValueNameDecodeMs,
161     kStatsValueNameDecodingCNG,
162     kStatsValueNameDecodingCTN,
163     kStatsValueNameDecodingCTSG,
164     kStatsValueNameDecodingMutedOutput,
165     kStatsValueNameDecodingNormal,
166     kStatsValueNameDecodingPLC,
167     kStatsValueNameDecodingCodecPLC,
168     kStatsValueNameDecodingPLCCNG,
169     kStatsValueNameDer,
170     kStatsValueNameDtlsCipher,
171     kStatsValueNameEchoDelayMedian,
172     kStatsValueNameEchoDelayStdDev,
173     kStatsValueNameEchoReturnLoss,
174     kStatsValueNameEchoReturnLossEnhancement,
175     kStatsValueNameEncodeUsagePercent,
176     kStatsValueNameExpandRate,
177     kStatsValueNameFingerprint,
178     kStatsValueNameFingerprintAlgorithm,
179     kStatsValueNameFirsReceived,
180     kStatsValueNameFirsSent,
181     kStatsValueNameFirstFrameReceivedToDecodedMs,
182     kStatsValueNameFrameHeightInput,
183     kStatsValueNameFrameHeightReceived,
184     kStatsValueNameFrameHeightSent,
185     kStatsValueNameFrameRateDecoded,
186     kStatsValueNameFrameRateInput,
187     kStatsValueNameFrameRateOutput,
188     kStatsValueNameFrameRateReceived,
189     kStatsValueNameFrameRateSent,
190     kStatsValueNameFrameWidthInput,
191     kStatsValueNameFrameWidthReceived,
192     kStatsValueNameFrameWidthSent,
193     kStatsValueNameHasEnteredLowResolution,
194     kStatsValueNameHugeFramesSent,
195     kStatsValueNameInitiator,
196     kStatsValueNameInterframeDelayMaxMs,  // Max over last 10 seconds.
197     kStatsValueNameIssuerId,
198     kStatsValueNameJitterBufferMs,
199     kStatsValueNameJitterReceived,
200     kStatsValueNameLabel,
201     kStatsValueNameLocalAddress,
202     kStatsValueNameLocalCandidateId,
203     kStatsValueNameLocalCandidateType,
204     kStatsValueNameLocalCertificateId,
205     kStatsValueNameMaxDecodeMs,
206     kStatsValueNameMinPlayoutDelayMs,
207     kStatsValueNameNacksReceived,
208     kStatsValueNameNacksSent,
209     kStatsValueNamePlisReceived,
210     kStatsValueNamePlisSent,
211     kStatsValueNamePreemptiveExpandRate,
212     kStatsValueNamePreferredJitterBufferMs,
213     kStatsValueNameRemoteAddress,
214     kStatsValueNameRemoteCandidateId,
215     kStatsValueNameRemoteCandidateType,
216     kStatsValueNameRemoteCertificateId,
217     kStatsValueNameRenderDelayMs,
218     kStatsValueNameResidualEchoLikelihood,
219     kStatsValueNameResidualEchoLikelihoodRecentMax,
220     kStatsValueNameAnaBitrateActionCounter,
221     kStatsValueNameAnaChannelActionCounter,
222     kStatsValueNameAnaDtxActionCounter,
223     kStatsValueNameAnaFecActionCounter,
224     kStatsValueNameAnaFrameLengthIncreaseCounter,
225     kStatsValueNameAnaFrameLengthDecreaseCounter,
226     kStatsValueNameAnaUplinkPacketLossFraction,
227     kStatsValueNameRetransmitBitrate,
228     kStatsValueNameRtt,
229     kStatsValueNameSecondaryDecodedRate,
230     kStatsValueNameSecondaryDiscardedRate,
231     kStatsValueNameSendPacketsDiscarded,
232     kStatsValueNameSpeechExpandRate,
233     kStatsValueNameSrtpCipher,
234     kStatsValueNameTargetDelayMs,
235     kStatsValueNameTargetEncBitrate,
236     kStatsValueNameTimingFrameInfo,  // Result of |TimingFrameInfo::ToString|
237     kStatsValueNameTrackId,
238     kStatsValueNameTransmitBitrate,
239     kStatsValueNameTransportType,
240     kStatsValueNameTypingNoiseState,
241     kStatsValueNameWritable,
242     kStatsValueNameAudioDeviceUnderrunCounter,
243   };
244 
245   class RTC_EXPORT IdBase : public rtc::RefCountInterface {
246    public:
247     ~IdBase() override;
248     StatsType type() const;
249 
250     // Users of IdBase will be using the Id typedef, which is compatible with
251     // this Equals() function.  It simply calls the protected (and overridden)
252     // Equals() method.
Equals(const rtc::scoped_refptr<IdBase> & other)253     bool Equals(const rtc::scoped_refptr<IdBase>& other) const {
254       return Equals(*other.get());
255     }
256 
257     virtual std::string ToString() const = 0;
258 
259    protected:
260     // Protected since users of the IdBase type will be using the Id typedef.
261     virtual bool Equals(const IdBase& other) const;
262 
263     explicit IdBase(StatsType type);  // Only meant for derived classes.
264     const StatsType type_;
265 
266     static const char kSeparator = '_';
267   };
268 
269   typedef rtc::scoped_refptr<IdBase> Id;
270 
271   struct RTC_EXPORT Value {
272     enum Type {
273       kInt,           // int.
274       kInt64,         // int64_t.
275       kFloat,         // float.
276       kString,        // std::string
277       kStaticString,  // const char*.
278       kBool,          // bool.
279       kId,            // Id.
280     };
281 
282     Value(StatsValueName name, int64_t value, Type int_type);
283     Value(StatsValueName name, float f);
284     Value(StatsValueName name, const std::string& value);
285     Value(StatsValueName name, const char* value);
286     Value(StatsValueName name, bool b);
287     Value(StatsValueName name, const Id& value);
288 
289     ~Value();
290 
291     // Support ref counting. Note that for performance reasons, we
292     // don't use thread safe operations. Therefore, all operations
293     // affecting the ref count (in practice, creation and copying of
294     // the Values mapping) must occur on webrtc's signalling thread.
AddRefValue295     int AddRef() const {
296       RTC_DCHECK_RUN_ON(&thread_checker_);
297       return ++ref_count_;
298     }
ReleaseValue299     int Release() const {
300       RTC_DCHECK_RUN_ON(&thread_checker_);
301       int count = --ref_count_;
302       if (!count)
303         delete this;
304       return count;
305     }
306 
307     // TODO(tommi): This compares name as well as value...
308     // I think we should only need to compare the value part and
309     // move the name part into a hash map.
310     bool Equals(const Value& other) const;
311 
312     // Comparison operators. Return true iff the current instance is of the
313     // correct type and holds the same value.  No conversion is performed so
314     // a string value of "123" is not equal to an int value of 123 and an int
315     // value of 123 is not equal to a float value of 123.0f.
316     // One exception to this is that types kInt and kInt64 can be compared and
317     // kString and kStaticString too.
318     bool operator==(const std::string& value) const;
319     bool operator==(const char* value) const;
320     bool operator==(int64_t value) const;
321     bool operator==(bool value) const;
322     bool operator==(float value) const;
323     bool operator==(const Id& value) const;
324 
325     // Getters that allow getting the native value directly.
326     // The caller must know the type beforehand or else hit a check.
327     int int_val() const;
328     int64_t int64_val() const;
329     float float_val() const;
330     const char* static_string_val() const;
331     const std::string& string_val() const;
332     bool bool_val() const;
333     const Id& id_val() const;
334 
335     // Returns the string representation of |name|.
336     const char* display_name() const;
337 
338     // Converts the native value to a string representation of the value.
339     std::string ToString() const;
340 
typeValue341     Type type() const { return type_; }
342 
343     // TODO(tommi): Move |name| and |display_name| out of the Value struct.
344     const StatsValueName name;
345 
346    private:
347     rtc::ThreadChecker thread_checker_;
348     mutable int ref_count_ RTC_GUARDED_BY(thread_checker_) = 0;
349 
350     const Type type_;
351     // TODO(tommi): Use C++ 11 union and make value_ const.
352     union InternalType {
353       int int_;
354       int64_t int64_;
355       float float_;
356       bool bool_;
357       std::string* string_;
358       const char* static_string_;
359       Id* id_;
360     } value_;
361 
362     RTC_DISALLOW_COPY_AND_ASSIGN(Value);
363   };
364 
365   typedef rtc::scoped_refptr<Value> ValuePtr;
366   typedef std::map<StatsValueName, ValuePtr> Values;
367 
368   // Ownership of |id| is passed to |this|.
369   explicit StatsReport(const Id& id);
370   ~StatsReport();
371 
372   // Factory functions for various types of stats IDs.
373   static Id NewBandwidthEstimationId();
374   static Id NewTypedId(StatsType type, const std::string& id);
375   static Id NewTypedIntId(StatsType type, int id);
376   static Id NewIdWithDirection(StatsType type,
377                                const std::string& id,
378                                Direction direction);
379   static Id NewCandidateId(bool local, const std::string& id);
380   static Id NewComponentId(const std::string& content_name, int component);
381   static Id NewCandidatePairId(const std::string& content_name,
382                                int component,
383                                int index);
384 
id()385   const Id& id() const { return id_; }
type()386   StatsType type() const { return id_->type(); }
timestamp()387   double timestamp() const { return timestamp_; }
set_timestamp(double t)388   void set_timestamp(double t) { timestamp_ = t; }
empty()389   bool empty() const { return values_.empty(); }
values()390   const Values& values() const { return values_; }
391 
392   const char* TypeToString() const;
393 
394   void AddString(StatsValueName name, const std::string& value);
395   void AddString(StatsValueName name, const char* value);
396   void AddInt64(StatsValueName name, int64_t value);
397   void AddInt(StatsValueName name, int value);
398   void AddFloat(StatsValueName name, float value);
399   void AddBoolean(StatsValueName name, bool value);
400   void AddId(StatsValueName name, const Id& value);
401 
402   const Value* FindValue(StatsValueName name) const;
403 
404  private:
405   // The unique identifier for this object.
406   // This is used as a key for this report in ordered containers,
407   // so it must never be changed.
408   const Id id_;
409   double timestamp_;  // Time since 1970-01-01T00:00:00Z in milliseconds.
410   Values values_;
411 
412   RTC_DISALLOW_COPY_AND_ASSIGN(StatsReport);
413 };
414 
415 // Typedef for an array of const StatsReport pointers.
416 // Ownership of the pointers held by this implementation is assumed to lie
417 // elsewhere and lifetime guarantees are made by the implementation that uses
418 // this type.  In the StatsCollector, object ownership lies with the
419 // StatsCollection class.
420 typedef std::vector<const StatsReport*> StatsReports;
421 
422 // A map from the report id to the report.
423 // This class wraps an STL container and provides a limited set of
424 // functionality in order to keep things simple.
425 class StatsCollection {
426  public:
427   StatsCollection();
428   ~StatsCollection();
429 
430   typedef std::list<StatsReport*> Container;
431   typedef Container::iterator iterator;
432   typedef Container::const_iterator const_iterator;
433 
434   const_iterator begin() const;
435   const_iterator end() const;
436   size_t size() const;
437 
438   // Creates a new report object with |id| that does not already
439   // exist in the list of reports.
440   StatsReport* InsertNew(const StatsReport::Id& id);
441   StatsReport* FindOrAddNew(const StatsReport::Id& id);
442   StatsReport* ReplaceOrAddNew(const StatsReport::Id& id);
443 
444   // Looks for a report with the given |id|.  If one is not found, null
445   // will be returned.
446   StatsReport* Find(const StatsReport::Id& id);
447 
448  private:
449   Container list_;
450   rtc::ThreadChecker thread_checker_;
451 };
452 
453 }  // namespace webrtc
454 
455 #endif  // API_STATS_TYPES_H_
456