Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / media / video_capture_device_impl.h
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 media::VideoCaptureParams& params);
49
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::TimeTicks timestamp, bool success)>
55       CaptureFrameCallback;
56
57   bool ObserveEventAndDecideCapture(VideoCaptureOracle::Event event,
58                                     base::TimeTicks event_time,
59                                     scoped_refptr<media::VideoFrame>* storage,
60                                     CaptureFrameCallback* callback);
61
62   base::TimeDelta capture_period() const {
63     return oracle_->capture_period();
64   }
65
66   // Updates capture resolution based on the supplied source size and the
67   // maximum frame size.
68   void UpdateCaptureSize(const gfx::Size& source_size);
69
70   // Stop new captures from happening (but doesn't forget the client).
71   void Stop();
72
73   // Signal an error to the client.
74   void ReportError(const std::string& reason);
75
76  private:
77   friend class base::RefCountedThreadSafe<ThreadSafeCaptureOracle>;
78   virtual ~ThreadSafeCaptureOracle();
79
80   // Callback invoked on completion of all captures.
81   void DidCaptureFrame(
82       scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer,
83       int frame_number,
84       base::TimeTicks timestamp,
85       bool success);
86   // Protects everything below it.
87   base::Lock lock_;
88
89   // Recipient of our capture activity.
90   scoped_ptr<media::VideoCaptureDevice::Client> client_;
91
92   // Makes the decision to capture a frame.
93   const scoped_ptr<VideoCaptureOracle> oracle_;
94
95   // The video capture parameters used to construct the oracle proxy.
96   const media::VideoCaptureParams params_;
97
98   // Indicates if capture size has been updated after construction.
99   bool capture_size_updated_;
100
101   // The current capturing resolution and frame rate.
102   gfx::Size capture_size_;
103   int frame_rate_;
104 };
105
106 // Keeps track of the video capture source frames and executes copying on the
107 // UI BrowserThread.
108 class VideoCaptureMachine {
109  public:
110   VideoCaptureMachine() : started_(false) {}
111   virtual ~VideoCaptureMachine() {}
112
113   // This should only be checked on the UI thread.
114   bool started() const { return started_; }
115
116   // Starts capturing. Returns true if succeeded.
117   // Must be run on the UI BrowserThread.
118   virtual bool Start(
119       const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) = 0;
120
121   // Stops capturing. Must be run on the UI BrowserThread.
122   // |callback| is invoked after the capturing has stopped.
123   virtual void Stop(const base::Closure& callback) = 0;
124
125  protected:
126   bool started_;
127
128  private:
129   DISALLOW_COPY_AND_ASSIGN(VideoCaptureMachine);
130 };
131
132 // The "meat" of the video capture implementation.
133 //
134 // Separating this from the "shell classes" WebContentsVideoCaptureDevice and
135 // BrowserCompositorCaptureDevice allows safe destruction without needing to
136 // block any threads (e.g., the IO BrowserThread), as well as code sharing.
137 //
138 // VideoCaptureDeviceImpl manages a simple state machine and the pipeline (see
139 // notes at top of this file).  It times the start of successive
140 // captures and facilitates the processing of each through the stages of the
141 // pipeline.
142 class CONTENT_EXPORT VideoCaptureDeviceImpl
143     : public base::SupportsWeakPtr<VideoCaptureDeviceImpl> {
144  public:
145   VideoCaptureDeviceImpl(scoped_ptr<VideoCaptureMachine> capture_machine);
146   virtual ~VideoCaptureDeviceImpl();
147
148   // Asynchronous requests to change VideoCaptureDeviceImpl state.
149   void AllocateAndStart(const media::VideoCaptureParams& params,
150                         scoped_ptr<media::VideoCaptureDevice::Client> client);
151   void StopAndDeAllocate();
152
153  private:
154   // Flag indicating current state.
155   enum State {
156     kIdle,
157     kCapturing,
158     kError
159   };
160
161   void TransitionStateTo(State next_state);
162
163   // Called on the IO thread in response to StartCaptureMachine().
164   // |success| is true if capture machine succeeded to start.
165   void CaptureStarted(bool success);
166
167   // Stops capturing and notifies client_ of an error state.
168   void Error(const std::string& reason);
169
170   // Tracks that all activity occurs on the media stream manager's thread.
171   base::ThreadChecker thread_checker_;
172
173   // Current lifecycle state.
174   State state_;
175
176   // Tracks the CaptureMachine that's doing work on our behalf on the UI thread.
177   // This value should never be dereferenced by this class, other than to
178   // create and destroy it on the UI thread.
179   scoped_ptr<VideoCaptureMachine> capture_machine_;
180
181   // Our thread-safe capture oracle which serves as the gateway to the video
182   // capture pipeline. Besides the WCVCD itself, it is the only component of the
183   // system with direct access to |client_|.
184   scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
185
186   DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceImpl);
187 };
188
189
190 }  // namespace content
191
192 #endif  // CONTENT_BROWSER_RENDERER_HOST_VIDEO_CAPTURE_DEVICE_IMPL_H_