1 /*
2  *  Copyright (c) 2013 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 #ifndef WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
12 #define WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
13 
14 #include <map>
15 #include <string>
16 
17 #include "webrtc/base/criticalsection.h"
18 #include "webrtc/base/exp_filter.h"
19 #include "webrtc/base/ratetracker.h"
20 #include "webrtc/base/scoped_ptr.h"
21 #include "webrtc/base/thread_annotations.h"
22 #include "webrtc/common_types.h"
23 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
24 #include "webrtc/modules/video_coding/include/video_coding_defines.h"
25 #include "webrtc/system_wrappers/include/clock.h"
26 #include "webrtc/video/overuse_frame_detector.h"
27 #include "webrtc/video/vie_encoder.h"
28 #include "webrtc/video_send_stream.h"
29 
30 namespace webrtc {
31 
32 class SendStatisticsProxy : public CpuOveruseMetricsObserver,
33                             public RtcpStatisticsCallback,
34                             public RtcpPacketTypeCounterObserver,
35                             public StreamDataCountersCallback,
36                             public BitrateStatisticsObserver,
37                             public FrameCountObserver,
38                             public VideoEncoderRateObserver,
39                             public SendSideDelayObserver {
40  public:
41   static const int kStatsTimeoutMs;
42 
43   SendStatisticsProxy(Clock* clock,
44                       const VideoSendStream::Config& config,
45                       VideoEncoderConfig::ContentType content_type);
46   virtual ~SendStatisticsProxy();
47 
48   VideoSendStream::Stats GetStats();
49 
50   virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
51                                   const RTPVideoHeader* rtp_video_header);
52   // Used to update incoming frame rate.
53   void OnIncomingFrame(int width, int height);
54 
55   // Used to update encode time of frames.
56   void OnEncodedFrame(int encode_time_ms);
57 
58   // From VideoEncoderRateObserver.
59   void OnSetRates(uint32_t bitrate_bps, int framerate) override;
60 
61   void OnEncoderImplementationName(const char* implementation_name);
62   void OnOutgoingRate(uint32_t framerate, uint32_t bitrate);
63   void OnSuspendChange(bool is_suspended);
64   void OnInactiveSsrc(uint32_t ssrc);
65 
66   // Used to indicate change in content type, which may require a change in
67   // how stats are collected.
68   void SetContentType(VideoEncoderConfig::ContentType content_type);
69 
70  protected:
71   // From CpuOveruseMetricsObserver.
72   void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) override;
73   // From RtcpStatisticsCallback.
74   void StatisticsUpdated(const RtcpStatistics& statistics,
75                          uint32_t ssrc) override;
76   void CNameChanged(const char* cname, uint32_t ssrc) override;
77   // From RtcpPacketTypeCounterObserver.
78   void RtcpPacketTypesCounterUpdated(
79       uint32_t ssrc,
80       const RtcpPacketTypeCounter& packet_counter) override;
81   // From StreamDataCountersCallback.
82   void DataCountersUpdated(const StreamDataCounters& counters,
83                            uint32_t ssrc) override;
84 
85   // From BitrateStatisticsObserver.
86   void Notify(const BitrateStatistics& total_stats,
87               const BitrateStatistics& retransmit_stats,
88               uint32_t ssrc) override;
89 
90   // From FrameCountObserver.
91   void FrameCountUpdated(const FrameCounts& frame_counts,
92                          uint32_t ssrc) override;
93 
94   void SendSideDelayUpdated(int avg_delay_ms,
95                             int max_delay_ms,
96                             uint32_t ssrc) override;
97 
98  private:
99   class SampleCounter {
100    public:
SampleCounter()101     SampleCounter() : sum(0), num_samples(0) {}
~SampleCounter()102     ~SampleCounter() {}
103     void Add(int sample);
104     int Avg(int min_required_samples) const;
105 
106    private:
107     int sum;
108     int num_samples;
109   };
110   class BoolSampleCounter {
111    public:
BoolSampleCounter()112     BoolSampleCounter() : sum(0), num_samples(0) {}
~BoolSampleCounter()113     ~BoolSampleCounter() {}
114     void Add(bool sample);
115     int Percent(int min_required_samples) const;
116     int Permille(int min_required_samples) const;
117 
118    private:
119     int Fraction(int min_required_samples, float multiplier) const;
120     int sum;
121     int num_samples;
122   };
123   struct StatsUpdateTimes {
StatsUpdateTimesStatsUpdateTimes124     StatsUpdateTimes() : resolution_update_ms(0), bitrate_update_ms(0) {}
125     int64_t resolution_update_ms;
126     int64_t bitrate_update_ms;
127   };
128   void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
129   VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
130       EXCLUSIVE_LOCKS_REQUIRED(crit_);
131 
132   Clock* const clock_;
133   const VideoSendStream::Config config_;
134   mutable rtc::CriticalSection crit_;
135   VideoEncoderConfig::ContentType content_type_ GUARDED_BY(crit_);
136   VideoSendStream::Stats stats_ GUARDED_BY(crit_);
137   uint32_t last_sent_frame_timestamp_ GUARDED_BY(crit_);
138   std::map<uint32_t, StatsUpdateTimes> update_times_ GUARDED_BY(crit_);
139   rtc::ExpFilter encode_time_ GUARDED_BY(crit_);
140 
141   // Contains stats used for UMA histograms. These stats will be reset if
142   // content type changes between real-time video and screenshare, since these
143   // will be reported separately.
144   struct UmaSamplesContainer {
145     explicit UmaSamplesContainer(const char* prefix);
146     ~UmaSamplesContainer();
147 
148     void UpdateHistograms();
149 
150     const std::string uma_prefix_;
151     int max_sent_width_per_timestamp_;
152     int max_sent_height_per_timestamp_;
153     SampleCounter input_width_counter_;
154     SampleCounter input_height_counter_;
155     SampleCounter sent_width_counter_;
156     SampleCounter sent_height_counter_;
157     SampleCounter encode_time_counter_;
158     BoolSampleCounter key_frame_counter_;
159     BoolSampleCounter quality_limited_frame_counter_;
160     SampleCounter quality_downscales_counter_;
161     BoolSampleCounter bw_limited_frame_counter_;
162     SampleCounter bw_resolutions_disabled_counter_;
163     SampleCounter delay_counter_;
164     SampleCounter max_delay_counter_;
165     rtc::RateTracker input_frame_rate_tracker_;
166     rtc::RateTracker sent_frame_rate_tracker_;
167   };
168 
169   rtc::scoped_ptr<UmaSamplesContainer> uma_container_ GUARDED_BY(crit_);
170 };
171 
172 }  // namespace webrtc
173 #endif  // WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
174