blob: 755ed021d91bba554927a3109db08db36eea6013 [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-Cohen3841a7f2016-07-19 17:27:52 -070028#include "stream.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070029
30//#define LOG_NDEBUG 0
31#define LOG_TAG "Camera"
32#include <cutils/log.h>
33
34#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
35#include <utils/Trace.h>
36
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070037#include "camera.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070038
39#define CAMERA_SYNC_TIMEOUT 5000 // in msecs
40
41namespace default_camera_hal {
42
43extern "C" {
44// Shim passed to the framework to close an opened device.
45static int close_device(hw_device_t* dev)
46{
47 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
48 Camera* cam = static_cast<Camera*>(cam_dev->priv);
49 return cam->close();
50}
51} // extern "C"
52
53Camera::Camera(int id)
54 : mId(id),
55 mStaticInfo(NULL),
56 mBusy(false),
57 mCallbackOps(NULL),
58 mStreams(NULL),
59 mNumStreams(0),
60 mSettings(NULL)
61{
62 memset(&mTemplates, 0, sizeof(mTemplates));
63 memset(&mDevice, 0, sizeof(mDevice));
64 mDevice.common.tag = HARDWARE_DEVICE_TAG;
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -070065 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070066 mDevice.common.close = close_device;
67 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
68 mDevice.priv = this;
69}
70
71Camera::~Camera()
72{
73 if (mStaticInfo != NULL) {
74 free_camera_metadata(mStaticInfo);
75 }
76 if (mSettings != NULL) {
77 free_camera_metadata(mSettings);
78 }
79 for (camera_metadata_t* metadata : mTemplates) {
80 if (metadata != NULL) {
81 free_camera_metadata(metadata);
82 }
83 }
84}
85
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070086int Camera::openDevice(const hw_module_t *module, hw_device_t **device)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070087{
88 ALOGI("%s:%d: Opening camera device", __func__, mId);
89 ATRACE_CALL();
90 android::Mutex::Autolock al(mDeviceLock);
91
92 if (mBusy) {
93 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
94 return -EBUSY;
95 }
96
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070097 int connectResult = connect();
98 if (connectResult != 0) {
99 return connectResult;
100 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700101 mBusy = true;
102 mDevice.common.module = const_cast<hw_module_t*>(module);
103 *device = &mDevice.common;
104 return 0;
105}
106
107int Camera::getInfo(struct camera_info *info)
108{
109 android::Mutex::Autolock al(mStaticInfoLock);
110
111 info->device_version = mDevice.common.version;
112 initDeviceInfo(info);
113 if (mStaticInfo == NULL) {
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700114 if (initStaticInfo(&mStaticInfo)) {
115 return -ENODEV;
116 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700117 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700118 info->static_camera_characteristics = mStaticInfo;
119 return 0;
120}
121
122int Camera::close()
123{
124 ALOGI("%s:%d: Closing camera device", __func__, mId);
125 ATRACE_CALL();
126 android::Mutex::Autolock al(mDeviceLock);
127
128 if (!mBusy) {
129 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
130 return -EINVAL;
131 }
132
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700133 disconnect();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700134 mBusy = false;
135 return 0;
136}
137
138int Camera::initialize(const camera3_callback_ops_t *callback_ops)
139{
140 int res;
141
142 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
143 mCallbackOps = callback_ops;
144 // per-device specific initialization
145 res = initDevice();
146 if (res != 0) {
147 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
148 return res;
149 }
150 return 0;
151}
152
153int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
154{
155 camera3_stream_t *astream;
156 Stream **newStreams = NULL;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700157 int res = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700158
159 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
160 ATRACE_CALL();
161 android::Mutex::Autolock al(mDeviceLock);
162
163 if (stream_config == NULL) {
164 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
165 return -EINVAL;
166 }
167 if (stream_config->num_streams == 0) {
168 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
169 return -EINVAL;
170 }
171
172 // Create new stream array
173 newStreams = new Stream*[stream_config->num_streams];
174 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
175 stream_config->num_streams);
176
177 // Mark all current streams unused for now
178 for (int i = 0; i < mNumStreams; i++)
179 mStreams[i]->mReuse = false;
180 // Fill new stream array with reused streams and new streams
181 for (unsigned int i = 0; i < stream_config->num_streams; i++) {
182 astream = stream_config->streams[i];
183 if (astream->max_buffers > 0) {
184 ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
185 newStreams[i] = reuseStream(astream);
186 } else {
187 ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
188 newStreams[i] = new Stream(mId, astream);
189 }
190
191 if (newStreams[i] == NULL) {
192 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
193 goto err_out;
194 }
195 astream->priv = newStreams[i];
196 }
197
198 // Verify the set of streams in aggregate
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700199 if (!isValidStreamSet(newStreams, stream_config->num_streams,
200 stream_config->operation_mode)) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700201 ALOGE("%s:%d: Invalid stream set", __func__, mId);
202 goto err_out;
203 }
204
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700205 // Set up all streams (calculate usage/max_buffers for each,
206 // do any device-specific initialization)
207 res = setupStreams(newStreams, stream_config->num_streams);
208 if (res) {
209 ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
210 goto err_out;
211 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700212
213 // Destroy all old streams and replace stream array with new one
214 destroyStreams(mStreams, mNumStreams);
215 mStreams = newStreams;
216 mNumStreams = stream_config->num_streams;
217
218 // Clear out last seen settings metadata
219 setSettings(NULL);
220 return 0;
221
222err_out:
223 // Clean up temporary streams, preserve existing mStreams/mNumStreams
224 destroyStreams(newStreams, stream_config->num_streams);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700225 // Set error if it wasn't specified.
226 if (!res) {
227 res = -EINVAL;
228 }
229 return res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700230}
231
232void Camera::destroyStreams(Stream **streams, int count)
233{
234 if (streams == NULL)
235 return;
236 for (int i = 0; i < count; i++) {
237 // Only destroy streams that weren't reused
238 if (streams[i] != NULL && !streams[i]->mReuse)
239 delete streams[i];
240 }
241 delete [] streams;
242}
243
244Stream *Camera::reuseStream(camera3_stream_t *astream)
245{
246 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
247 // Verify the re-used stream's parameters match
248 if (!priv->isValidReuseStream(mId, astream)) {
249 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
250 return NULL;
251 }
252 // Mark stream to be reused
253 priv->mReuse = true;
254 return priv;
255}
256
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700257bool Camera::isValidStreamSet(Stream **streams, int count, uint32_t mode)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700258{
259 int inputs = 0;
260 int outputs = 0;
261
262 if (streams == NULL) {
263 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
264 return false;
265 }
266 if (count == 0) {
267 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
268 return false;
269 }
270 // Validate there is at most one input stream and at least one output stream
271 for (int i = 0; i < count; i++) {
272 // A stream may be both input and output (bidirectional)
273 if (streams[i]->isInputType())
274 inputs++;
275 if (streams[i]->isOutputType())
276 outputs++;
277 }
278 ALOGV("%s:%d: Configuring %d output streams and %d input streams",
279 __func__, mId, outputs, inputs);
280 if (outputs < 1) {
281 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
282 return false;
283 }
284 if (inputs > 1) {
285 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
286 return false;
287 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700288
289 // check for correct number of Bayer/YUV/JPEG/Encoder streams
290 return isSupportedStreamSet(streams, count, mode);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700291}
292
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700293int Camera::setupStreams(Stream **streams, int count)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700294{
295 /*
296 * This is where the HAL has to decide internally how to handle all of the
297 * streams, and then produce usage and max_buffer values for each stream.
298 * Note, the stream array has been checked before this point for ALL invalid
299 * conditions, so it must find a successful configuration for this stream
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700300 * array. The only errors should be from individual streams requesting
301 * unsupported features (such as data_space or rotation).
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700302 */
303 for (int i = 0; i < count; i++) {
304 uint32_t usage = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700305 if (streams[i]->isOutputType())
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700306 usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700307 if (streams[i]->isInputType())
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700308 usage |= GRALLOC_USAGE_HW_CAMERA_READ;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700309 streams[i]->setUsage(usage);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700310
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700311 uint32_t max_buffers;
312 int res = setupStream(streams[i], &max_buffers);
313 if (res) {
314 return res;
315 }
316 streams[i]->setMaxBuffers(max_buffers);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700317 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700318 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700319}
320
321bool Camera::isValidTemplateType(int type)
322{
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700323 return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700324}
325
326const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
327{
328 ALOGV("%s:%d: type=%d", __func__, mId, type);
329
330 if (!isValidTemplateType(type)) {
331 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
332 return NULL;
333 }
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700334
335 // Will return NULL (indicating unsupported) if the template is not
336 // initialized.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700337 return mTemplates[type];
338}
339
340int Camera::processCaptureRequest(camera3_capture_request_t *request)
341{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700342 int res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700343
344 ALOGV("%s:%d: request=%p", __func__, mId, request);
345 ATRACE_CALL();
346
347 if (request == NULL) {
348 ALOGE("%s:%d: NULL request recieved", __func__, mId);
349 return -EINVAL;
350 }
351
352 ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId,
353 request->frame_number, request->settings);
354
355 // NULL indicates use last settings
356 if (request->settings == NULL) {
357 if (mSettings == NULL) {
358 ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p",
359 __func__, mId, request->frame_number, request);
360 return -EINVAL;
361 }
362 } else {
363 setSettings(request->settings);
364 }
365
366 if (request->input_buffer != NULL) {
367 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
368 request->input_buffer);
369
370 if (!isValidReprocessSettings(request->settings)) {
371 ALOGE("%s:%d: Invalid settings for reprocess request: %p",
372 __func__, mId, request->settings);
373 return -EINVAL;
374 }
375 } else {
376 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
377
378 if (!isValidCaptureSettings(request->settings)) {
379 ALOGE("%s:%d: Invalid settings for capture request: %p",
380 __func__, mId, request->settings);
381 return -EINVAL;
382 }
383 }
384
385 if (request->num_output_buffers <= 0) {
386 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
387 request->num_output_buffers);
388 return -EINVAL;
389 }
Ari Hausman-Cohen784c8492016-07-06 13:28:53 -0700390
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700391 camera3_capture_result result;
392 result.num_output_buffers = request->num_output_buffers;
393 std::vector<camera3_stream_buffer_t> output_buffers(
394 result.num_output_buffers);
395 for (unsigned int i = 0; i < request->num_output_buffers; i++) {
396 res = processCaptureBuffer(&request->output_buffers[i],
397 &output_buffers[i]);
398 if (res)
399 return -ENODEV;
400 }
401 result.output_buffers = &output_buffers[0];
402
403 // Get metadata for this frame. Since the framework guarantees only
404 // one call to process_capture_request at a time, this call is guaranteed
405 // to correspond with the most recently enqueued buffer.
406
407 // Not wrapped in a unique_ptr since control is immediately
408 // handed off to the device via getResultSettings.
409 // TODO(b/30035628): This shouldn't even be an issue actually -
410 // the result settings returned should be a completely new
411 // object allocated by the function, not passed in and back
412 // out (the cloning of the request metadata is just a shim
413 // to fill in all the control fields until the device actually
414 // checks their real values).
415 camera_metadata_t* result_metadata = clone_camera_metadata(
416 request->settings);
417 if (!result_metadata) {
418 return -ENODEV;
419 }
420 uint64_t timestamp = 0;
421 // TODO(b/29334616): this may also want to use a callback, since
422 // the shutter may not happen immediately.
423 res = getResultSettings(&result_metadata, &timestamp);
424 // Upon getting result settings (for now from this function,
425 // eventually by callback, the Camera regains responsibility for
426 // the metadata, so immediately wrap it in a unique_ptr, before
427 // potentially returning due to failure.
428 std::unique_ptr<camera_metadata_t, void(*)(camera_metadata_t *)>
429 returned_metadata(result_metadata, free_camera_metadata);
430 if (res) {
431 return res;
432 }
433 result.result = returned_metadata.get();
434
435 // Notify the framework with the shutter time.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700436 result.frame_number = request->frame_number;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700437 notifyShutter(result.frame_number, timestamp);
438
439 // TODO(b/29334616): asynchronously return results (the following should
440 // be done once all enqueued buffers for the request complete and callback).
441 result.partial_result = 1;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700442 mCallbackOps->process_capture_result(mCallbackOps, &result);
443
444 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700445}
446
447void Camera::setSettings(const camera_metadata_t *new_settings)
448{
449 if (mSettings != NULL) {
450 free_camera_metadata(mSettings);
451 mSettings = NULL;
452 }
453
454 if (new_settings != NULL)
455 mSettings = clone_camera_metadata(new_settings);
456}
457
458bool Camera::isValidReprocessSettings(const camera_metadata_t* /*settings*/)
459{
460 // TODO: reject settings that cannot be reprocessed
461 // input buffers unimplemented, use this to reject reprocessing requests
462 ALOGE("%s:%d: Input buffer reprocessing not implemented", __func__, mId);
463 return false;
464}
465
466int Camera::processCaptureBuffer(const camera3_stream_buffer_t *in,
467 camera3_stream_buffer_t *out)
468{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700469 int res;
470 // TODO(b/29334616): This probably should be non-blocking (currently blocks
471 // here and on gralloc lock). Perhaps caller should put "in" in a queue
472 // initially, then have a thread that dequeues from there and calls this
473 // function.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700474 if (in->acquire_fence != -1) {
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700475 res = sync_wait(in->acquire_fence, CAMERA_SYNC_TIMEOUT);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700476 if (res == -ETIME) {
477 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
478 __func__, mId);
479 return res;
480 } else if (res) {
481 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
482 __func__, mId, strerror(-res), res);
483 return res;
484 }
485 }
486
487 out->stream = in->stream;
488 out->buffer = in->buffer;
489 out->status = CAMERA3_BUFFER_STATUS_OK;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700490
491 // Enqueue buffer for software-painting
492 res = enqueueBuffer(out);
493 if (res) {
494 return res;
495 }
496
497 // TODO(b/29334616): This should be part of a callback made when the
498 // enqueued buffer finishes painting.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700499 // TODO: use driver-backed release fences
500 out->acquire_fence = -1;
501 out->release_fence = -1;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700502 return 0;
503}
504
505void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
506{
507 int res;
508 struct timespec ts;
509
510 // If timestamp is 0, get timestamp from right now instead
511 if (timestamp == 0) {
512 ALOGW("%s:%d: No timestamp provided, using CLOCK_BOOTTIME",
513 __func__, mId);
514 res = clock_gettime(CLOCK_BOOTTIME, &ts);
515 if (res == 0) {
516 timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
517 } else {
518 ALOGE("%s:%d: No timestamp and failed to get CLOCK_BOOTTIME %s(%d)",
519 __func__, mId, strerror(errno), errno);
520 }
521 }
522 camera3_notify_msg_t m;
523 memset(&m, 0, sizeof(m));
524 m.type = CAMERA3_MSG_SHUTTER;
525 m.message.shutter.frame_number = frame_number;
526 m.message.shutter.timestamp = timestamp;
527 mCallbackOps->notify(mCallbackOps, &m);
528}
529
530void Camera::dump(int fd)
531{
532 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
533 ATRACE_CALL();
534 android::Mutex::Autolock al(mDeviceLock);
535
536 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
537
538 // TODO: dump all settings
539 dprintf(fd, "Most Recent Settings: (%p)\n", mSettings);
540
541 dprintf(fd, "Number of streams: %d\n", mNumStreams);
542 for (int i = 0; i < mNumStreams; i++) {
543 dprintf(fd, "Stream %d/%d:\n", i, mNumStreams);
544 mStreams[i]->dump(fd);
545 }
546}
547
548const char* Camera::templateToString(int type)
549{
550 switch (type) {
551 case CAMERA3_TEMPLATE_PREVIEW:
552 return "CAMERA3_TEMPLATE_PREVIEW";
553 case CAMERA3_TEMPLATE_STILL_CAPTURE:
554 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
555 case CAMERA3_TEMPLATE_VIDEO_RECORD:
556 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
557 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
558 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
559 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
560 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
561 }
562 // TODO: support vendor templates
563 return "Invalid template type!";
564}
565
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700566int Camera::setTemplate(int type, const camera_metadata_t *settings)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700567{
568 android::Mutex::Autolock al(mDeviceLock);
569
570 if (!isValidTemplateType(type)) {
571 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
572 return -EINVAL;
573 }
574
575 if (mTemplates[type] != NULL) {
576 ALOGE("%s:%d: Setting already constructed template type %s(%d)",
577 __func__, mId, templateToString(type), type);
578 return -EINVAL;
579 }
580
581 // Make a durable copy of the underlying metadata
582 mTemplates[type] = clone_camera_metadata(settings);
583 if (mTemplates[type] == NULL) {
584 ALOGE("%s:%d: Failed to clone metadata %p for template type %s(%d)",
585 __func__, mId, settings, templateToString(type), type);
586 return -EINVAL;
587 }
588 return 0;
589}
590
591extern "C" {
592// Get handle to camera from device priv data
593static Camera *camdev_to_camera(const camera3_device_t *dev)
594{
595 return reinterpret_cast<Camera*>(dev->priv);
596}
597
598static int initialize(const camera3_device_t *dev,
599 const camera3_callback_ops_t *callback_ops)
600{
601 return camdev_to_camera(dev)->initialize(callback_ops);
602}
603
604static int configure_streams(const camera3_device_t *dev,
605 camera3_stream_configuration_t *stream_list)
606{
607 return camdev_to_camera(dev)->configureStreams(stream_list);
608}
609
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700610static const camera_metadata_t *construct_default_request_settings(
611 const camera3_device_t *dev, int type)
612{
613 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
614}
615
616static int process_capture_request(const camera3_device_t *dev,
617 camera3_capture_request_t *request)
618{
619 return camdev_to_camera(dev)->processCaptureRequest(request);
620}
621
622static void dump(const camera3_device_t *dev, int fd)
623{
624 camdev_to_camera(dev)->dump(fd);
625}
626
627static int flush(const camera3_device_t*)
628{
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700629 // TODO(b/29937783)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700630 ALOGE("%s: unimplemented.", __func__);
631 return -1;
632}
633
634} // extern "C"
635
636const camera3_device_ops_t Camera::sOps = {
637 .initialize = default_camera_hal::initialize,
638 .configure_streams = default_camera_hal::configure_streams,
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700639 .register_stream_buffers = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700640 .construct_default_request_settings
641 = default_camera_hal::construct_default_request_settings,
642 .process_capture_request = default_camera_hal::process_capture_request,
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700643 .get_metadata_vendor_tag_ops = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700644 .dump = default_camera_hal::dump,
645 .flush = default_camera_hal::flush,
646 .reserved = {0},
647};
648
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700649} // namespace default_camera_hal