diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h index b38a757036..0247a4e5c6 100644 --- a/talk/media/webrtc/fakewebrtcvideoengine.h +++ b/talk/media/webrtc/fakewebrtcvideoengine.h @@ -699,6 +699,8 @@ class FakeWebRtcVideoEngine return 0; } WEBRTC_STUB(GetCpuOveruseMetrics, (int, webrtc::CpuOveruseMetrics*)); + WEBRTC_VOID_STUB(RegisterCpuOveruseMetricsObserver, + (int, webrtc::CpuOveruseMetricsObserver*)); WEBRTC_FUNC(SetCpuOveruseOptions, (int channel, const webrtc::CpuOveruseOptions& options)) { WEBRTC_CHECK_CHANNEL(channel); diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc index baa0911789..5a380cbad6 100644 --- a/talk/media/webrtc/webrtcvideoengine2.cc +++ b/talk/media/webrtc/webrtcvideoengine2.cc @@ -1774,6 +1774,8 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { } info.framerate_input = stats.input_frame_rate; info.framerate_sent = stats.encode_frame_rate; + info.avg_encode_ms = stats.avg_encode_time_ms; + info.encode_usage_percent = stats.encode_usage_percent; info.nominal_bitrate = stats.media_bitrate_bps; diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc index 3fa220451c..751765dbb7 100644 --- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc @@ -2038,6 +2038,19 @@ TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) { EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState()); } +TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) { + FakeVideoSendStream* stream = AddSendStream(); + webrtc::VideoSendStream::Stats stats; + stats.avg_encode_time_ms = 13; + stats.encode_usage_percent = 42; + stream->SetStats(stats); + + cricket::VideoMediaInfo info; + ASSERT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info)); + EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms); + EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent); +} + TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) { FakeVideoSendStream* stream = AddSendStream(); webrtc::VideoSendStream::Stats stats; diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index 3d46cc3444..07e3fdc917 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -1660,6 +1660,9 @@ TEST_F(EndToEndTest, GetStats) { send_stats_filled_["NumStreams"] |= stats.substreams.size() == expected_send_ssrcs_.size(); + send_stats_filled_["CpuOveruseMetrics"] |= + stats.avg_encode_time_ms != 0 || stats.encode_usage_percent != 0; + for (std::map::const_iterator it = stats.substreams.begin(); it != stats.substreams.end(); ++it) { diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index 64126d28f2..7c148b7dac 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -38,6 +38,13 @@ void SendStatisticsProxy::OutgoingRate(const int video_channel, stats_.media_bitrate_bps = bitrate; } +void SendStatisticsProxy::CpuOveruseMetricsUpdated( + const CpuOveruseMetrics& metrics) { + CriticalSectionScoped lock(crit_.get()); + stats_.avg_encode_time_ms = metrics.avg_encode_time_ms; + stats_.encode_usage_percent = metrics.encode_usage_percent; +} + void SendStatisticsProxy::SuspendChange(int video_channel, bool is_suspended) { CriticalSectionScoped lock(crit_.get()); stats_.suspended = is_suspended; diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h index 5d4edcd83d..540ee3277e 100644 --- a/webrtc/video/send_statistics_proxy.h +++ b/webrtc/video/send_statistics_proxy.h @@ -18,6 +18,7 @@ #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" #include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/video_engine/include/vie_base.h" #include "webrtc/video_engine/include/vie_capture.h" #include "webrtc/video_engine/include/vie_codec.h" #include "webrtc/video_send_stream.h" @@ -26,7 +27,8 @@ namespace webrtc { class CriticalSectionWrapper; -class SendStatisticsProxy : public RtcpStatisticsCallback, +class SendStatisticsProxy : public CpuOveruseMetricsObserver, + public RtcpStatisticsCallback, public RtcpPacketTypeCounterObserver, public StreamDataCountersCallback, public BitrateStatisticsObserver, @@ -46,6 +48,8 @@ class SendStatisticsProxy : public RtcpStatisticsCallback, const RTPVideoHeader* rtp_video_header); protected: + // From CpuOveruseMetricsObserver. + void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) OVERRIDE; // From RtcpStatisticsCallback. virtual void StatisticsUpdated(const RtcpStatistics& statistics, uint32_t ssrc) OVERRIDE; diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 82af66e34c..881802afb1 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -210,6 +210,9 @@ VideoSendStream::VideoSendStream( if (overuse_observer) video_engine_base_->RegisterCpuOveruseObserver(channel_, overuse_observer); + // Registered regardless of monitoring, used for stats. + video_engine_base_->RegisterCpuOveruseMetricsObserver(channel_, + &stats_proxy_); video_engine_base_->RegisterSendSideDelayObserver(channel_, &stats_proxy_); video_engine_base_->RegisterSendStatisticsProxy(channel_, &stats_proxy_); diff --git a/webrtc/video_engine/include/vie_base.h b/webrtc/video_engine/include/vie_base.h index 3f4840a5f5..7262ca2868 100644 --- a/webrtc/video_engine/include/vie_base.h +++ b/webrtc/video_engine/include/vie_base.h @@ -112,7 +112,6 @@ struct CpuOveruseMetrics { : capture_jitter_ms(-1), avg_encode_time_ms(-1), encode_usage_percent(-1), - encode_rsd(-1), capture_queue_delay_ms_per_s(-1) {} int capture_jitter_ms; // The current estimated jitter in ms based on @@ -120,14 +119,18 @@ struct CpuOveruseMetrics { int avg_encode_time_ms; // The average encode time in ms. int encode_usage_percent; // The average encode time divided by the average // time difference between incoming captured frames. - // TODO(asapersson): Remove metric, not used. - int encode_rsd; // The relative std dev of encode time of frames. int capture_queue_delay_ms_per_s; // The current time delay between an // incoming captured frame until the frame // is being processed. The delay is // expressed in ms delay per second. }; +class CpuOveruseMetricsObserver { + public: + virtual ~CpuOveruseMetricsObserver() {} + virtual void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) = 0; +}; + class WEBRTC_DLLEXPORT VideoEngine { public: // Creates a VideoEngine object, which can then be used to acquire sub‐APIs. @@ -208,6 +211,9 @@ class WEBRTC_DLLEXPORT ViEBase { // Gets cpu overuse measures. virtual int GetCpuOveruseMetrics(int channel, CpuOveruseMetrics* metrics) = 0; + virtual void RegisterCpuOveruseMetricsObserver( + int channel, + CpuOveruseMetricsObserver* observer) = 0; // Registers a callback which is called when send-side delay statistics has // been updated. diff --git a/webrtc/video_engine/overuse_frame_detector.cc b/webrtc/video_engine/overuse_frame_detector.cc index b4e1e36b09..b4204db793 100644 --- a/webrtc/video_engine/overuse_frame_detector.cc +++ b/webrtc/video_engine/overuse_frame_detector.cc @@ -317,8 +317,11 @@ class OveruseFrameDetector::CaptureQueueDelay { scoped_ptr filtered_delay_ms_per_s_; }; -OveruseFrameDetector::OveruseFrameDetector(Clock* clock) +OveruseFrameDetector::OveruseFrameDetector( + Clock* clock, + CpuOveruseMetricsObserver* metrics_observer) : observer_(NULL), + metrics_observer_(metrics_observer), clock_(clock), next_process_time_(clock_->TimeInMilliseconds()), num_process_times_(0), @@ -336,6 +339,7 @@ OveruseFrameDetector::OveruseFrameDetector(Clock* clock) frame_queue_(new FrameQueue()), last_sample_time_ms_(0), capture_queue_delay_(new CaptureQueueDelay()) { + DCHECK(metrics_observer != nullptr); processing_thread_.DetachFromThread(); } @@ -374,14 +378,13 @@ int OveruseFrameDetector::FramesInQueue() const { return frame_queue_->NumFrames(); } -void OveruseFrameDetector::GetCpuOveruseMetrics( - CpuOveruseMetrics* metrics) const { - rtc::CritScope cs(&crit_); - metrics->capture_jitter_ms = static_cast(capture_deltas_.StdDev() + 0.5); - metrics->avg_encode_time_ms = encode_time_->Value(); - metrics->encode_rsd = 0; - metrics->encode_usage_percent = usage_->Value(); - metrics->capture_queue_delay_ms_per_s = capture_queue_delay_->Value(); +void OveruseFrameDetector::UpdateCpuOveruseMetrics() { + metrics_.capture_jitter_ms = static_cast(capture_deltas_.StdDev() + 0.5); + metrics_.avg_encode_time_ms = encode_time_->Value(); + metrics_.encode_usage_percent = usage_->Value(); + metrics_.capture_queue_delay_ms_per_s = capture_queue_delay_->Value(); + + metrics_observer_->CpuOveruseMetricsUpdated(metrics_); } int64_t OveruseFrameDetector::TimeUntilNextProcess() { @@ -411,6 +414,7 @@ void OveruseFrameDetector::ResetAll(int num_pixels) { capture_queue_delay_->ClearFrames(); last_capture_time_ = 0; num_process_times_ = 0; + UpdateCpuOveruseMetrics(); } void OveruseFrameDetector::FrameCaptured(int width, @@ -434,6 +438,7 @@ void OveruseFrameDetector::FrameCaptured(int width, if (options_.enable_extended_processing_usage) { frame_queue_->Start(capture_time_ms, now); } + UpdateCpuOveruseMetrics(); } void OveruseFrameDetector::FrameProcessingStarted() { @@ -453,6 +458,7 @@ void OveruseFrameDetector::FrameEncoded(int encode_time_ms) { if (!options_.enable_extended_processing_usage) { AddProcessingTime(encode_time_ms); } + UpdateCpuOveruseMetrics(); } void OveruseFrameDetector::FrameSent(int64_t capture_time_ms) { @@ -465,6 +471,7 @@ void OveruseFrameDetector::FrameSent(int64_t capture_time_ms) { if (delay_ms > 0) { AddProcessingTime(delay_ms); } + UpdateCpuOveruseMetrics(); } void OveruseFrameDetector::AddProcessingTime(int elapsed_ms) { @@ -492,6 +499,7 @@ int32_t OveruseFrameDetector::Process() { ++num_process_times_; capture_queue_delay_->CalculateDelayChange(diff_ms); + UpdateCpuOveruseMetrics(); if (num_process_times_ <= options_.min_process_count) { return 0; @@ -537,6 +545,7 @@ int32_t OveruseFrameDetector::Process() { << " encode usage " << usage_->Value() << " overuse detections " << num_overuse_detections_ << " rampup delay " << rampup_delay; + return 0; } diff --git a/webrtc/video_engine/overuse_frame_detector.h b/webrtc/video_engine/overuse_frame_detector.h index 969639cdd4..28bac391ff 100644 --- a/webrtc/video_engine/overuse_frame_detector.h +++ b/webrtc/video_engine/overuse_frame_detector.h @@ -52,7 +52,8 @@ class Statistics { // Use to detect system overuse based on jitter in incoming frames. class OveruseFrameDetector : public Module { public: - explicit OveruseFrameDetector(Clock* clock); + OveruseFrameDetector(Clock* clock, + CpuOveruseMetricsObserver* metrics_observer); ~OveruseFrameDetector(); // Registers an observer receiving overuse and underuse callbacks. Set @@ -74,26 +75,6 @@ class OveruseFrameDetector : public Module { // Called for each sent frame. void FrameSent(int64_t capture_time_ms); - // Accessors. - - // Returns CpuOveruseMetrics where - // capture_jitter_ms: The estimated jitter based on incoming captured frames. - // avg_encode_time_ms: Running average of reported encode time - // (FrameEncoded()). Only used for stats. - // TODO(asapersson): Rename metric. - // encode_usage_percent: The average processing time of a frame on the - // send-side divided by the average time difference - // between incoming captured frames. - // capture_queue_delay_ms_per_s: The current time delay between an incoming - // captured frame (FrameCaptured()) until the - // frame is being processed - // (FrameProcessingStarted()). (Note: if a new - // frame is received before an old frame has - // been processed, the old frame is skipped). - // The delay is expressed in ms delay per sec. - // Only used for stats. - void GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const; - // Only public for testing. int CaptureQueueDelayMsPerS() const; int LastProcessingTimeMs() const; @@ -109,6 +90,8 @@ class OveruseFrameDetector : public Module { class CaptureQueueDelay; class FrameQueue; + void UpdateCpuOveruseMetrics() EXCLUSIVE_LOCKS_REQUIRED(crit_); + // TODO(asapersson): This method is only used on one thread, so it shouldn't // need a guard. void AddProcessingTime(int elapsed_ms) EXCLUSIVE_LOCKS_REQUIRED(crit_); @@ -136,6 +119,10 @@ class OveruseFrameDetector : public Module { CpuOveruseOptions options_ GUARDED_BY(crit_); + // Stats metrics. + CpuOveruseMetricsObserver* const metrics_observer_; + CpuOveruseMetrics metrics_ GUARDED_BY(crit_); + Clock* const clock_; int64_t next_process_time_; // Only accessed on the processing thread. int64_t num_process_times_ GUARDED_BY(crit_); diff --git a/webrtc/video_engine/overuse_frame_detector_unittest.cc b/webrtc/video_engine/overuse_frame_detector_unittest.cc index 84f0e0462e..d10d81ffce 100644 --- a/webrtc/video_engine/overuse_frame_detector_unittest.cc +++ b/webrtc/video_engine/overuse_frame_detector_unittest.cc @@ -47,12 +47,13 @@ class CpuOveruseObserverImpl : public CpuOveruseObserver { int normaluse_; }; -class OveruseFrameDetectorTest : public ::testing::Test { +class OveruseFrameDetectorTest : public ::testing::Test, + public CpuOveruseMetricsObserver { protected: virtual void SetUp() { clock_.reset(new SimulatedClock(1234)); observer_.reset(new MockCpuOveruseObserver()); - overuse_detector_.reset(new OveruseFrameDetector(clock_.get())); + overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), this)); options_.low_capture_jitter_threshold_ms = 10.0f; options_.high_capture_jitter_threshold_ms = 15.0f; @@ -61,6 +62,11 @@ class OveruseFrameDetectorTest : public ::testing::Test { overuse_detector_->SetObserver(observer_.get()); } + virtual void CpuOveruseMetricsUpdated( + const CpuOveruseMetrics& metrics) override { + metrics_ = metrics; + } + int InitialJitter() { return ((options_.low_capture_jitter_threshold_ms + options_.high_capture_jitter_threshold_ms) / 2.0f) + 0.5; @@ -124,28 +130,17 @@ class OveruseFrameDetectorTest : public ::testing::Test { overuse_detector_->Process(); } - int CaptureJitterMs() { - CpuOveruseMetrics metrics; - overuse_detector_->GetCpuOveruseMetrics(&metrics); - return metrics.capture_jitter_ms; - } + int CaptureJitterMs() { return metrics_.capture_jitter_ms; } - int AvgEncodeTimeMs() { - CpuOveruseMetrics metrics; - overuse_detector_->GetCpuOveruseMetrics(&metrics); - return metrics.avg_encode_time_ms; - } + int AvgEncodeTimeMs() { return metrics_.avg_encode_time_ms; } - int UsagePercent() { - CpuOveruseMetrics metrics; - overuse_detector_->GetCpuOveruseMetrics(&metrics); - return metrics.encode_usage_percent; - } + int UsagePercent() { return metrics_.encode_usage_percent; } CpuOveruseOptions options_; scoped_ptr clock_; scoped_ptr observer_; scoped_ptr overuse_detector_; + CpuOveruseMetrics metrics_; }; // enable_capture_jitter_method = true; @@ -257,16 +252,6 @@ TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) { TriggerOveruse(1); } -TEST_F(OveruseFrameDetectorTest, GetCpuOveruseMetrics) { - CpuOveruseMetrics metrics; - overuse_detector_->GetCpuOveruseMetrics(&metrics); - EXPECT_GT(metrics.capture_jitter_ms, 0); - EXPECT_GT(metrics.avg_encode_time_ms, 0); - EXPECT_GT(metrics.encode_usage_percent, 0); - EXPECT_GE(metrics.capture_queue_delay_ms_per_s, 0); - EXPECT_GE(metrics.encode_rsd, 0); -} - TEST_F(OveruseFrameDetectorTest, CaptureJitter) { EXPECT_EQ(InitialJitter(), CaptureJitterMs()); InsertFramesWithInterval(1000, kFrameInterval33ms, kWidth, kHeight); diff --git a/webrtc/video_engine/vie_base_impl.cc b/webrtc/video_engine/vie_base_impl.cc index 9e9350dd37..4b977de8e8 100644 --- a/webrtc/video_engine/vie_base_impl.cc +++ b/webrtc/video_engine/vie_base_impl.cc @@ -120,6 +120,23 @@ int ViEBaseImpl::SetCpuOveruseOptions(int video_channel, return -1; } +void ViEBaseImpl::RegisterCpuOveruseMetricsObserver( + int video_channel, + CpuOveruseMetricsObserver* observer) { + ViEChannelManagerScoped cs(*(shared_data_.channel_manager())); + ViEEncoder* vie_encoder = cs.Encoder(video_channel); + assert(vie_encoder); + + ViEInputManagerScoped is(*(shared_data_.input_manager())); + ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder); + assert(provider != NULL); + + ViECapturer* capturer = is.Capture(provider->Id()); + assert(capturer); + + capturer->RegisterCpuOveruseMetricsObserver(observer); +} + int ViEBaseImpl::GetCpuOveruseMetrics(int video_channel, CpuOveruseMetrics* metrics) { ViEChannelManagerScoped cs(*(shared_data_.channel_manager())); diff --git a/webrtc/video_engine/vie_base_impl.h b/webrtc/video_engine/vie_base_impl.h index dd21a045a6..7e025c7402 100644 --- a/webrtc/video_engine/vie_base_impl.h +++ b/webrtc/video_engine/vie_base_impl.h @@ -35,6 +35,9 @@ class ViEBaseImpl CpuOveruseObserver* observer); virtual int SetCpuOveruseOptions(int channel, const CpuOveruseOptions& options); + virtual void RegisterCpuOveruseMetricsObserver( + int channel, + CpuOveruseMetricsObserver* observer) override; virtual int GetCpuOveruseMetrics(int channel, CpuOveruseMetrics* metrics); virtual void RegisterSendSideDelayObserver(int channel, diff --git a/webrtc/video_engine/vie_capturer.cc b/webrtc/video_engine/vie_capturer.cc index f9e42e6646..29685fd4bf 100644 --- a/webrtc/video_engine/vie_capturer.cc +++ b/webrtc/video_engine/vie_capturer.cc @@ -32,6 +32,32 @@ namespace webrtc { const int kThreadWaitTimeMs = 100; +class RegistrableCpuOveruseMetricsObserver : public CpuOveruseMetricsObserver { + public: + virtual void CpuOveruseMetricsUpdated( + const CpuOveruseMetrics& metrics) override { + rtc::CritScope lock(&crit_); + if (observer_) + observer_->CpuOveruseMetricsUpdated(metrics); + metrics_ = metrics; + } + + CpuOveruseMetrics GetCpuOveruseMetrics() const { + rtc::CritScope lock(&crit_); + return metrics_; + } + + void Set(CpuOveruseMetricsObserver* observer) { + rtc::CritScope lock(&crit_); + observer_ = observer; + } + + private: + mutable rtc::CriticalSection crit_; + CpuOveruseMetricsObserver* observer_ GUARDED_BY(crit_) = nullptr; + CpuOveruseMetrics metrics_ GUARDED_BY(crit_); +}; + ViECapturer::ViECapturer(int capture_id, int engine_id, const Config& config, @@ -45,7 +71,8 @@ ViECapturer::ViECapturer(int capture_id, capture_id_(capture_id), incoming_frame_cs_(CriticalSectionWrapper::CreateCriticalSection()), capture_thread_(*ThreadWrapper::CreateThread(ViECaptureThreadFunction, - this, kHighPriority, + this, + kHighPriority, "ViECaptureThread")), capture_event_(*EventWrapper::Create()), deliver_event_(*EventWrapper::Create()), @@ -59,7 +86,10 @@ ViECapturer::ViECapturer(int capture_id, reported_brightness_level_(Normal), observer_cs_(CriticalSectionWrapper::CreateCriticalSection()), observer_(NULL), - overuse_detector_(new OveruseFrameDetector(Clock::GetRealTimeClock())) { + cpu_overuse_metrics_observer_(new RegistrableCpuOveruseMetricsObserver()), + overuse_detector_( + new OveruseFrameDetector(Clock::GetRealTimeClock(), + cpu_overuse_metrics_observer_.get())) { unsigned int t_id = 0; if (!capture_thread_.Start(t_id)) { assert(false); @@ -246,8 +276,13 @@ void ViECapturer::SetCpuOveruseOptions(const CpuOveruseOptions& options) { overuse_detector_->SetOptions(options); } +void ViECapturer::RegisterCpuOveruseMetricsObserver( + CpuOveruseMetricsObserver* observer) { + cpu_overuse_metrics_observer_->Set(observer); +} + void ViECapturer::GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const { - overuse_detector_->GetCpuOveruseMetrics(metrics); + *metrics = cpu_overuse_metrics_observer_->GetCpuOveruseMetrics(); } int32_t ViECapturer::SetCaptureDelay(int32_t delay_ms) { diff --git a/webrtc/video_engine/vie_capturer.h b/webrtc/video_engine/vie_capturer.h index 00e2f36885..3183d8c43e 100644 --- a/webrtc/video_engine/vie_capturer.h +++ b/webrtc/video_engine/vie_capturer.h @@ -13,6 +13,7 @@ #include +#include "webrtc/base/criticalsection.h" #include "webrtc/base/thread_annotations.h" #include "webrtc/common_types.h" #include "webrtc/engine_configurations.h" @@ -20,6 +21,7 @@ #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" #include "webrtc/modules/video_coding/main/interface/video_coding.h" #include "webrtc/modules/video_processing/main/interface/video_processing.h" +#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/typedefs.h" #include "webrtc/video_engine/include/vie_base.h" @@ -39,6 +41,7 @@ class ThreadWrapper; class ViEEffectFilter; class ViEEncoder; struct ViEPicture; +class RegistrableCpuOveruseMetricsObserver; class ViECapturer : public ViEFrameProviderBase, @@ -107,6 +110,7 @@ class ViECapturer void RegisterCpuOveruseObserver(CpuOveruseObserver* observer); void SetCpuOveruseOptions(const CpuOveruseOptions& options); + void RegisterCpuOveruseMetricsObserver(CpuOveruseMetricsObserver* observer); void GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const; protected: @@ -187,6 +191,9 @@ class ViECapturer CaptureCapability requested_capability_; + // Must be declared before overuse_detector_ where it's registered. + const scoped_ptr + cpu_overuse_metrics_observer_; scoped_ptr overuse_detector_; }; diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index dbb07b194f..73dbb2b1f9 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -442,8 +442,7 @@ class ViEChannel if (callback_) callback_->Notify(total_stats, retransmit_stats, ssrc); } - } - send_bitrate_observer_; + } send_bitrate_observer_; class RegisterableFrameCountObserver : public RegisterableCallback { diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h index 0e41cc5054..eb6dfe679f 100644 --- a/webrtc/video_send_stream.h +++ b/webrtc/video_send_stream.h @@ -55,10 +55,14 @@ class VideoSendStream { Stats() : input_frame_rate(0), encode_frame_rate(0), + avg_encode_time_ms(0), + encode_usage_percent(0), media_bitrate_bps(0), suspended(false) {} int input_frame_rate; int encode_frame_rate; + int avg_encode_time_ms; + int encode_usage_percent; int media_bitrate_bps; bool suspended; std::map substreams;