send_statistics_proxy.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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. #ifndef VIDEO_SEND_STATISTICS_PROXY_H_
  11. #define VIDEO_SEND_STATISTICS_PROXY_H_
  12. #include <array>
  13. #include <map>
  14. #include <memory>
  15. #include <string>
  16. #include <vector>
  17. #include "api/video/video_codec_constants.h"
  18. #include "api/video/video_stream_encoder_observer.h"
  19. #include "api/video_codecs/video_encoder_config.h"
  20. #include "call/video_send_stream.h"
  21. #include "modules/include/module_common_types_public.h"
  22. #include "modules/rtp_rtcp/include/report_block_data.h"
  23. #include "modules/video_coding/include/video_codec_interface.h"
  24. #include "modules/video_coding/include/video_coding_defines.h"
  25. #include "rtc_base/numerics/exp_filter.h"
  26. #include "rtc_base/rate_tracker.h"
  27. #include "rtc_base/synchronization/mutex.h"
  28. #include "rtc_base/thread_annotations.h"
  29. #include "system_wrappers/include/clock.h"
  30. #include "video/quality_limitation_reason_tracker.h"
  31. #include "video/report_block_stats.h"
  32. #include "video/stats_counter.h"
  33. namespace webrtc {
  34. class SendStatisticsProxy : public VideoStreamEncoderObserver,
  35. public RtcpStatisticsCallback,
  36. public ReportBlockDataObserver,
  37. public RtcpPacketTypeCounterObserver,
  38. public StreamDataCountersCallback,
  39. public BitrateStatisticsObserver,
  40. public FrameCountObserver,
  41. public SendSideDelayObserver {
  42. public:
  43. static const int kStatsTimeoutMs;
  44. // Number of required samples to be collected before a metric is added
  45. // to a rtc histogram.
  46. static const int kMinRequiredMetricsSamples = 200;
  47. SendStatisticsProxy(Clock* clock,
  48. const VideoSendStream::Config& config,
  49. VideoEncoderConfig::ContentType content_type);
  50. ~SendStatisticsProxy() override;
  51. virtual VideoSendStream::Stats GetStats();
  52. void OnSendEncodedImage(const EncodedImage& encoded_image,
  53. const CodecSpecificInfo* codec_info) override;
  54. void OnEncoderImplementationChanged(
  55. const std::string& implementation_name) override;
  56. // Used to update incoming frame rate.
  57. void OnIncomingFrame(int width, int height) override;
  58. // Dropped frame stats.
  59. void OnFrameDropped(DropReason) override;
  60. // Adaptation stats.
  61. void OnAdaptationChanged(
  62. VideoAdaptationReason reason,
  63. const VideoAdaptationCounters& cpu_counters,
  64. const VideoAdaptationCounters& quality_counters) override;
  65. void ClearAdaptationStats() override;
  66. void UpdateAdaptationSettings(AdaptationSettings cpu_settings,
  67. AdaptationSettings quality_settings) override;
  68. void OnBitrateAllocationUpdated(
  69. const VideoCodec& codec,
  70. const VideoBitrateAllocation& allocation) override;
  71. void OnEncoderInternalScalerUpdate(bool is_scaled) override;
  72. void OnMinPixelLimitReached() override;
  73. void OnInitialQualityResolutionAdaptDown() override;
  74. void OnSuspendChange(bool is_suspended) override;
  75. void OnInactiveSsrc(uint32_t ssrc);
  76. // Used to indicate change in content type, which may require a change in
  77. // how stats are collected.
  78. void OnEncoderReconfigured(const VideoEncoderConfig& encoder_config,
  79. const std::vector<VideoStream>& streams) override;
  80. // Used to update the encoder target rate.
  81. void OnSetEncoderTargetRate(uint32_t bitrate_bps);
  82. // Implements CpuOveruseMetricsObserver.
  83. void OnEncodedFrameTimeMeasured(int encode_time_ms,
  84. int encode_usage_percent) override;
  85. int GetInputFrameRate() const override;
  86. int GetSendFrameRate() const;
  87. protected:
  88. // From RtcpStatisticsCallback.
  89. void StatisticsUpdated(const RtcpStatistics& statistics,
  90. uint32_t ssrc) override;
  91. // From ReportBlockDataObserver.
  92. void OnReportBlockDataUpdated(ReportBlockData report_block_data) override;
  93. // From RtcpPacketTypeCounterObserver.
  94. void RtcpPacketTypesCounterUpdated(
  95. uint32_t ssrc,
  96. const RtcpPacketTypeCounter& packet_counter) override;
  97. // From StreamDataCountersCallback.
  98. void DataCountersUpdated(const StreamDataCounters& counters,
  99. uint32_t ssrc) override;
  100. // From BitrateStatisticsObserver.
  101. void Notify(uint32_t total_bitrate_bps,
  102. uint32_t retransmit_bitrate_bps,
  103. uint32_t ssrc) override;
  104. // From FrameCountObserver.
  105. void FrameCountUpdated(const FrameCounts& frame_counts,
  106. uint32_t ssrc) override;
  107. void SendSideDelayUpdated(int avg_delay_ms,
  108. int max_delay_ms,
  109. uint64_t total_delay_ms,
  110. uint32_t ssrc) override;
  111. private:
  112. class SampleCounter {
  113. public:
  114. SampleCounter() : sum(0), num_samples(0) {}
  115. ~SampleCounter() {}
  116. void Add(int sample);
  117. int Avg(int64_t min_required_samples) const;
  118. private:
  119. int64_t sum;
  120. int64_t num_samples;
  121. };
  122. class BoolSampleCounter {
  123. public:
  124. BoolSampleCounter() : sum(0), num_samples(0) {}
  125. ~BoolSampleCounter() {}
  126. void Add(bool sample);
  127. void Add(bool sample, int64_t count);
  128. int Percent(int64_t min_required_samples) const;
  129. int Permille(int64_t min_required_samples) const;
  130. private:
  131. int Fraction(int64_t min_required_samples, float multiplier) const;
  132. int64_t sum;
  133. int64_t num_samples;
  134. };
  135. struct StatsUpdateTimes {
  136. StatsUpdateTimes() : resolution_update_ms(0), bitrate_update_ms(0) {}
  137. int64_t resolution_update_ms;
  138. int64_t bitrate_update_ms;
  139. };
  140. struct TargetRateUpdates {
  141. TargetRateUpdates()
  142. : pause_resume_events(0), last_paused_or_resumed(false), last_ms(-1) {}
  143. int pause_resume_events;
  144. bool last_paused_or_resumed;
  145. int64_t last_ms;
  146. };
  147. struct FallbackEncoderInfo {
  148. FallbackEncoderInfo();
  149. bool is_possible = true;
  150. bool is_active = false;
  151. int on_off_events = 0;
  152. int64_t elapsed_ms = 0;
  153. absl::optional<int64_t> last_update_ms;
  154. const int max_frame_diff_ms = 2000;
  155. };
  156. struct FallbackEncoderInfoDisabled {
  157. bool is_possible = true;
  158. bool min_pixel_limit_reached = false;
  159. };
  160. struct StatsTimer {
  161. void Start(int64_t now_ms);
  162. void Stop(int64_t now_ms);
  163. void Restart(int64_t now_ms);
  164. int64_t start_ms = -1;
  165. int64_t total_ms = 0;
  166. };
  167. struct QpCounters {
  168. SampleCounter vp8; // QP range: 0-127.
  169. SampleCounter vp9; // QP range: 0-255.
  170. SampleCounter h264; // QP range: 0-51.
  171. };
  172. struct AdaptChanges {
  173. int down = 0;
  174. int up = 0;
  175. };
  176. // Map holding encoded frames (mapped by timestamp).
  177. // If simulcast layers are encoded on different threads, there is no guarantee
  178. // that one frame of all layers are encoded before the next start.
  179. struct TimestampOlderThan {
  180. bool operator()(uint32_t ts1, uint32_t ts2) const {
  181. return IsNewerTimestamp(ts2, ts1);
  182. }
  183. };
  184. struct Frame {
  185. Frame(int64_t send_ms, uint32_t width, uint32_t height, int simulcast_idx)
  186. : send_ms(send_ms),
  187. max_width(width),
  188. max_height(height),
  189. max_simulcast_idx(simulcast_idx) {}
  190. const int64_t
  191. send_ms; // Time when first frame with this timestamp is sent.
  192. uint32_t max_width; // Max width with this timestamp.
  193. uint32_t max_height; // Max height with this timestamp.
  194. int max_simulcast_idx; // Max simulcast index with this timestamp.
  195. };
  196. typedef std::map<uint32_t, Frame, TimestampOlderThan> EncodedFrameMap;
  197. void PurgeOldStats() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  198. VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
  199. RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  200. struct MaskedAdaptationCounts {
  201. absl::optional<int> resolution_adaptations = absl::nullopt;
  202. absl::optional<int> num_framerate_reductions = absl::nullopt;
  203. };
  204. struct Adaptations {
  205. public:
  206. MaskedAdaptationCounts MaskedCpuCounts() const;
  207. MaskedAdaptationCounts MaskedQualityCounts() const;
  208. void set_cpu_counts(const VideoAdaptationCounters& cpu_counts);
  209. void set_quality_counts(const VideoAdaptationCounters& quality_counts);
  210. VideoAdaptationCounters cpu_counts() const;
  211. VideoAdaptationCounters quality_counts() const;
  212. void UpdateMaskingSettings(AdaptationSettings cpu_settings,
  213. AdaptationSettings quality_settings);
  214. private:
  215. VideoAdaptationCounters cpu_counts_;
  216. AdaptationSettings cpu_settings_;
  217. VideoAdaptationCounters quality_counts_;
  218. AdaptationSettings quality_settings_;
  219. MaskedAdaptationCounts Mask(const VideoAdaptationCounters& counters,
  220. const AdaptationSettings& settings) const;
  221. };
  222. void SetAdaptTimer(const MaskedAdaptationCounts& counts, StatsTimer* timer)
  223. RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  224. void UpdateAdaptationStats() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  225. void TryUpdateInitialQualityResolutionAdaptUp(
  226. absl::optional<int> old_quality_downscales,
  227. absl::optional<int> updated_quality_downscales)
  228. RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  229. void UpdateEncoderFallbackStats(const CodecSpecificInfo* codec_info,
  230. int pixels,
  231. int simulcast_index)
  232. RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  233. void UpdateFallbackDisabledStats(const CodecSpecificInfo* codec_info,
  234. int pixels,
  235. int simulcast_index)
  236. RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  237. Clock* const clock_;
  238. const std::string payload_name_;
  239. const RtpConfig rtp_config_;
  240. const absl::optional<int> fallback_max_pixels_;
  241. const absl::optional<int> fallback_max_pixels_disabled_;
  242. mutable Mutex mutex_;
  243. VideoEncoderConfig::ContentType content_type_ RTC_GUARDED_BY(mutex_);
  244. const int64_t start_ms_;
  245. VideoSendStream::Stats stats_ RTC_GUARDED_BY(mutex_);
  246. std::map<uint32_t, StatsUpdateTimes> update_times_ RTC_GUARDED_BY(mutex_);
  247. rtc::ExpFilter encode_time_ RTC_GUARDED_BY(mutex_);
  248. QualityLimitationReasonTracker quality_limitation_reason_tracker_
  249. RTC_GUARDED_BY(mutex_);
  250. rtc::RateTracker media_byte_rate_tracker_ RTC_GUARDED_BY(mutex_);
  251. rtc::RateTracker encoded_frame_rate_tracker_ RTC_GUARDED_BY(mutex_);
  252. std::map<uint32_t, std::unique_ptr<rtc::RateTracker>>
  253. encoded_frame_rate_trackers_ RTC_GUARDED_BY(mutex_);
  254. absl::optional<int64_t> last_outlier_timestamp_ RTC_GUARDED_BY(mutex_);
  255. int last_num_spatial_layers_ RTC_GUARDED_BY(mutex_);
  256. int last_num_simulcast_streams_ RTC_GUARDED_BY(mutex_);
  257. std::array<bool, kMaxSpatialLayers> last_spatial_layer_use_
  258. RTC_GUARDED_BY(mutex_);
  259. // Indicates if the latest bitrate allocation had layers disabled by low
  260. // available bandwidth.
  261. bool bw_limited_layers_ RTC_GUARDED_BY(mutex_);
  262. // Indicastes if the encoder internally downscales input image.
  263. bool internal_encoder_scaler_ RTC_GUARDED_BY(mutex_);
  264. Adaptations adaptation_limitations_ RTC_GUARDED_BY(mutex_);
  265. struct EncoderChangeEvent {
  266. std::string previous_encoder_implementation;
  267. std::string new_encoder_implementation;
  268. };
  269. // Stores the last change in encoder implementation in an optional, so that
  270. // the event can be consumed.
  271. absl::optional<EncoderChangeEvent> encoder_changed_;
  272. // Contains stats used for UMA histograms. These stats will be reset if
  273. // content type changes between real-time video and screenshare, since these
  274. // will be reported separately.
  275. struct UmaSamplesContainer {
  276. UmaSamplesContainer(const char* prefix,
  277. const VideoSendStream::Stats& start_stats,
  278. Clock* clock);
  279. ~UmaSamplesContainer();
  280. void UpdateHistograms(const RtpConfig& rtp_config,
  281. const VideoSendStream::Stats& current_stats);
  282. void InitializeBitrateCounters(const VideoSendStream::Stats& stats);
  283. bool InsertEncodedFrame(const EncodedImage& encoded_frame,
  284. int simulcast_idx);
  285. void RemoveOld(int64_t now_ms);
  286. const std::string uma_prefix_;
  287. Clock* const clock_;
  288. SampleCounter input_width_counter_;
  289. SampleCounter input_height_counter_;
  290. SampleCounter sent_width_counter_;
  291. SampleCounter sent_height_counter_;
  292. SampleCounter encode_time_counter_;
  293. BoolSampleCounter key_frame_counter_;
  294. BoolSampleCounter quality_limited_frame_counter_;
  295. SampleCounter quality_downscales_counter_;
  296. BoolSampleCounter cpu_limited_frame_counter_;
  297. BoolSampleCounter bw_limited_frame_counter_;
  298. SampleCounter bw_resolutions_disabled_counter_;
  299. SampleCounter delay_counter_;
  300. SampleCounter max_delay_counter_;
  301. rtc::RateTracker input_frame_rate_tracker_;
  302. RateCounter input_fps_counter_;
  303. RateCounter sent_fps_counter_;
  304. RateAccCounter total_byte_counter_;
  305. RateAccCounter media_byte_counter_;
  306. RateAccCounter rtx_byte_counter_;
  307. RateAccCounter padding_byte_counter_;
  308. RateAccCounter retransmit_byte_counter_;
  309. RateAccCounter fec_byte_counter_;
  310. int64_t first_rtcp_stats_time_ms_;
  311. int64_t first_rtp_stats_time_ms_;
  312. StatsTimer cpu_adapt_timer_;
  313. StatsTimer quality_adapt_timer_;
  314. BoolSampleCounter paused_time_counter_;
  315. TargetRateUpdates target_rate_updates_;
  316. BoolSampleCounter fallback_active_counter_;
  317. FallbackEncoderInfo fallback_info_;
  318. FallbackEncoderInfoDisabled fallback_info_disabled_;
  319. ReportBlockStats report_block_stats_;
  320. const VideoSendStream::Stats start_stats_;
  321. size_t num_streams_; // Number of configured streams to encoder.
  322. size_t num_pixels_highest_stream_;
  323. EncodedFrameMap encoded_frames_;
  324. AdaptChanges initial_quality_changes_;
  325. std::map<int, QpCounters>
  326. qp_counters_; // QP counters mapped by spatial idx.
  327. };
  328. std::unique_ptr<UmaSamplesContainer> uma_container_ RTC_GUARDED_BY(mutex_);
  329. };
  330. } // namespace webrtc
  331. #endif // VIDEO_SEND_STATISTICS_PROXY_H_