blob: a1f7e860a131db60639351c07ac0ca3ab96ad8fb [file] [log] [blame]
Ari Hausman-Cohen73442152016-06-08 15:50:49 -07001/*
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>
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -070020#include <memory>
21#include <vector>
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070022#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>
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070028
29#include "metadata/metadata_common.h"
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070030#include "stream.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070031
32//#define LOG_NDEBUG 0
33#define LOG_TAG "Camera"
34#include <cutils/log.h>
35
36#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
37#include <utils/Trace.h>
38
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070039#include "camera.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070040
41#define CAMERA_SYNC_TIMEOUT 5000 // in msecs
42
43namespace default_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{
49 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
50 Camera* cam = static_cast<Camera*>(cam_dev->priv);
51 return cam->close();
52}
53} // extern "C"
54
55Camera::Camera(int id)
56 : mId(id),
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070057 mSettingsSet(false),
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070058 mBusy(false),
59 mCallbackOps(NULL),
60 mStreams(NULL),
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070061 mNumStreams(0)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070062{
63 memset(&mTemplates, 0, sizeof(mTemplates));
64 memset(&mDevice, 0, sizeof(mDevice));
65 mDevice.common.tag = HARDWARE_DEVICE_TAG;
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -070066 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070067 mDevice.common.close = close_device;
68 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
69 mDevice.priv = this;
70}
71
72Camera::~Camera()
73{
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070074}
75
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070076int Camera::openDevice(const hw_module_t *module, hw_device_t **device)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070077{
78 ALOGI("%s:%d: Opening camera device", __func__, mId);
79 ATRACE_CALL();
80 android::Mutex::Autolock al(mDeviceLock);
81
82 if (mBusy) {
83 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
84 return -EBUSY;
85 }
86
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070087 int connectResult = connect();
88 if (connectResult != 0) {
89 return connectResult;
90 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070091 mBusy = true;
92 mDevice.common.module = const_cast<hw_module_t*>(module);
93 *device = &mDevice.common;
94 return 0;
95}
96
97int Camera::getInfo(struct camera_info *info)
98{
99 android::Mutex::Autolock al(mStaticInfoLock);
100
101 info->device_version = mDevice.common.version;
102 initDeviceInfo(info);
103 if (mStaticInfo == NULL) {
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700104 std::unique_ptr<android::CameraMetadata> static_info =
105 std::make_unique<android::CameraMetadata>();
106 if (initStaticInfo(static_info.get())) {
107 return -ENODEV;
108 }
109 mStaticInfo = std::move(static_info);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700110 }
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700111 // The "locking" here only causes non-const methods to fail,
112 // which is not a problem since the CameraMetadata being locked
113 // is already const. Destructing automatically "unlocks".
114 info->static_camera_characteristics = mStaticInfo->getAndLock();
115
116 // Get facing & orientation from the static info.
117 uint8_t facing = 0;
118 int res = v4l2_camera_hal::SingleTagValue(
119 *mStaticInfo, ANDROID_LENS_FACING, &facing);
120 if (res) {
121 ALOGE("%s:%d: Failed to get facing from static metadata.",
122 __func__, mId);
123 return res;
124 }
125 switch (facing) {
126 case (ANDROID_LENS_FACING_FRONT):
127 info->facing = CAMERA_FACING_FRONT;
128 break;
129 case (ANDROID_LENS_FACING_BACK):
130 info->facing = CAMERA_FACING_BACK;
131 break;
132 case (ANDROID_LENS_FACING_EXTERNAL):
133 info->facing = CAMERA_FACING_EXTERNAL;
134 break;
135 default:
136 ALOGE("%s:%d: Invalid facing from metadata: %d.",
137 __func__, mId, facing);
138 return -ENODEV;
139 }
140 int32_t orientation = 0;
141 res = v4l2_camera_hal::SingleTagValue(
142 *mStaticInfo, ANDROID_SENSOR_ORIENTATION, &orientation);
143 if (res) {
144 ALOGE("%s:%d: Failed to get orientation from static metadata.",
145 __func__, mId);
146 return res;
147 }
148 info->orientation = static_cast<int>(orientation);
149
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700150 return 0;
151}
152
153int Camera::close()
154{
155 ALOGI("%s:%d: Closing camera device", __func__, mId);
156 ATRACE_CALL();
157 android::Mutex::Autolock al(mDeviceLock);
158
159 if (!mBusy) {
160 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
161 return -EINVAL;
162 }
163
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700164 disconnect();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700165 mBusy = false;
166 return 0;
167}
168
169int Camera::initialize(const camera3_callback_ops_t *callback_ops)
170{
171 int res;
172
173 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
174 mCallbackOps = callback_ops;
175 // per-device specific initialization
176 res = initDevice();
177 if (res != 0) {
178 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
179 return res;
180 }
181 return 0;
182}
183
184int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
185{
186 camera3_stream_t *astream;
187 Stream **newStreams = NULL;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700188 int res = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700189
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700190 // Must provide new settings after configureStreams.
191 mSettingsSet = false;
192
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700193 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
194 ATRACE_CALL();
195 android::Mutex::Autolock al(mDeviceLock);
196
197 if (stream_config == NULL) {
198 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
199 return -EINVAL;
200 }
201 if (stream_config->num_streams == 0) {
202 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
203 return -EINVAL;
204 }
205
206 // Create new stream array
207 newStreams = new Stream*[stream_config->num_streams];
208 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
209 stream_config->num_streams);
210
211 // Mark all current streams unused for now
212 for (int i = 0; i < mNumStreams; i++)
213 mStreams[i]->mReuse = false;
214 // Fill new stream array with reused streams and new streams
215 for (unsigned int i = 0; i < stream_config->num_streams; i++) {
216 astream = stream_config->streams[i];
217 if (astream->max_buffers > 0) {
218 ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
219 newStreams[i] = reuseStream(astream);
220 } else {
221 ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
222 newStreams[i] = new Stream(mId, astream);
223 }
224
225 if (newStreams[i] == NULL) {
226 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
227 goto err_out;
228 }
229 astream->priv = newStreams[i];
230 }
231
232 // Verify the set of streams in aggregate
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700233 if (!isValidStreamSet(newStreams, stream_config->num_streams,
234 stream_config->operation_mode)) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700235 ALOGE("%s:%d: Invalid stream set", __func__, mId);
236 goto err_out;
237 }
238
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700239 // Set up all streams (calculate usage/max_buffers for each,
240 // do any device-specific initialization)
241 res = setupStreams(newStreams, stream_config->num_streams);
242 if (res) {
243 ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
244 goto err_out;
245 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700246
247 // Destroy all old streams and replace stream array with new one
248 destroyStreams(mStreams, mNumStreams);
249 mStreams = newStreams;
250 mNumStreams = stream_config->num_streams;
251
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700252 return 0;
253
254err_out:
255 // Clean up temporary streams, preserve existing mStreams/mNumStreams
256 destroyStreams(newStreams, stream_config->num_streams);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700257 // Set error if it wasn't specified.
258 if (!res) {
259 res = -EINVAL;
260 }
261 return res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700262}
263
264void Camera::destroyStreams(Stream **streams, int count)
265{
266 if (streams == NULL)
267 return;
268 for (int i = 0; i < count; i++) {
269 // Only destroy streams that weren't reused
270 if (streams[i] != NULL && !streams[i]->mReuse)
271 delete streams[i];
272 }
273 delete [] streams;
274}
275
276Stream *Camera::reuseStream(camera3_stream_t *astream)
277{
278 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
279 // Verify the re-used stream's parameters match
280 if (!priv->isValidReuseStream(mId, astream)) {
281 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
282 return NULL;
283 }
284 // Mark stream to be reused
285 priv->mReuse = true;
286 return priv;
287}
288
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700289bool Camera::isValidStreamSet(Stream **streams, int count, uint32_t mode)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700290{
291 int inputs = 0;
292 int outputs = 0;
293
294 if (streams == NULL) {
295 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
296 return false;
297 }
298 if (count == 0) {
299 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
300 return false;
301 }
302 // Validate there is at most one input stream and at least one output stream
303 for (int i = 0; i < count; i++) {
304 // A stream may be both input and output (bidirectional)
305 if (streams[i]->isInputType())
306 inputs++;
307 if (streams[i]->isOutputType())
308 outputs++;
309 }
310 ALOGV("%s:%d: Configuring %d output streams and %d input streams",
311 __func__, mId, outputs, inputs);
312 if (outputs < 1) {
313 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
314 return false;
315 }
316 if (inputs > 1) {
317 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
318 return false;
319 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700320
321 // check for correct number of Bayer/YUV/JPEG/Encoder streams
322 return isSupportedStreamSet(streams, count, mode);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700323}
324
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700325int Camera::setupStreams(Stream **streams, int count)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700326{
327 /*
328 * This is where the HAL has to decide internally how to handle all of the
329 * streams, and then produce usage and max_buffer values for each stream.
330 * Note, the stream array has been checked before this point for ALL invalid
331 * conditions, so it must find a successful configuration for this stream
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700332 * array. The only errors should be from individual streams requesting
333 * unsupported features (such as data_space or rotation).
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700334 */
335 for (int i = 0; i < count; i++) {
336 uint32_t usage = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700337 if (streams[i]->isOutputType())
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700338 usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700339 if (streams[i]->isInputType())
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700340 usage |= GRALLOC_USAGE_HW_CAMERA_READ;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700341 streams[i]->setUsage(usage);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700342
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700343 uint32_t max_buffers;
344 int res = setupStream(streams[i], &max_buffers);
345 if (res) {
346 return res;
347 }
348 streams[i]->setMaxBuffers(max_buffers);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700349 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700350 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700351}
352
353bool Camera::isValidTemplateType(int type)
354{
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700355 return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700356}
357
358const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
359{
360 ALOGV("%s:%d: type=%d", __func__, mId, type);
361
362 if (!isValidTemplateType(type)) {
363 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
364 return NULL;
365 }
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700366
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700367 if (!mTemplates[type]) {
368 // Initialize this template if it hasn't been initialized yet.
369 std::unique_ptr<android::CameraMetadata> new_template =
370 std::make_unique<android::CameraMetadata>();
371 int res = initTemplate(type, new_template.get());
372 if (res || !new_template) {
373 ALOGE("%s:%d: Failed to generate template of type: %d",
374 __func__, mId, type);
375 return NULL;
376 }
377 mTemplates[type] = std::move(new_template);
378 }
379
380 // The "locking" here only causes non-const methods to fail,
381 // which is not a problem since the CameraMetadata being locked
382 // is already const. Destructing automatically "unlocks".
383 return mTemplates[type]->getAndLock();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700384}
385
386int Camera::processCaptureRequest(camera3_capture_request_t *request)
387{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700388 int res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700389
390 ALOGV("%s:%d: request=%p", __func__, mId, request);
391 ATRACE_CALL();
392
393 if (request == NULL) {
394 ALOGE("%s:%d: NULL request recieved", __func__, mId);
395 return -EINVAL;
396 }
397
398 ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId,
399 request->frame_number, request->settings);
400
401 // NULL indicates use last settings
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700402 if (request->settings == NULL && !mSettingsSet) {
403 ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p",
404 __func__, mId, request->frame_number, request);
405 return -EINVAL;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700406 }
407
408 if (request->input_buffer != NULL) {
409 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
410 request->input_buffer);
411
412 if (!isValidReprocessSettings(request->settings)) {
413 ALOGE("%s:%d: Invalid settings for reprocess request: %p",
414 __func__, mId, request->settings);
415 return -EINVAL;
416 }
417 } else {
418 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
419
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700420 // Make a copy since CameraMetadata doesn't support weak ownership,
421 // but |request| is supposed to maintain ownership.
422 android::CameraMetadata request_settings;
423 request_settings = request->settings;
424 if (!isValidCaptureSettings(request_settings)) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700425 ALOGE("%s:%d: Invalid settings for capture request: %p",
426 __func__, mId, request->settings);
427 return -EINVAL;
428 }
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700429 // Settings are valid, go ahead and set them.
430 res = setSettings(request_settings);
431 if (res) {
432 ALOGE("%s:%d: Failed to set valid settings for capture request: %p",
433 __func__, mId, request->settings);
434 return res;
435 }
436 mSettingsSet = true;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700437 }
438
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700439 // Setup and process output buffers.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700440 if (request->num_output_buffers <= 0) {
441 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
442 request->num_output_buffers);
443 return -EINVAL;
444 }
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700445 camera3_capture_result result;
446 result.num_output_buffers = request->num_output_buffers;
447 std::vector<camera3_stream_buffer_t> output_buffers(
448 result.num_output_buffers);
449 for (unsigned int i = 0; i < request->num_output_buffers; i++) {
450 res = processCaptureBuffer(&request->output_buffers[i],
451 &output_buffers[i]);
452 if (res)
453 return -ENODEV;
454 }
455 result.output_buffers = &output_buffers[0];
456
457 // Get metadata for this frame. Since the framework guarantees only
458 // one call to process_capture_request at a time, this call is guaranteed
459 // to correspond with the most recently enqueued buffer.
460
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700461 android::CameraMetadata result_metadata;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700462 uint64_t timestamp = 0;
463 // TODO(b/29334616): this may also want to use a callback, since
464 // the shutter may not happen immediately.
465 res = getResultSettings(&result_metadata, &timestamp);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700466 if (res) {
467 return res;
468 }
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700469 result.result = result_metadata.release();
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700470
471 // Notify the framework with the shutter time.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700472 result.frame_number = request->frame_number;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700473 notifyShutter(result.frame_number, timestamp);
474
475 // TODO(b/29334616): asynchronously return results (the following should
476 // be done once all enqueued buffers for the request complete and callback).
477 result.partial_result = 1;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700478 mCallbackOps->process_capture_result(mCallbackOps, &result);
479
480 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700481}
482
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700483bool Camera::isValidReprocessSettings(const camera_metadata_t* /*settings*/)
484{
485 // TODO: reject settings that cannot be reprocessed
486 // input buffers unimplemented, use this to reject reprocessing requests
487 ALOGE("%s:%d: Input buffer reprocessing not implemented", __func__, mId);
488 return false;
489}
490
491int Camera::processCaptureBuffer(const camera3_stream_buffer_t *in,
492 camera3_stream_buffer_t *out)
493{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700494 int res;
495 // TODO(b/29334616): This probably should be non-blocking (currently blocks
496 // here and on gralloc lock). Perhaps caller should put "in" in a queue
497 // initially, then have a thread that dequeues from there and calls this
498 // function.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700499 if (in->acquire_fence != -1) {
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700500 res = sync_wait(in->acquire_fence, CAMERA_SYNC_TIMEOUT);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700501 if (res == -ETIME) {
502 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
503 __func__, mId);
504 return res;
505 } else if (res) {
506 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
507 __func__, mId, strerror(-res), res);
508 return res;
509 }
510 }
511
512 out->stream = in->stream;
513 out->buffer = in->buffer;
514 out->status = CAMERA3_BUFFER_STATUS_OK;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700515
516 // Enqueue buffer for software-painting
517 res = enqueueBuffer(out);
518 if (res) {
519 return res;
520 }
521
522 // TODO(b/29334616): This should be part of a callback made when the
523 // enqueued buffer finishes painting.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700524 // TODO: use driver-backed release fences
525 out->acquire_fence = -1;
526 out->release_fence = -1;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700527 return 0;
528}
529
530void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
531{
532 int res;
533 struct timespec ts;
534
535 // If timestamp is 0, get timestamp from right now instead
536 if (timestamp == 0) {
537 ALOGW("%s:%d: No timestamp provided, using CLOCK_BOOTTIME",
538 __func__, mId);
539 res = clock_gettime(CLOCK_BOOTTIME, &ts);
540 if (res == 0) {
541 timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
542 } else {
543 ALOGE("%s:%d: No timestamp and failed to get CLOCK_BOOTTIME %s(%d)",
544 __func__, mId, strerror(errno), errno);
545 }
546 }
547 camera3_notify_msg_t m;
548 memset(&m, 0, sizeof(m));
549 m.type = CAMERA3_MSG_SHUTTER;
550 m.message.shutter.frame_number = frame_number;
551 m.message.shutter.timestamp = timestamp;
552 mCallbackOps->notify(mCallbackOps, &m);
553}
554
555void Camera::dump(int fd)
556{
557 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
558 ATRACE_CALL();
559 android::Mutex::Autolock al(mDeviceLock);
560
561 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
562
563 // TODO: dump all settings
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700564
565 dprintf(fd, "Number of streams: %d\n", mNumStreams);
566 for (int i = 0; i < mNumStreams; i++) {
567 dprintf(fd, "Stream %d/%d:\n", i, mNumStreams);
568 mStreams[i]->dump(fd);
569 }
570}
571
572const char* Camera::templateToString(int type)
573{
574 switch (type) {
575 case CAMERA3_TEMPLATE_PREVIEW:
576 return "CAMERA3_TEMPLATE_PREVIEW";
577 case CAMERA3_TEMPLATE_STILL_CAPTURE:
578 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
579 case CAMERA3_TEMPLATE_VIDEO_RECORD:
580 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
581 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
582 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
583 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
584 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
585 }
586 // TODO: support vendor templates
587 return "Invalid template type!";
588}
589
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700590extern "C" {
591// Get handle to camera from device priv data
592static Camera *camdev_to_camera(const camera3_device_t *dev)
593{
594 return reinterpret_cast<Camera*>(dev->priv);
595}
596
597static int initialize(const camera3_device_t *dev,
598 const camera3_callback_ops_t *callback_ops)
599{
600 return camdev_to_camera(dev)->initialize(callback_ops);
601}
602
603static int configure_streams(const camera3_device_t *dev,
604 camera3_stream_configuration_t *stream_list)
605{
606 return camdev_to_camera(dev)->configureStreams(stream_list);
607}
608
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700609static const camera_metadata_t *construct_default_request_settings(
610 const camera3_device_t *dev, int type)
611{
612 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
613}
614
615static int process_capture_request(const camera3_device_t *dev,
616 camera3_capture_request_t *request)
617{
618 return camdev_to_camera(dev)->processCaptureRequest(request);
619}
620
621static void dump(const camera3_device_t *dev, int fd)
622{
623 camdev_to_camera(dev)->dump(fd);
624}
625
626static int flush(const camera3_device_t*)
627{
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700628 // TODO(b/29937783)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700629 ALOGE("%s: unimplemented.", __func__);
630 return -1;
631}
632
633} // extern "C"
634
635const camera3_device_ops_t Camera::sOps = {
636 .initialize = default_camera_hal::initialize,
637 .configure_streams = default_camera_hal::configure_streams,
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700638 .register_stream_buffers = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700639 .construct_default_request_settings
640 = default_camera_hal::construct_default_request_settings,
641 .process_capture_request = default_camera_hal::process_capture_request,
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700642 .get_metadata_vendor_tag_ops = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700643 .dump = default_camera_hal::dump,
644 .flush = default_camera_hal::flush,
645 .reserved = {0},
646};
647
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700648} // namespace default_camera_hal