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