1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_MEDIA_CAPTURE_CONTENT_VIDEO_CAPTURE_DEVICE_CORE_H_ 6 #define CONTENT_BROWSER_MEDIA_CAPTURE_CONTENT_VIDEO_CAPTURE_DEVICE_CORE_H_ 7 8 #include <string> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/threading/thread.h" 13 #include "base/threading/thread_checker.h" 14 #include "content/browser/media/capture/video_capture_oracle.h" 15 #include "content/common/content_export.h" 16 #include "media/base/video_frame.h" 17 #include "media/video/capture/video_capture_device.h" 18 19 namespace media { 20 class VideoCaptureParams; 21 class VideoFrame; 22 } // namespace media 23 24 namespace content { 25 26 const int kMinFrameWidth = 2; 27 const int kMinFrameHeight = 2; 28 29 // Returns the nearest even integer closer to zero. 30 template<typename IntType> 31 IntType MakeEven(IntType x) { 32 return x & static_cast<IntType>(-2); 33 } 34 35 // TODO(nick): Remove this once frame subscription is supported on Aura and 36 // Linux. 37 #if (defined(OS_WIN) || defined(OS_MACOSX)) || defined(USE_AURA) 38 const bool kAcceleratedSubscriberIsSupported = true; 39 #else 40 const bool kAcceleratedSubscriberIsSupported = false; 41 #endif 42 43 class VideoCaptureMachine; 44 45 // Thread-safe, refcounted proxy to the VideoCaptureOracle. This proxy wraps 46 // the VideoCaptureOracle, which decides which frames to capture, and a 47 // VideoCaptureDevice::Client, which allocates and receives the captured 48 // frames, in a lock to synchronize state between the two. 49 class ThreadSafeCaptureOracle 50 : public base::RefCountedThreadSafe<ThreadSafeCaptureOracle> { 51 public: 52 ThreadSafeCaptureOracle(scoped_ptr<media::VideoCaptureDevice::Client> client, 53 scoped_ptr<VideoCaptureOracle> oracle, 54 const media::VideoCaptureParams& params); 55 56 // Called when a captured frame is available or an error has occurred. 57 // If |success| is true then |frame| is valid and |timestamp| indicates when 58 // the frame was painted. 59 // If |success| is false, all other parameters are invalid. 60 typedef base::Callback<void(const scoped_refptr<media::VideoFrame>& frame, 61 base::TimeTicks timestamp, 62 bool success)> CaptureFrameCallback; 63 64 bool ObserveEventAndDecideCapture(VideoCaptureOracle::Event event, 65 const gfx::Rect& damage_rect, 66 base::TimeTicks event_time, 67 scoped_refptr<media::VideoFrame>* storage, 68 CaptureFrameCallback* callback); 69 70 base::TimeDelta min_capture_period() const { 71 return oracle_->min_capture_period(); 72 } 73 74 // Returns the current capture resolution. 75 gfx::Size GetCaptureSize() const; 76 77 // Updates capture resolution based on the supplied source size and the 78 // maximum frame size. 79 void UpdateCaptureSize(const gfx::Size& source_size); 80 81 // Stop new captures from happening (but doesn't forget the client). 82 void Stop(); 83 84 // Signal an error to the client. 85 void ReportError(const std::string& reason); 86 87 private: 88 friend class base::RefCountedThreadSafe<ThreadSafeCaptureOracle>; 89 virtual ~ThreadSafeCaptureOracle(); 90 91 // Callback invoked on completion of all captures. 92 void DidCaptureFrame( 93 int frame_number, 94 const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer, 95 const scoped_refptr<media::VideoFrame>& frame, 96 base::TimeTicks timestamp, 97 bool success); 98 99 // Protects everything below it. 100 mutable base::Lock lock_; 101 102 // Recipient of our capture activity. 103 scoped_ptr<media::VideoCaptureDevice::Client> client_; 104 105 // Makes the decision to capture a frame. 106 const scoped_ptr<VideoCaptureOracle> oracle_; 107 108 // The video capture parameters used to construct the oracle proxy. 109 media::VideoCaptureParams params_; 110 111 // Indicates if capture size has been updated after construction. 112 bool capture_size_updated_; 113 114 // The current capturing format, as a media::VideoFrame::Format. 115 media::VideoFrame::Format video_frame_format_; 116 }; 117 118 // Keeps track of the video capture source frames and executes copying on the 119 // UI BrowserThread. 120 class VideoCaptureMachine { 121 public: 122 VideoCaptureMachine() {} 123 virtual ~VideoCaptureMachine() {} 124 125 // Starts capturing. Returns true if succeeded. 126 // Must be run on the UI BrowserThread. 127 virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, 128 const media::VideoCaptureParams& params) = 0; 129 130 // Stops capturing. Must be run on the UI BrowserThread. 131 // |callback| is invoked after the capturing has stopped. 132 virtual void Stop(const base::Closure& callback) = 0; 133 134 private: 135 DISALLOW_COPY_AND_ASSIGN(VideoCaptureMachine); 136 }; 137 138 // The "meat" of a content video capturer. 139 // 140 // Separating this from the "shell classes" WebContentsVideoCaptureDevice and 141 // DesktopCaptureDeviceAura allows safe destruction without needing to block any 142 // threads, as well as code sharing. 143 // 144 // ContentVideoCaptureDeviceCore manages a simple state machine and the pipeline 145 // (see notes at top of this file). It times the start of successive captures 146 // and facilitates the processing of each through the stages of the 147 // pipeline. 148 class CONTENT_EXPORT ContentVideoCaptureDeviceCore 149 : public base::SupportsWeakPtr<ContentVideoCaptureDeviceCore> { 150 public: 151 ContentVideoCaptureDeviceCore( 152 scoped_ptr<VideoCaptureMachine> capture_machine); 153 virtual ~ContentVideoCaptureDeviceCore(); 154 155 // Asynchronous requests to change ContentVideoCaptureDeviceCore state. 156 void AllocateAndStart(const media::VideoCaptureParams& params, 157 scoped_ptr<media::VideoCaptureDevice::Client> client); 158 void StopAndDeAllocate(); 159 160 private: 161 // Flag indicating current state. 162 enum State { 163 kIdle, 164 kCapturing, 165 kError 166 }; 167 168 void TransitionStateTo(State next_state); 169 170 // Called back in response to StartCaptureMachine(). |success| is true if 171 // capture machine succeeded to start. 172 void CaptureStarted(bool success); 173 174 // Stops capturing and notifies client_ of an error state. 175 void Error(const std::string& reason); 176 177 // Tracks that all activity occurs on the media stream manager's thread. 178 base::ThreadChecker thread_checker_; 179 180 // Current lifecycle state. 181 State state_; 182 183 // Tracks the CaptureMachine that's doing work on our behalf on the UI thread. 184 // This value should never be dereferenced by this class, other than to 185 // create and destroy it on the UI thread. 186 scoped_ptr<VideoCaptureMachine> capture_machine_; 187 188 // Our thread-safe capture oracle which serves as the gateway to the video 189 // capture pipeline. Besides the VideoCaptureDevice itself, it is the only 190 // component of the system with direct access to |client_|. 191 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; 192 193 DISALLOW_COPY_AND_ASSIGN(ContentVideoCaptureDeviceCore); 194 }; 195 196 197 } // namespace content 198 199 #endif // CONTENT_BROWSER_MEDIA_CAPTURE_CONTENT_VIDEO_CAPTURE_DEVICE_CORE_H_ 200