Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(271)

Side by Side Diff: media/capture/video/chromeos/camera_device_delegate.h

Issue 2837273004: media: add video capture device for ARC++ camera HAL v3 (Closed)
Patch Set: address wuchengli@'s comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_DEVICE_DELEGATE_H_
6 #define MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_DEVICE_DELEGATE_H_
7
8 #include <map>
9 #include <memory>
10 #include <unordered_map>
11 #include <vector>
12
13 #include "base/macros.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "media/capture/video/chromeos/mojo/arc_camera3.mojom.h"
16 #include "media/capture/video/video_capture_device.h"
17 #include "media/capture/video_capture_types.h"
18 #include "mojo/public/cpp/bindings/binding.h"
19
20 namespace media {
21
22 // CameraDeviceDelegate is instantiated on the capture thread where
23 // AllocateAndStart of VideoCaptureDeviceArcChromeOS runs on. All the methods
24 // in CameraDeviceDelegate runs on |ipc_task_runner_| and hence all the
wuchengli 2017/05/08 04:22:03 s/runs/run/
jcliang 2017/05/13 08:53:15 Done.
25 // access to member variables is sequenced.
26 class CAPTURE_EXPORT CameraDeviceDelegate final
27 : public base::RefCountedThreadSafe<CameraDeviceDelegate>,
28 public arc::mojom::Camera3CallbackOps {
29 public:
30 enum State {
31 // The camera device is completely stopped. This is the initial state, and
32 // is also set in OnClosed().
33 kStopped,
34
35 // The camera device is starting and waiting to be initialized.
36 //
37 // The kStarting state is set in AllocateAndStart().
38 kStarting,
39
40 // The camera device is initialized and can accept stream configuration
41 // requests.
42 //
43 // The state is transitioned to kInitialized through:
44 //
45 // Initialize() -> OnInitialized()
46 kInitialized,
47
48 // The various capture streams are configured and the camera device is ready
49 // to process capture requests.
50 //
51 // The state is transitioned to kStreamConfigured through:
52 //
53 // ConfigureStreams() -> OnConfiguredStreams() ->
54 // ConstructDefaultRequestSettings() ->
55 // OnConstructedDefaultRequestSettings()
56 kStreamConfigured,
57
58 // The camera device is capturing video streams.
59 //
60 // The kCapturing state is set in StartCapture().
61 kCapturing,
62
63 // When the camera device is in the kCapturing state, a capture loop is
64 // constantly running:
65 //
66 // On the CameraDeviceDelegate side, we register and submit a capture
67 // request whenever a free buffer is available:
68 //
69 // RegisterBuffer() -> OnRegisteredBuffer() ->
70 // ProcessCaptureRequest() -> OnProcessedCaptureRequest()
71 //
72 // We get various capture metadata and error notifications from the camera
73 // HAL through the following callbacks:
74 //
75 // ProcessCaptureResult()
76 // Notify()
77
78 // The camera device is going through the shut down process; in order to
79 // avoid race conditions, no new Mojo messages may be sent to camera HAL in
80 // the kStopping state.
81 //
82 // The kStopping state is set in StopAndDeAllocate().
83 kStopping,
84
85 // The camera device encountered an unrecoverable error and needs to be
86 // StopAndDeAllocate()'d.
87 //
88 // The kError state is set in SetErrorState().
89 kError,
90 };
91
92 CameraDeviceDelegate(
93 VideoCaptureDeviceDescriptor device_descriptor,
94 arc::mojom::CameraMetadataPtr static_metadata,
95 mojo::InterfacePtrInfo<arc::mojom::Camera3DeviceOps> device_ops_info,
96 const scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner);
97
98 // Converts the HAL pixel format |from| to Chromium pixel format. Returns
99 // PIXEL_FORMAT_UNKNOWN if |from| is not supported.
100 static VideoPixelFormat PixFormatHalToChromium(
101 arc::mojom::HalPixelFormat from);
102
103 // Converts the Chromium pixel format |from| to DRM pixel format. Returns 0
104 // if |from| is not supported.
105 static uint32_t PixFormatChromiumToDrm(VideoPixelFormat from);
106
107 // Delegation methods for the VideoCaptureDevice interface.
108 void AllocateAndStart(const VideoCaptureParams& params,
109 std::unique_ptr<VideoCaptureDevice::Client> client);
110 void StopAndDeAllocate(base::WaitableEvent* closed);
111 void TakePhoto(VideoCaptureDevice::TakePhotoCallback callback);
112 void GetPhotoCapabilities(
113 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback);
114 void SetPhotoOptions(mojom::PhotoSettingsPtr settings,
115 VideoCaptureDevice::SetPhotoOptionsCallback callback);
116
117 // Sets the frame rotation angle in |rotation_|.
wuchengli 2017/05/08 04:22:02 Document this in more detail. What's this for? Is
jcliang 2017/05/13 08:53:15 Done.
118 void SetRotation(int rotation);
119
120 private:
121 friend class base::RefCountedThreadSafe<CameraDeviceDelegate>;
122
123 ~CameraDeviceDelegate() = default;
124
125 // Sets the state.
126 void SetState(State state);
127
128 // Sets state to kError and call |client_->OnError| to tear down the
129 // VideoCaptureDevice.
130 void SetErrorState(const tracked_objects::Location& from_here,
131 const std::string& reason);
132
133 // Resets the Mojo interface and bindings.
134 void ResetMojoInterface();
135
136 // Mojo connection error handler.
137 void OnMojoConnectionError();
138
139 // Callback method for the Close Mojo IPC call. This method resets the Mojo
140 // connection and closes the camera device, then signals |closed_| to unblock
141 // the caller.
142 void OnClosed(int32_t result);
143
144 // Initializes the camera HAL. Initialize sets up the Camera3CallbackOps with
145 // the camera HAL. OnInitialized continues to ConfigureStreams if the
146 // Initialize call succeeds.
147 void Initialize();
148 void OnInitialized(int32_t result);
149
150 // ConfigureStreams sets up stream context in |streams_| and configure the
151 // streams with the camera HAL. OnConfiguredStreams updates |streams_| with
152 // the stream config returned, and allocates buffers as per |updated_config|
153 // indicates. If there's no error OnConfiguredStreams notifies
154 // |client_| the capture has started by calling OnStarted, and proceeds to
155 // ConstructDefaultRequestSettings.
156 void ConfigureStreams();
157 void OnConfiguredStreams(
158 arc::mojom::Camera3StreamConfigurationPtr updated_config);
159
160 // ConstructDefaultRequestSettings asks the camera HAL for the default request
161 // settings of each stream in |streams_|. OnConstructedDefaultRequestSettings
162 // sets the request settings for |stream_type| in |streams_|. If there's no
163 // error OnConstructedDefaultRequestSettings calls StartCapture to start the
164 // video capture loop.
165 void ConstructDefaultRequestSettings(
166 arc::mojom::Camera3RequestTemplate stream_type);
167 void OnConstructedDefaultRequestSettings(
168 arc::mojom::Camera3RequestTemplate stream_type,
169 arc::mojom::CameraMetadataPtr settings);
170
171 // StartCapture is the entry point to starting the video capture of
172 // |stream_type|. The way the video capture loop works is:
173 //
174 // (1) If there is a free buffer, RegisterBuffer registers the buffer with
175 // the camera HAL.
176 // (2) Once the free buffer is registered, ProcessCaptureRequest is called to
177 // issue a capture request which will eventually fill the registered
178 // buffer. Goto (1) to register the remaining free buffers.
179 // (3) The camera HAL returns shutter time of a capture request through
180 // Notify, and the filled buffer through ProcessCaptureResult.
181 // (4) Once all the result metadata are collected, SubmitCaptureResult is
182 // called to deliver the filled buffer to Chrome. After the buffer is
183 // consumed by Chrome it is enqueued back to the free buffer queue.
184 // Goto (1) to start another capture loop.
185 //
186 // The capture loop runs asynchronously. (1), (2), (3) and (4) may be
wuchengli 2017/05/08 04:22:03 "The capture loop runs asynchronously." is not ver
jcliang 2017/05/13 08:53:15 I've remove this since it's not important informat
187 // interleaved.
188 void StartCapture(arc::mojom::Camera3RequestTemplate stream_type);
189
190 // Registers a free buffer, if any, of |stream_type| to the camera HAL.
191 void RegisterBuffer(arc::mojom::Camera3RequestTemplate stream_type);
192
193 // Calls ProcessCaptureRequest if the buffer indicated by |buffer_index| is
194 // successfully registered.
195 void OnRegisteredBuffer(arc::mojom::Camera3RequestTemplate stream_type,
196 size_t buffer_index,
197 int32_t result);
198
199 // Creates and sends out a capture request for |stream_type|. The capture
200 // request contains the buffer handle indicated by |buffer_index|.
201 void ProcessCaptureRequest(arc::mojom::Camera3RequestTemplate stream_type,
202 size_t buffer_index);
203 // Calls RegisterBuffer to attempt to register any remaining free buffers of
204 // |stream_type|.
205 void OnProcessedCaptureRequest(arc::mojom::Camera3RequestTemplate stream_type,
206 int32_t result);
207
208 // Camera3CallbackOps implementations.
209
210 // ProcessCaptureResult receives the result metadata as well as the filled
211 // buffer from camera HAL. The result metadata may be divided and delivered
212 // in several stages. Before all the result metadata is received the partial
213 // results are kept in |partial_results_|.
214 void ProcessCaptureResult(arc::mojom::Camera3CaptureResultPtr result) final;
215
216 // Notify receives the shutter time of capture requests and various errors
217 // from camera HAL. The shutter time is used as the timestamp in the video
218 // frame delivered to Chrome.
219 void Notify(arc::mojom::Camera3NotifyMsgPtr message) final;
220
221 // Submits the captured buffer of frame |frame_number_| to Chrome, then
222 // enqueues the buffer to free buffer queue for the next capture request.
223 void SubmitCaptureResult(uint32_t frame_number);
224
225 VideoCaptureDeviceDescriptor device_descriptor_;
226 std::unique_ptr<VideoCaptureDevice::Client> client_;
227
228 // Stores the static camera characteristics of the camera device.
229 arc::mojom::CameraMetadataPtr static_metadata_;
230
231 // The state the CameraDeviceDelegate currently is in.
232 State state_;
233
234 base::WaitableEvent* closed_;
wuchengli 2017/05/08 04:22:02 Document the client owns this.
jcliang 2017/05/13 08:53:15 Done.
235
236 // Clockwise rotation in degrees. This value should be 0, 90, 180, or 270.
237 int rotation_;
238
239 // Mojo proxy and binding for the camera HAL device ops and callback ops API.
240 mojo::InterfacePtrInfo<arc::mojom::Camera3DeviceOps> device_ops_info_;
241 arc::mojom::Camera3DeviceOpsPtr device_ops_;
242 mojo::Binding<arc::mojom::Camera3CallbackOps> callback_ops_;
243
244 // Where all the Mojo IPC calls takes place.
245 const scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
246
247 // The frame number. Increased by one for each capture request sent; reset to
248 // zero in AllocateAndStart.
249 uint32_t frame_number_;
wuchengli 2017/05/08 04:22:02 How does HAL handle wrap-around? If the camera is
jcliang 2017/05/13 08:53:15 It should be okay for frame number to wrap around.
250
251 struct StreamContext {
252 // Capture parameters provided by Chrome.
253 VideoCaptureParams params;
254 // The actual pixel format used in the capture request.
255 VideoCaptureFormat capture_format;
256 // The camera HAL stream.
257 arc::mojom::Camera3StreamPtr stream;
258 // The request settings used in the capture request of this stream.
259 arc::mojom::CameraMetadataPtr request_settings;
260 // The allocated buffers of this stream.
261 std::vector<std::unique_ptr<base::SharedMemory>> buffers;
262 // The free buffers of this stream. The queue stores indices into the
263 // |buffers| vector.
264 std::queue<size_t> free_buffers;
265 };
266
267 StreamContext* GetStreamContext(
268 arc::mojom::Camera3RequestTemplate stream_type) {
269 auto it = streams_.find(stream_type);
wuchengli 2017/05/08 04:22:02 The style guides says the implementation should no
jcliang 2017/05/13 08:53:15 Done.
270 if (it == streams_.end()) {
271 return nullptr;
272 }
273 return &(it->second);
274 }
275
276 // Stores the stream context of each active stream.
277 std::unordered_map<arc::mojom::Camera3RequestTemplate, StreamContext>
wuchengli 2017/05/08 04:22:03 Let's use array or vector because we'll need to ac
jcliang 2017/05/13 08:53:15 This is now a unique ptr of a StreamContext after
278 streams_;
279
280 // CaptureResult is used to hold the partial capture results for each frame.
281 struct CaptureResult {
282 CaptureResult()
283 : metadata(arc::mojom::CameraMetadata::New()), partial_stage(0) {}
284 // |reference_time| and |timestamp| are derived from the shutter time of
285 // this frame. They are be passed to |client_->OnIncomingCapturedData|
286 // along with the |buffers| when the captured frame is submitted.
287 base::TimeTicks reference_time;
288 base::TimeDelta timestamp;
289 // The result metadata. Contains various information about the captured
290 // frame.
291 arc::mojom::CameraMetadataPtr metadata;
292 // The buffer handles that hold the captured data of this frame.
293 std::unordered_map<arc::mojom::Camera3RequestTemplate,
wuchengli 2017/05/08 04:22:03 JPEG (picture callback) won't be implemented anyti
jcliang 2017/05/13 08:53:15 Done.
294 arc::mojom::Camera3StreamBufferPtr>
295 buffers;
296 // The current stage of this partial result.
297 uint32_t partial_stage;
298 };
299
300 // The number of partial stages. |partial_result_count_| is learned by
301 // querying |static_metadata_|. In case the result count is absent in
302 // |static_metadata_|, it defaults to one which means all the result metadata
303 // and captured buffer of a frame are returned together in one shot.
304 uint32_t partial_result_count_;
305
306 // The shutter time of the first frame. We derive the |timestamp| of a frame
307 // using the difference between the frame's shutter time and
308 // |first_frame_shutter_time_|.
309 base::TimeTicks first_frame_shutter_time_;
310
311 // Stores the partial capture results of the current in-flight frames.
312 std::map<uint32_t, CaptureResult> partial_results_;
313
314 DISALLOW_IMPLICIT_CONSTRUCTORS(CameraDeviceDelegate);
315 };
316
317 } // namespace media
318
319 #endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_DEVICE_DELEGATE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698