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