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