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