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