blob: 4e9c18d89a5760a1f686f6d3556c6ddacfc94ce2 [file] [log] [blame]
Alex Ray7ee0b7a2012-11-06 00:12:49 -08001/*
2 * Copyright (C) 2012 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#include <cstdlib>
18#include <pthread.h>
Alex Raya0ed4be2013-02-25 15:02:16 -080019#include <hardware/camera3.h>
Alex Ray083315c2013-04-26 19:32:29 -070020#include <sync/sync.h>
Alex Raybfcbd952013-03-20 13:20:02 -070021#include <system/camera_metadata.h>
Alex Rayb0be1032013-05-28 15:52:47 -070022#include <system/graphics.h>
Alex Raya0ed4be2013-02-25 15:02:16 -080023#include "CameraHAL.h"
Alex Rayb0be1032013-05-28 15:52:47 -070024#include "Metadata.h"
Alex Raybcaf7882013-02-28 16:04:35 -080025#include "Stream.h"
Alex Ray7ee0b7a2012-11-06 00:12:49 -080026
Alex Rayed6b8a72012-12-27 10:42:22 -080027//#define LOG_NDEBUG 0
Alex Ray7ee0b7a2012-11-06 00:12:49 -080028#define LOG_TAG "Camera"
29#include <cutils/log.h>
30
Alex Rayed6b8a72012-12-27 10:42:22 -080031#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
Alex Rayea803822013-10-14 15:56:43 -070032#include <utils/Trace.h>
Alex Rayed6b8a72012-12-27 10:42:22 -080033
Alex Ray7ee0b7a2012-11-06 00:12:49 -080034#include "Camera.h"
35
Alex Ray083315c2013-04-26 19:32:29 -070036#define CAMERA_SYNC_TIMEOUT 5000 // in msecs
37
Alex Ray7ee0b7a2012-11-06 00:12:49 -080038namespace default_camera_hal {
39
40extern "C" {
41// Shim passed to the framework to close an opened device.
42static int close_device(hw_device_t* dev)
43{
Alex Raya0ed4be2013-02-25 15:02:16 -080044 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080045 Camera* cam = static_cast<Camera*>(cam_dev->priv);
46 return cam->close();
47}
48} // extern "C"
49
Alex Raya0ed4be2013-02-25 15:02:16 -080050Camera::Camera(int id)
51 : mId(id),
Alex Rayb0be1032013-05-28 15:52:47 -070052 mStaticInfo(NULL),
Alex Raya0ed4be2013-02-25 15:02:16 -080053 mBusy(false),
Alex Raybcaf7882013-02-28 16:04:35 -080054 mCallbackOps(NULL),
55 mStreams(NULL),
Alex Raybfcbd952013-03-20 13:20:02 -070056 mNumStreams(0),
57 mSettings(NULL)
Alex Ray7ee0b7a2012-11-06 00:12:49 -080058{
Alex Ray0f82f5a2013-07-17 14:23:04 -070059 pthread_mutex_init(&mMutex, NULL);
60 pthread_mutex_init(&mStaticInfoMutex, NULL);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080061
Alex Ray61f7a0c2013-07-03 17:54:19 -070062 memset(&mTemplates, 0, sizeof(mTemplates));
Alex Raya0ed4be2013-02-25 15:02:16 -080063 memset(&mDevice, 0, sizeof(mDevice));
Alex Ray7ee0b7a2012-11-06 00:12:49 -080064 mDevice.common.tag = HARDWARE_DEVICE_TAG;
Alex Rayb0be1032013-05-28 15:52:47 -070065 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_0;
Alex Ray7ee0b7a2012-11-06 00:12:49 -080066 mDevice.common.close = close_device;
Alex Raya0ed4be2013-02-25 15:02:16 -080067 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080068 mDevice.priv = this;
69}
70
71Camera::~Camera()
72{
Alex Ray0f82f5a2013-07-17 14:23:04 -070073 pthread_mutex_destroy(&mMutex);
74 pthread_mutex_destroy(&mStaticInfoMutex);
Alex Ray61f7a0c2013-07-03 17:54:19 -070075 if (mStaticInfo != NULL) {
76 free_camera_metadata(mStaticInfo);
77 }
Alex Ray7ee0b7a2012-11-06 00:12:49 -080078}
79
Alex Raya0ed4be2013-02-25 15:02:16 -080080int Camera::open(const hw_module_t *module, hw_device_t **device)
Alex Ray7ee0b7a2012-11-06 00:12:49 -080081{
Alex Raya0ed4be2013-02-25 15:02:16 -080082 ALOGI("%s:%d: Opening camera device", __func__, mId);
Alex Rayea803822013-10-14 15:56:43 -070083 ATRACE_CALL();
Alex Ray7ee0b7a2012-11-06 00:12:49 -080084 pthread_mutex_lock(&mMutex);
85 if (mBusy) {
86 pthread_mutex_unlock(&mMutex);
Alex Raya0ed4be2013-02-25 15:02:16 -080087 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080088 return -EBUSY;
89 }
90
91 // TODO: open camera dev nodes, etc
92 mBusy = true;
Alex Raya0ed4be2013-02-25 15:02:16 -080093 mDevice.common.module = const_cast<hw_module_t*>(module);
94 *device = &mDevice.common;
Alex Ray7ee0b7a2012-11-06 00:12:49 -080095
96 pthread_mutex_unlock(&mMutex);
97 return 0;
98}
99
Alex Rayb0be1032013-05-28 15:52:47 -0700100int Camera::getInfo(struct camera_info *info)
101{
Alex Rayb0be1032013-05-28 15:52:47 -0700102 info->facing = CAMERA_FACING_FRONT;
103 info->orientation = 0;
104 info->device_version = mDevice.common.version;
105
Alex Ray0f82f5a2013-07-17 14:23:04 -0700106 pthread_mutex_lock(&mStaticInfoMutex);
Alex Rayb0be1032013-05-28 15:52:47 -0700107 if (mStaticInfo == NULL) {
Alex Ray0f82f5a2013-07-17 14:23:04 -0700108 mStaticInfo = initStaticInfo();
Alex Rayb0be1032013-05-28 15:52:47 -0700109 }
Alex Ray0f82f5a2013-07-17 14:23:04 -0700110 pthread_mutex_unlock(&mStaticInfoMutex);
Alex Rayb0be1032013-05-28 15:52:47 -0700111
112 info->static_camera_characteristics = mStaticInfo;
113
Alex Ray0f82f5a2013-07-17 14:23:04 -0700114 return 0;
Alex Rayb0be1032013-05-28 15:52:47 -0700115}
116
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800117int Camera::close()
118{
Alex Raya0ed4be2013-02-25 15:02:16 -0800119 ALOGI("%s:%d: Closing camera device", __func__, mId);
Alex Rayea803822013-10-14 15:56:43 -0700120 ATRACE_CALL();
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800121 pthread_mutex_lock(&mMutex);
122 if (!mBusy) {
123 pthread_mutex_unlock(&mMutex);
Alex Raya0ed4be2013-02-25 15:02:16 -0800124 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800125 return -EINVAL;
126 }
127
128 // TODO: close camera dev nodes, etc
129 mBusy = false;
130
131 pthread_mutex_unlock(&mMutex);
132 return 0;
133}
134
Alex Raya0ed4be2013-02-25 15:02:16 -0800135int Camera::initialize(const camera3_callback_ops_t *callback_ops)
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800136{
Alex Ray61f7a0c2013-07-03 17:54:19 -0700137 int res;
138
Alex Raya0ed4be2013-02-25 15:02:16 -0800139 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
140 mCallbackOps = callback_ops;
Alex Ray61f7a0c2013-07-03 17:54:19 -0700141 // per-device specific initialization
142 res = initDevice();
143 if (res != 0) {
144 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
145 return res;
Alex Ray89a82662013-05-28 20:32:48 -0700146 }
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800147 return 0;
148}
149
Alex Raybcaf7882013-02-28 16:04:35 -0800150int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800151{
Alex Raybcaf7882013-02-28 16:04:35 -0800152 camera3_stream_t *astream;
153 Stream **newStreams = NULL;
154
Alex Rayea803822013-10-14 15:56:43 -0700155 ATRACE_CALL();
Alex Raybcaf7882013-02-28 16:04:35 -0800156 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
157
158 if (stream_config == NULL) {
159 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
160 return -EINVAL;
161 }
162 if (stream_config->num_streams == 0) {
163 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
164 return -EINVAL;
165 }
166
167 // Create new stream array
168 newStreams = new Stream*[stream_config->num_streams];
169 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
170 stream_config->num_streams);
171
172 pthread_mutex_lock(&mMutex);
173
174 // Mark all current streams unused for now
175 for (int i = 0; i < mNumStreams; i++)
176 mStreams[i]->mReuse = false;
177 // Fill new stream array with reused streams and new streams
Alex Rayc6bf2f22013-05-28 15:52:04 -0700178 for (unsigned int i = 0; i < stream_config->num_streams; i++) {
Alex Raybcaf7882013-02-28 16:04:35 -0800179 astream = stream_config->streams[i];
Alex Ray2b286da2013-05-29 15:08:29 -0700180 if (astream->max_buffers > 0) {
181 ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
Alex Raybcaf7882013-02-28 16:04:35 -0800182 newStreams[i] = reuseStream(astream);
Alex Ray2b286da2013-05-29 15:08:29 -0700183 } else {
184 ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
Alex Raybcaf7882013-02-28 16:04:35 -0800185 newStreams[i] = new Stream(mId, astream);
Alex Ray2b286da2013-05-29 15:08:29 -0700186 }
Alex Raybcaf7882013-02-28 16:04:35 -0800187
188 if (newStreams[i] == NULL) {
189 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
190 goto err_out;
191 }
192 astream->priv = newStreams[i];
193 }
194
195 // Verify the set of streams in aggregate
196 if (!isValidStreamSet(newStreams, stream_config->num_streams)) {
197 ALOGE("%s:%d: Invalid stream set", __func__, mId);
198 goto err_out;
199 }
200
201 // Set up all streams (calculate usage/max_buffers for each)
202 setupStreams(newStreams, stream_config->num_streams);
203
204 // Destroy all old streams and replace stream array with new one
205 destroyStreams(mStreams, mNumStreams);
206 mStreams = newStreams;
207 mNumStreams = stream_config->num_streams;
208
Alex Raybfcbd952013-03-20 13:20:02 -0700209 // Clear out last seen settings metadata
210 setSettings(NULL);
211
Alex Raybcaf7882013-02-28 16:04:35 -0800212 pthread_mutex_unlock(&mMutex);
Alex Raya0ed4be2013-02-25 15:02:16 -0800213 return 0;
Alex Raybcaf7882013-02-28 16:04:35 -0800214
215err_out:
216 // Clean up temporary streams, preserve existing mStreams/mNumStreams
217 destroyStreams(newStreams, stream_config->num_streams);
218 pthread_mutex_unlock(&mMutex);
219 return -EINVAL;
220}
221
222void Camera::destroyStreams(Stream **streams, int count)
223{
224 if (streams == NULL)
225 return;
226 for (int i = 0; i < count; i++) {
227 // Only destroy streams that weren't reused
228 if (streams[i] != NULL && !streams[i]->mReuse)
229 delete streams[i];
230 }
231 delete [] streams;
232}
233
234Stream *Camera::reuseStream(camera3_stream_t *astream)
235{
236 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
237 // Verify the re-used stream's parameters match
238 if (!priv->isValidReuseStream(mId, astream)) {
239 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
240 return NULL;
241 }
242 // Mark stream to be reused
243 priv->mReuse = true;
244 return priv;
245}
246
247bool Camera::isValidStreamSet(Stream **streams, int count)
248{
249 int inputs = 0;
250 int outputs = 0;
251
252 if (streams == NULL) {
253 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
254 return false;
255 }
256 if (count == 0) {
257 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
258 return false;
259 }
260 // Validate there is at most one input stream and at least one output stream
261 for (int i = 0; i < count; i++) {
262 // A stream may be both input and output (bidirectional)
263 if (streams[i]->isInputType())
264 inputs++;
265 if (streams[i]->isOutputType())
266 outputs++;
267 }
Alex Ray768216e2013-07-02 16:56:14 -0700268 ALOGV("%s:%d: Configuring %d output streams and %d input streams",
269 __func__, mId, outputs, inputs);
Alex Raybcaf7882013-02-28 16:04:35 -0800270 if (outputs < 1) {
271 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
272 return false;
273 }
274 if (inputs > 1) {
275 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
276 return false;
277 }
278 // TODO: check for correct number of Bayer/YUV/JPEG/Encoder streams
279 return true;
280}
281
282void Camera::setupStreams(Stream **streams, int count)
283{
284 /*
285 * This is where the HAL has to decide internally how to handle all of the
286 * streams, and then produce usage and max_buffer values for each stream.
287 * Note, the stream array has been checked before this point for ALL invalid
288 * conditions, so it must find a successful configuration for this stream
289 * array. The HAL may not return an error from this point.
290 *
291 * In this demo HAL, we just set all streams to be the same dummy values;
292 * real implementations will want to avoid USAGE_SW_{READ|WRITE}_OFTEN.
293 */
294 for (int i = 0; i < count; i++) {
295 uint32_t usage = 0;
296
297 if (streams[i]->isOutputType())
298 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN |
299 GRALLOC_USAGE_HW_CAMERA_WRITE;
300 if (streams[i]->isInputType())
301 usage |= GRALLOC_USAGE_SW_READ_OFTEN |
302 GRALLOC_USAGE_HW_CAMERA_READ;
303
304 streams[i]->setUsage(usage);
305 streams[i]->setMaxBuffers(1);
306 }
Alex Raya0ed4be2013-02-25 15:02:16 -0800307}
308
309int Camera::registerStreamBuffers(const camera3_stream_buffer_set_t *buf_set)
310{
311 ALOGV("%s:%d: buffer_set=%p", __func__, mId, buf_set);
Alex Ray8a8f86b2013-03-01 01:32:21 -0800312 if (buf_set == NULL) {
313 ALOGE("%s:%d: NULL buffer set", __func__, mId);
314 return -EINVAL;
315 }
316 if (buf_set->stream == NULL) {
317 ALOGE("%s:%d: NULL stream handle", __func__, mId);
318 return -EINVAL;
319 }
320 Stream *stream = reinterpret_cast<Stream*>(buf_set->stream->priv);
321 return stream->registerBuffers(buf_set);
Alex Raya0ed4be2013-02-25 15:02:16 -0800322}
323
Alex Ray61f7a0c2013-07-03 17:54:19 -0700324bool Camera::isValidTemplateType(int type)
325{
326 return type < 1 || type >= CAMERA3_TEMPLATE_COUNT;
327}
328
Alex Raya0ed4be2013-02-25 15:02:16 -0800329const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
330{
331 ALOGV("%s:%d: type=%d", __func__, mId, type);
Alex Ray89a82662013-05-28 20:32:48 -0700332
Alex Ray61f7a0c2013-07-03 17:54:19 -0700333 if (!isValidTemplateType(type)) {
Alex Ray89a82662013-05-28 20:32:48 -0700334 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
335 return NULL;
336 }
Alex Ray61f7a0c2013-07-03 17:54:19 -0700337 return mTemplates[type];
Alex Raya0ed4be2013-02-25 15:02:16 -0800338}
339
340int Camera::processCaptureRequest(camera3_capture_request_t *request)
341{
Alex Ray083315c2013-04-26 19:32:29 -0700342 camera3_capture_result result;
343
Alex Raya0ed4be2013-02-25 15:02:16 -0800344 ALOGV("%s:%d: request=%p", __func__, mId, request);
Alex Rayea803822013-10-14 15:56:43 -0700345 ATRACE_CALL();
Alex Raya0ed4be2013-02-25 15:02:16 -0800346
347 if (request == NULL) {
348 ALOGE("%s:%d: NULL request recieved", __func__, mId);
Alex Raya0ed4be2013-02-25 15:02:16 -0800349 return -EINVAL;
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800350 }
351
Alex Raybfcbd952013-03-20 13:20:02 -0700352 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
Alex Ray11bbeef2013-04-26 14:47:08 -0700366 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
Alex Ray083315c2013-04-26 19:32:29 -0700385 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 }
390 result.num_output_buffers = request->num_output_buffers;
391 result.output_buffers = new camera3_stream_buffer_t[result.num_output_buffers];
392 for (unsigned int i = 0; i < request->num_output_buffers; i++) {
393 int res = processCaptureBuffer(&request->output_buffers[i],
394 const_cast<camera3_stream_buffer_t*>(&result.output_buffers[i]));
395 if (res)
396 goto err_out;
397 }
398
399 result.frame_number = request->frame_number;
400 // TODO: return actual captured/reprocessed settings
401 result.result = request->settings;
402 // TODO: asynchronously return results
Alex Ray764e4422013-06-04 12:38:07 -0700403 notifyShutter(request->frame_number, 0);
Alex Ray083315c2013-04-26 19:32:29 -0700404 mCallbackOps->process_capture_result(mCallbackOps, &result);
405
Alex Raya0ed4be2013-02-25 15:02:16 -0800406 return 0;
Alex Ray083315c2013-04-26 19:32:29 -0700407
408err_out:
409 delete [] result.output_buffers;
410 // TODO: this should probably be a total device failure; transient for now
411 return -EINVAL;
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800412}
413
Alex Raybfcbd952013-03-20 13:20:02 -0700414void Camera::setSettings(const camera_metadata_t *new_settings)
415{
416 if (mSettings != NULL) {
417 free_camera_metadata(mSettings);
418 mSettings = NULL;
419 }
420
421 if (new_settings != NULL)
422 mSettings = clone_camera_metadata(new_settings);
423}
424
Alex Rayc6bf2f22013-05-28 15:52:04 -0700425bool Camera::isValidReprocessSettings(const camera_metadata_t* /*settings*/)
Alex Ray11bbeef2013-04-26 14:47:08 -0700426{
427 // TODO: reject settings that cannot be reprocessed
428 // input buffers unimplemented, use this to reject reprocessing requests
429 ALOGE("%s:%d: Input buffer reprocessing not implemented", __func__, mId);
430 return false;
431}
432
Alex Ray083315c2013-04-26 19:32:29 -0700433int Camera::processCaptureBuffer(const camera3_stream_buffer_t *in,
434 camera3_stream_buffer_t *out)
435{
Alex Ray77ecfd72013-05-30 00:19:04 -0700436 if (in->acquire_fence != -1) {
437 int res = sync_wait(in->acquire_fence, CAMERA_SYNC_TIMEOUT);
438 if (res == -ETIME) {
439 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
440 __func__, mId);
441 return res;
442 } else if (res) {
443 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
444 __func__, mId, strerror(-res), res);
445 return res;
446 }
Alex Ray083315c2013-04-26 19:32:29 -0700447 }
448
449 out->stream = in->stream;
450 out->buffer = in->buffer;
451 out->status = CAMERA3_BUFFER_STATUS_OK;
452 // TODO: use driver-backed release fences
453 out->acquire_fence = -1;
454 out->release_fence = -1;
455
456 // TODO: lock and software-paint buffer
457 return 0;
458}
459
Alex Ray764e4422013-06-04 12:38:07 -0700460void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
461{
462 int res;
463 struct timespec ts;
464
465 // If timestamp is 0, get timestamp from right now instead
466 if (timestamp == 0) {
467 ALOGW("%s:%d: No timestamp provided, using CLOCK_BOOTTIME",
468 __func__, mId);
469 res = clock_gettime(CLOCK_BOOTTIME, &ts);
470 if (res == 0) {
471 timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
472 } else {
473 ALOGE("%s:%d: No timestamp and failed to get CLOCK_BOOTTIME %s(%d)",
474 __func__, mId, strerror(errno), errno);
475 }
476 }
477 camera3_notify_msg_t m;
478 memset(&m, 0, sizeof(m));
479 m.type = CAMERA3_MSG_SHUTTER;
480 m.message.shutter.frame_number = frame_number;
481 m.message.shutter.timestamp = timestamp;
482 mCallbackOps->notify(mCallbackOps, &m);
483}
484
Alex Raya0ed4be2013-02-25 15:02:16 -0800485void Camera::getMetadataVendorTagOps(vendor_tag_query_ops_t *ops)
486{
487 ALOGV("%s:%d: ops=%p", __func__, mId, ops);
488 // TODO: return vendor tag ops
489}
490
491void Camera::dump(int fd)
492{
Alex Rayaf3a4612013-04-29 14:16:10 -0700493 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
Alex Raya0ed4be2013-02-25 15:02:16 -0800494 // TODO: dprintf all relevant state to fd
495}
496
Alex Ray61f7a0c2013-07-03 17:54:19 -0700497void Camera::setTemplate(int type, camera_metadata_t *settings)
498{
499 if (!isValidTemplateType(type)) {
500 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
501 return;
502 }
503 pthread_mutex_lock(&mMutex);
504 if (mTemplates[type] != NULL) {
505 ALOGE("%s:%d: Setting already constructed template type %d: %p to %p!",
506 __func__, mId, type, mStaticInfo, settings);
507 free_camera_metadata(mTemplates[type]);
508 }
509 mTemplates[type] = clone_camera_metadata(settings);
510 pthread_mutex_unlock(&mMutex);
511}
512
Alex Raya0ed4be2013-02-25 15:02:16 -0800513extern "C" {
514// Get handle to camera from device priv data
515static Camera *camdev_to_camera(const camera3_device_t *dev)
516{
517 return reinterpret_cast<Camera*>(dev->priv);
518}
519
520static int initialize(const camera3_device_t *dev,
521 const camera3_callback_ops_t *callback_ops)
522{
523 return camdev_to_camera(dev)->initialize(callback_ops);
524}
525
526static int configure_streams(const camera3_device_t *dev,
527 camera3_stream_configuration_t *stream_list)
528{
529 return camdev_to_camera(dev)->configureStreams(stream_list);
530}
531
532static int register_stream_buffers(const camera3_device_t *dev,
533 const camera3_stream_buffer_set_t *buffer_set)
534{
535 return camdev_to_camera(dev)->registerStreamBuffers(buffer_set);
536}
537
538static const camera_metadata_t *construct_default_request_settings(
539 const camera3_device_t *dev, int type)
540{
541 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
542}
543
544static int process_capture_request(const camera3_device_t *dev,
545 camera3_capture_request_t *request)
546{
547 return camdev_to_camera(dev)->processCaptureRequest(request);
548}
549
550static void get_metadata_vendor_tag_ops(const camera3_device_t *dev,
551 vendor_tag_query_ops_t *ops)
552{
553 camdev_to_camera(dev)->getMetadataVendorTagOps(ops);
554}
555
556static void dump(const camera3_device_t *dev, int fd)
557{
558 camdev_to_camera(dev)->dump(fd);
559}
560} // extern "C"
561
562const camera3_device_ops_t Camera::sOps = {
563 .initialize = default_camera_hal::initialize,
564 .configure_streams = default_camera_hal::configure_streams,
565 .register_stream_buffers = default_camera_hal::register_stream_buffers,
566 .construct_default_request_settings =
567 default_camera_hal::construct_default_request_settings,
568 .process_capture_request = default_camera_hal::process_capture_request,
569 .get_metadata_vendor_tag_ops =
570 default_camera_hal::get_metadata_vendor_tag_ops,
571 .dump = default_camera_hal::dump
572};
573
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800574} // namespace default_camera_hal