blob: 0324da8bc84173b2c40145c9e36082c2eacb4422 [file] [log] [blame]
Zhijun He046205c2015-01-08 17:40:00 -08001/*
2 * Copyright (C) 2015 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//#define LOG_NDEBUG 0
18#define LOG_TAG "Camera"
Mark Salyzynd88dfe82017-04-11 08:56:09 -070019
20#include <errno.h>
21#include <stdio.h>
22#include <string.h>
23#include <time.h>
Zhijun He046205c2015-01-08 17:40:00 -080024
25#include <cstdlib>
Mark Salyzynd88dfe82017-04-11 08:56:09 -070026
27#include <log/log.h>
Zhijun He046205c2015-01-08 17:40:00 -080028#include <utils/Mutex.h>
Zhijun He046205c2015-01-08 17:40:00 -080029
30#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
31#include <utils/Trace.h>
32
Mark Salyzynd88dfe82017-04-11 08:56:09 -070033#include <hardware/camera3.h>
34#include <system/camera_metadata.h>
35#include <system/graphics.h>
36
37#include "CameraHAL.h"
38#include "Metadata.h"
39#include "Stream.h"
40
Zhijun He046205c2015-01-08 17:40:00 -080041#include "Camera.h"
42
43namespace usb_camera_hal {
44
45extern "C" {
46// Shim passed to the framework to close an opened device.
47static int close_device(hw_device_t* dev) {
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
53// Get handle to camera from device priv data
54static Camera *camdev_to_camera(const camera3_device_t *dev) {
55 return reinterpret_cast<Camera*>(dev->priv);
56}
57
58static int initialize(const camera3_device_t *dev,
59 const camera3_callback_ops_t *callback_ops) {
60 return camdev_to_camera(dev)->initialize(callback_ops);
61}
62
63static int configure_streams(const camera3_device_t *dev,
64 camera3_stream_configuration_t *stream_list) {
65 return camdev_to_camera(dev)->configureStreams(stream_list);
66}
67
68static const camera_metadata_t *construct_default_request_settings(
69 const camera3_device_t *dev, int type) {
70 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
71}
72
73static int process_capture_request(const camera3_device_t *dev,
74 camera3_capture_request_t *request) {
75 return camdev_to_camera(dev)->processCaptureRequest(request);
76}
77
78static void dump(const camera3_device_t *dev, int fd) {
79 camdev_to_camera(dev)->dump(fd);
80}
81
82static int flush(const camera3_device_t *dev) {
83 return camdev_to_camera(dev)->flush();
84}
85
86} // extern "C"
87
88const camera3_device_ops_t Camera::sOps = {
89 .initialize = usb_camera_hal::initialize,
90 .configure_streams = usb_camera_hal::configure_streams,
91 .register_stream_buffers = NULL,
92 .construct_default_request_settings
93 = usb_camera_hal::construct_default_request_settings,
94 .process_capture_request = usb_camera_hal::process_capture_request,
95 .get_metadata_vendor_tag_ops = NULL,
96 .dump = usb_camera_hal::dump,
97 .flush = usb_camera_hal::flush,
98 .reserved = {0},
99};
100
101Camera::Camera(int id)
102 : mId(id),
103 mStaticInfo(NULL),
104 mBusy(false),
105 mCallbackOps(NULL),
106 mSettings(NULL),
107 mIsInitialized(false) {
108 memset(&mTemplates, 0, sizeof(mTemplates));
109 memset(&mDevice, 0, sizeof(mDevice));
110 mDevice.common.tag = HARDWARE_DEVICE_TAG;
111 // TODO: Upgrade to HAL3.3
112 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_2;
113 mDevice.common.close = close_device;
114 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
115 mDevice.priv = this;
116}
117
118Camera::~Camera() {
119 if (mStaticInfo != NULL) {
120 free_camera_metadata(mStaticInfo);
121 }
122
123 for (int i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
124 free_camera_metadata(mTemplates[i]);
125 }
126
127 if (mSettings != NULL) {
128 free_camera_metadata(mSettings);
129 }
130}
131
132int Camera::open(const hw_module_t *module, hw_device_t **device) {
133 ALOGI("%s:%d: Opening camera device", __func__, mId);
134 ATRACE_CALL();
135 android::Mutex::Autolock al(mDeviceLock);
136
137 if (mBusy) {
138 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
139 return -EBUSY;
140 }
141
142 mBusy = true;
143 mDevice.common.module = const_cast<hw_module_t*>(module);
144 *device = &mDevice.common;
145 return openDevice();
146}
147
148int Camera::getInfo(struct camera_info *info) {
149 android::Mutex::Autolock al(mStaticInfoLock);
150
151 // TODO: update to CAMERA_FACING_EXTERNAL once the HAL API changes are merged.
152 info->facing = CAMERA_FACING_FRONT;
153 info->orientation = 0;
154 info->device_version = mDevice.common.version;
155 if (mStaticInfo == NULL) {
156 initStaticInfo();
157 }
158 info->static_camera_characteristics = mStaticInfo;
159 return 0;
160}
161
162void Camera::updateInfo() {
163 android::Mutex::Autolock al(mStaticInfoLock);
164 initStaticInfo();
165}
166
167int Camera::close() {
168 ALOGI("%s:%d: Closing camera device", __func__, mId);
169 ATRACE_CALL();
170 android::Mutex::Autolock al(mDeviceLock);
171
172 if (!mBusy) {
173 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
174 return -EINVAL;
175 }
176
177 mBusy = false;
178 mIsInitialized = false;
179 return closeDevice();
180}
181
182int Camera::initialize(const camera3_callback_ops_t *callback_ops) {
183 int res;
184
185 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
186 ATRACE_CALL();
187 android::Mutex::Autolock al(mDeviceLock);
188
189 mCallbackOps = callback_ops;
190 // per-device specific initialization
191 res = initDevice();
192 if (res != 0) {
193 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
194 return res;
195 }
196
197 mIsInitialized = true;
198 return 0;
199}
200
201int Camera::configureStreams(camera3_stream_configuration_t *stream_config) {
202 camera3_stream_t *astream;
203 android::Vector<Stream *> newStreams;
204
205 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
206 ATRACE_CALL();
207 android::Mutex::Autolock al(mDeviceLock);
208 if (!mIsInitialized) {
209 ALOGE("Device is not initialized yet");
210 return -EINVAL;
211 }
212
213 if (stream_config == NULL) {
214 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
215 return -EINVAL;
216 }
217 if (stream_config->num_streams == 0) {
218 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
219 return -EINVAL;
220 }
221
222 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
223 stream_config->num_streams);
224 // Mark all current streams unused for now
225 for (size_t i = 0; i < mStreams.size(); i++) {
226 mStreams[i]->mReuse = false;
227 }
228 // Fill new stream array with reused streams and new streams
229 for (unsigned int i = 0; i < stream_config->num_streams; i++) {
230 astream = stream_config->streams[i];
231 if (astream->max_buffers > 0) {
232 ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
233 newStreams.add(reuseStreamLocked(astream));
234 } else {
235 ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
236 newStreams.add(new Stream(mId, astream));
237 }
238
239 if (newStreams[i] == NULL) {
240 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
241 goto err_out;
242 }
243 astream->priv = reinterpret_cast<void *>(newStreams[i]);
244 }
245
246 // Verify the set of streams in aggregate
247 if (!isValidStreamSetLocked(newStreams)) {
248 ALOGE("%s:%d: Invalid stream set", __func__, mId);
249 goto err_out;
250 }
251
252 // Set up all streams (calculate usage/max_buffers for each)
253 setupStreamsLocked(newStreams);
254
255 // Destroy all old streams and replace stream array with new one
256 destroyStreamsLocked(mStreams);
257 mStreams = newStreams;
258
259 // Clear out last seen settings metadata
260 updateSettingsLocked(NULL);
261 return 0;
262
263err_out:
264 // Clean up temporary streams, preserve existing mStreams
265 destroyStreamsLocked(newStreams);
266 return -EINVAL;
267}
268
269void Camera::destroyStreamsLocked(android::Vector<Stream *> &streams) {
270 for (size_t i = 0; i < streams.size(); i++) {
271 delete streams[i];
272 }
273 streams.clear();
274}
275
276Stream *Camera::reuseStreamLocked(camera3_stream_t *astream) {
277 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
278 // Verify the re-used stream's parameters match
279 if (!priv->isValidReuseStream(mId, astream)) {
280 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
281 return NULL;
282 }
283 // Mark stream to be reused
284 priv->mReuse = true;
285 return priv;
286}
287
288bool Camera::isValidStreamSetLocked(const android::Vector<Stream *> &streams) {
289 int inputs = 0;
290 int outputs = 0;
291
292 if (streams.isEmpty()) {
293 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
294 return false;
295 }
296 // Validate there is at most one input stream and at least one output stream
297 for (size_t i = 0; i < streams.size(); i++) {
298 // A stream may be both input and output (bidirectional)
299 if (streams[i]->isInputType())
300 inputs++;
301 if (streams[i]->isOutputType())
302 outputs++;
303 }
304 ALOGV("%s:%d: Configuring %d output streams and %d input streams",
305 __func__, mId, outputs, inputs);
306 if (outputs < 1) {
307 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
308 return false;
309 }
310 if (inputs > 1) {
311 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
312 return false;
313 }
314 // TODO: check for correct number of Bayer/YUV/JPEG/Encoder streams
315 return true;
316}
317
318void Camera::setupStreamsLocked(android::Vector<Stream *> &streams) {
319 /*
320 * This is where the HAL has to decide internally how to handle all of the
321 * streams, and then produce usage and max_buffer values for each stream.
322 * Note, the stream vector has been checked before this point for ALL invalid
323 * conditions, so it must find a successful configuration for this stream
324 * array. The HAL may not return an error from this point.
325 *
326 * TODO: we just set all streams to be the same dummy values;
327 * real implementations will want to avoid USAGE_SW_{READ|WRITE}_OFTEN.
328 */
329 for (size_t i = 0; i < streams.size(); i++) {
330 uint32_t usage = 0;
331
332 if (streams[i]->isOutputType())
333 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN |
334 GRALLOC_USAGE_HW_CAMERA_WRITE;
335 if (streams[i]->isInputType())
336 usage |= GRALLOC_USAGE_SW_READ_OFTEN |
337 GRALLOC_USAGE_HW_CAMERA_READ;
338
339 streams[i]->setUsage(usage);
340 streams[i]->setMaxBuffers(1);
341 }
342}
343
344bool Camera::isValidTemplateType(int type) {
345 return type >= 1 && type < CAMERA3_TEMPLATE_COUNT;
346}
347
348const camera_metadata_t* Camera::constructDefaultRequestSettings(int type) {
349 ALOGV("%s:%d: type=%d", __func__, mId, type);
350 android::Mutex::Autolock al(mDeviceLock);
351
352 if (!isValidTemplateType(type)) {
353 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
354 return NULL;
355 }
356
357 // DO NOT try to initialize the device here, it will be guaranteed deadlock.
358 if (!mIsInitialized) {
359 ALOGE("Device is not initialized yet");
360 return NULL;
361 }
362
363 return mTemplates[type];
364}
365
366// This implementation is a copy-paste, probably we should override (or move) this to
367// device specific class.
368int Camera::processCaptureRequest(camera3_capture_request_t *request) {
369 camera3_capture_result result;
370 ALOGV("%s:%d: request=%p", __func__, mId, request);
371 ATRACE_CALL();
372 android::Mutex::Autolock al(mDeviceLock);
373
374 if (request == NULL) {
375 ALOGE("%s:%d: NULL request recieved", __func__, mId);
376 return -EINVAL;
377 }
378
379 ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId,
380 request->frame_number, request->settings);
381
382 // NULL indicates use last settings
383 if (request->settings == NULL) {
384 if (mSettings == NULL) {
385 ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p",
386 __func__, mId, request->frame_number, request);
387 return -EINVAL;
388 }
389 } else {
390 updateSettingsLocked(request->settings);
391 }
392
393 if (request->input_buffer != NULL) {
394 ALOGV("%s:%d: Reprocessing input buffer is not supported yet", __func__, mId);
395 return -EINVAL;
396 } else {
397 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
398
399 if (!isValidCaptureSettings(request->settings)) {
400 ALOGE("%s:%d: Invalid settings for capture request: %p",
401 __func__, mId, request->settings);
402 return -EINVAL;
403 }
404 }
405
406 if (request->num_output_buffers <= 0) {
407 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
408 request->num_output_buffers);
409 return -EINVAL;
410 }
411 result.num_output_buffers = request->num_output_buffers;
412 result.output_buffers = new camera3_stream_buffer_t[result.num_output_buffers];
413 for (unsigned int i = 0; i < request->num_output_buffers; i++) {
414 int res = processCaptureBuffer(&request->output_buffers[i],
415 const_cast<camera3_stream_buffer_t*>(&result.output_buffers[i]));
416 if (res) {
417 delete [] result.output_buffers;
418 // TODO: this should probably be a total device failure; transient for now
419 return -EINVAL;
420 }
421 }
422
423 result.frame_number = request->frame_number;
424 // TODO: return actual captured/reprocessed settings
425 result.result = request->settings;
426 // TODO: asynchronously return results
427 notifyShutter(request->frame_number, 0);
428 mCallbackOps->process_capture_result(mCallbackOps, &result);
429
430 // Free up capture result related resources, HAL owns the capture result, and it
431 // is only valid during the process_capture_result call.
432 delete[] result.output_buffers;
433
434 return 0;
435}
436
437int Camera::flush() {
438 int res;
439
440 ALOGV("%s:%d: flush device", __func__, mId);
441 // per-device specific flush
442 res = flushDevice();
443 if (res != 0) {
444 ALOGE("%s:%d: Failed to flush device!", __func__, mId);
445 return res;
446 }
447 return 0;
448}
449
450void Camera::updateSettingsLocked(const camera_metadata_t *new_settings) {
451 if (mSettings != NULL) {
452 free_camera_metadata(mSettings);
453 mSettings = NULL;
454 }
455
456 if (new_settings != NULL)
457 mSettings = clone_camera_metadata(new_settings);
458}
459
460void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp) {
461 int res;
462 struct timespec ts;
463
464 // If timestamp is 0, get timestamp from right now instead
465 if (timestamp == 0) {
466 ALOGW("%s:%d: No timestamp provided, using CLOCK_BOOTTIME",
467 __func__, mId);
468 res = clock_gettime(CLOCK_BOOTTIME, &ts);
469 if (res == 0) {
470 timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
471 } else {
472 ALOGE("%s:%d: No timestamp and failed to get CLOCK_BOOTTIME %s(%d)",
473 __func__, mId, strerror(errno), errno);
474 }
475 }
476 camera3_notify_msg_t m;
477 memset(&m, 0, sizeof(m));
478 m.type = CAMERA3_MSG_SHUTTER;
479 m.message.shutter.frame_number = frame_number;
480 m.message.shutter.timestamp = timestamp;
481 mCallbackOps->notify(mCallbackOps, &m);
482}
483
484void Camera::dump(int fd) {
485 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
486 ATRACE_CALL();
487 android::Mutex::Autolock al(mDeviceLock);
488
489 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
490
491 // TODO: dump all settings
492 dprintf(fd, "Most Recent Settings: (%p)\n", mSettings);
493
Greg Kaiser7a915ef2016-06-30 16:59:38 -0700494 dprintf(fd, "Number of streams: %zu\n", mStreams.size());
Zhijun He046205c2015-01-08 17:40:00 -0800495 for (size_t i = 0; i < mStreams.size(); i++) {
Greg Kaiser7a915ef2016-06-30 16:59:38 -0700496 dprintf(fd, "Stream %zu/%zu:\n", i, mStreams.size());
Zhijun He046205c2015-01-08 17:40:00 -0800497 mStreams[i]->dump(fd);
498 }
499}
500
501const char* Camera::templateToString(int type) {
502 switch (type) {
503 case CAMERA3_TEMPLATE_PREVIEW:
504 return "CAMERA3_TEMPLATE_PREVIEW";
505 case CAMERA3_TEMPLATE_STILL_CAPTURE:
506 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
507 case CAMERA3_TEMPLATE_VIDEO_RECORD:
508 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
509 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
510 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
511 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
512 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
513 case CAMERA3_TEMPLATE_MANUAL:
514 return "CAMERA3_TEMPLATE_MANUAL";
515 }
516
517 return "Invalid template type!";
518}
519
520int Camera::setTemplate(int type, camera_metadata_t *settings) {
521 android::Mutex::Autolock al(mDeviceLock);
522
523 if (!isValidTemplateType(type)) {
524 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
525 return -EINVAL;
526 }
527
528 if (mTemplates[type] != NULL) {
529 ALOGE("%s:%d: Setting already constructed template type %s(%d)",
530 __func__, mId, templateToString(type), type);
531 return -EINVAL;
532 }
533
534 // Make a durable copy of the underlying metadata
535 mTemplates[type] = clone_camera_metadata(settings);
536 if (mTemplates[type] == NULL) {
537 ALOGE("%s:%d: Failed to clone metadata %p for template type %s(%d)",
538 __func__, mId, settings, templateToString(type), type);
539 return -EINVAL;
540 }
541 return 0;
542}
543
544} // namespace usb_camera_hal