Camera3Device.cpp revision e11ae4b2f7d38c8092e7c67ff06610165d866d98
1/* 2 * Copyright (C) 2013 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#define LOG_TAG "Camera3-Device" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20//#define LOG_NNDEBUG 0 // Per-frame verbose logging 21 22#ifdef LOG_NNDEBUG 23#define ALOGVV(...) ALOGV(__VA_ARGS__) 24#else 25#define ALOGVV(...) ((void)0) 26#endif 27 28// Convenience macro for transient errors 29#define CLOGE(fmt, ...) ALOGE("Camera %d: %s: " fmt, mId, __FUNCTION__, \ 30 ##__VA_ARGS__) 31 32// Convenience macros for transitioning to the error state 33#define SET_ERR(fmt, ...) setErrorState( \ 34 "%s: " fmt, __FUNCTION__, \ 35 ##__VA_ARGS__) 36#define SET_ERR_L(fmt, ...) setErrorStateLocked( \ 37 "%s: " fmt, __FUNCTION__, \ 38 ##__VA_ARGS__) 39 40#include <inttypes.h> 41 42#include <utils/Log.h> 43#include <utils/Trace.h> 44#include <utils/Timers.h> 45 46#include "utils/CameraTraces.h" 47#include "device3/Camera3Device.h" 48#include "device3/Camera3OutputStream.h" 49#include "device3/Camera3InputStream.h" 50#include "device3/Camera3ZslStream.h" 51 52using namespace android::camera3; 53 54namespace android { 55 56Camera3Device::Camera3Device(int id): 57 mId(id), 58 mHal3Device(NULL), 59 mStatus(STATUS_UNINITIALIZED), 60 mUsePartialResultQuirk(false), 61 mNextResultFrameNumber(0), 62 mNextShutterFrameNumber(0), 63 mListener(NULL) 64{ 65 ATRACE_CALL(); 66 camera3_callback_ops::notify = &sNotify; 67 camera3_callback_ops::process_capture_result = &sProcessCaptureResult; 68 ALOGV("%s: Created device for camera %d", __FUNCTION__, id); 69} 70 71Camera3Device::~Camera3Device() 72{ 73 ATRACE_CALL(); 74 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId); 75 disconnect(); 76} 77 78int Camera3Device::getId() const { 79 return mId; 80} 81 82/** 83 * CameraDeviceBase interface 84 */ 85 86status_t Camera3Device::initialize(camera_module_t *module) 87{ 88 ATRACE_CALL(); 89 Mutex::Autolock il(mInterfaceLock); 90 Mutex::Autolock l(mLock); 91 92 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId); 93 if (mStatus != STATUS_UNINITIALIZED) { 94 CLOGE("Already initialized!"); 95 return INVALID_OPERATION; 96 } 97 98 /** Open HAL device */ 99 100 status_t res; 101 String8 deviceName = String8::format("%d", mId); 102 103 camera3_device_t *device; 104 105 ATRACE_BEGIN("camera3->open"); 106 res = module->common.methods->open(&module->common, deviceName.string(), 107 reinterpret_cast<hw_device_t**>(&device)); 108 ATRACE_END(); 109 110 if (res != OK) { 111 SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res); 112 return res; 113 } 114 115 /** Cross-check device version */ 116 117 if (device->common.version < CAMERA_DEVICE_API_VERSION_3_0) { 118 SET_ERR_L("Could not open camera: " 119 "Camera device should be at least %x, reports %x instead", 120 CAMERA_DEVICE_API_VERSION_3_0, 121 device->common.version); 122 device->common.close(&device->common); 123 return BAD_VALUE; 124 } 125 126 camera_info info; 127 res = module->get_camera_info(mId, &info); 128 if (res != OK) return res; 129 130 if (info.device_version != device->common.version) { 131 SET_ERR_L("HAL reporting mismatched camera_info version (%x)" 132 " and device version (%x).", 133 info.device_version, device->common.version); 134 device->common.close(&device->common); 135 return BAD_VALUE; 136 } 137 138 /** Initialize device with callback functions */ 139 140 ATRACE_BEGIN("camera3->initialize"); 141 res = device->ops->initialize(device, this); 142 ATRACE_END(); 143 144 if (res != OK) { 145 SET_ERR_L("Unable to initialize HAL device: %s (%d)", 146 strerror(-res), res); 147 device->common.close(&device->common); 148 return BAD_VALUE; 149 } 150 151 /** Start up status tracker thread */ 152 mStatusTracker = new StatusTracker(this); 153 res = mStatusTracker->run(String8::format("C3Dev-%d-Status", mId).string()); 154 if (res != OK) { 155 SET_ERR_L("Unable to start status tracking thread: %s (%d)", 156 strerror(-res), res); 157 device->common.close(&device->common); 158 mStatusTracker.clear(); 159 return res; 160 } 161 162 /** Start up request queue thread */ 163 164 mRequestThread = new RequestThread(this, mStatusTracker, device); 165 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string()); 166 if (res != OK) { 167 SET_ERR_L("Unable to start request queue thread: %s (%d)", 168 strerror(-res), res); 169 device->common.close(&device->common); 170 mRequestThread.clear(); 171 return res; 172 } 173 174 /** Everything is good to go */ 175 176 mDeviceInfo = info.static_camera_characteristics; 177 mHal3Device = device; 178 mStatus = STATUS_UNCONFIGURED; 179 mNextStreamId = 0; 180 mNeedConfig = true; 181 mPauseStateNotify = false; 182 183 /** Check for quirks */ 184 185 // Will the HAL be sending in early partial result metadata? 186 camera_metadata_entry partialResultsQuirk = 187 mDeviceInfo.find(ANDROID_QUIRKS_USE_PARTIAL_RESULT); 188 if (partialResultsQuirk.count > 0 && partialResultsQuirk.data.u8[0] == 1) { 189 mUsePartialResultQuirk = true; 190 } 191 192 return OK; 193} 194 195status_t Camera3Device::disconnect() { 196 ATRACE_CALL(); 197 Mutex::Autolock il(mInterfaceLock); 198 199 ALOGV("%s: E", __FUNCTION__); 200 201 status_t res = OK; 202 203 { 204 Mutex::Autolock l(mLock); 205 if (mStatus == STATUS_UNINITIALIZED) return res; 206 207 if (mStatus == STATUS_ACTIVE || 208 (mStatus == STATUS_ERROR && mRequestThread != NULL)) { 209 res = mRequestThread->clearRepeatingRequests(); 210 if (res != OK) { 211 SET_ERR_L("Can't stop streaming"); 212 // Continue to close device even in case of error 213 } else { 214 res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout); 215 if (res != OK) { 216 SET_ERR_L("Timeout waiting for HAL to drain"); 217 // Continue to close device even in case of error 218 } 219 } 220 } 221 222 if (mStatus == STATUS_ERROR) { 223 CLOGE("Shutting down in an error state"); 224 } 225 226 if (mStatusTracker != NULL) { 227 mStatusTracker->requestExit(); 228 } 229 230 if (mRequestThread != NULL) { 231 mRequestThread->requestExit(); 232 } 233 234 mOutputStreams.clear(); 235 mInputStream.clear(); 236 } 237 238 // Joining done without holding mLock, otherwise deadlocks may ensue 239 // as the threads try to access parent state 240 if (mRequestThread != NULL && mStatus != STATUS_ERROR) { 241 // HAL may be in a bad state, so waiting for request thread 242 // (which may be stuck in the HAL processCaptureRequest call) 243 // could be dangerous. 244 mRequestThread->join(); 245 } 246 247 if (mStatusTracker != NULL) { 248 mStatusTracker->join(); 249 } 250 251 { 252 Mutex::Autolock l(mLock); 253 254 mRequestThread.clear(); 255 mStatusTracker.clear(); 256 257 if (mHal3Device != NULL) { 258 ATRACE_BEGIN("camera3->close"); 259 mHal3Device->common.close(&mHal3Device->common); 260 ATRACE_END(); 261 mHal3Device = NULL; 262 } 263 264 mStatus = STATUS_UNINITIALIZED; 265 } 266 267 ALOGV("%s: X", __FUNCTION__); 268 return res; 269} 270 271// For dumping/debugging only - 272// try to acquire a lock a few times, eventually give up to proceed with 273// debug/dump operations 274bool Camera3Device::tryLockSpinRightRound(Mutex& lock) { 275 bool gotLock = false; 276 for (size_t i = 0; i < kDumpLockAttempts; ++i) { 277 if (lock.tryLock() == NO_ERROR) { 278 gotLock = true; 279 break; 280 } else { 281 usleep(kDumpSleepDuration); 282 } 283 } 284 return gotLock; 285} 286 287ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const { 288 // TODO: replace below with availableStreamConfiguration for HAL3.2+. 289 camera_metadata_ro_entry availableJpegSizes = 290 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_JPEG_SIZES); 291 if (availableJpegSizes.count == 0 || availableJpegSizes.count % 2 != 0) { 292 ALOGE("%s: Camera %d: Can't find find valid available jpeg sizes in static metadata!", 293 __FUNCTION__, mId); 294 return BAD_VALUE; 295 } 296 297 // Get max jpeg size (area-wise). 298 int32_t maxJpegWidth = 0, maxJpegHeight = 0; 299 bool foundMax = false; 300 for (size_t i = 0; i < availableJpegSizes.count; i += 2) { 301 if ((availableJpegSizes.data.i32[i] * availableJpegSizes.data.i32[i + 1]) 302 > (maxJpegWidth * maxJpegHeight)) { 303 maxJpegWidth = availableJpegSizes.data.i32[i]; 304 maxJpegHeight = availableJpegSizes.data.i32[i + 1]; 305 foundMax = true; 306 } 307 } 308 if (!foundMax) { 309 return BAD_VALUE; 310 } 311 312 // Get max jpeg buffer size 313 ssize_t maxJpegBufferSize = 0; 314 camera_metadata_ro_entry jpegMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE); 315 if (jpegMaxSize.count == 0) { 316 ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId); 317 return BAD_VALUE; 318 } 319 maxJpegBufferSize = jpegMaxSize.data.i32[0]; 320 321 // Calculate final jpeg buffer size for the given resolution. 322 float scaleFactor = ((float) (width * height)) / (maxJpegWidth * maxJpegHeight); 323 ssize_t jpegBufferSize = scaleFactor * maxJpegBufferSize; 324 // Bound the buffer size to [MIN_JPEG_BUFFER_SIZE, maxJpegBufferSize]. 325 if (jpegBufferSize > maxJpegBufferSize) { 326 jpegBufferSize = maxJpegBufferSize; 327 } else if (jpegBufferSize < kMinJpegBufferSize) { 328 jpegBufferSize = kMinJpegBufferSize; 329 } 330 331 return jpegBufferSize; 332} 333 334status_t Camera3Device::dump(int fd, const Vector<String16> &args) { 335 ATRACE_CALL(); 336 (void)args; 337 338 // Try to lock, but continue in case of failure (to avoid blocking in 339 // deadlocks) 340 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock); 341 bool gotLock = tryLockSpinRightRound(mLock); 342 343 ALOGW_IF(!gotInterfaceLock, 344 "Camera %d: %s: Unable to lock interface lock, proceeding anyway", 345 mId, __FUNCTION__); 346 ALOGW_IF(!gotLock, 347 "Camera %d: %s: Unable to lock main lock, proceeding anyway", 348 mId, __FUNCTION__); 349 350 String8 lines; 351 352 const char *status = 353 mStatus == STATUS_ERROR ? "ERROR" : 354 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" : 355 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" : 356 mStatus == STATUS_CONFIGURED ? "CONFIGURED" : 357 mStatus == STATUS_ACTIVE ? "ACTIVE" : 358 "Unknown"; 359 360 lines.appendFormat(" Device status: %s\n", status); 361 if (mStatus == STATUS_ERROR) { 362 lines.appendFormat(" Error cause: %s\n", mErrorCause.string()); 363 } 364 lines.appendFormat(" Stream configuration:\n"); 365 366 if (mInputStream != NULL) { 367 write(fd, lines.string(), lines.size()); 368 mInputStream->dump(fd, args); 369 } else { 370 lines.appendFormat(" No input stream.\n"); 371 write(fd, lines.string(), lines.size()); 372 } 373 for (size_t i = 0; i < mOutputStreams.size(); i++) { 374 mOutputStreams[i]->dump(fd,args); 375 } 376 377 lines = String8(" In-flight requests:\n"); 378 if (mInFlightMap.size() == 0) { 379 lines.append(" None\n"); 380 } else { 381 for (size_t i = 0; i < mInFlightMap.size(); i++) { 382 InFlightRequest r = mInFlightMap.valueAt(i); 383 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata" 384 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i), 385 r.captureTimestamp, r.haveResultMetadata ? "true" : "false", 386 r.numBuffersLeft); 387 } 388 } 389 write(fd, lines.string(), lines.size()); 390 391 { 392 lines = String8(" Last request sent:\n"); 393 write(fd, lines.string(), lines.size()); 394 395 CameraMetadata lastRequest = getLatestRequestLocked(); 396 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6); 397 } 398 399 if (mHal3Device != NULL) { 400 lines = String8(" HAL device dump:\n"); 401 write(fd, lines.string(), lines.size()); 402 mHal3Device->ops->dump(mHal3Device, fd); 403 } 404 405 if (gotLock) mLock.unlock(); 406 if (gotInterfaceLock) mInterfaceLock.unlock(); 407 408 return OK; 409} 410 411const CameraMetadata& Camera3Device::info() const { 412 ALOGVV("%s: E", __FUNCTION__); 413 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED || 414 mStatus == STATUS_ERROR)) { 415 ALOGW("%s: Access to static info %s!", __FUNCTION__, 416 mStatus == STATUS_ERROR ? 417 "when in error state" : "before init"); 418 } 419 return mDeviceInfo; 420} 421 422status_t Camera3Device::checkStatusOkToCaptureLocked() { 423 switch (mStatus) { 424 case STATUS_ERROR: 425 CLOGE("Device has encountered a serious error"); 426 return INVALID_OPERATION; 427 case STATUS_UNINITIALIZED: 428 CLOGE("Device not initialized"); 429 return INVALID_OPERATION; 430 case STATUS_UNCONFIGURED: 431 case STATUS_CONFIGURED: 432 case STATUS_ACTIVE: 433 // OK 434 break; 435 default: 436 SET_ERR_L("Unexpected status: %d", mStatus); 437 return INVALID_OPERATION; 438 } 439 return OK; 440} 441 442status_t Camera3Device::convertMetadataListToRequestListLocked( 443 const List<const CameraMetadata> &metadataList, RequestList *requestList) { 444 if (requestList == NULL) { 445 CLOGE("requestList cannot be NULL."); 446 return BAD_VALUE; 447 } 448 449 int32_t burstId = 0; 450 for (List<const CameraMetadata>::const_iterator it = metadataList.begin(); 451 it != metadataList.end(); ++it) { 452 sp<CaptureRequest> newRequest = setUpRequestLocked(*it); 453 if (newRequest == 0) { 454 CLOGE("Can't create capture request"); 455 return BAD_VALUE; 456 } 457 458 // Setup burst Id and request Id 459 newRequest->mResultExtras.burstId = burstId++; 460 if (it->exists(ANDROID_REQUEST_ID)) { 461 if (it->find(ANDROID_REQUEST_ID).count == 0) { 462 CLOGE("RequestID entry exists; but must not be empty in metadata"); 463 return BAD_VALUE; 464 } 465 newRequest->mResultExtras.requestId = it->find(ANDROID_REQUEST_ID).data.i32[0]; 466 } else { 467 CLOGE("RequestID does not exist in metadata"); 468 return BAD_VALUE; 469 } 470 471 requestList->push_back(newRequest); 472 473 ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId); 474 } 475 return OK; 476} 477 478status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) { 479 ATRACE_CALL(); 480 481 List<const CameraMetadata> requests; 482 requests.push_back(request); 483 return captureList(requests, /*lastFrameNumber*/NULL); 484} 485 486status_t Camera3Device::submitRequestsHelper( 487 const List<const CameraMetadata> &requests, bool repeating, 488 /*out*/ 489 int64_t *lastFrameNumber) { 490 ATRACE_CALL(); 491 Mutex::Autolock il(mInterfaceLock); 492 Mutex::Autolock l(mLock); 493 494 status_t res = checkStatusOkToCaptureLocked(); 495 if (res != OK) { 496 // error logged by previous call 497 return res; 498 } 499 500 RequestList requestList; 501 502 res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList); 503 if (res != OK) { 504 // error logged by previous call 505 return res; 506 } 507 508 if (repeating) { 509 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber); 510 } else { 511 res = mRequestThread->queueRequestList(requestList, lastFrameNumber); 512 } 513 514 if (res == OK) { 515 waitUntilStateThenRelock(/*active*/true, kActiveTimeout); 516 if (res != OK) { 517 SET_ERR_L("Can't transition to active in %f seconds!", 518 kActiveTimeout/1e9); 519 } 520 ALOGV("Camera %d: Capture request %" PRId32 " enqueued", mId, 521 (*(requestList.begin()))->mResultExtras.requestId); 522 } else { 523 CLOGE("Cannot queue request. Impossible."); 524 return BAD_VALUE; 525 } 526 527 return res; 528} 529 530status_t Camera3Device::captureList(const List<const CameraMetadata> &requests, 531 int64_t *lastFrameNumber) { 532 ATRACE_CALL(); 533 534 return submitRequestsHelper(requests, /*repeating*/false, lastFrameNumber); 535} 536 537status_t Camera3Device::setStreamingRequest(const CameraMetadata &request, 538 int64_t* /*lastFrameNumber*/) { 539 ATRACE_CALL(); 540 541 List<const CameraMetadata> requests; 542 requests.push_back(request); 543 return setStreamingRequestList(requests, /*lastFrameNumber*/NULL); 544} 545 546status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests, 547 int64_t *lastFrameNumber) { 548 ATRACE_CALL(); 549 550 return submitRequestsHelper(requests, /*repeating*/true, lastFrameNumber); 551} 552 553sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked( 554 const CameraMetadata &request) { 555 status_t res; 556 557 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) { 558 res = configureStreamsLocked(); 559 if (res != OK) { 560 SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res); 561 return NULL; 562 } 563 if (mStatus == STATUS_UNCONFIGURED) { 564 CLOGE("No streams configured"); 565 return NULL; 566 } 567 } 568 569 sp<CaptureRequest> newRequest = createCaptureRequest(request); 570 return newRequest; 571} 572 573status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) { 574 ATRACE_CALL(); 575 Mutex::Autolock il(mInterfaceLock); 576 Mutex::Autolock l(mLock); 577 578 switch (mStatus) { 579 case STATUS_ERROR: 580 CLOGE("Device has encountered a serious error"); 581 return INVALID_OPERATION; 582 case STATUS_UNINITIALIZED: 583 CLOGE("Device not initialized"); 584 return INVALID_OPERATION; 585 case STATUS_UNCONFIGURED: 586 case STATUS_CONFIGURED: 587 case STATUS_ACTIVE: 588 // OK 589 break; 590 default: 591 SET_ERR_L("Unexpected status: %d", mStatus); 592 return INVALID_OPERATION; 593 } 594 ALOGV("Camera %d: Clearing repeating request", mId); 595 596 return mRequestThread->clearRepeatingRequests(lastFrameNumber); 597} 598 599status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) { 600 ATRACE_CALL(); 601 Mutex::Autolock il(mInterfaceLock); 602 603 return mRequestThread->waitUntilRequestProcessed(requestId, timeout); 604} 605 606status_t Camera3Device::createInputStream( 607 uint32_t width, uint32_t height, int format, int *id) { 608 ATRACE_CALL(); 609 Mutex::Autolock il(mInterfaceLock); 610 Mutex::Autolock l(mLock); 611 ALOGV("Camera %d: Creating new input stream %d: %d x %d, format %d", 612 mId, mNextStreamId, width, height, format); 613 614 status_t res; 615 bool wasActive = false; 616 617 switch (mStatus) { 618 case STATUS_ERROR: 619 ALOGE("%s: Device has encountered a serious error", __FUNCTION__); 620 return INVALID_OPERATION; 621 case STATUS_UNINITIALIZED: 622 ALOGE("%s: Device not initialized", __FUNCTION__); 623 return INVALID_OPERATION; 624 case STATUS_UNCONFIGURED: 625 case STATUS_CONFIGURED: 626 // OK 627 break; 628 case STATUS_ACTIVE: 629 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__); 630 res = internalPauseAndWaitLocked(); 631 if (res != OK) { 632 SET_ERR_L("Can't pause captures to reconfigure streams!"); 633 return res; 634 } 635 wasActive = true; 636 break; 637 default: 638 SET_ERR_L("%s: Unexpected status: %d", mStatus); 639 return INVALID_OPERATION; 640 } 641 assert(mStatus != STATUS_ACTIVE); 642 643 if (mInputStream != 0) { 644 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__); 645 return INVALID_OPERATION; 646 } 647 648 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId, 649 width, height, format); 650 newStream->setStatusTracker(mStatusTracker); 651 652 mInputStream = newStream; 653 654 *id = mNextStreamId++; 655 656 // Continue captures if active at start 657 if (wasActive) { 658 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__); 659 res = configureStreamsLocked(); 660 if (res != OK) { 661 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)", 662 __FUNCTION__, mNextStreamId, strerror(-res), res); 663 return res; 664 } 665 internalResumeLocked(); 666 } 667 668 ALOGV("Camera %d: Created input stream", mId); 669 return OK; 670} 671 672 673status_t Camera3Device::createZslStream( 674 uint32_t width, uint32_t height, 675 int depth, 676 /*out*/ 677 int *id, 678 sp<Camera3ZslStream>* zslStream) { 679 ATRACE_CALL(); 680 Mutex::Autolock il(mInterfaceLock); 681 Mutex::Autolock l(mLock); 682 ALOGV("Camera %d: Creating ZSL stream %d: %d x %d, depth %d", 683 mId, mNextStreamId, width, height, depth); 684 685 status_t res; 686 bool wasActive = false; 687 688 switch (mStatus) { 689 case STATUS_ERROR: 690 ALOGE("%s: Device has encountered a serious error", __FUNCTION__); 691 return INVALID_OPERATION; 692 case STATUS_UNINITIALIZED: 693 ALOGE("%s: Device not initialized", __FUNCTION__); 694 return INVALID_OPERATION; 695 case STATUS_UNCONFIGURED: 696 case STATUS_CONFIGURED: 697 // OK 698 break; 699 case STATUS_ACTIVE: 700 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__); 701 res = internalPauseAndWaitLocked(); 702 if (res != OK) { 703 SET_ERR_L("Can't pause captures to reconfigure streams!"); 704 return res; 705 } 706 wasActive = true; 707 break; 708 default: 709 SET_ERR_L("Unexpected status: %d", mStatus); 710 return INVALID_OPERATION; 711 } 712 assert(mStatus != STATUS_ACTIVE); 713 714 if (mInputStream != 0) { 715 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__); 716 return INVALID_OPERATION; 717 } 718 719 sp<Camera3ZslStream> newStream = new Camera3ZslStream(mNextStreamId, 720 width, height, depth); 721 newStream->setStatusTracker(mStatusTracker); 722 723 res = mOutputStreams.add(mNextStreamId, newStream); 724 if (res < 0) { 725 ALOGE("%s: Can't add new stream to set: %s (%d)", 726 __FUNCTION__, strerror(-res), res); 727 return res; 728 } 729 mInputStream = newStream; 730 731 mNeedConfig = true; 732 733 *id = mNextStreamId++; 734 *zslStream = newStream; 735 736 // Continue captures if active at start 737 if (wasActive) { 738 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__); 739 res = configureStreamsLocked(); 740 if (res != OK) { 741 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)", 742 __FUNCTION__, mNextStreamId, strerror(-res), res); 743 return res; 744 } 745 internalResumeLocked(); 746 } 747 748 ALOGV("Camera %d: Created ZSL stream", mId); 749 return OK; 750} 751 752status_t Camera3Device::createStream(sp<ANativeWindow> consumer, 753 uint32_t width, uint32_t height, int format, size_t size, int *id) { 754 ATRACE_CALL(); 755 Mutex::Autolock il(mInterfaceLock); 756 Mutex::Autolock l(mLock); 757 ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %zu", 758 mId, mNextStreamId, width, height, format, size); 759 760 status_t res; 761 bool wasActive = false; 762 763 switch (mStatus) { 764 case STATUS_ERROR: 765 CLOGE("Device has encountered a serious error"); 766 return INVALID_OPERATION; 767 case STATUS_UNINITIALIZED: 768 CLOGE("Device not initialized"); 769 return INVALID_OPERATION; 770 case STATUS_UNCONFIGURED: 771 case STATUS_CONFIGURED: 772 // OK 773 break; 774 case STATUS_ACTIVE: 775 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__); 776 res = internalPauseAndWaitLocked(); 777 if (res != OK) { 778 SET_ERR_L("Can't pause captures to reconfigure streams!"); 779 return res; 780 } 781 wasActive = true; 782 break; 783 default: 784 SET_ERR_L("Unexpected status: %d", mStatus); 785 return INVALID_OPERATION; 786 } 787 assert(mStatus != STATUS_ACTIVE); 788 789 sp<Camera3OutputStream> newStream; 790 if (format == HAL_PIXEL_FORMAT_BLOB) { 791 ssize_t jpegBufferSize = getJpegBufferSize(width, height); 792 if (jpegBufferSize > 0) { 793 ALOGV("%s: Overwrite Jpeg output buffer size from %zu to %zu", 794 __FUNCTION__, size, jpegBufferSize); 795 } else { 796 SET_ERR_L("Invalid jpeg buffer size %zd", jpegBufferSize); 797 return BAD_VALUE; 798 } 799 800 newStream = new Camera3OutputStream(mNextStreamId, consumer, 801 width, height, jpegBufferSize, format); 802 } else { 803 newStream = new Camera3OutputStream(mNextStreamId, consumer, 804 width, height, format); 805 } 806 newStream->setStatusTracker(mStatusTracker); 807 808 res = mOutputStreams.add(mNextStreamId, newStream); 809 if (res < 0) { 810 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res); 811 return res; 812 } 813 814 *id = mNextStreamId++; 815 mNeedConfig = true; 816 817 // Continue captures if active at start 818 if (wasActive) { 819 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__); 820 res = configureStreamsLocked(); 821 if (res != OK) { 822 CLOGE("Can't reconfigure device for new stream %d: %s (%d)", 823 mNextStreamId, strerror(-res), res); 824 return res; 825 } 826 internalResumeLocked(); 827 } 828 ALOGV("Camera %d: Created new stream", mId); 829 return OK; 830} 831 832status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) { 833 ATRACE_CALL(); 834 (void)outputId; (void)id; 835 836 CLOGE("Unimplemented"); 837 return INVALID_OPERATION; 838} 839 840 841status_t Camera3Device::getStreamInfo(int id, 842 uint32_t *width, uint32_t *height, uint32_t *format) { 843 ATRACE_CALL(); 844 Mutex::Autolock il(mInterfaceLock); 845 Mutex::Autolock l(mLock); 846 847 switch (mStatus) { 848 case STATUS_ERROR: 849 CLOGE("Device has encountered a serious error"); 850 return INVALID_OPERATION; 851 case STATUS_UNINITIALIZED: 852 CLOGE("Device not initialized!"); 853 return INVALID_OPERATION; 854 case STATUS_UNCONFIGURED: 855 case STATUS_CONFIGURED: 856 case STATUS_ACTIVE: 857 // OK 858 break; 859 default: 860 SET_ERR_L("Unexpected status: %d", mStatus); 861 return INVALID_OPERATION; 862 } 863 864 ssize_t idx = mOutputStreams.indexOfKey(id); 865 if (idx == NAME_NOT_FOUND) { 866 CLOGE("Stream %d is unknown", id); 867 return idx; 868 } 869 870 if (width) *width = mOutputStreams[idx]->getWidth(); 871 if (height) *height = mOutputStreams[idx]->getHeight(); 872 if (format) *format = mOutputStreams[idx]->getFormat(); 873 874 return OK; 875} 876 877status_t Camera3Device::setStreamTransform(int id, 878 int transform) { 879 ATRACE_CALL(); 880 Mutex::Autolock il(mInterfaceLock); 881 Mutex::Autolock l(mLock); 882 883 switch (mStatus) { 884 case STATUS_ERROR: 885 CLOGE("Device has encountered a serious error"); 886 return INVALID_OPERATION; 887 case STATUS_UNINITIALIZED: 888 CLOGE("Device not initialized"); 889 return INVALID_OPERATION; 890 case STATUS_UNCONFIGURED: 891 case STATUS_CONFIGURED: 892 case STATUS_ACTIVE: 893 // OK 894 break; 895 default: 896 SET_ERR_L("Unexpected status: %d", mStatus); 897 return INVALID_OPERATION; 898 } 899 900 ssize_t idx = mOutputStreams.indexOfKey(id); 901 if (idx == NAME_NOT_FOUND) { 902 CLOGE("Stream %d does not exist", 903 id); 904 return BAD_VALUE; 905 } 906 907 return mOutputStreams.editValueAt(idx)->setTransform(transform); 908} 909 910status_t Camera3Device::deleteStream(int id) { 911 ATRACE_CALL(); 912 Mutex::Autolock il(mInterfaceLock); 913 Mutex::Autolock l(mLock); 914 status_t res; 915 916 ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id); 917 918 // CameraDevice semantics require device to already be idle before 919 // deleteStream is called, unlike for createStream. 920 if (mStatus == STATUS_ACTIVE) { 921 ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId); 922 return -EBUSY; 923 } 924 925 sp<Camera3StreamInterface> deletedStream; 926 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id); 927 if (mInputStream != NULL && id == mInputStream->getId()) { 928 deletedStream = mInputStream; 929 mInputStream.clear(); 930 } else { 931 if (outputStreamIdx == NAME_NOT_FOUND) { 932 CLOGE("Stream %d does not exist", id); 933 return BAD_VALUE; 934 } 935 } 936 937 // Delete output stream or the output part of a bi-directional stream. 938 if (outputStreamIdx != NAME_NOT_FOUND) { 939 deletedStream = mOutputStreams.editValueAt(outputStreamIdx); 940 mOutputStreams.removeItem(id); 941 } 942 943 // Free up the stream endpoint so that it can be used by some other stream 944 res = deletedStream->disconnect(); 945 if (res != OK) { 946 SET_ERR_L("Can't disconnect deleted stream %d", id); 947 // fall through since we want to still list the stream as deleted. 948 } 949 mDeletedStreams.add(deletedStream); 950 mNeedConfig = true; 951 952 return res; 953} 954 955status_t Camera3Device::deleteReprocessStream(int id) { 956 ATRACE_CALL(); 957 (void)id; 958 959 CLOGE("Unimplemented"); 960 return INVALID_OPERATION; 961} 962 963 964status_t Camera3Device::createDefaultRequest(int templateId, 965 CameraMetadata *request) { 966 ATRACE_CALL(); 967 ALOGV("%s: for template %d", __FUNCTION__, templateId); 968 Mutex::Autolock il(mInterfaceLock); 969 Mutex::Autolock l(mLock); 970 971 switch (mStatus) { 972 case STATUS_ERROR: 973 CLOGE("Device has encountered a serious error"); 974 return INVALID_OPERATION; 975 case STATUS_UNINITIALIZED: 976 CLOGE("Device is not initialized!"); 977 return INVALID_OPERATION; 978 case STATUS_UNCONFIGURED: 979 case STATUS_CONFIGURED: 980 case STATUS_ACTIVE: 981 // OK 982 break; 983 default: 984 SET_ERR_L("Unexpected status: %d", mStatus); 985 return INVALID_OPERATION; 986 } 987 988 const camera_metadata_t *rawRequest; 989 ATRACE_BEGIN("camera3->construct_default_request_settings"); 990 rawRequest = mHal3Device->ops->construct_default_request_settings( 991 mHal3Device, templateId); 992 ATRACE_END(); 993 if (rawRequest == NULL) { 994 SET_ERR_L("HAL is unable to construct default settings for template %d", 995 templateId); 996 return DEAD_OBJECT; 997 } 998 *request = rawRequest; 999 1000 return OK; 1001} 1002 1003status_t Camera3Device::waitUntilDrained() { 1004 ATRACE_CALL(); 1005 Mutex::Autolock il(mInterfaceLock); 1006 Mutex::Autolock l(mLock); 1007 1008 return waitUntilDrainedLocked(); 1009} 1010 1011status_t Camera3Device::waitUntilDrainedLocked() { 1012 switch (mStatus) { 1013 case STATUS_UNINITIALIZED: 1014 case STATUS_UNCONFIGURED: 1015 ALOGV("%s: Already idle", __FUNCTION__); 1016 return OK; 1017 case STATUS_CONFIGURED: 1018 // To avoid race conditions, check with tracker to be sure 1019 case STATUS_ERROR: 1020 case STATUS_ACTIVE: 1021 // Need to verify shut down 1022 break; 1023 default: 1024 SET_ERR_L("Unexpected status: %d",mStatus); 1025 return INVALID_OPERATION; 1026 } 1027 1028 ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId); 1029 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout); 1030 return res; 1031} 1032 1033// Pause to reconfigure 1034status_t Camera3Device::internalPauseAndWaitLocked() { 1035 mRequestThread->setPaused(true); 1036 mPauseStateNotify = true; 1037 1038 ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId); 1039 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout); 1040 if (res != OK) { 1041 SET_ERR_L("Can't idle device in %f seconds!", 1042 kShutdownTimeout/1e9); 1043 } 1044 1045 return res; 1046} 1047 1048// Resume after internalPauseAndWaitLocked 1049status_t Camera3Device::internalResumeLocked() { 1050 status_t res; 1051 1052 mRequestThread->setPaused(false); 1053 1054 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout); 1055 if (res != OK) { 1056 SET_ERR_L("Can't transition to active in %f seconds!", 1057 kActiveTimeout/1e9); 1058 } 1059 mPauseStateNotify = false; 1060 return OK; 1061} 1062 1063status_t Camera3Device::waitUntilStateThenRelock(bool active, 1064 nsecs_t timeout) { 1065 status_t res = OK; 1066 if (active == (mStatus == STATUS_ACTIVE)) { 1067 // Desired state already reached 1068 return res; 1069 } 1070 1071 bool stateSeen = false; 1072 do { 1073 mRecentStatusUpdates.clear(); 1074 1075 res = mStatusChanged.waitRelative(mLock, timeout); 1076 if (res != OK) break; 1077 1078 // Check state change history during wait 1079 for (size_t i = 0; i < mRecentStatusUpdates.size(); i++) { 1080 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) { 1081 stateSeen = true; 1082 break; 1083 } 1084 } 1085 } while (!stateSeen); 1086 1087 return res; 1088} 1089 1090 1091status_t Camera3Device::setNotifyCallback(NotificationListener *listener) { 1092 ATRACE_CALL(); 1093 Mutex::Autolock l(mOutputLock); 1094 1095 if (listener != NULL && mListener != NULL) { 1096 ALOGW("%s: Replacing old callback listener", __FUNCTION__); 1097 } 1098 mListener = listener; 1099 1100 return OK; 1101} 1102 1103bool Camera3Device::willNotify3A() { 1104 return false; 1105} 1106 1107status_t Camera3Device::waitForNextFrame(nsecs_t timeout) { 1108 status_t res; 1109 Mutex::Autolock l(mOutputLock); 1110 1111 while (mResultQueue.empty()) { 1112 res = mResultSignal.waitRelative(mOutputLock, timeout); 1113 if (res == TIMED_OUT) { 1114 return res; 1115 } else if (res != OK) { 1116 ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)", 1117 __FUNCTION__, mId, timeout, strerror(-res), res); 1118 return res; 1119 } 1120 } 1121 return OK; 1122} 1123 1124status_t Camera3Device::getNextResult(CaptureResult *frame) { 1125 ATRACE_CALL(); 1126 Mutex::Autolock l(mOutputLock); 1127 1128 if (mResultQueue.empty()) { 1129 return NOT_ENOUGH_DATA; 1130 } 1131 1132 if (frame == NULL) { 1133 ALOGE("%s: argument cannot be NULL", __FUNCTION__); 1134 return BAD_VALUE; 1135 } 1136 1137 CaptureResult &result = *(mResultQueue.begin()); 1138 frame->mResultExtras = result.mResultExtras; 1139 frame->mMetadata.acquire(result.mMetadata); 1140 mResultQueue.erase(mResultQueue.begin()); 1141 1142 return OK; 1143} 1144 1145status_t Camera3Device::triggerAutofocus(uint32_t id) { 1146 ATRACE_CALL(); 1147 Mutex::Autolock il(mInterfaceLock); 1148 1149 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id); 1150 // Mix-in this trigger into the next request and only the next request. 1151 RequestTrigger trigger[] = { 1152 { 1153 ANDROID_CONTROL_AF_TRIGGER, 1154 ANDROID_CONTROL_AF_TRIGGER_START 1155 }, 1156 { 1157 ANDROID_CONTROL_AF_TRIGGER_ID, 1158 static_cast<int32_t>(id) 1159 }, 1160 }; 1161 1162 return mRequestThread->queueTrigger(trigger, 1163 sizeof(trigger)/sizeof(trigger[0])); 1164} 1165 1166status_t Camera3Device::triggerCancelAutofocus(uint32_t id) { 1167 ATRACE_CALL(); 1168 Mutex::Autolock il(mInterfaceLock); 1169 1170 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id); 1171 // Mix-in this trigger into the next request and only the next request. 1172 RequestTrigger trigger[] = { 1173 { 1174 ANDROID_CONTROL_AF_TRIGGER, 1175 ANDROID_CONTROL_AF_TRIGGER_CANCEL 1176 }, 1177 { 1178 ANDROID_CONTROL_AF_TRIGGER_ID, 1179 static_cast<int32_t>(id) 1180 }, 1181 }; 1182 1183 return mRequestThread->queueTrigger(trigger, 1184 sizeof(trigger)/sizeof(trigger[0])); 1185} 1186 1187status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) { 1188 ATRACE_CALL(); 1189 Mutex::Autolock il(mInterfaceLock); 1190 1191 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id); 1192 // Mix-in this trigger into the next request and only the next request. 1193 RequestTrigger trigger[] = { 1194 { 1195 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, 1196 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START 1197 }, 1198 { 1199 ANDROID_CONTROL_AE_PRECAPTURE_ID, 1200 static_cast<int32_t>(id) 1201 }, 1202 }; 1203 1204 return mRequestThread->queueTrigger(trigger, 1205 sizeof(trigger)/sizeof(trigger[0])); 1206} 1207 1208status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId, 1209 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) { 1210 ATRACE_CALL(); 1211 (void)reprocessStreamId; (void)buffer; (void)listener; 1212 1213 CLOGE("Unimplemented"); 1214 return INVALID_OPERATION; 1215} 1216 1217status_t Camera3Device::flush(int64_t *frameNumber) { 1218 ATRACE_CALL(); 1219 ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId); 1220 Mutex::Autolock il(mInterfaceLock); 1221 1222 { 1223 Mutex::Autolock l(mLock); 1224 mRequestThread->clear(/*out*/frameNumber); 1225 } 1226 1227 status_t res; 1228 if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) { 1229 res = mHal3Device->ops->flush(mHal3Device); 1230 } else { 1231 Mutex::Autolock l(mLock); 1232 res = waitUntilDrainedLocked(); 1233 } 1234 1235 return res; 1236} 1237 1238/** 1239 * Methods called by subclasses 1240 */ 1241 1242void Camera3Device::notifyStatus(bool idle) { 1243 { 1244 // Need mLock to safely update state and synchronize to current 1245 // state of methods in flight. 1246 Mutex::Autolock l(mLock); 1247 // We can get various system-idle notices from the status tracker 1248 // while starting up. Only care about them if we've actually sent 1249 // in some requests recently. 1250 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) { 1251 return; 1252 } 1253 ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId, 1254 idle ? "idle" : "active"); 1255 mStatus = idle ? STATUS_CONFIGURED : STATUS_ACTIVE; 1256 mRecentStatusUpdates.add(mStatus); 1257 mStatusChanged.signal(); 1258 1259 // Skip notifying listener if we're doing some user-transparent 1260 // state changes 1261 if (mPauseStateNotify) return; 1262 } 1263 NotificationListener *listener; 1264 { 1265 Mutex::Autolock l(mOutputLock); 1266 listener = mListener; 1267 } 1268 if (idle && listener != NULL) { 1269 listener->notifyIdle(); 1270 } 1271} 1272 1273/** 1274 * Camera3Device private methods 1275 */ 1276 1277sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest( 1278 const CameraMetadata &request) { 1279 ATRACE_CALL(); 1280 status_t res; 1281 1282 sp<CaptureRequest> newRequest = new CaptureRequest; 1283 newRequest->mSettings = request; 1284 1285 camera_metadata_entry_t inputStreams = 1286 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS); 1287 if (inputStreams.count > 0) { 1288 if (mInputStream == NULL || 1289 mInputStream->getId() != inputStreams.data.i32[0]) { 1290 CLOGE("Request references unknown input stream %d", 1291 inputStreams.data.u8[0]); 1292 return NULL; 1293 } 1294 // Lazy completion of stream configuration (allocation/registration) 1295 // on first use 1296 if (mInputStream->isConfiguring()) { 1297 res = mInputStream->finishConfiguration(mHal3Device); 1298 if (res != OK) { 1299 SET_ERR_L("Unable to finish configuring input stream %d:" 1300 " %s (%d)", 1301 mInputStream->getId(), strerror(-res), res); 1302 return NULL; 1303 } 1304 } 1305 1306 newRequest->mInputStream = mInputStream; 1307 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS); 1308 } 1309 1310 camera_metadata_entry_t streams = 1311 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS); 1312 if (streams.count == 0) { 1313 CLOGE("Zero output streams specified!"); 1314 return NULL; 1315 } 1316 1317 for (size_t i = 0; i < streams.count; i++) { 1318 int idx = mOutputStreams.indexOfKey(streams.data.i32[i]); 1319 if (idx == NAME_NOT_FOUND) { 1320 CLOGE("Request references unknown stream %d", 1321 streams.data.u8[i]); 1322 return NULL; 1323 } 1324 sp<Camera3OutputStreamInterface> stream = 1325 mOutputStreams.editValueAt(idx); 1326 1327 // Lazy completion of stream configuration (allocation/registration) 1328 // on first use 1329 if (stream->isConfiguring()) { 1330 res = stream->finishConfiguration(mHal3Device); 1331 if (res != OK) { 1332 SET_ERR_L("Unable to finish configuring stream %d: %s (%d)", 1333 stream->getId(), strerror(-res), res); 1334 return NULL; 1335 } 1336 } 1337 1338 newRequest->mOutputStreams.push(stream); 1339 } 1340 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS); 1341 1342 return newRequest; 1343} 1344 1345status_t Camera3Device::configureStreamsLocked() { 1346 ATRACE_CALL(); 1347 status_t res; 1348 1349 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) { 1350 CLOGE("Not idle"); 1351 return INVALID_OPERATION; 1352 } 1353 1354 if (!mNeedConfig) { 1355 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__); 1356 return OK; 1357 } 1358 1359 // Start configuring the streams 1360 ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId); 1361 1362 camera3_stream_configuration config; 1363 1364 config.num_streams = (mInputStream != NULL) + mOutputStreams.size(); 1365 1366 Vector<camera3_stream_t*> streams; 1367 streams.setCapacity(config.num_streams); 1368 1369 if (mInputStream != NULL) { 1370 camera3_stream_t *inputStream; 1371 inputStream = mInputStream->startConfiguration(); 1372 if (inputStream == NULL) { 1373 SET_ERR_L("Can't start input stream configuration"); 1374 return INVALID_OPERATION; 1375 } 1376 streams.add(inputStream); 1377 } 1378 1379 for (size_t i = 0; i < mOutputStreams.size(); i++) { 1380 1381 // Don't configure bidi streams twice, nor add them twice to the list 1382 if (mOutputStreams[i].get() == 1383 static_cast<Camera3StreamInterface*>(mInputStream.get())) { 1384 1385 config.num_streams--; 1386 continue; 1387 } 1388 1389 camera3_stream_t *outputStream; 1390 outputStream = mOutputStreams.editValueAt(i)->startConfiguration(); 1391 if (outputStream == NULL) { 1392 SET_ERR_L("Can't start output stream configuration"); 1393 return INVALID_OPERATION; 1394 } 1395 streams.add(outputStream); 1396 } 1397 1398 config.streams = streams.editArray(); 1399 1400 // Do the HAL configuration; will potentially touch stream 1401 // max_buffers, usage, priv fields. 1402 ATRACE_BEGIN("camera3->configure_streams"); 1403 res = mHal3Device->ops->configure_streams(mHal3Device, &config); 1404 ATRACE_END(); 1405 1406 if (res != OK) { 1407 SET_ERR_L("Unable to configure streams with HAL: %s (%d)", 1408 strerror(-res), res); 1409 return res; 1410 } 1411 1412 // Finish all stream configuration immediately. 1413 // TODO: Try to relax this later back to lazy completion, which should be 1414 // faster 1415 1416 if (mInputStream != NULL && mInputStream->isConfiguring()) { 1417 res = mInputStream->finishConfiguration(mHal3Device); 1418 if (res != OK) { 1419 SET_ERR_L("Can't finish configuring input stream %d: %s (%d)", 1420 mInputStream->getId(), strerror(-res), res); 1421 return res; 1422 } 1423 } 1424 1425 for (size_t i = 0; i < mOutputStreams.size(); i++) { 1426 sp<Camera3OutputStreamInterface> outputStream = 1427 mOutputStreams.editValueAt(i); 1428 if (outputStream->isConfiguring()) { 1429 res = outputStream->finishConfiguration(mHal3Device); 1430 if (res != OK) { 1431 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)", 1432 outputStream->getId(), strerror(-res), res); 1433 return res; 1434 } 1435 } 1436 } 1437 1438 // Request thread needs to know to avoid using repeat-last-settings protocol 1439 // across configure_streams() calls 1440 mRequestThread->configurationComplete(); 1441 1442 // Update device state 1443 1444 mNeedConfig = false; 1445 1446 if (config.num_streams > 0) { 1447 mStatus = STATUS_CONFIGURED; 1448 } else { 1449 mStatus = STATUS_UNCONFIGURED; 1450 } 1451 1452 ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId); 1453 1454 return OK; 1455} 1456 1457void Camera3Device::setErrorState(const char *fmt, ...) { 1458 Mutex::Autolock l(mLock); 1459 va_list args; 1460 va_start(args, fmt); 1461 1462 setErrorStateLockedV(fmt, args); 1463 1464 va_end(args); 1465} 1466 1467void Camera3Device::setErrorStateV(const char *fmt, va_list args) { 1468 Mutex::Autolock l(mLock); 1469 setErrorStateLockedV(fmt, args); 1470} 1471 1472void Camera3Device::setErrorStateLocked(const char *fmt, ...) { 1473 va_list args; 1474 va_start(args, fmt); 1475 1476 setErrorStateLockedV(fmt, args); 1477 1478 va_end(args); 1479} 1480 1481void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) { 1482 // Print out all error messages to log 1483 String8 errorCause = String8::formatV(fmt, args); 1484 ALOGE("Camera %d: %s", mId, errorCause.string()); 1485 1486 // But only do error state transition steps for the first error 1487 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return; 1488 1489 // Save stack trace. View by dumping it later. 1490 CameraTraces::saveTrace(); 1491 // TODO: consider adding errorCause and client pid/procname 1492 1493 mErrorCause = errorCause; 1494 1495 mRequestThread->setPaused(true); 1496 mStatus = STATUS_ERROR; 1497} 1498 1499/** 1500 * In-flight request management 1501 */ 1502 1503status_t Camera3Device::registerInFlight(uint32_t frameNumber, 1504 int32_t numBuffers, CaptureResultExtras resultExtras) { 1505 ATRACE_CALL(); 1506 Mutex::Autolock l(mInFlightLock); 1507 1508 ssize_t res; 1509 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras)); 1510 if (res < 0) return res; 1511 1512 return OK; 1513} 1514 1515/** 1516 * QUIRK(partial results) 1517 * Check if all 3A fields are ready, and send off a partial 3A-only result 1518 * to the output frame queue 1519 */ 1520bool Camera3Device::processPartial3AQuirk( 1521 uint32_t frameNumber, 1522 const CameraMetadata& partial, const CaptureResultExtras& resultExtras) { 1523 1524 // Check if all 3A states are present 1525 // The full list of fields is 1526 // android.control.afMode 1527 // android.control.awbMode 1528 // android.control.aeState 1529 // android.control.awbState 1530 // android.control.afState 1531 // android.control.afTriggerID 1532 // android.control.aePrecaptureID 1533 // TODO: Add android.control.aeMode 1534 1535 bool gotAllStates = true; 1536 1537 uint8_t afMode; 1538 uint8_t awbMode; 1539 uint8_t aeState; 1540 uint8_t afState; 1541 uint8_t awbState; 1542 int32_t afTriggerId; 1543 int32_t aeTriggerId; 1544 1545 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE, 1546 &afMode, frameNumber); 1547 1548 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE, 1549 &awbMode, frameNumber); 1550 1551 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE, 1552 &aeState, frameNumber); 1553 1554 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE, 1555 &afState, frameNumber); 1556 1557 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE, 1558 &awbState, frameNumber); 1559 1560 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_TRIGGER_ID, 1561 &afTriggerId, frameNumber); 1562 1563 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_PRECAPTURE_ID, 1564 &aeTriggerId, frameNumber); 1565 1566 if (!gotAllStates) return false; 1567 1568 ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, " 1569 "AF state %d, AE state %d, AWB state %d, " 1570 "AF trigger %d, AE precapture trigger %d", 1571 __FUNCTION__, mId, frameNumber, resultExtras.requestId, 1572 afMode, awbMode, 1573 afState, aeState, awbState, 1574 afTriggerId, aeTriggerId); 1575 1576 // Got all states, so construct a minimal result to send 1577 // In addition to the above fields, this means adding in 1578 // android.request.frameCount 1579 // android.request.requestId 1580 // android.quirks.partialResult 1581 1582 const size_t kMinimal3AResultEntries = 10; 1583 1584 Mutex::Autolock l(mOutputLock); 1585 1586 CaptureResult captureResult; 1587 captureResult.mResultExtras = resultExtras; 1588 captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0); 1589 // TODO: change this to sp<CaptureResult>. This will need other changes, including, 1590 // but not limited to CameraDeviceBase::getNextResult 1591 CaptureResult& min3AResult = 1592 *mResultQueue.insert(mResultQueue.end(), captureResult); 1593 1594 if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT, 1595 // TODO: This is problematic casting. Need to fix CameraMetadata. 1596 reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) { 1597 return false; 1598 } 1599 1600 int32_t requestId = resultExtras.requestId; 1601 if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID, 1602 &requestId, frameNumber)) { 1603 return false; 1604 } 1605 1606 static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL; 1607 if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT, 1608 &partialResult, frameNumber)) { 1609 return false; 1610 } 1611 1612 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE, 1613 &afMode, frameNumber)) { 1614 return false; 1615 } 1616 1617 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE, 1618 &awbMode, frameNumber)) { 1619 return false; 1620 } 1621 1622 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE, 1623 &aeState, frameNumber)) { 1624 return false; 1625 } 1626 1627 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE, 1628 &afState, frameNumber)) { 1629 return false; 1630 } 1631 1632 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE, 1633 &awbState, frameNumber)) { 1634 return false; 1635 } 1636 1637 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID, 1638 &afTriggerId, frameNumber)) { 1639 return false; 1640 } 1641 1642 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, 1643 &aeTriggerId, frameNumber)) { 1644 return false; 1645 } 1646 1647 mResultSignal.signal(); 1648 1649 return true; 1650} 1651 1652template<typename T> 1653bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag, 1654 T* value, uint32_t frameNumber) { 1655 (void) frameNumber; 1656 1657 camera_metadata_ro_entry_t entry; 1658 1659 entry = result.find(tag); 1660 if (entry.count == 0) { 1661 ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__, 1662 mId, frameNumber, get_camera_metadata_tag_name(tag)); 1663 return false; 1664 } 1665 1666 if (sizeof(T) == sizeof(uint8_t)) { 1667 *value = entry.data.u8[0]; 1668 } else if (sizeof(T) == sizeof(int32_t)) { 1669 *value = entry.data.i32[0]; 1670 } else { 1671 ALOGE("%s: Unexpected type", __FUNCTION__); 1672 return false; 1673 } 1674 return true; 1675} 1676 1677template<typename T> 1678bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag, 1679 const T* value, uint32_t frameNumber) { 1680 if (result.update(tag, value, 1) != NO_ERROR) { 1681 mResultQueue.erase(--mResultQueue.end(), mResultQueue.end()); 1682 SET_ERR("Frame %d: Failed to set %s in partial metadata", 1683 frameNumber, get_camera_metadata_tag_name(tag)); 1684 return false; 1685 } 1686 return true; 1687} 1688 1689/** 1690 * Camera HAL device callback methods 1691 */ 1692 1693void Camera3Device::processCaptureResult(const camera3_capture_result *result) { 1694 ATRACE_CALL(); 1695 1696 status_t res; 1697 1698 uint32_t frameNumber = result->frame_number; 1699 if (result->result == NULL && result->num_output_buffers == 0) { 1700 SET_ERR("No result data provided by HAL for frame %d", 1701 frameNumber); 1702 return; 1703 } 1704 bool partialResultQuirk = false; 1705 CameraMetadata collectedQuirkResult; 1706 CaptureResultExtras resultExtras; 1707 1708 // Get capture timestamp and resultExtras from list of in-flight requests, 1709 // where it was added by the shutter notification for this frame. 1710 // Then update the in-flight status and remove the in-flight entry if 1711 // all result data has been received. 1712 nsecs_t timestamp = 0; 1713 { 1714 Mutex::Autolock l(mInFlightLock); 1715 ssize_t idx = mInFlightMap.indexOfKey(frameNumber); 1716 if (idx == NAME_NOT_FOUND) { 1717 SET_ERR("Unknown frame number for capture result: %d", 1718 frameNumber); 1719 return; 1720 } 1721 InFlightRequest &request = mInFlightMap.editValueAt(idx); 1722 ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64 1723 ", burstId = %" PRId32, 1724 __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber, 1725 request.resultExtras.burstId); 1726 1727 // Check if this result carries only partial metadata 1728 if (mUsePartialResultQuirk && result->result != NULL) { 1729 camera_metadata_ro_entry_t partialResultEntry; 1730 res = find_camera_metadata_ro_entry(result->result, 1731 ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry); 1732 if (res != NAME_NOT_FOUND && 1733 partialResultEntry.count > 0 && 1734 partialResultEntry.data.u8[0] == 1735 ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { 1736 // A partial result. Flag this as such, and collect this 1737 // set of metadata into the in-flight entry. 1738 partialResultQuirk = true; 1739 request.partialResultQuirk.collectedResult.append( 1740 result->result); 1741 request.partialResultQuirk.collectedResult.erase( 1742 ANDROID_QUIRKS_PARTIAL_RESULT); 1743 // Fire off a 3A-only result if possible 1744 if (!request.partialResultQuirk.haveSent3A) { 1745 request.partialResultQuirk.haveSent3A = 1746 processPartial3AQuirk(frameNumber, 1747 request.partialResultQuirk.collectedResult, 1748 request.resultExtras); 1749 } 1750 } 1751 } 1752 1753 timestamp = request.captureTimestamp; 1754 resultExtras = request.resultExtras; 1755 1756 /** 1757 * One of the following must happen before it's legal to call process_capture_result, 1758 * unless partial metadata is being provided: 1759 * - CAMERA3_MSG_SHUTTER (expected during normal operation) 1760 * - CAMERA3_MSG_ERROR (expected during flush) 1761 */ 1762 if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) { 1763 SET_ERR("Called before shutter notify for frame %d", 1764 frameNumber); 1765 return; 1766 } 1767 1768 // Did we get the (final) result metadata for this capture? 1769 if (result->result != NULL && !partialResultQuirk) { 1770 if (request.haveResultMetadata) { 1771 SET_ERR("Called multiple times with metadata for frame %d", 1772 frameNumber); 1773 return; 1774 } 1775 if (mUsePartialResultQuirk && 1776 !request.partialResultQuirk.collectedResult.isEmpty()) { 1777 collectedQuirkResult.acquire( 1778 request.partialResultQuirk.collectedResult); 1779 } 1780 request.haveResultMetadata = true; 1781 } 1782 1783 request.numBuffersLeft -= result->num_output_buffers; 1784 1785 if (request.numBuffersLeft < 0) { 1786 SET_ERR("Too many buffers returned for frame %d", 1787 frameNumber); 1788 return; 1789 } 1790 1791 // Check if everything has arrived for this result (buffers and metadata), remove it from 1792 // InFlightMap if both arrived or HAL reports error for this request (i.e. during flush). 1793 if ((request.requestStatus != OK) || 1794 (request.haveResultMetadata && request.numBuffersLeft == 0)) { 1795 ATRACE_ASYNC_END("frame capture", frameNumber); 1796 mInFlightMap.removeItemsAt(idx, 1); 1797 } 1798 1799 // Sanity check - if we have too many in-flight frames, something has 1800 // likely gone wrong 1801 if (mInFlightMap.size() > kInFlightWarnLimit) { 1802 CLOGE("In-flight list too large: %zu", mInFlightMap.size()); 1803 } 1804 1805 } 1806 1807 // Process the result metadata, if provided 1808 bool gotResult = false; 1809 if (result->result != NULL && !partialResultQuirk) { 1810 Mutex::Autolock l(mOutputLock); 1811 1812 gotResult = true; 1813 1814 // TODO: need to track errors for tighter bounds on expected frame number 1815 if (frameNumber < mNextResultFrameNumber) { 1816 SET_ERR("Out-of-order capture result metadata submitted! " 1817 "(got frame number %d, expecting %d)", 1818 frameNumber, mNextResultFrameNumber); 1819 return; 1820 } 1821 mNextResultFrameNumber = frameNumber + 1; 1822 1823 CaptureResult captureResult; 1824 captureResult.mResultExtras = resultExtras; 1825 captureResult.mMetadata = result->result; 1826 1827 if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, 1828 (int32_t*)&frameNumber, 1) != OK) { 1829 SET_ERR("Failed to set frame# in metadata (%d)", 1830 frameNumber); 1831 gotResult = false; 1832 } else { 1833 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)", 1834 __FUNCTION__, mId, frameNumber); 1835 } 1836 1837 // Append any previous partials to form a complete result 1838 if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) { 1839 captureResult.mMetadata.append(collectedQuirkResult); 1840 } 1841 1842 captureResult.mMetadata.sort(); 1843 1844 // Check that there's a timestamp in the result metadata 1845 1846 camera_metadata_entry entry = 1847 captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); 1848 if (entry.count == 0) { 1849 SET_ERR("No timestamp provided by HAL for frame %d!", 1850 frameNumber); 1851 gotResult = false; 1852 } else if (timestamp != entry.data.i64[0]) { 1853 SET_ERR("Timestamp mismatch between shutter notify and result" 1854 " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)", 1855 frameNumber, timestamp, entry.data.i64[0]); 1856 gotResult = false; 1857 } 1858 1859 if (gotResult) { 1860 // Valid result, insert into queue 1861 List<CaptureResult>::iterator queuedResult = 1862 mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult)); 1863 ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 1864 ", burstId = %" PRId32, __FUNCTION__, 1865 queuedResult->mResultExtras.requestId, 1866 queuedResult->mResultExtras.frameNumber, 1867 queuedResult->mResultExtras.burstId); 1868 } 1869 } // scope for mOutputLock 1870 1871 // Return completed buffers to their streams with the timestamp 1872 1873 for (size_t i = 0; i < result->num_output_buffers; i++) { 1874 Camera3Stream *stream = 1875 Camera3Stream::cast(result->output_buffers[i].stream); 1876 res = stream->returnBuffer(result->output_buffers[i], timestamp); 1877 // Note: stream may be deallocated at this point, if this buffer was the 1878 // last reference to it. 1879 if (res != OK) { 1880 ALOGE("Can't return buffer %zu for frame %d to its stream: " 1881 " %s (%d)", i, frameNumber, strerror(-res), res); 1882 } 1883 } 1884 1885 // Finally, signal any waiters for new frames 1886 1887 if (gotResult) { 1888 mResultSignal.signal(); 1889 } 1890 1891} 1892 1893void Camera3Device::notify(const camera3_notify_msg *msg) { 1894 ATRACE_CALL(); 1895 NotificationListener *listener; 1896 { 1897 Mutex::Autolock l(mOutputLock); 1898 listener = mListener; 1899 } 1900 1901 if (msg == NULL) { 1902 SET_ERR("HAL sent NULL notify message!"); 1903 return; 1904 } 1905 1906 switch (msg->type) { 1907 case CAMERA3_MSG_ERROR: { 1908 int streamId = 0; 1909 if (msg->message.error.error_stream != NULL) { 1910 Camera3Stream *stream = 1911 Camera3Stream::cast( 1912 msg->message.error.error_stream); 1913 streamId = stream->getId(); 1914 } 1915 ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d", 1916 mId, __FUNCTION__, msg->message.error.frame_number, 1917 streamId, msg->message.error.error_code); 1918 1919 CaptureResultExtras resultExtras; 1920 // Set request error status for the request in the in-flight tracking 1921 { 1922 Mutex::Autolock l(mInFlightLock); 1923 ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number); 1924 if (idx >= 0) { 1925 InFlightRequest &r = mInFlightMap.editValueAt(idx); 1926 r.requestStatus = msg->message.error.error_code; 1927 resultExtras = r.resultExtras; 1928 } else { 1929 resultExtras.frameNumber = msg->message.error.frame_number; 1930 ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64 1931 " error", mId, __FUNCTION__, resultExtras.frameNumber); 1932 } 1933 } 1934 1935 if (listener != NULL) { 1936 if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) { 1937 listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE, 1938 resultExtras); 1939 } 1940 } else { 1941 ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__); 1942 } 1943 break; 1944 } 1945 case CAMERA3_MSG_SHUTTER: { 1946 ssize_t idx; 1947 uint32_t frameNumber = msg->message.shutter.frame_number; 1948 nsecs_t timestamp = msg->message.shutter.timestamp; 1949 // Verify ordering of shutter notifications 1950 { 1951 Mutex::Autolock l(mOutputLock); 1952 // TODO: need to track errors for tighter bounds on expected frame number. 1953 if (frameNumber < mNextShutterFrameNumber) { 1954 SET_ERR("Shutter notification out-of-order. Expected " 1955 "notification for frame %d, got frame %d", 1956 mNextShutterFrameNumber, frameNumber); 1957 break; 1958 } 1959 mNextShutterFrameNumber = frameNumber + 1; 1960 } 1961 1962 CaptureResultExtras resultExtras; 1963 1964 // Set timestamp for the request in the in-flight tracking 1965 // and get the request ID to send upstream 1966 { 1967 Mutex::Autolock l(mInFlightLock); 1968 idx = mInFlightMap.indexOfKey(frameNumber); 1969 if (idx >= 0) { 1970 InFlightRequest &r = mInFlightMap.editValueAt(idx); 1971 r.captureTimestamp = timestamp; 1972 resultExtras = r.resultExtras; 1973 } 1974 } 1975 if (idx < 0) { 1976 SET_ERR("Shutter notification for non-existent frame number %d", 1977 frameNumber); 1978 break; 1979 } 1980 ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64, 1981 mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp); 1982 // Call listener, if any 1983 if (listener != NULL) { 1984 listener->notifyShutter(resultExtras, timestamp); 1985 } 1986 break; 1987 } 1988 default: 1989 SET_ERR("Unknown notify message from HAL: %d", 1990 msg->type); 1991 } 1992} 1993 1994CameraMetadata Camera3Device::getLatestRequestLocked() { 1995 ALOGV("%s", __FUNCTION__); 1996 1997 CameraMetadata retVal; 1998 1999 if (mRequestThread != NULL) { 2000 retVal = mRequestThread->getLatestRequest(); 2001 } 2002 2003 return retVal; 2004} 2005 2006 2007/** 2008 * RequestThread inner class methods 2009 */ 2010 2011Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent, 2012 sp<StatusTracker> statusTracker, 2013 camera3_device_t *hal3Device) : 2014 Thread(false), 2015 mParent(parent), 2016 mStatusTracker(statusTracker), 2017 mHal3Device(hal3Device), 2018 mId(getId(parent)), 2019 mReconfigured(false), 2020 mDoPause(false), 2021 mPaused(true), 2022 mFrameNumber(0), 2023 mLatestRequestId(NAME_NOT_FOUND), 2024 mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) { 2025 mStatusId = statusTracker->addComponent(); 2026} 2027 2028void Camera3Device::RequestThread::configurationComplete() { 2029 Mutex::Autolock l(mRequestLock); 2030 mReconfigured = true; 2031} 2032 2033status_t Camera3Device::RequestThread::queueRequestList( 2034 List<sp<CaptureRequest> > &requests, 2035 /*out*/ 2036 int64_t *lastFrameNumber) { 2037 Mutex::Autolock l(mRequestLock); 2038 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); 2039 ++it) { 2040 mRequestQueue.push_back(*it); 2041 } 2042 2043 if (lastFrameNumber != NULL) { 2044 *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1; 2045 ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".", 2046 __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber, 2047 *lastFrameNumber); 2048 } 2049 2050 unpauseForNewRequests(); 2051 2052 return OK; 2053} 2054 2055 2056status_t Camera3Device::RequestThread::queueTrigger( 2057 RequestTrigger trigger[], 2058 size_t count) { 2059 2060 Mutex::Autolock l(mTriggerMutex); 2061 status_t ret; 2062 2063 for (size_t i = 0; i < count; ++i) { 2064 ret = queueTriggerLocked(trigger[i]); 2065 2066 if (ret != OK) { 2067 return ret; 2068 } 2069 } 2070 2071 return OK; 2072} 2073 2074int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) { 2075 sp<Camera3Device> d = device.promote(); 2076 if (d != NULL) return d->mId; 2077 return 0; 2078} 2079 2080status_t Camera3Device::RequestThread::queueTriggerLocked( 2081 RequestTrigger trigger) { 2082 2083 uint32_t tag = trigger.metadataTag; 2084 ssize_t index = mTriggerMap.indexOfKey(tag); 2085 2086 switch (trigger.getTagType()) { 2087 case TYPE_BYTE: 2088 // fall-through 2089 case TYPE_INT32: 2090 break; 2091 default: 2092 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__, 2093 trigger.getTagType()); 2094 return INVALID_OPERATION; 2095 } 2096 2097 /** 2098 * Collect only the latest trigger, since we only have 1 field 2099 * in the request settings per trigger tag, and can't send more than 1 2100 * trigger per request. 2101 */ 2102 if (index != NAME_NOT_FOUND) { 2103 mTriggerMap.editValueAt(index) = trigger; 2104 } else { 2105 mTriggerMap.add(tag, trigger); 2106 } 2107 2108 return OK; 2109} 2110 2111status_t Camera3Device::RequestThread::setRepeatingRequests( 2112 const RequestList &requests, 2113 /*out*/ 2114 int64_t *lastFrameNumber) { 2115 Mutex::Autolock l(mRequestLock); 2116 if (lastFrameNumber != NULL) { 2117 *lastFrameNumber = mRepeatingLastFrameNumber; 2118 } 2119 mRepeatingRequests.clear(); 2120 mRepeatingRequests.insert(mRepeatingRequests.begin(), 2121 requests.begin(), requests.end()); 2122 2123 unpauseForNewRequests(); 2124 2125 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES; 2126 return OK; 2127} 2128 2129status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) { 2130 Mutex::Autolock l(mRequestLock); 2131 mRepeatingRequests.clear(); 2132 if (lastFrameNumber != NULL) { 2133 *lastFrameNumber = mRepeatingLastFrameNumber; 2134 } 2135 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES; 2136 return OK; 2137} 2138 2139status_t Camera3Device::RequestThread::clear(/*out*/int64_t *lastFrameNumber) { 2140 Mutex::Autolock l(mRequestLock); 2141 ALOGV("RequestThread::%s:", __FUNCTION__); 2142 mRepeatingRequests.clear(); 2143 mRequestQueue.clear(); 2144 mTriggerMap.clear(); 2145 if (lastFrameNumber != NULL) { 2146 *lastFrameNumber = mRepeatingLastFrameNumber; 2147 } 2148 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES; 2149 return OK; 2150} 2151 2152void Camera3Device::RequestThread::setPaused(bool paused) { 2153 Mutex::Autolock l(mPauseLock); 2154 mDoPause = paused; 2155 mDoPauseSignal.signal(); 2156} 2157 2158status_t Camera3Device::RequestThread::waitUntilRequestProcessed( 2159 int32_t requestId, nsecs_t timeout) { 2160 Mutex::Autolock l(mLatestRequestMutex); 2161 status_t res; 2162 while (mLatestRequestId != requestId) { 2163 nsecs_t startTime = systemTime(); 2164 2165 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout); 2166 if (res != OK) return res; 2167 2168 timeout -= (systemTime() - startTime); 2169 } 2170 2171 return OK; 2172} 2173 2174void Camera3Device::RequestThread::requestExit() { 2175 // Call parent to set up shutdown 2176 Thread::requestExit(); 2177 // The exit from any possible waits 2178 mDoPauseSignal.signal(); 2179 mRequestSignal.signal(); 2180} 2181 2182bool Camera3Device::RequestThread::threadLoop() { 2183 2184 status_t res; 2185 2186 // Handle paused state. 2187 if (waitIfPaused()) { 2188 return true; 2189 } 2190 2191 // Get work to do 2192 2193 sp<CaptureRequest> nextRequest = waitForNextRequest(); 2194 if (nextRequest == NULL) { 2195 return true; 2196 } 2197 2198 // Create request to HAL 2199 camera3_capture_request_t request = camera3_capture_request_t(); 2200 request.frame_number = nextRequest->mResultExtras.frameNumber; 2201 Vector<camera3_stream_buffer_t> outputBuffers; 2202 2203 // Get the request ID, if any 2204 int requestId; 2205 camera_metadata_entry_t requestIdEntry = 2206 nextRequest->mSettings.find(ANDROID_REQUEST_ID); 2207 if (requestIdEntry.count > 0) { 2208 requestId = requestIdEntry.data.i32[0]; 2209 } else { 2210 ALOGW("%s: Did not have android.request.id set in the request", 2211 __FUNCTION__); 2212 requestId = NAME_NOT_FOUND; 2213 } 2214 2215 // Insert any queued triggers (before metadata is locked) 2216 int32_t triggerCount; 2217 res = insertTriggers(nextRequest); 2218 if (res < 0) { 2219 SET_ERR("RequestThread: Unable to insert triggers " 2220 "(capture request %d, HAL device: %s (%d)", 2221 request.frame_number, strerror(-res), res); 2222 cleanUpFailedRequest(request, nextRequest, outputBuffers); 2223 return false; 2224 } 2225 triggerCount = res; 2226 2227 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0); 2228 2229 // If the request is the same as last, or we had triggers last time 2230 if (mPrevRequest != nextRequest || triggersMixedIn) { 2231 /** 2232 * HAL workaround: 2233 * Insert a dummy trigger ID if a trigger is set but no trigger ID is 2234 */ 2235 res = addDummyTriggerIds(nextRequest); 2236 if (res != OK) { 2237 SET_ERR("RequestThread: Unable to insert dummy trigger IDs " 2238 "(capture request %d, HAL device: %s (%d)", 2239 request.frame_number, strerror(-res), res); 2240 cleanUpFailedRequest(request, nextRequest, outputBuffers); 2241 return false; 2242 } 2243 2244 /** 2245 * The request should be presorted so accesses in HAL 2246 * are O(logn). Sidenote, sorting a sorted metadata is nop. 2247 */ 2248 nextRequest->mSettings.sort(); 2249 request.settings = nextRequest->mSettings.getAndLock(); 2250 mPrevRequest = nextRequest; 2251 ALOGVV("%s: Request settings are NEW", __FUNCTION__); 2252 2253 IF_ALOGV() { 2254 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t(); 2255 find_camera_metadata_ro_entry( 2256 request.settings, 2257 ANDROID_CONTROL_AF_TRIGGER, 2258 &e 2259 ); 2260 if (e.count > 0) { 2261 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x", 2262 __FUNCTION__, 2263 request.frame_number, 2264 e.data.u8[0]); 2265 } 2266 } 2267 } else { 2268 // leave request.settings NULL to indicate 'reuse latest given' 2269 ALOGVV("%s: Request settings are REUSED", 2270 __FUNCTION__); 2271 } 2272 2273 camera3_stream_buffer_t inputBuffer; 2274 2275 // Fill in buffers 2276 2277 if (nextRequest->mInputStream != NULL) { 2278 request.input_buffer = &inputBuffer; 2279 res = nextRequest->mInputStream->getInputBuffer(&inputBuffer); 2280 if (res != OK) { 2281 ALOGE("RequestThread: Can't get input buffer, skipping request:" 2282 " %s (%d)", strerror(-res), res); 2283 cleanUpFailedRequest(request, nextRequest, outputBuffers); 2284 return true; 2285 } 2286 } else { 2287 request.input_buffer = NULL; 2288 } 2289 2290 outputBuffers.insertAt(camera3_stream_buffer_t(), 0, 2291 nextRequest->mOutputStreams.size()); 2292 request.output_buffers = outputBuffers.array(); 2293 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) { 2294 res = nextRequest->mOutputStreams.editItemAt(i)-> 2295 getBuffer(&outputBuffers.editItemAt(i)); 2296 if (res != OK) { 2297 ALOGE("RequestThread: Can't get output buffer, skipping request:" 2298 " %s (%d)", strerror(-res), res); 2299 cleanUpFailedRequest(request, nextRequest, outputBuffers); 2300 return true; 2301 } 2302 request.num_output_buffers++; 2303 } 2304 2305 // Log request in the in-flight queue 2306 sp<Camera3Device> parent = mParent.promote(); 2307 if (parent == NULL) { 2308 CLOGE("RequestThread: Parent is gone"); 2309 cleanUpFailedRequest(request, nextRequest, outputBuffers); 2310 return false; 2311 } 2312 2313 res = parent->registerInFlight(request.frame_number, 2314 request.num_output_buffers, nextRequest->mResultExtras); 2315 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64 2316 ", burstId = %" PRId32 ".", 2317 __FUNCTION__, 2318 nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber, 2319 nextRequest->mResultExtras.burstId); 2320 if (res != OK) { 2321 SET_ERR("RequestThread: Unable to register new in-flight request:" 2322 " %s (%d)", strerror(-res), res); 2323 cleanUpFailedRequest(request, nextRequest, outputBuffers); 2324 return false; 2325 } 2326 2327 // Inform waitUntilRequestProcessed thread of a new request ID 2328 { 2329 Mutex::Autolock al(mLatestRequestMutex); 2330 2331 mLatestRequestId = requestId; 2332 mLatestRequestSignal.signal(); 2333 } 2334 2335 // Submit request and block until ready for next one 2336 ATRACE_ASYNC_BEGIN("frame capture", request.frame_number); 2337 ATRACE_BEGIN("camera3->process_capture_request"); 2338 res = mHal3Device->ops->process_capture_request(mHal3Device, &request); 2339 ATRACE_END(); 2340 2341 if (res != OK) { 2342 SET_ERR("RequestThread: Unable to submit capture request %d to HAL" 2343 " device: %s (%d)", request.frame_number, strerror(-res), res); 2344 cleanUpFailedRequest(request, nextRequest, outputBuffers); 2345 return false; 2346 } 2347 2348 // Update the latest request sent to HAL 2349 if (request.settings != NULL) { // Don't update them if they were unchanged 2350 Mutex::Autolock al(mLatestRequestMutex); 2351 2352 camera_metadata_t* cloned = clone_camera_metadata(request.settings); 2353 mLatestRequest.acquire(cloned); 2354 } 2355 2356 if (request.settings != NULL) { 2357 nextRequest->mSettings.unlock(request.settings); 2358 } 2359 2360 // Remove any previously queued triggers (after unlock) 2361 res = removeTriggers(mPrevRequest); 2362 if (res != OK) { 2363 SET_ERR("RequestThread: Unable to remove triggers " 2364 "(capture request %d, HAL device: %s (%d)", 2365 request.frame_number, strerror(-res), res); 2366 return false; 2367 } 2368 mPrevTriggers = triggerCount; 2369 2370 // Return input buffer back to framework 2371 if (request.input_buffer != NULL) { 2372 Camera3Stream *stream = 2373 Camera3Stream::cast(request.input_buffer->stream); 2374 res = stream->returnInputBuffer(*(request.input_buffer)); 2375 // Note: stream may be deallocated at this point, if this buffer was the 2376 // last reference to it. 2377 if (res != OK) { 2378 ALOGE("%s: RequestThread: Can't return input buffer for frame %d to" 2379 " its stream:%s (%d)", __FUNCTION__, 2380 request.frame_number, strerror(-res), res); 2381 // TODO: Report error upstream 2382 } 2383 } 2384 2385 return true; 2386} 2387 2388CameraMetadata Camera3Device::RequestThread::getLatestRequest() const { 2389 Mutex::Autolock al(mLatestRequestMutex); 2390 2391 ALOGV("RequestThread::%s", __FUNCTION__); 2392 2393 return mLatestRequest; 2394} 2395 2396 2397void Camera3Device::RequestThread::cleanUpFailedRequest( 2398 camera3_capture_request_t &request, 2399 sp<CaptureRequest> &nextRequest, 2400 Vector<camera3_stream_buffer_t> &outputBuffers) { 2401 2402 if (request.settings != NULL) { 2403 nextRequest->mSettings.unlock(request.settings); 2404 } 2405 if (request.input_buffer != NULL) { 2406 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR; 2407 nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer)); 2408 } 2409 for (size_t i = 0; i < request.num_output_buffers; i++) { 2410 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; 2411 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer( 2412 outputBuffers[i], 0); 2413 } 2414} 2415 2416sp<Camera3Device::CaptureRequest> 2417 Camera3Device::RequestThread::waitForNextRequest() { 2418 status_t res; 2419 sp<CaptureRequest> nextRequest; 2420 2421 // Optimized a bit for the simple steady-state case (single repeating 2422 // request), to avoid putting that request in the queue temporarily. 2423 Mutex::Autolock l(mRequestLock); 2424 2425 while (mRequestQueue.empty()) { 2426 if (!mRepeatingRequests.empty()) { 2427 // Always atomically enqueue all requests in a repeating request 2428 // list. Guarantees a complete in-sequence set of captures to 2429 // application. 2430 const RequestList &requests = mRepeatingRequests; 2431 RequestList::const_iterator firstRequest = 2432 requests.begin(); 2433 nextRequest = *firstRequest; 2434 mRequestQueue.insert(mRequestQueue.end(), 2435 ++firstRequest, 2436 requests.end()); 2437 // No need to wait any longer 2438 2439 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1; 2440 2441 break; 2442 } 2443 2444 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout); 2445 2446 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) || 2447 exitPending()) { 2448 Mutex::Autolock pl(mPauseLock); 2449 if (mPaused == false) { 2450 ALOGV("%s: RequestThread: Going idle", __FUNCTION__); 2451 mPaused = true; 2452 // Let the tracker know 2453 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 2454 if (statusTracker != 0) { 2455 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE); 2456 } 2457 } 2458 // Stop waiting for now and let thread management happen 2459 return NULL; 2460 } 2461 } 2462 2463 if (nextRequest == NULL) { 2464 // Don't have a repeating request already in hand, so queue 2465 // must have an entry now. 2466 RequestList::iterator firstRequest = 2467 mRequestQueue.begin(); 2468 nextRequest = *firstRequest; 2469 mRequestQueue.erase(firstRequest); 2470 } 2471 2472 // In case we've been unpaused by setPaused clearing mDoPause, need to 2473 // update internal pause state (capture/setRepeatingRequest unpause 2474 // directly). 2475 Mutex::Autolock pl(mPauseLock); 2476 if (mPaused) { 2477 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__); 2478 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 2479 if (statusTracker != 0) { 2480 statusTracker->markComponentActive(mStatusId); 2481 } 2482 } 2483 mPaused = false; 2484 2485 // Check if we've reconfigured since last time, and reset the preview 2486 // request if so. Can't use 'NULL request == repeat' across configure calls. 2487 if (mReconfigured) { 2488 mPrevRequest.clear(); 2489 mReconfigured = false; 2490 } 2491 2492 if (nextRequest != NULL) { 2493 nextRequest->mResultExtras.frameNumber = mFrameNumber++; 2494 } 2495 return nextRequest; 2496} 2497 2498bool Camera3Device::RequestThread::waitIfPaused() { 2499 status_t res; 2500 Mutex::Autolock l(mPauseLock); 2501 while (mDoPause) { 2502 if (mPaused == false) { 2503 mPaused = true; 2504 ALOGV("%s: RequestThread: Paused", __FUNCTION__); 2505 // Let the tracker know 2506 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 2507 if (statusTracker != 0) { 2508 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE); 2509 } 2510 } 2511 2512 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout); 2513 if (res == TIMED_OUT || exitPending()) { 2514 return true; 2515 } 2516 } 2517 // We don't set mPaused to false here, because waitForNextRequest needs 2518 // to further manage the paused state in case of starvation. 2519 return false; 2520} 2521 2522void Camera3Device::RequestThread::unpauseForNewRequests() { 2523 // With work to do, mark thread as unpaused. 2524 // If paused by request (setPaused), don't resume, to avoid 2525 // extra signaling/waiting overhead to waitUntilPaused 2526 mRequestSignal.signal(); 2527 Mutex::Autolock p(mPauseLock); 2528 if (!mDoPause) { 2529 ALOGV("%s: RequestThread: Going active", __FUNCTION__); 2530 if (mPaused) { 2531 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 2532 if (statusTracker != 0) { 2533 statusTracker->markComponentActive(mStatusId); 2534 } 2535 } 2536 mPaused = false; 2537 } 2538} 2539 2540void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) { 2541 sp<Camera3Device> parent = mParent.promote(); 2542 if (parent != NULL) { 2543 va_list args; 2544 va_start(args, fmt); 2545 2546 parent->setErrorStateV(fmt, args); 2547 2548 va_end(args); 2549 } 2550} 2551 2552status_t Camera3Device::RequestThread::insertTriggers( 2553 const sp<CaptureRequest> &request) { 2554 2555 Mutex::Autolock al(mTriggerMutex); 2556 2557 CameraMetadata &metadata = request->mSettings; 2558 size_t count = mTriggerMap.size(); 2559 2560 for (size_t i = 0; i < count; ++i) { 2561 RequestTrigger trigger = mTriggerMap.valueAt(i); 2562 2563 uint32_t tag = trigger.metadataTag; 2564 camera_metadata_entry entry = metadata.find(tag); 2565 2566 if (entry.count > 0) { 2567 /** 2568 * Already has an entry for this trigger in the request. 2569 * Rewrite it with our requested trigger value. 2570 */ 2571 RequestTrigger oldTrigger = trigger; 2572 2573 oldTrigger.entryValue = entry.data.u8[0]; 2574 2575 mTriggerReplacedMap.add(tag, oldTrigger); 2576 } else { 2577 /** 2578 * More typical, no trigger entry, so we just add it 2579 */ 2580 mTriggerRemovedMap.add(tag, trigger); 2581 } 2582 2583 status_t res; 2584 2585 switch (trigger.getTagType()) { 2586 case TYPE_BYTE: { 2587 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue); 2588 res = metadata.update(tag, 2589 &entryValue, 2590 /*count*/1); 2591 break; 2592 } 2593 case TYPE_INT32: 2594 res = metadata.update(tag, 2595 &trigger.entryValue, 2596 /*count*/1); 2597 break; 2598 default: 2599 ALOGE("%s: Type not supported: 0x%x", 2600 __FUNCTION__, 2601 trigger.getTagType()); 2602 return INVALID_OPERATION; 2603 } 2604 2605 if (res != OK) { 2606 ALOGE("%s: Failed to update request metadata with trigger tag %s" 2607 ", value %d", __FUNCTION__, trigger.getTagName(), 2608 trigger.entryValue); 2609 return res; 2610 } 2611 2612 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__, 2613 trigger.getTagName(), 2614 trigger.entryValue); 2615 } 2616 2617 mTriggerMap.clear(); 2618 2619 return count; 2620} 2621 2622status_t Camera3Device::RequestThread::removeTriggers( 2623 const sp<CaptureRequest> &request) { 2624 Mutex::Autolock al(mTriggerMutex); 2625 2626 CameraMetadata &metadata = request->mSettings; 2627 2628 /** 2629 * Replace all old entries with their old values. 2630 */ 2631 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) { 2632 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i); 2633 2634 status_t res; 2635 2636 uint32_t tag = trigger.metadataTag; 2637 switch (trigger.getTagType()) { 2638 case TYPE_BYTE: { 2639 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue); 2640 res = metadata.update(tag, 2641 &entryValue, 2642 /*count*/1); 2643 break; 2644 } 2645 case TYPE_INT32: 2646 res = metadata.update(tag, 2647 &trigger.entryValue, 2648 /*count*/1); 2649 break; 2650 default: 2651 ALOGE("%s: Type not supported: 0x%x", 2652 __FUNCTION__, 2653 trigger.getTagType()); 2654 return INVALID_OPERATION; 2655 } 2656 2657 if (res != OK) { 2658 ALOGE("%s: Failed to restore request metadata with trigger tag %s" 2659 ", trigger value %d", __FUNCTION__, 2660 trigger.getTagName(), trigger.entryValue); 2661 return res; 2662 } 2663 } 2664 mTriggerReplacedMap.clear(); 2665 2666 /** 2667 * Remove all new entries. 2668 */ 2669 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) { 2670 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i); 2671 status_t res = metadata.erase(trigger.metadataTag); 2672 2673 if (res != OK) { 2674 ALOGE("%s: Failed to erase metadata with trigger tag %s" 2675 ", trigger value %d", __FUNCTION__, 2676 trigger.getTagName(), trigger.entryValue); 2677 return res; 2678 } 2679 } 2680 mTriggerRemovedMap.clear(); 2681 2682 return OK; 2683} 2684 2685status_t Camera3Device::RequestThread::addDummyTriggerIds( 2686 const sp<CaptureRequest> &request) { 2687 // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here 2688 static const int32_t dummyTriggerId = 1; 2689 status_t res; 2690 2691 CameraMetadata &metadata = request->mSettings; 2692 2693 // If AF trigger is active, insert a dummy AF trigger ID if none already 2694 // exists 2695 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER); 2696 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID); 2697 if (afTrigger.count > 0 && 2698 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE && 2699 afId.count == 0) { 2700 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1); 2701 if (res != OK) return res; 2702 } 2703 2704 // If AE precapture trigger is active, insert a dummy precapture trigger ID 2705 // if none already exists 2706 camera_metadata_entry pcTrigger = 2707 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER); 2708 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID); 2709 if (pcTrigger.count > 0 && 2710 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE && 2711 pcId.count == 0) { 2712 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID, 2713 &dummyTriggerId, 1); 2714 if (res != OK) return res; 2715 } 2716 2717 return OK; 2718} 2719 2720 2721/** 2722 * Static callback forwarding methods from HAL to instance 2723 */ 2724 2725void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb, 2726 const camera3_capture_result *result) { 2727 Camera3Device *d = 2728 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb)); 2729 d->processCaptureResult(result); 2730} 2731 2732void Camera3Device::sNotify(const camera3_callback_ops *cb, 2733 const camera3_notify_msg *msg) { 2734 Camera3Device *d = 2735 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb)); 2736 d->notify(msg); 2737} 2738 2739}; // namespace android 2740