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.
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_VIDEO_CAPTURE_DEVICE_IMPL_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_VIDEO_CAPTURE_DEVICE_IMPL_H_
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"
20 const int kMinFrameWidth
= 2;
21 const int kMinFrameHeight
= 2;
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);
29 // TODO(nick): Remove this once frame subscription is supported on Aura and
31 #if (defined(OS_WIN) || defined(OS_MACOSX)) || defined(USE_AURA)
32 const bool kAcceleratedSubscriberIsSupported
= true;
34 const bool kAcceleratedSubscriberIsSupported
= false;
37 class VideoCaptureMachine
;
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
> {
46 ThreadSafeCaptureOracle(scoped_ptr
<media::VideoCaptureDevice::Client
> client
,
47 scoped_ptr
<VideoCaptureOracle
> oracle
,
48 const media::VideoCaptureParams
& params
);
50 // Called when a captured frame is available or an error has occurred.
51 // If |success| is true then the frame provided is valid and |timestamp|
52 // indicates when the frame was painted.
53 // If |success| is false, both the frame provided and |timestamp| are invalid.
54 typedef base::Callback
<void(base::Time timestamp
, bool success
)>
57 bool ObserveEventAndDecideCapture(VideoCaptureOracle::Event event
,
58 base::Time event_time
,
59 scoped_refptr
<media::VideoFrame
>* storage
,
60 CaptureFrameCallback
* callback
);
62 base::TimeDelta
capture_period() const {
63 return oracle_
->capture_period();
66 // Updates capture resolution based on the supplied source size and the
67 // maximum frame size.
68 void UpdateCaptureSize(const gfx::Size
& source_size
);
70 // Stop new captures from happening (but doesn't forget the client).
73 // Signal an error to the client.
77 friend class base::RefCountedThreadSafe
<ThreadSafeCaptureOracle
>;
78 virtual ~ThreadSafeCaptureOracle();
80 // Callback invoked on completion of all captures.
82 scoped_refptr
<media::VideoCaptureDevice::Client::Buffer
> buffer
,
86 // Protects everything below it.
89 // Recipient of our capture activity.
90 scoped_ptr
<media::VideoCaptureDevice::Client
> client_
;
92 // Makes the decision to capture a frame.
93 const scoped_ptr
<VideoCaptureOracle
> oracle_
;
95 // The video capture parameters used to construct the oracle proxy.
96 const media::VideoCaptureParams params_
;
98 // Indicates if capture size has been updated after construction.
99 bool capture_size_updated_
;
101 // The current capturing resolution and frame rate.
102 gfx::Size capture_size_
;
106 // Keeps track of the video capture source frames and executes copying on the
108 class VideoCaptureMachine
{
110 VideoCaptureMachine() : started_(false) {}
111 virtual ~VideoCaptureMachine() {}
113 // This should only be checked on the UI thread.
114 bool started() const { return started_
; }
116 // Starts capturing. Returns true if succeeded.
117 // Must be run on the UI BrowserThread.
119 const scoped_refptr
<ThreadSafeCaptureOracle
>& oracle_proxy
) = 0;
121 // Stops capturing. Must be run on the UI BrowserThread.
122 virtual void Stop() = 0;
128 DISALLOW_COPY_AND_ASSIGN(VideoCaptureMachine
);
131 // The "meat" of the video capture implementation.
133 // Separating this from the "shell classes" WebContentsVideoCaptureDevice and
134 // BrowserCompositorCaptureDevice allows safe destruction without needing to
135 // block any threads (e.g., the IO BrowserThread), as well as code sharing.
137 // VideoCaptureDeviceImpl manages a simple state machine and the pipeline (see
138 // notes at top of this file). It times the start of successive
139 // captures and facilitates the processing of each through the stages of the
141 class CONTENT_EXPORT VideoCaptureDeviceImpl
142 : public base::SupportsWeakPtr
<VideoCaptureDeviceImpl
> {
144 VideoCaptureDeviceImpl(scoped_ptr
<VideoCaptureMachine
> capture_machine
);
145 virtual ~VideoCaptureDeviceImpl();
147 // Asynchronous requests to change VideoCaptureDeviceImpl state.
148 void AllocateAndStart(const media::VideoCaptureParams
& params
,
149 scoped_ptr
<media::VideoCaptureDevice::Client
> client
);
150 void StopAndDeAllocate();
153 // Flag indicating current state.
160 void TransitionStateTo(State next_state
);
162 // Called on the IO thread in response to StartCaptureMachine().
163 // |success| is true if capture machine succeeded to start.
164 void CaptureStarted(bool success
);
166 // Stops capturing and notifies client_ of an error state.
169 // Tracks that all activity occurs on the media stream manager's thread.
170 base::ThreadChecker thread_checker_
;
172 // Current lifecycle state.
175 // Tracks the CaptureMachine that's doing work on our behalf on the UI thread.
176 // This value should never be dereferenced by this class, other than to
177 // create and destroy it on the UI thread.
178 scoped_ptr
<VideoCaptureMachine
> capture_machine_
;
180 // Our thread-safe capture oracle which serves as the gateway to the video
181 // capture pipeline. Besides the WCVCD itself, it is the only component of the
182 // system with direct access to |client_|.
183 scoped_refptr
<ThreadSafeCaptureOracle
> oracle_proxy_
;
185 DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceImpl
);
189 } // namespace content
191 #endif // CONTENT_BROWSER_RENDERER_HOST_VIDEO_CAPTURE_DEVICE_IMPL_H_