1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // Modified from hardware/libhardware/modules/camera/Camera.cpp
18
19 #include <cstdlib>
20 #include <memory>
21 #include <vector>
22 #include <stdio.h>
23 #include <hardware/camera3.h>
24 #include <sync/sync.h>
25 #include <system/camera_metadata.h>
26 #include <system/graphics.h>
27 #include <utils/Mutex.h>
28
29 #include "metadata/metadata_common.h"
30
31 //#define LOG_NDEBUG 0
32 #define LOG_TAG "Camera"
33 #include <cutils/log.h>
34
35 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
36 #include <utils/Trace.h>
37
38 #include "camera.h"
39
40 #define CAMERA_SYNC_TIMEOUT 5000 // in msecs
41
42 namespace default_camera_hal {
43
44 extern "C" {
45 // Shim passed to the framework to close an opened device.
close_device(hw_device_t * dev)46 static int close_device(hw_device_t* dev)
47 {
48 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
49 Camera* cam = static_cast<Camera*>(cam_dev->priv);
50 return cam->close();
51 }
52 } // extern "C"
53
Camera(int id)54 Camera::Camera(int id)
55 : mId(id),
56 mSettingsSet(false),
57 mBusy(false),
58 mCallbackOps(NULL),
59 mInFlightTracker(new RequestTracker)
60 {
61 memset(&mTemplates, 0, sizeof(mTemplates));
62 memset(&mDevice, 0, sizeof(mDevice));
63 mDevice.common.tag = HARDWARE_DEVICE_TAG;
64 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
65 mDevice.common.close = close_device;
66 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
67 mDevice.priv = this;
68 }
69
~Camera()70 Camera::~Camera()
71 {
72 }
73
openDevice(const hw_module_t * module,hw_device_t ** device)74 int Camera::openDevice(const hw_module_t *module, hw_device_t **device)
75 {
76 ALOGI("%s:%d: Opening camera device", __func__, mId);
77 ATRACE_CALL();
78 android::Mutex::Autolock al(mDeviceLock);
79
80 if (mBusy) {
81 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
82 return -EBUSY;
83 }
84
85 int connectResult = connect();
86 if (connectResult != 0) {
87 return connectResult;
88 }
89 mBusy = true;
90 mDevice.common.module = const_cast<hw_module_t*>(module);
91 *device = &mDevice.common;
92 return 0;
93 }
94
getInfo(struct camera_info * info)95 int Camera::getInfo(struct camera_info *info)
96 {
97 info->device_version = mDevice.common.version;
98 initDeviceInfo(info);
99 if (!mStaticInfo) {
100 int res = loadStaticInfo();
101 if (res) {
102 return res;
103 }
104 }
105 info->static_camera_characteristics = mStaticInfo->raw_metadata();
106 info->facing = mStaticInfo->facing();
107 info->orientation = mStaticInfo->orientation();
108
109 return 0;
110 }
111
loadStaticInfo()112 int Camera::loadStaticInfo() {
113 // Using a lock here ensures |mStaticInfo| will only ever be set once,
114 // even in concurrent situations.
115 android::Mutex::Autolock al(mStaticInfoLock);
116
117 if (mStaticInfo) {
118 return 0;
119 }
120
121 std::unique_ptr<android::CameraMetadata> static_metadata =
122 std::make_unique<android::CameraMetadata>();
123 int res = initStaticInfo(static_metadata.get());
124 if (res) {
125 ALOGE("%s:%d: Failed to get static info from device.",
126 __func__, mId);
127 return res;
128 }
129
130 mStaticInfo.reset(StaticProperties::NewStaticProperties(
131 std::move(static_metadata)));
132 if (!mStaticInfo) {
133 ALOGE("%s:%d: Failed to initialize static properties from device metadata.",
134 __func__, mId);
135 return -ENODEV;
136 }
137
138 return 0;
139 }
140
close()141 int Camera::close()
142 {
143 ALOGI("%s:%d: Closing camera device", __func__, mId);
144 ATRACE_CALL();
145 android::Mutex::Autolock al(mDeviceLock);
146
147 if (!mBusy) {
148 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
149 return -EINVAL;
150 }
151
152 flush();
153 disconnect();
154 mBusy = false;
155 return 0;
156 }
157
initialize(const camera3_callback_ops_t * callback_ops)158 int Camera::initialize(const camera3_callback_ops_t *callback_ops)
159 {
160 int res;
161
162 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
163 mCallbackOps = callback_ops;
164 // per-device specific initialization
165 res = initDevice();
166 if (res != 0) {
167 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
168 return res;
169 }
170 return 0;
171 }
172
configureStreams(camera3_stream_configuration_t * stream_config)173 int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
174 {
175 android::Mutex::Autolock al(mDeviceLock);
176
177 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
178 ATRACE_CALL();
179
180 // Check that there are no in-flight requests.
181 if (!mInFlightTracker->Empty()) {
182 ALOGE("%s:%d: Can't configure streams while frames are in flight.",
183 __func__, mId);
184 return -EINVAL;
185 }
186
187 // Verify the set of streams in aggregate, and perform configuration if valid.
188 int res = validateStreamConfiguration(stream_config);
189 if (res) {
190 ALOGE("%s:%d: Failed to validate stream set", __func__, mId);
191 } else {
192 // Set up all streams. Since they've been validated,
193 // this should only result in fatal (-ENODEV) errors.
194 // This occurs after validation to ensure that if there
195 // is a non-fatal error, the stream configuration doesn't change states.
196 res = setupStreams(stream_config);
197 if (res) {
198 ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
199 }
200 }
201
202 // Set trackers based on result.
203 if (!res) {
204 // Success, set up the in-flight trackers for the new streams.
205 mInFlightTracker->SetStreamConfiguration(*stream_config);
206 // Must provide new settings for the new configuration.
207 mSettingsSet = false;
208 } else if (res != -EINVAL) {
209 // Fatal error, the old configuration is invalid.
210 mInFlightTracker->ClearStreamConfiguration();
211 }
212 // On a non-fatal error the old configuration, if any, remains valid.
213 return res;
214 }
215
validateStreamConfiguration(const camera3_stream_configuration_t * stream_config)216 int Camera::validateStreamConfiguration(
217 const camera3_stream_configuration_t* stream_config)
218 {
219 // Check that the configuration is well-formed.
220 if (stream_config == nullptr) {
221 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
222 return -EINVAL;
223 } else if (stream_config->num_streams == 0) {
224 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
225 return -EINVAL;
226 } else if (stream_config->streams == nullptr) {
227 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
228 return -EINVAL;
229 }
230
231 // Check that the configuration is supported.
232 // Make sure static info has been initialized before trying to use it.
233 if (!mStaticInfo) {
234 int res = loadStaticInfo();
235 if (res) {
236 return res;
237 }
238 }
239 if (!mStaticInfo->StreamConfigurationSupported(stream_config)) {
240 ALOGE("%s:%d: Stream configuration does not match static "
241 "metadata restrictions.", __func__, mId);
242 return -EINVAL;
243 }
244
245 // Dataspace support is poorly documented - unclear if the expectation
246 // is that a device supports ALL dataspaces that could match a given
247 // format. For now, defer to child class implementation.
248 // Rotation support isn't described by metadata, so must defer to device.
249 if (!validateDataspacesAndRotations(stream_config)) {
250 ALOGE("%s:%d: Device can not handle configuration "
251 "dataspaces or rotations.", __func__, mId);
252 return -EINVAL;
253 }
254
255 return 0;
256 }
257
isValidTemplateType(int type)258 bool Camera::isValidTemplateType(int type)
259 {
260 return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
261 }
262
constructDefaultRequestSettings(int type)263 const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
264 {
265 ALOGV("%s:%d: type=%d", __func__, mId, type);
266
267 if (!isValidTemplateType(type)) {
268 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
269 return NULL;
270 }
271
272 if (!mTemplates[type]) {
273 // Check if the device has the necessary features
274 // for the requested template. If not, don't bother.
275 if (!mStaticInfo->TemplateSupported(type)) {
276 ALOGW("%s:%d: Camera does not support template type %d",
277 __func__, mId, type);
278 return NULL;
279 }
280
281 // Initialize this template if it hasn't been initialized yet.
282 std::unique_ptr<android::CameraMetadata> new_template =
283 std::make_unique<android::CameraMetadata>();
284 int res = initTemplate(type, new_template.get());
285 if (res || !new_template) {
286 ALOGE("%s:%d: Failed to generate template of type: %d",
287 __func__, mId, type);
288 return NULL;
289 }
290 mTemplates[type] = std::move(new_template);
291 }
292
293 // The "locking" here only causes non-const methods to fail,
294 // which is not a problem since the CameraMetadata being locked
295 // is already const. Destructing automatically "unlocks".
296 return mTemplates[type]->getAndLock();
297 }
298
processCaptureRequest(camera3_capture_request_t * temp_request)299 int Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
300 {
301 int res;
302 // TODO(b/32917568): A capture request submitted or ongoing during a flush
303 // should be returned with an error; for now they are mutually exclusive.
304 android::Mutex::Autolock al(mFlushLock);
305
306 ATRACE_CALL();
307
308 if (temp_request == NULL) {
309 ALOGE("%s:%d: NULL request recieved", __func__, mId);
310 return -EINVAL;
311 }
312
313 // Make a persistent copy of request, since otherwise it won't live
314 // past the end of this method.
315 std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
316
317 ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
318
319 if (!mInFlightTracker->CanAddRequest(*request)) {
320 // Streams are full or frame number is not unique.
321 ALOGE("%s:%d: Can not add request.", __func__, mId);
322 return -EINVAL;
323 }
324
325 // Null/Empty indicates use last settings
326 if (request->settings.isEmpty() && !mSettingsSet) {
327 ALOGE("%s:%d: NULL settings without previous set Frame:%d",
328 __func__, mId, request->frame_number);
329 return -EINVAL;
330 }
331
332 if (request->input_buffer != NULL) {
333 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
334 request->input_buffer.get());
335 } else {
336 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
337 }
338
339 if (!isValidRequestSettings(request->settings)) {
340 ALOGE("%s:%d: Invalid request settings.", __func__, mId);
341 return -EINVAL;
342 }
343
344 // Pre-process output buffers.
345 if (request->output_buffers.size() <= 0) {
346 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
347 request->output_buffers.size());
348 return -EINVAL;
349 }
350 for (auto& output_buffer : request->output_buffers) {
351 res = preprocessCaptureBuffer(&output_buffer);
352 if (res)
353 return -ENODEV;
354 }
355
356 // Add the request to tracking.
357 if (!mInFlightTracker->Add(request)) {
358 ALOGE("%s:%d: Failed to track request for frame %d.",
359 __func__, mId, request->frame_number);
360 return -ENODEV;
361 }
362
363 // Valid settings have been provided (mSettingsSet is a misnomer;
364 // all that matters is that a previous request with valid settings
365 // has been passed to the device, not that they've been set).
366 mSettingsSet = true;
367
368 // Send the request off to the device for completion.
369 enqueueRequest(request);
370
371 // Request is now in flight. The device will call completeRequest
372 // asynchronously when it is done filling buffers and metadata.
373 return 0;
374 }
375
completeRequest(std::shared_ptr<CaptureRequest> request,int err)376 void Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
377 {
378 if (!mInFlightTracker->Remove(request)) {
379 ALOGE("%s:%d: Completed request %p is not being tracked. "
380 "It may have been cleared out during a flush.",
381 __func__, mId, request.get());
382 return;
383 }
384
385 // Since |request| has been removed from the tracking, this method
386 // MUST call sendResult (can still return a result in an error state, e.g.
387 // through completeRequestWithError) so the frame doesn't get lost.
388
389 if (err) {
390 ALOGE("%s:%d: Error completing request for frame %d.",
391 __func__, mId, request->frame_number);
392 completeRequestWithError(request);
393 return;
394 }
395
396 // Notify the framework with the shutter time (extracted from the result).
397 int64_t timestamp = 0;
398 // TODO(b/31360070): The general metadata methods should be part of the
399 // default_camera_hal namespace, not the v4l2_camera_hal namespace.
400 int res = v4l2_camera_hal::SingleTagValue(
401 request->settings, ANDROID_SENSOR_TIMESTAMP, ×tamp);
402 if (res) {
403 ALOGE("%s:%d: Request for frame %d is missing required metadata.",
404 __func__, mId, request->frame_number);
405 // TODO(b/31653322): Send RESULT error.
406 // For now sending REQUEST error instead.
407 completeRequestWithError(request);
408 return;
409 }
410 notifyShutter(request->frame_number, timestamp);
411
412 // TODO(b/31653322): Check all returned buffers for errors
413 // (if any, send BUFFER error).
414
415 sendResult(request);
416 }
417
flush()418 int Camera::flush()
419 {
420 ALOGV("%s:%d: Flushing.", __func__, mId);
421 // TODO(b/32917568): Synchronization. Behave "appropriately"
422 // (i.e. according to camera3.h) if process_capture_request()
423 // is called concurrently with this (in either order).
424 // Since the callback to completeRequest also may happen on a separate
425 // thread, this function should behave nicely concurrently with that too.
426 android::Mutex::Autolock al(mFlushLock);
427
428 std::set<std::shared_ptr<CaptureRequest>> requests;
429 mInFlightTracker->Clear(&requests);
430 for (auto& request : requests) {
431 // TODO(b/31653322): See camera3.h. Should return different error
432 // depending on status of the request.
433 completeRequestWithError(request);
434 }
435
436 ALOGV("%s:%d: Flushed %u requests.", __func__, mId, requests.size());
437
438 // Call down into the device flushing.
439 return flushBuffers();
440 }
441
preprocessCaptureBuffer(camera3_stream_buffer_t * buffer)442 int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
443 {
444 int res;
445 // TODO(b/29334616): This probably should be non-blocking; part
446 // of the asynchronous request processing.
447 if (buffer->acquire_fence != -1) {
448 res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
449 if (res == -ETIME) {
450 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
451 __func__, mId);
452 return res;
453 } else if (res) {
454 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
455 __func__, mId, strerror(-res), res);
456 return res;
457 }
458 ::close(buffer->acquire_fence);
459 }
460
461 // Acquire fence has been waited upon.
462 buffer->acquire_fence = -1;
463 // No release fence waiting unless the device sets it.
464 buffer->release_fence = -1;
465
466 buffer->status = CAMERA3_BUFFER_STATUS_OK;
467 return 0;
468 }
469
notifyShutter(uint32_t frame_number,uint64_t timestamp)470 void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
471 {
472 camera3_notify_msg_t message;
473 memset(&message, 0, sizeof(message));
474 message.type = CAMERA3_MSG_SHUTTER;
475 message.message.shutter.frame_number = frame_number;
476 message.message.shutter.timestamp = timestamp;
477 mCallbackOps->notify(mCallbackOps, &message);
478 }
479
completeRequestWithError(std::shared_ptr<CaptureRequest> request)480 void Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
481 {
482 // Send an error notification.
483 camera3_notify_msg_t message;
484 memset(&message, 0, sizeof(message));
485 message.type = CAMERA3_MSG_ERROR;
486 message.message.error.frame_number = request->frame_number;
487 message.message.error.error_stream = nullptr;
488 message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
489 mCallbackOps->notify(mCallbackOps, &message);
490
491 // TODO(b/31856611): Ensure all the buffers indicate their error status.
492
493 // Send the errored out result.
494 sendResult(request);
495 }
496
sendResult(std::shared_ptr<CaptureRequest> request)497 void Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
498 // Fill in the result struct
499 // (it only needs to live until the end of the framework callback).
500 camera3_capture_result_t result {
501 request->frame_number,
502 request->settings.getAndLock(),
503 static_cast<uint32_t>(request->output_buffers.size()),
504 request->output_buffers.data(),
505 request->input_buffer.get(),
506 1 // Total result; only 1 part.
507 };
508 // Make the framework callback.
509 mCallbackOps->process_capture_result(mCallbackOps, &result);
510 }
511
dump(int fd)512 void Camera::dump(int fd)
513 {
514 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
515 ATRACE_CALL();
516 android::Mutex::Autolock al(mDeviceLock);
517
518 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
519
520 // TODO: dump all settings
521 }
522
templateToString(int type)523 const char* Camera::templateToString(int type)
524 {
525 switch (type) {
526 case CAMERA3_TEMPLATE_PREVIEW:
527 return "CAMERA3_TEMPLATE_PREVIEW";
528 case CAMERA3_TEMPLATE_STILL_CAPTURE:
529 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
530 case CAMERA3_TEMPLATE_VIDEO_RECORD:
531 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
532 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
533 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
534 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
535 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
536 }
537 // TODO: support vendor templates
538 return "Invalid template type!";
539 }
540
541 extern "C" {
542 // Get handle to camera from device priv data
camdev_to_camera(const camera3_device_t * dev)543 static Camera *camdev_to_camera(const camera3_device_t *dev)
544 {
545 return reinterpret_cast<Camera*>(dev->priv);
546 }
547
initialize(const camera3_device_t * dev,const camera3_callback_ops_t * callback_ops)548 static int initialize(const camera3_device_t *dev,
549 const camera3_callback_ops_t *callback_ops)
550 {
551 return camdev_to_camera(dev)->initialize(callback_ops);
552 }
553
configure_streams(const camera3_device_t * dev,camera3_stream_configuration_t * stream_list)554 static int configure_streams(const camera3_device_t *dev,
555 camera3_stream_configuration_t *stream_list)
556 {
557 return camdev_to_camera(dev)->configureStreams(stream_list);
558 }
559
construct_default_request_settings(const camera3_device_t * dev,int type)560 static const camera_metadata_t *construct_default_request_settings(
561 const camera3_device_t *dev, int type)
562 {
563 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
564 }
565
process_capture_request(const camera3_device_t * dev,camera3_capture_request_t * request)566 static int process_capture_request(const camera3_device_t *dev,
567 camera3_capture_request_t *request)
568 {
569 return camdev_to_camera(dev)->processCaptureRequest(request);
570 }
571
dump(const camera3_device_t * dev,int fd)572 static void dump(const camera3_device_t *dev, int fd)
573 {
574 camdev_to_camera(dev)->dump(fd);
575 }
576
flush(const camera3_device_t * dev)577 static int flush(const camera3_device_t *dev)
578 {
579 return camdev_to_camera(dev)->flush();
580 }
581
582 } // extern "C"
583
584 const camera3_device_ops_t Camera::sOps = {
585 .initialize = default_camera_hal::initialize,
586 .configure_streams = default_camera_hal::configure_streams,
587 .register_stream_buffers = nullptr,
588 .construct_default_request_settings
589 = default_camera_hal::construct_default_request_settings,
590 .process_capture_request = default_camera_hal::process_capture_request,
591 .get_metadata_vendor_tag_ops = nullptr,
592 .dump = default_camera_hal::dump,
593 .flush = default_camera_hal::flush,
594 .reserved = {0},
595 };
596
597 } // namespace default_camera_hal
598