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