1ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org/*
2ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org *
4ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org *  Use of this source code is governed by a BSD-style license
5ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org *  that can be found in the LICENSE file in the root of the source
6ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org *  tree. An additional intellectual property rights grant can be found
7ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org *  in the file PATENTS.  All contributing project authors may
8ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org */
10ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
11ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org#ifndef WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
12ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org#define WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
13ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
14d1590b2571c4cb33416e14c92e4f2dfed42ec3d4mflodman#include <map>
15ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org#include <string>
16ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
17f2f828374c3ee1e1834c72bb27eaae88ef67bb40Peter Boström#include "webrtc/base/criticalsection.h"
181aa420b6aa70bd97cbe33e396e5dc0346aeb6415asapersson#include "webrtc/base/exp_filter.h"
19af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org#include "webrtc/base/ratetracker.h"
2000b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h"
2138344ed2806c8fed60d67d280ca44c32e36707c0pbos@webrtc.org#include "webrtc/base/thread_annotations.h"
22ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org#include "webrtc/common_types.h"
232557b86e7648ffebc5781df9f093ca5a84efc219Henrik Kjellander#include "webrtc/modules/video_coding/include/video_codec_interface.h"
242557b86e7648ffebc5781df9f093ca5a84efc219Henrik Kjellander#include "webrtc/modules/video_coding/include/video_coding_defines.h"
2598f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/clock.h"
267623ce4aeb9130c937ba5836490cbb3a35679e79Peter Boström#include "webrtc/video/overuse_frame_detector.h"
277623ce4aeb9130c937ba5836490cbb3a35679e79Peter Boström#include "webrtc/video/vie_encoder.h"
28ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org#include "webrtc/video_send_stream.h"
29ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
30ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.orgnamespace webrtc {
31ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
323e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.orgclass SendStatisticsProxy : public CpuOveruseMetricsObserver,
333e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org                            public RtcpStatisticsCallback,
341d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org                            public RtcpPacketTypeCounterObserver,
35ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org                            public StreamDataCountersCallback,
36ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org                            public BitrateStatisticsObserver,
37ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org                            public FrameCountObserver,
38891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org                            public VideoEncoderRateObserver,
39168f23faa5b8a49d4dd709c6649e77d5fecf36bfstefan@webrtc.org                            public SendSideDelayObserver {
40ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org public:
41273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  static const int kStatsTimeoutMs;
42273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org
43b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  SendStatisticsProxy(Clock* clock,
44b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang                      const VideoSendStream::Config& config,
45b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang                      VideoEncoderConfig::ContentType content_type);
46ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org  virtual ~SendStatisticsProxy();
47ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
48273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  VideoSendStream::Stats GetStats();
49273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org
50273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
51273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org                                  const RTPVideoHeader* rtp_video_header);
52af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org  // Used to update incoming frame rate.
53d89920b74a173b7bf80c6760908a382c095a66ccasapersson  void OnIncomingFrame(int width, int height);
54ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
556718e97e730dfeb0c4290128b5682e123dd75866asapersson  // Used to update encode time of frames.
566718e97e730dfeb0c4290128b5682e123dd75866asapersson  void OnEncodedFrame(int encode_time_ms);
576718e97e730dfeb0c4290128b5682e123dd75866asapersson
58891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org  // From VideoEncoderRateObserver.
59891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org  void OnSetRates(uint32_t bitrate_bps, int framerate) override;
60891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org
61b7d9a97ce41022e984348efb5f28bf6dd6c6b779Peter Boström  void OnEncoderImplementationName(const char* implementation_name);
627083e119e8f39d2ec9e504461c1bb6e0bc6be5ffPeter Boström  void OnOutgoingRate(uint32_t framerate, uint32_t bitrate);
637083e119e8f39d2ec9e504461c1bb6e0bc6be5ffPeter Boström  void OnSuspendChange(bool is_suspended);
6420f3f942a05a4b37d39891ff28be67d984c345f7Peter Boström  void OnInactiveSsrc(uint32_t ssrc);
6520f3f942a05a4b37d39891ff28be67d984c345f7Peter Boström
66b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  // Used to indicate change in content type, which may require a change in
67b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  // how stats are collected.
68b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  void SetContentType(VideoEncoderConfig::ContentType content_type);
69b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang
70ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org protected:
713e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org  // From CpuOveruseMetricsObserver.
7214665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) override;
73ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org  // From RtcpStatisticsCallback.
7414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void StatisticsUpdated(const RtcpStatistics& statistics,
7514665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org                         uint32_t ssrc) override;
7614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void CNameChanged(const char* cname, uint32_t ssrc) override;
77d89920b74a173b7bf80c6760908a382c095a66ccasapersson  // From RtcpPacketTypeCounterObserver.
7814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void RtcpPacketTypesCounterUpdated(
791d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org      uint32_t ssrc,
8014665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org      const RtcpPacketTypeCounter& packet_counter) override;
81ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org  // From StreamDataCountersCallback.
8214665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void DataCountersUpdated(const StreamDataCounters& counters,
8314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org                           uint32_t ssrc) override;
84ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
85ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org  // From BitrateStatisticsObserver.
8614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void Notify(const BitrateStatistics& total_stats,
8714665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org              const BitrateStatistics& retransmit_stats,
8814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org              uint32_t ssrc) override;
89ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
90ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org  // From FrameCountObserver.
9114665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void FrameCountUpdated(const FrameCounts& frame_counts,
9214665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org                         uint32_t ssrc) override;
93ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
9414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void SendSideDelayUpdated(int avg_delay_ms,
9514665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org                            int max_delay_ms,
9614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org                            uint32_t ssrc) override;
97168f23faa5b8a49d4dd709c6649e77d5fecf36bfstefan@webrtc.org
98ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org private:
99da535c405597864b8396b2029dec70ab9fb76e8basapersson  class SampleCounter {
100da535c405597864b8396b2029dec70ab9fb76e8basapersson   public:
101d89920b74a173b7bf80c6760908a382c095a66ccasapersson    SampleCounter() : sum(0), num_samples(0) {}
102da535c405597864b8396b2029dec70ab9fb76e8basapersson    ~SampleCounter() {}
103d89920b74a173b7bf80c6760908a382c095a66ccasapersson    void Add(int sample);
104d89920b74a173b7bf80c6760908a382c095a66ccasapersson    int Avg(int min_required_samples) const;
105d89920b74a173b7bf80c6760908a382c095a66ccasapersson
106d89920b74a173b7bf80c6760908a382c095a66ccasapersson   private:
107d89920b74a173b7bf80c6760908a382c095a66ccasapersson    int sum;
108d89920b74a173b7bf80c6760908a382c095a66ccasapersson    int num_samples;
109d89920b74a173b7bf80c6760908a382c095a66ccasapersson  };
110da535c405597864b8396b2029dec70ab9fb76e8basapersson  class BoolSampleCounter {
111da535c405597864b8396b2029dec70ab9fb76e8basapersson   public:
112dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson    BoolSampleCounter() : sum(0), num_samples(0) {}
113da535c405597864b8396b2029dec70ab9fb76e8basapersson    ~BoolSampleCounter() {}
114dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson    void Add(bool sample);
115dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson    int Percent(int min_required_samples) const;
116dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson    int Permille(int min_required_samples) const;
117dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson
118dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson   private:
119dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson    int Fraction(int min_required_samples, float multiplier) const;
120dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson    int sum;
121dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson    int num_samples;
122dec5ebf10614115d6f2561c65f0cce3fd80ecfd2asapersson  };
123273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  struct StatsUpdateTimes {
124b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    StatsUpdateTimes() : resolution_update_ms(0), bitrate_update_ms(0) {}
125273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org    int64_t resolution_update_ms;
12620f3f942a05a4b37d39891ff28be67d984c345f7Peter Boström    int64_t bitrate_update_ms;
127273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  };
128273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
12909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org  VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
13009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org      EXCLUSIVE_LOCKS_REQUIRED(crit_);
131ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
132273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  Clock* const clock_;
133ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org  const VideoSendStream::Config config_;
134f2f828374c3ee1e1834c72bb27eaae88ef67bb40Peter Boström  mutable rtc::CriticalSection crit_;
135b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  VideoEncoderConfig::ContentType content_type_ GUARDED_BY(crit_);
136de1429e9ad9a3a207ca191e1d748aa7271066860pbos@webrtc.org  VideoSendStream::Stats stats_ GUARDED_BY(crit_);
13724b4eda6f4fdfd33d2c3e82df1390bad55953f5dÅsa Persson  uint32_t last_sent_frame_timestamp_ GUARDED_BY(crit_);
138273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org  std::map<uint32_t, StatsUpdateTimes> update_times_ GUARDED_BY(crit_);
1391aa420b6aa70bd97cbe33e396e5dc0346aeb6415asapersson  rtc::ExpFilter encode_time_ GUARDED_BY(crit_);
140d89920b74a173b7bf80c6760908a382c095a66ccasapersson
141b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  // Contains stats used for UMA histograms. These stats will be reset if
142b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  // content type changes between real-time video and screenshare, since these
143b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  // will be reported separately.
144b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  struct UmaSamplesContainer {
145b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    explicit UmaSamplesContainer(const char* prefix);
146b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    ~UmaSamplesContainer();
147b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang
148b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    void UpdateHistograms();
149b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang
150b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    const std::string uma_prefix_;
151b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    int max_sent_width_per_timestamp_;
152b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    int max_sent_height_per_timestamp_;
153b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter input_width_counter_;
154b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter input_height_counter_;
155b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter sent_width_counter_;
156b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter sent_height_counter_;
157b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter encode_time_counter_;
158b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    BoolSampleCounter key_frame_counter_;
159b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    BoolSampleCounter quality_limited_frame_counter_;
160b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter quality_downscales_counter_;
161b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    BoolSampleCounter bw_limited_frame_counter_;
162b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter bw_resolutions_disabled_counter_;
163b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter delay_counter_;
164b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    SampleCounter max_delay_counter_;
165b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    rtc::RateTracker input_frame_rate_tracker_;
166b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang    rtc::RateTracker sent_frame_rate_tracker_;
167b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  };
168b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang
169b4a1ae5299fd57be66c7cbb7a982179bb1ecfb90sprang  rtc::scoped_ptr<UmaSamplesContainer> uma_container_ GUARDED_BY(crit_);
170ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org};
171ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org
172ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org}  // namespace webrtc
173ccd42840bcee8db145be91b3308912a24f710a6fsprang@webrtc.org#endif  // WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
174