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