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
30namespace webrtc {
31
32class 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:
101    SampleCounter() : sum(0), num_samples(0) {}
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:
112    BoolSampleCounter() : sum(0), num_samples(0) {}
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 {
124    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