Bug 1060796 - Limit screen capture FPS. r=jesup, a=lmandel
authorGian-Carlo Pascutto <gpascutto@mozilla.com>
Wed, 03 Sep 2014 10:48:09 +0200
changeset 216701 18ba9aece9bd
parent 216700 5638564e0d94
child 216702 02474d192901
push id3883
push userryanvm@gmail.com
push date2014-09-11 20:34 +0000
treeherdermozilla-beta@d4082d3a082c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup, lmandel
bugs1060796
milestone33.0
Bug 1060796 - Limit screen capture FPS. r=jesup, a=lmandel
media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.cc
media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.h
--- a/media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.cc
+++ b/media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.cc
@@ -477,27 +477,30 @@ DesktopCaptureImpl::DesktopCaptureImpl(c
     _dataCallBack(NULL),
     _captureCallBack(NULL),
   _lastProcessFrameCount(TickTime::Now()),
   _rotateFrame(kRotateNone),
   last_capture_time_(TickTime::MillisecondTimestamp()),
   delta_ntp_internal_ms_(
                          Clock::GetRealTimeClock()->CurrentNtpInMilliseconds() -
                          TickTime::MillisecondTimestamp()),
+  time_event_(*EventWrapper::Create()),
   capturer_thread_(*ThreadWrapper::CreateThread(Run, this, kHighPriority, "ScreenCaptureThread")) {
   _requestedCapability.width = kDefaultWidth;
   _requestedCapability.height = kDefaultHeight;
   _requestedCapability.maxFPS = 30;
   _requestedCapability.rawType = kVideoI420;
   _requestedCapability.codecType = kVideoCodecUnknown;
   memset(_incomingFrameTimes, 0, sizeof(_incomingFrameTimes));
 }
 
 DesktopCaptureImpl::~DesktopCaptureImpl() {
+  time_event_.Set();
   capturer_thread_.Stop();
+  delete &time_event_;
   delete &capturer_thread_;
 
   DeRegisterCaptureDataCallback();
   DeRegisterCaptureCallback();
   delete &_callBackCs;
   delete &_apiCs;
 
   delete[] _deviceUniqueId;
@@ -799,17 +802,25 @@ void DesktopCaptureImpl::OnCaptureComple
 SharedMemory* DesktopCaptureImpl::CreateSharedMemory(size_t size) {
   return NULL;
 }
 
 void DesktopCaptureImpl::process() {
   DesktopRect desktop_rect;
   DesktopRegion desktop_region;
 
+  TickTime startProcessTime = TickTime::Now();
   desktop_capturer_cursor_composer_->Capture(DesktopRegion());
+  const uint32_t processTime =
+      (uint32_t)(TickTime::Now() - startProcessTime).Milliseconds();
+  // Use at most x% CPU or limit framerate
+  const uint32_t maxFPSNeeded = 1000/_requestedCapability.maxFPS;
+  const float sleepTimeFactor = (100.0f / kMaxDesktopCaptureCpuUsage) - 1.0f;
+  const uint32_t sleepTime = sleepTimeFactor * processTime;
+  time_event_.Wait(std::max<uint32_t>(maxFPSNeeded, sleepTime));
 }
 
 void DesktopCaptureImpl::OnCursorShapeChanged(MouseCursorShape* cursor_shape) {
   // do nothing, DesktopAndCursorComposer does it all
 }
 
 }  // namespace webrtc
 
--- a/media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.h
+++ b/media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.h
@@ -17,16 +17,17 @@
 
 #include "webrtc/common_video/interface/i420_video_frame.h"
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/modules/desktop_capture/screen_capturer.h"
 #include "webrtc/system_wrappers/interface/tick_util.h"
 #include "webrtc/modules/video_capture/video_capture_config.h"
 #include "webrtc/modules/desktop_capture/shared_memory.h"
 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
+#include "webrtc/system_wrappers/interface/event_wrapper.h"
 #include "webrtc/modules/desktop_capture/mouse_cursor_shape.h"
 #include "webrtc/modules/desktop_capture/desktop_device_info.h"
 #include "webrtc/modules/desktop_capture/desktop_and_cursor_composer.h"
 #include "webrtc/video_engine/include/vie_capture.h"
 
 using namespace webrtc::videocapturemodule;
 
 namespace webrtc {
@@ -212,16 +213,18 @@ public:
   virtual void OnCursorShapeChanged(MouseCursorShape* cursor_shape) OVERRIDE;
 
 protected:
   DesktopCaptureImpl(const int32_t id);
   virtual ~DesktopCaptureImpl();
   int32_t DeliverCapturedFrame(I420VideoFrame& captureFrame,
                                int64_t capture_time);
 
+  static const uint32_t kMaxDesktopCaptureCpuUsage = 50; // maximum CPU usage in %
+
   int32_t _id; // Module ID
   char* _deviceUniqueId; // current Device unique name;
   CriticalSectionWrapper& _apiCs;
   int32_t _captureDelay; // Current capture delay. May be changed of platform dependent parts.
   VideoCaptureCapability _requestedCapability; // Should be set by platform dependent code in StartCapture.
 
 private:
   void UpdateFrameCount();
@@ -256,14 +259,15 @@ public:
   static bool Run(void*obj) {
     static_cast<DesktopCaptureImpl*>(obj)->process();
     return true;
   };
   void process();
 
 private:
   scoped_ptr<DesktopAndCursorComposer> desktop_capturer_cursor_composer_;
+  EventWrapper& time_event_;
   ThreadWrapper&  capturer_thread_;
 };
 
 }  // namespace webrtc
 
 #endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_MAIN_SOURCE_DESKTOP_CAPTURE_IMPL_H_