diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index 365995515b..84bd888622 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -81,7 +81,7 @@ class EndToEndTest : public test::CallTest { void TestXrReceiverReferenceTimeReport(bool enable_rrtr); void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first); void TestRtpStatePreservation(bool use_rtx); - void VerifyHistogramStats(bool use_rtx, bool use_red); + void VerifyHistogramStats(bool use_rtx, bool use_red, bool screenshare); }; TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) { @@ -1877,13 +1877,16 @@ TEST_F(EndToEndTest, VerifyNackStats) { "WebRTC.Video.NackPacketsReceivedPerMinute"), 0); } -void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { +void EndToEndTest::VerifyHistogramStats(bool use_rtx, + bool use_red, + bool screenshare) { class StatsObserver : public test::EndToEndTest { public: - StatsObserver(bool use_rtx, bool use_red) + StatsObserver(bool use_rtx, bool use_red, bool screenshare) : EndToEndTest(kLongTimeoutMs), use_rtx_(use_rtx), use_red_(use_red), + screenshare_(screenshare), sender_call_(nullptr), receiver_call_(nullptr), start_runtime_ms_(-1) {} @@ -1934,6 +1937,9 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { (*receive_configs)[0].rtp.rtx[kFakeSendPayloadType].payload_type = kSendRtxPayloadType; } + encoder_config->content_type = + screenshare_ ? VideoEncoderConfig::ContentType::kScreen + : VideoEncoderConfig::ContentType::kRealtimeVideo; } void OnCallsCreated(Call* sender_call, Call* receiver_call) override { @@ -1946,12 +1952,13 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { << "Timed out waiting for packet to be NACKed."; } - bool use_rtx_; - bool use_red_; + const bool use_rtx_; + const bool use_red_; + const bool screenshare_; Call* sender_call_; Call* receiver_call_; int64_t start_runtime_ms_; - } test(use_rtx, use_red); + } test(use_rtx, use_red, screenshare); test::ClearHistograms(); RunBaseTest(&test, FakeNetworkPipe::Config()); @@ -1960,6 +1967,9 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { sender_call_.reset(); receiver_call_.reset(); + std::string video_prefix = + screenshare ? "WebRTC.Video.Screenshare." : "WebRTC.Video."; + // Verify that stats have been updated once. EXPECT_EQ( 1, test::NumHistogramSamples("WebRTC.Call.VideoBitrateReceivedInKbps")); @@ -1983,8 +1993,8 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.PliPacketsReceivedPerMinute")); - EXPECT_EQ(1, test::NumHistogramSamples( - "WebRTC.Video.KeyFramesSentInPermille")); + EXPECT_EQ( + 1, test::NumHistogramSamples(video_prefix + "KeyFramesSentInPermille")); EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.KeyFramesReceivedInPermille")); @@ -1993,29 +2003,30 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.ReceivedPacketsLostInPercent")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputWidthInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputHeightInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentWidthInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentHeightInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "InputWidthInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "InputHeightInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SentWidthInPixels")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SentHeightInPixels")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.ReceivedWidthInPixels")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.ReceivedHeightInPixels")); EXPECT_EQ(static_cast(encoder_config_.streams[0].width), - test::LastHistogramSample("WebRTC.Video.InputWidthInPixels")); + test::LastHistogramSample(video_prefix + "InputWidthInPixels")); EXPECT_EQ(static_cast(encoder_config_.streams[0].height), - test::LastHistogramSample("WebRTC.Video.InputHeightInPixels")); + test::LastHistogramSample(video_prefix + "InputHeightInPixels")); EXPECT_EQ(static_cast(encoder_config_.streams[0].width), - test::LastHistogramSample("WebRTC.Video.SentWidthInPixels")); + test::LastHistogramSample(video_prefix + "SentWidthInPixels")); EXPECT_EQ(static_cast(encoder_config_.streams[0].height), - test::LastHistogramSample("WebRTC.Video.SentHeightInPixels")); + test::LastHistogramSample(video_prefix + "SentHeightInPixels")); EXPECT_EQ(static_cast(encoder_config_.streams[0].width), test::LastHistogramSample("WebRTC.Video.ReceivedWidthInPixels")); EXPECT_EQ(static_cast(encoder_config_.streams[0].height), test::LastHistogramSample("WebRTC.Video.ReceivedHeightInPixels")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputFramesPerSecond")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentFramesPerSecond")); + EXPECT_EQ(1, + test::NumHistogramSamples(video_prefix + "InputFramesPerSecond")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SentFramesPerSecond")); EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.DecodedFramesPerSecond")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.RenderFramesPerSecond")); @@ -2024,7 +2035,7 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { EXPECT_EQ( 1, test::NumHistogramSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.EncodeTimeInMs")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "EncodeTimeInMs")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.DecodeTimeInMs")); EXPECT_EQ(1, test::NumHistogramSamples( @@ -2044,8 +2055,9 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.RetransmittedBitrateReceivedInKbps")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SendSideDelayInMs")); - EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SendSideDelayMaxInMs")); + EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "SendSideDelayInMs")); + EXPECT_EQ(1, + test::NumHistogramSamples(video_prefix + "SendSideDelayMaxInMs")); int num_rtx_samples = use_rtx ? 1 : 0; EXPECT_EQ(num_rtx_samples, test::NumHistogramSamples( @@ -2065,13 +2077,22 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { TEST_F(EndToEndTest, VerifyHistogramStatsWithRtx) { const bool kEnabledRtx = true; const bool kEnabledRed = false; - VerifyHistogramStats(kEnabledRtx, kEnabledRed); + const bool kScreenshare = false; + VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); } TEST_F(EndToEndTest, VerifyHistogramStatsWithRed) { const bool kEnabledRtx = false; const bool kEnabledRed = true; - VerifyHistogramStats(kEnabledRtx, kEnabledRed); + const bool kScreenshare = false; + VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); +} + +TEST_F(EndToEndTest, VerifyHistogramStatsWithScreenshare) { + const bool kEnabledRtx = false; + const bool kEnabledRed = false; + const bool kScreenshare = true; + VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare); } void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index 5c2052a207..8dd91d90f4 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -31,6 +31,17 @@ enum HistogramCodecType { kVideoMax = 64, }; +const char* GetUmaPrefix(VideoEncoderConfig::ContentType content_type) { + switch (content_type) { + case VideoEncoderConfig::ContentType::kRealtimeVideo: + return "WebRTC.Video."; + case VideoEncoderConfig::ContentType::kScreen: + return "WebRTC.Video.Screenshare."; + } + RTC_NOTREACHED(); + return nullptr; +} + HistogramCodecType PayloadNameToHistogramCodecType( const std::string& payload_name) { if (payload_name == "VP8") { @@ -53,78 +64,98 @@ void UpdateCodecTypeHistogram(const std::string& payload_name) { const int SendStatisticsProxy::kStatsTimeoutMs = 5000; -SendStatisticsProxy::SendStatisticsProxy(Clock* clock, - const VideoSendStream::Config& config) +SendStatisticsProxy::SendStatisticsProxy( + Clock* clock, + const VideoSendStream::Config& config, + VideoEncoderConfig::ContentType content_type) : clock_(clock), config_(config), - input_frame_rate_tracker_(100u, 10u), - sent_frame_rate_tracker_(100u, 10u), + content_type_(content_type), last_sent_frame_timestamp_(0), - max_sent_width_per_timestamp_(0), - max_sent_height_per_timestamp_(0) { + uma_container_(new UmaSamplesContainer(GetUmaPrefix(content_type_))) { UpdateCodecTypeHistogram(config_.encoder_settings.payload_name); } -SendStatisticsProxy::~SendStatisticsProxy() { +SendStatisticsProxy::~SendStatisticsProxy() {} + +SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer( + const char* prefix) + : uma_prefix_(prefix), + max_sent_width_per_timestamp_(0), + max_sent_height_per_timestamp_(0), + input_frame_rate_tracker_(100u, 10u), + sent_frame_rate_tracker_(100u, 10u) {} + +SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() { UpdateHistograms(); } -void SendStatisticsProxy::UpdateHistograms() { +void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms() { const int kMinRequiredSamples = 200; int in_width = input_width_counter_.Avg(kMinRequiredSamples); int in_height = input_height_counter_.Avg(kMinRequiredSamples); int in_fps = round(input_frame_rate_tracker_.ComputeTotalRate()); if (in_width != -1) { - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InputWidthInPixels", in_width); - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InputHeightInPixels", in_height); - RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.InputFramesPerSecond", in_fps); + RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "InputWidthInPixels", in_width); + RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "InputHeightInPixels", in_height); + RTC_HISTOGRAM_COUNTS_100(uma_prefix_ + "InputFramesPerSecond", in_fps); } int sent_width = sent_width_counter_.Avg(kMinRequiredSamples); int sent_height = sent_height_counter_.Avg(kMinRequiredSamples); int sent_fps = round(sent_frame_rate_tracker_.ComputeTotalRate()); if (sent_width != -1) { - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentWidthInPixels", sent_width); - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentHeightInPixels", sent_height); - RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.SentFramesPerSecond", sent_fps); + RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "SentWidthInPixels", sent_width); + RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "SentHeightInPixels", sent_height); + RTC_HISTOGRAM_COUNTS_100(uma_prefix_ + "SentFramesPerSecond", sent_fps); } int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples); if (encode_ms != -1) - RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.EncodeTimeInMs", encode_ms); + RTC_HISTOGRAM_COUNTS_1000(uma_prefix_ + "EncodeTimeInMs", encode_ms); int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples); if (key_frames_permille != -1) { - RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesSentInPermille", - key_frames_permille); + RTC_HISTOGRAM_COUNTS_1000(uma_prefix_ + "KeyFramesSentInPermille", + key_frames_permille); } int quality_limited = quality_limited_frame_counter_.Percent(kMinRequiredSamples); if (quality_limited != -1) { - RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.QualityLimitedResolutionInPercent", + RTC_HISTOGRAM_PERCENTAGE(uma_prefix_ + "QualityLimitedResolutionInPercent", quality_limited); } int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples); if (downscales != -1) { - RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.QualityLimitedResolutionDownscales", - downscales, 20); + RTC_HISTOGRAM_ENUMERATION( + uma_prefix_ + "QualityLimitedResolutionDownscales", downscales, 20); } int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples); if (bw_limited != -1) { - RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BandwidthLimitedResolutionInPercent", - bw_limited); + RTC_HISTOGRAM_PERCENTAGE( + uma_prefix_ + "BandwidthLimitedResolutionInPercent", bw_limited); } int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples); if (num_disabled != -1) { RTC_HISTOGRAM_ENUMERATION( - "WebRTC.Video.BandwidthLimitedResolutionsDisabled", num_disabled, 10); + uma_prefix_ + "BandwidthLimitedResolutionsDisabled", num_disabled, 10); } int delay_ms = delay_counter_.Avg(kMinRequiredSamples); if (delay_ms != -1) - RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.SendSideDelayInMs", delay_ms); + RTC_HISTOGRAM_COUNTS_100000(uma_prefix_ + "SendSideDelayInMs", delay_ms); int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples); if (max_delay_ms != -1) { - RTC_HISTOGRAM_COUNTS_100000( - "WebRTC.Video.SendSideDelayMaxInMs", max_delay_ms); + RTC_HISTOGRAM_COUNTS_100000(uma_prefix_ + "SendSideDelayMaxInMs", + max_delay_ms); + } +} + +void SendStatisticsProxy::SetContentType( + VideoEncoderConfig::ContentType content_type) { + rtc::CritScope lock(&crit_); + if (content_type_ != content_type) { + uma_container_->UpdateHistograms(); + uma_container_.reset(new UmaSamplesContainer(GetUmaPrefix(content_type))); + content_type_ = content_type; } } @@ -151,7 +182,7 @@ VideoSendStream::Stats SendStatisticsProxy::GetStats() { rtc::CritScope lock(&crit_); PurgeOldStats(); stats_.input_frame_rate = - round(input_frame_rate_tracker_.ComputeRate()); + round(uma_container_->input_frame_rate_tracker_.ComputeRate()); return stats_; } @@ -224,23 +255,24 @@ void SendStatisticsProxy::OnSendEncodedImage( stats->height = encoded_image._encodedHeight; update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds(); - key_frame_counter_.Add(encoded_image._frameType == kVideoFrameKey); + uma_container_->key_frame_counter_.Add(encoded_image._frameType == + kVideoFrameKey); if (encoded_image.adapt_reason_.quality_resolution_downscales != -1) { bool downscaled = encoded_image.adapt_reason_.quality_resolution_downscales > 0; - quality_limited_frame_counter_.Add(downscaled); + uma_container_->quality_limited_frame_counter_.Add(downscaled); if (downscaled) { - quality_downscales_counter_.Add( + uma_container_->quality_downscales_counter_.Add( encoded_image.adapt_reason_.quality_resolution_downscales); } } if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) { bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0; - bw_limited_frame_counter_.Add(bw_limited); + uma_container_->bw_limited_frame_counter_.Add(bw_limited); if (bw_limited) { - bw_resolutions_disabled_counter_.Add( - encoded_image.adapt_reason_.bw_resolutions_disabled); + uma_container_->bw_resolutions_disabled_counter_.Add( + encoded_image.adapt_reason_.bw_resolutions_disabled); } } @@ -249,31 +281,33 @@ void SendStatisticsProxy::OnSendEncodedImage( // are encoded before the next start. if (last_sent_frame_timestamp_ > 0 && encoded_image._timeStamp != last_sent_frame_timestamp_) { - sent_frame_rate_tracker_.AddSamples(1); - sent_width_counter_.Add(max_sent_width_per_timestamp_); - sent_height_counter_.Add(max_sent_height_per_timestamp_); - max_sent_width_per_timestamp_ = 0; - max_sent_height_per_timestamp_ = 0; + uma_container_->sent_frame_rate_tracker_.AddSamples(1); + uma_container_->sent_width_counter_.Add( + uma_container_->max_sent_width_per_timestamp_); + uma_container_->sent_height_counter_.Add( + uma_container_->max_sent_height_per_timestamp_); + uma_container_->max_sent_width_per_timestamp_ = 0; + uma_container_->max_sent_height_per_timestamp_ = 0; } last_sent_frame_timestamp_ = encoded_image._timeStamp; - max_sent_width_per_timestamp_ = - std::max(max_sent_width_per_timestamp_, + uma_container_->max_sent_width_per_timestamp_ = + std::max(uma_container_->max_sent_width_per_timestamp_, static_cast(encoded_image._encodedWidth)); - max_sent_height_per_timestamp_ = - std::max(max_sent_height_per_timestamp_, + uma_container_->max_sent_height_per_timestamp_ = + std::max(uma_container_->max_sent_height_per_timestamp_, static_cast(encoded_image._encodedHeight)); } void SendStatisticsProxy::OnIncomingFrame(int width, int height) { rtc::CritScope lock(&crit_); - input_frame_rate_tracker_.AddSamples(1); - input_width_counter_.Add(width); - input_height_counter_.Add(height); + uma_container_->input_frame_rate_tracker_.AddSamples(1); + uma_container_->input_width_counter_.Add(width); + uma_container_->input_height_counter_.Add(height); } void SendStatisticsProxy::OnEncodedFrame(int encode_time_ms) { rtc::CritScope lock(&crit_); - encode_time_counter_.Add(encode_time_ms); + uma_container_->encode_time_counter_.Add(encode_time_ms); } void SendStatisticsProxy::RtcpPacketTypesCounterUpdated( @@ -343,8 +377,8 @@ void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms, stats->avg_delay_ms = avg_delay_ms; stats->max_delay_ms = max_delay_ms; - delay_counter_.Add(avg_delay_ms); - max_delay_counter_.Add(max_delay_ms); + uma_container_->delay_counter_.Add(avg_delay_ms); + uma_container_->max_delay_counter_.Add(max_delay_ms); } void SendStatisticsProxy::SampleCounter::Add(int sample) { @@ -380,5 +414,4 @@ int SendStatisticsProxy::BoolSampleCounter::Fraction( return -1; return static_cast((sum * multiplier / num_samples) + 0.5f); } - } // namespace webrtc diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h index 7209094fe6..a2b840eff6 100644 --- a/webrtc/video/send_statistics_proxy.h +++ b/webrtc/video/send_statistics_proxy.h @@ -38,7 +38,9 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, public: static const int kStatsTimeoutMs; - SendStatisticsProxy(Clock* clock, const VideoSendStream::Config& config); + SendStatisticsProxy(Clock* clock, + const VideoSendStream::Config& config, + VideoEncoderConfig::ContentType content_type); virtual ~SendStatisticsProxy(); VideoSendStream::Stats GetStats(); @@ -58,6 +60,10 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, void OnSuspendChange(bool is_suspended); void OnInactiveSsrc(uint32_t ssrc); + // Used to indicate change in content type, which may require a change in + // how stats are collected. + void SetContentType(VideoEncoderConfig::ContentType content_type); + protected: // From CpuOveruseMetricsObserver. void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) override; @@ -112,38 +118,51 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, int num_samples; }; struct StatsUpdateTimes { - StatsUpdateTimes() : resolution_update_ms(0) {} + StatsUpdateTimes() : resolution_update_ms(0), bitrate_update_ms(0) {} int64_t resolution_update_ms; int64_t bitrate_update_ms; }; void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_); VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc) EXCLUSIVE_LOCKS_REQUIRED(crit_); - void UpdateHistograms() EXCLUSIVE_LOCKS_REQUIRED(crit_); Clock* const clock_; const VideoSendStream::Config config_; mutable rtc::CriticalSection crit_; + VideoEncoderConfig::ContentType content_type_ GUARDED_BY(crit_); VideoSendStream::Stats stats_ GUARDED_BY(crit_); - rtc::RateTracker input_frame_rate_tracker_ GUARDED_BY(crit_); - rtc::RateTracker sent_frame_rate_tracker_ GUARDED_BY(crit_); uint32_t last_sent_frame_timestamp_ GUARDED_BY(crit_); std::map update_times_ GUARDED_BY(crit_); - int max_sent_width_per_timestamp_ GUARDED_BY(crit_); - int max_sent_height_per_timestamp_ GUARDED_BY(crit_); - SampleCounter input_width_counter_ GUARDED_BY(crit_); - SampleCounter input_height_counter_ GUARDED_BY(crit_); - SampleCounter sent_width_counter_ GUARDED_BY(crit_); - SampleCounter sent_height_counter_ GUARDED_BY(crit_); - SampleCounter encode_time_counter_ GUARDED_BY(crit_); - BoolSampleCounter key_frame_counter_ GUARDED_BY(crit_); - BoolSampleCounter quality_limited_frame_counter_ GUARDED_BY(crit_); - SampleCounter quality_downscales_counter_ GUARDED_BY(crit_); - BoolSampleCounter bw_limited_frame_counter_ GUARDED_BY(crit_); - SampleCounter bw_resolutions_disabled_counter_ GUARDED_BY(crit_); - SampleCounter delay_counter_ GUARDED_BY(crit_); - SampleCounter max_delay_counter_ GUARDED_BY(crit_); + // Contains stats used for UMA histograms. These stats will be reset if + // content type changes between real-time video and screenshare, since these + // will be reported separately. + struct UmaSamplesContainer { + explicit UmaSamplesContainer(const char* prefix); + ~UmaSamplesContainer(); + + void UpdateHistograms(); + + const std::string uma_prefix_; + int max_sent_width_per_timestamp_; + int max_sent_height_per_timestamp_; + SampleCounter input_width_counter_; + SampleCounter input_height_counter_; + SampleCounter sent_width_counter_; + SampleCounter sent_height_counter_; + SampleCounter encode_time_counter_; + BoolSampleCounter key_frame_counter_; + BoolSampleCounter quality_limited_frame_counter_; + SampleCounter quality_downscales_counter_; + BoolSampleCounter bw_limited_frame_counter_; + SampleCounter bw_resolutions_disabled_counter_; + SampleCounter delay_counter_; + SampleCounter max_delay_counter_; + rtc::RateTracker input_frame_rate_tracker_; + rtc::RateTracker sent_frame_rate_tracker_; + }; + + rtc::scoped_ptr uma_container_ GUARDED_BY(crit_); }; } // namespace webrtc diff --git a/webrtc/video/send_statistics_proxy_unittest.cc b/webrtc/video/send_statistics_proxy_unittest.cc index 8e6b7bcab3..1bf9814412 100644 --- a/webrtc/video/send_statistics_proxy_unittest.cc +++ b/webrtc/video/send_statistics_proxy_unittest.cc @@ -28,8 +28,9 @@ class SendStatisticsProxyTest : public ::testing::Test { protected: virtual void SetUp() { - statistics_proxy_.reset( - new SendStatisticsProxy(&fake_clock_, GetTestConfig())); + statistics_proxy_.reset(new SendStatisticsProxy( + &fake_clock_, GetTestConfig(), + VideoEncoderConfig::ContentType::kRealtimeVideo)); expected_ = VideoSendStream::Stats(); } diff --git a/webrtc/video/video_capture_input_unittest.cc b/webrtc/video/video_capture_input_unittest.cc index 12ef076c6d..34bb7d609f 100644 --- a/webrtc/video/video_capture_input_unittest.cc +++ b/webrtc/video/video_capture_input_unittest.cc @@ -53,7 +53,8 @@ class VideoCaptureInputTest : public ::testing::Test { mock_frame_callback_(new NiceMock), output_frame_event_(EventWrapper::Create()), stats_proxy_(Clock::GetRealTimeClock(), - webrtc::VideoSendStream::Config(nullptr)) {} + webrtc::VideoSendStream::Config(nullptr), + webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo) {} virtual void SetUp() { EXPECT_CALL(*mock_frame_callback_, DeliverFrame(_)) diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index bc59900eff..3bc026cd2c 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -117,7 +117,9 @@ VideoSendStream::VideoSendStream( const VideoSendStream::Config& config, const VideoEncoderConfig& encoder_config, const std::map& suspended_ssrcs) - : stats_proxy_(Clock::GetRealTimeClock(), config), + : stats_proxy_(Clock::GetRealTimeClock(), + config, + encoder_config.content_type), transport_adapter_(config.send_transport), encoded_frame_proxy_(config.post_encode_callback), config_(config), @@ -435,6 +437,8 @@ bool VideoSendStream::ReconfigureVideoEncoder( stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]); } + stats_proxy_.SetContentType(config.content_type); + RTC_DCHECK_GE(config.min_transmit_bitrate_bps, 0); vie_encoder_->SetMinTransmitBitrate(config.min_transmit_bitrate_bps / 1000);