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 19namespace media { 20class VideoCaptureParams; 21class VideoFrame; 22} // namespace media 23 24namespace content { 25 26const int kMinFrameWidth = 2; 27const int kMinFrameHeight = 2; 28 29// Returns the nearest even integer closer to zero. 30template<typename IntType> 31IntType 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) 38const bool kAcceleratedSubscriberIsSupported = true; 39#else 40const bool kAcceleratedSubscriberIsSupported = false; 41#endif 42 43class 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. 49class 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. 120class 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. 148class 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