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

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

Issue 2936373002: Revert of media: add video capture device for ARC++ camera HAL v3 (Closed)
Patch Set: Created 3 years, 6 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 #include "media/capture/video/chromeos/camera_device_delegate.h"
6
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/memory/ptr_util.h"
12 #include "media/base/bind_to_current_loop.h"
13 #include "media/capture/video/chromeos/camera_device_context.h"
14 #include "media/capture/video/chromeos/camera_hal_delegate.h"
15 #include "media/capture/video/chromeos/camera_metadata_utils.h"
16 #include "media/capture/video/chromeos/pixel_format_utils.h"
17 #include "media/capture/video/chromeos/stream_buffer_manager.h"
18 #include "mojo/edk/embedder/embedder.h"
19 #include "mojo/edk/embedder/scoped_platform_handle.h"
20
21 namespace media {
22
23 StreamCaptureInterface::Plane::Plane() {}
24
25 StreamCaptureInterface::Plane::~Plane() {}
26
27 class CameraDeviceDelegate::StreamCaptureInterfaceImpl final
28 : public StreamCaptureInterface {
29 public:
30 StreamCaptureInterfaceImpl(
31 base::WeakPtr<CameraDeviceDelegate> camera_device_delegate)
32 : camera_device_delegate_(std::move(camera_device_delegate)) {}
33
34 void RegisterBuffer(uint64_t buffer_id,
35 arc::mojom::Camera3DeviceOps::BufferType type,
36 uint32_t drm_format,
37 arc::mojom::HalPixelFormat hal_pixel_format,
38 uint32_t width,
39 uint32_t height,
40 std::vector<StreamCaptureInterface::Plane> planes,
41 base::OnceCallback<void(int32_t)> callback) final {
42 if (camera_device_delegate_) {
43 camera_device_delegate_->RegisterBuffer(
44 buffer_id, type, drm_format, hal_pixel_format, width, height,
45 std::move(planes), std::move(callback));
46 }
47 }
48
49 void ProcessCaptureRequest(arc::mojom::Camera3CaptureRequestPtr request,
50 base::OnceCallback<void(int32_t)> callback) final {
51 if (camera_device_delegate_) {
52 camera_device_delegate_->ProcessCaptureRequest(std::move(request),
53 std::move(callback));
54 }
55 }
56
57 private:
58 const base::WeakPtr<CameraDeviceDelegate> camera_device_delegate_;
59 };
60
61 CameraDeviceDelegate::CameraDeviceDelegate(
62 VideoCaptureDeviceDescriptor device_descriptor,
63 scoped_refptr<CameraHalDelegate> camera_hal_delegate,
64 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner)
65 : device_descriptor_(device_descriptor),
66 camera_id_(std::stoi(device_descriptor.device_id)),
67 camera_hal_delegate_(std::move(camera_hal_delegate)),
68 ipc_task_runner_(std::move(ipc_task_runner)),
69 weak_ptr_factory_(this) {}
70
71 CameraDeviceDelegate::~CameraDeviceDelegate() {}
72
73 void CameraDeviceDelegate::AllocateAndStart(
74 const VideoCaptureParams& params,
75 std::unique_ptr<VideoCaptureDevice::Client> client) {
76 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
77
78 chrome_capture_params_ = params;
79 device_context_.reset(new CameraDeviceContext(std::move(client)));
80 device_context_->SetState(CameraDeviceContext::State::kStarting);
81
82 // We need to get the static camera metadata of the camera device first.
83 camera_hal_delegate_->GetCameraInfo(
84 camera_id_, BindToCurrentLoop(base::Bind(
85 &CameraDeviceDelegate::OnGotCameraInfo, GetWeakPtr())));
86 }
87
88 void CameraDeviceDelegate::StopAndDeAllocate(
89 base::Closure device_close_callback) {
90 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
91 // StopAndDeAllocate may be called at any state except
92 // CameraDeviceContext::State::kStopping.
93 DCHECK_NE(device_context_->GetState(), CameraDeviceContext::State::kStopping);
94
95 if (device_context_->GetState() == CameraDeviceContext::State::kStopped) {
96 // In case of Mojo connection error the device may be stopped before
97 // StopAndDeAllocate is called.
98 std::move(device_close_callback).Run();
99 return;
100 }
101
102 device_close_callback_ = std::move(device_close_callback);
103 device_context_->SetState(CameraDeviceContext::State::kStopping);
104 if (!device_ops_.is_bound()) {
105 // The device delegate is in the process of opening the camera device.
106 return;
107 }
108 stream_buffer_manager_->StopCapture();
109 device_ops_->Close(base::Bind(&CameraDeviceDelegate::OnClosed, GetWeakPtr()));
110 }
111
112 void CameraDeviceDelegate::TakePhoto(
113 VideoCaptureDevice::TakePhotoCallback callback) {
114 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
115 // TODO(jcliang): Implement TakePhoto.
116 NOTIMPLEMENTED() << "TakePhoto is not implemented";
117 }
118
119 void CameraDeviceDelegate::GetPhotoState(
120 VideoCaptureDevice::GetPhotoStateCallback callback) {
121 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
122 // TODO(jcliang): Implement GetPhotoState.
123 NOTIMPLEMENTED() << "GetPhotoState is not implemented";
124 }
125
126 void CameraDeviceDelegate::SetPhotoOptions(
127 mojom::PhotoSettingsPtr settings,
128 VideoCaptureDevice::SetPhotoOptionsCallback callback) {
129 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
130 // TODO(jcliang): Implement SetPhotoOptions.
131 NOTIMPLEMENTED() << "SetPhotoOptions is not implemented";
132 }
133
134 void CameraDeviceDelegate::SetRotation(int rotation) {
135 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
136 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0);
137 device_context_->SetRotation(rotation);
138 }
139
140 base::WeakPtr<CameraDeviceDelegate> CameraDeviceDelegate::GetWeakPtr() {
141 return weak_ptr_factory_.GetWeakPtr();
142 }
143
144 void CameraDeviceDelegate::OnMojoConnectionError() {
145 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
146
147 if (device_context_->GetState() == CameraDeviceContext::State::kStopping) {
148 // When in stopping state the camera HAL adapter may terminate the Mojo
149 // channel before we do, in which case the OnClosed callback will not be
150 // called.
151 OnClosed(0);
152 } else {
153 // The Mojo channel terminated unexpectedly.
154 stream_buffer_manager_->StopCapture();
155 device_context_->SetState(CameraDeviceContext::State::kStopped);
156 device_context_->SetErrorState(FROM_HERE, "Mojo connection error");
157 ResetMojoInterface();
158 // We cannnot reset |device_context_| here because
159 // |device_context_->SetErrorState| above will call StopAndDeAllocate later
160 // to handle the class destruction.
161 }
162 }
163
164 void CameraDeviceDelegate::OnClosed(int32_t result) {
165 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
166 DCHECK_EQ(device_context_->GetState(), CameraDeviceContext::State::kStopping);
167
168 device_context_->SetState(CameraDeviceContext::State::kStopped);
169 if (result) {
170 device_context_->LogToClient(std::string("Failed to close device: ") +
171 std::string(strerror(result)));
172 }
173 ResetMojoInterface();
174 device_context_.reset();
175 std::move(device_close_callback_).Run();
176 }
177
178 void CameraDeviceDelegate::ResetMojoInterface() {
179 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
180
181 device_ops_.reset();
182 stream_buffer_manager_.reset();
183 }
184
185 void CameraDeviceDelegate::OnGotCameraInfo(
186 int32_t result,
187 arc::mojom::CameraInfoPtr camera_info) {
188 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
189
190 if (device_context_->GetState() != CameraDeviceContext::State::kStarting) {
191 DCHECK_EQ(device_context_->GetState(),
192 CameraDeviceContext::State::kStopping);
193 OnClosed(0);
194 return;
195 }
196
197 if (result) {
198 device_context_->SetErrorState(FROM_HERE, "Failed to get camera info");
199 return;
200 }
201 static_metadata_ = std::move(camera_info->static_camera_characteristics);
202 // |device_ops_| is bound after the MakeRequest call.
203 arc::mojom::Camera3DeviceOpsRequest device_ops_request =
204 mojo::MakeRequest(&device_ops_);
205 device_ops_.set_connection_error_handler(
206 base::Bind(&CameraDeviceDelegate::OnMojoConnectionError, GetWeakPtr()));
207 camera_hal_delegate_->OpenDevice(
208 camera_id_, std::move(device_ops_request),
209 BindToCurrentLoop(
210 base::Bind(&CameraDeviceDelegate::OnOpenedDevice, GetWeakPtr())));
211 }
212
213 void CameraDeviceDelegate::OnOpenedDevice(int32_t result) {
214 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
215
216 if (device_context_->GetState() != CameraDeviceContext::State::kStarting) {
217 DCHECK_EQ(device_context_->GetState(),
218 CameraDeviceContext::State::kStopping);
219 OnClosed(0);
220 return;
221 }
222
223 if (result) {
224 device_context_->SetErrorState(FROM_HERE, "Failed to open camera device");
225 return;
226 }
227 Initialize();
228 }
229
230 void CameraDeviceDelegate::Initialize() {
231 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
232 DCHECK_EQ(device_context_->GetState(), CameraDeviceContext::State::kStarting);
233
234 arc::mojom::Camera3CallbackOpsPtr callback_ops_ptr;
235 arc::mojom::Camera3CallbackOpsRequest callback_ops_request =
236 mojo::MakeRequest(&callback_ops_ptr);
237 stream_buffer_manager_ = base::MakeUnique<StreamBufferManager>(
238 std::move(callback_ops_request),
239 base::MakeUnique<StreamCaptureInterfaceImpl>(GetWeakPtr()),
240 device_context_.get(), ipc_task_runner_);
241 device_ops_->Initialize(
242 std::move(callback_ops_ptr),
243 base::Bind(&CameraDeviceDelegate::OnInitialized, GetWeakPtr()));
244 }
245
246 void CameraDeviceDelegate::OnInitialized(int32_t result) {
247 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
248
249 if (device_context_->GetState() != CameraDeviceContext::State::kStarting) {
250 DCHECK_EQ(device_context_->GetState(),
251 CameraDeviceContext::State::kStopping);
252 return;
253 }
254 if (result) {
255 device_context_->SetErrorState(
256 FROM_HERE, std::string("Failed to initialize camera device") +
257 std::string(strerror(result)));
258 return;
259 }
260 device_context_->SetState(CameraDeviceContext::State::kInitialized);
261 ConfigureStreams();
262 }
263
264 void CameraDeviceDelegate::ConfigureStreams() {
265 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
266 DCHECK_EQ(device_context_->GetState(),
267 CameraDeviceContext::State::kInitialized);
268
269 // Set up context for preview stream.
270 arc::mojom::Camera3StreamPtr preview_stream =
271 arc::mojom::Camera3Stream::New();
272 preview_stream->id = static_cast<uint64_t>(
273 arc::mojom::Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW);
274 preview_stream->stream_type =
275 arc::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
276 preview_stream->width =
277 chrome_capture_params_.requested_format.frame_size.width();
278 preview_stream->height =
279 chrome_capture_params_.requested_format.frame_size.height();
280 preview_stream->format =
281 arc::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888;
282 preview_stream->data_space = 0;
283 preview_stream->rotation =
284 arc::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
285
286 arc::mojom::Camera3StreamConfigurationPtr stream_config =
287 arc::mojom::Camera3StreamConfiguration::New();
288 stream_config->streams.push_back(std::move(preview_stream));
289 stream_config->operation_mode = arc::mojom::Camera3StreamConfigurationMode::
290 CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
291 device_ops_->ConfigureStreams(
292 std::move(stream_config),
293 base::Bind(&CameraDeviceDelegate::OnConfiguredStreams, GetWeakPtr()));
294 }
295
296 void CameraDeviceDelegate::OnConfiguredStreams(
297 int32_t result,
298 arc::mojom::Camera3StreamConfigurationPtr updated_config) {
299 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
300
301 if (device_context_->GetState() != CameraDeviceContext::State::kInitialized) {
302 DCHECK_EQ(device_context_->GetState(),
303 CameraDeviceContext::State::kStopping);
304 return;
305 }
306 if (result) {
307 device_context_->SetErrorState(
308 FROM_HERE, std::string("Failed to configure streams: ") +
309 std::string(strerror(result)));
310 return;
311 }
312 if (!updated_config || updated_config->streams.size() != 1) {
313 device_context_->SetErrorState(
314 FROM_HERE, std::string("Wrong number of streams configured: ") +
315 std::to_string(updated_config->streams.size()));
316 return;
317 }
318
319 VideoCaptureFormat capture_format = chrome_capture_params_.requested_format;
320 // TODO(jcliang): Determine the best format from metadata.
321 capture_format.pixel_format = PIXEL_FORMAT_NV12;
322
323 // The partial result count metadata is optional; defaults to 1 in case it
324 // is not set in the static metadata.
325 uint32_t partial_result_count = 1;
326 const arc::mojom::CameraMetadataEntryPtr* partial_count = GetMetadataEntry(
327 static_metadata_,
328 arc::mojom::CameraMetadataTag::ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
329 if (partial_count) {
330 partial_result_count =
331 *reinterpret_cast<int32_t*>((*partial_count)->data.data());
332 }
333 stream_buffer_manager_->SetUpStreamAndBuffers(
334 capture_format, partial_result_count,
335 std::move(updated_config->streams[0]));
336
337 device_context_->SetState(CameraDeviceContext::State::kStreamConfigured);
338 ConstructDefaultRequestSettings();
339 }
340
341 void CameraDeviceDelegate::ConstructDefaultRequestSettings() {
342 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
343 DCHECK_EQ(device_context_->GetState(),
344 CameraDeviceContext::State::kStreamConfigured);
345
346 device_ops_->ConstructDefaultRequestSettings(
347 arc::mojom::Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW,
348 base::Bind(&CameraDeviceDelegate::OnConstructedDefaultRequestSettings,
349 GetWeakPtr()));
350 }
351
352 void CameraDeviceDelegate::OnConstructedDefaultRequestSettings(
353 arc::mojom::CameraMetadataPtr settings) {
354 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
355
356 if (device_context_->GetState() !=
357 CameraDeviceContext::State::kStreamConfigured) {
358 DCHECK_EQ(device_context_->GetState(),
359 CameraDeviceContext::State::kStopping);
360 return;
361 }
362 if (!settings) {
363 device_context_->SetErrorState(FROM_HERE,
364 "Failed to get default request settings");
365 return;
366 }
367 device_context_->SetState(CameraDeviceContext::State::kCapturing);
368 stream_buffer_manager_->StartCapture(std::move(settings));
369 }
370
371 void CameraDeviceDelegate::RegisterBuffer(
372 uint64_t buffer_id,
373 arc::mojom::Camera3DeviceOps::BufferType type,
374 uint32_t drm_format,
375 arc::mojom::HalPixelFormat hal_pixel_format,
376 uint32_t width,
377 uint32_t height,
378 std::vector<StreamCaptureInterface::Plane> planes,
379 base::OnceCallback<void(int32_t)> callback) {
380 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
381
382 if (device_context_->GetState() != CameraDeviceContext::State::kCapturing) {
383 DCHECK_EQ(device_context_->GetState(),
384 CameraDeviceContext::State::kStopping);
385 return;
386 }
387 size_t num_planes = planes.size();
388 std::vector<mojo::ScopedHandle> fds(num_planes);
389 std::vector<uint32_t> strides(num_planes);
390 std::vector<uint32_t> offsets(num_planes);
391 for (size_t i = 0; i < num_planes; ++i) {
392 fds[i] = std::move(planes[i].fd);
393 strides[i] = planes[i].stride;
394 offsets[i] = planes[i].offset;
395 }
396 device_ops_->RegisterBuffer(
397 buffer_id, type, std::move(fds), drm_format, hal_pixel_format, width,
398 height, std::move(strides), std::move(offsets), std::move(callback));
399 }
400
401 void CameraDeviceDelegate::ProcessCaptureRequest(
402 arc::mojom::Camera3CaptureRequestPtr request,
403 base::OnceCallback<void(int32_t)> callback) {
404 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
405
406 if (device_context_->GetState() != CameraDeviceContext::State::kCapturing) {
407 DCHECK_EQ(device_context_->GetState(),
408 CameraDeviceContext::State::kStopping);
409 return;
410 }
411 device_ops_->ProcessCaptureRequest(std::move(request), std::move(callback));
412 }
413
414 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/chromeos/camera_device_delegate.h ('k') | media/capture/video/chromeos/camera_device_delegate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698