CaptureSequencer.cpp revision 25a0aef19e170d2695f64b4c48296e7914155a88
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Camera2-CaptureSequencer" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20 21#include <inttypes.h> 22 23#include <utils/Log.h> 24#include <utils/Trace.h> 25#include <utils/Vector.h> 26 27#include "api1/Camera2Client.h" 28#include "api1/client2/CaptureSequencer.h" 29#include "api1/client2/BurstCapture.h" 30#include "api1/client2/Parameters.h" 31#include "api1/client2/ZslProcessorInterface.h" 32 33namespace android { 34namespace camera2 { 35 36/** Public members */ 37 38CaptureSequencer::CaptureSequencer(wp<Camera2Client> client): 39 Thread(false), 40 mStartCapture(false), 41 mBusy(false), 42 mNewAEState(false), 43 mNewFrameReceived(false), 44 mNewCaptureReceived(false), 45 mShutterNotified(false), 46 mClient(client), 47 mCaptureState(IDLE), 48 mStateTransitionCount(0), 49 mTriggerId(0), 50 mTimeoutCount(0), 51 mCaptureId(Camera2Client::kCaptureRequestIdStart), 52 mMsgType(0) { 53 ALOGV("%s", __FUNCTION__); 54} 55 56CaptureSequencer::~CaptureSequencer() { 57 ALOGV("%s: Exit", __FUNCTION__); 58} 59 60void CaptureSequencer::setZslProcessor(wp<ZslProcessorInterface> processor) { 61 Mutex::Autolock l(mInputMutex); 62 mZslProcessor = processor; 63} 64 65status_t CaptureSequencer::startCapture(int msgType) { 66 ALOGV("%s", __FUNCTION__); 67 ATRACE_CALL(); 68 Mutex::Autolock l(mInputMutex); 69 if (mBusy) { 70 ALOGE("%s: Already busy capturing!", __FUNCTION__); 71 return INVALID_OPERATION; 72 } 73 if (!mStartCapture) { 74 mMsgType = msgType; 75 mStartCapture = true; 76 mStartCaptureSignal.signal(); 77 } 78 return OK; 79} 80 81status_t CaptureSequencer::waitUntilIdle(nsecs_t timeout) { 82 ATRACE_CALL(); 83 ALOGV("%s: Waiting for idle", __FUNCTION__); 84 Mutex::Autolock l(mStateMutex); 85 status_t res = -1; 86 while (mCaptureState != IDLE) { 87 nsecs_t startTime = systemTime(); 88 89 res = mStateChanged.waitRelative(mStateMutex, timeout); 90 if (res != OK) return res; 91 92 timeout -= (systemTime() - startTime); 93 } 94 ALOGV("%s: Now idle", __FUNCTION__); 95 return OK; 96} 97 98void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) { 99 ATRACE_CALL(); 100 Mutex::Autolock l(mInputMutex); 101 mAEState = newState; 102 mAETriggerId = triggerId; 103 if (!mNewAEState) { 104 mNewAEState = true; 105 mNewNotifySignal.signal(); 106 } 107} 108 109void CaptureSequencer::onResultAvailable(const CaptureResult &result) { 110 ATRACE_CALL(); 111 ALOGV("%s: New result available.", __FUNCTION__); 112 Mutex::Autolock l(mInputMutex); 113 mNewFrameId = result.mResultExtras.requestId; 114 mNewFrame = result.mMetadata; 115 if (!mNewFrameReceived) { 116 mNewFrameReceived = true; 117 mNewFrameSignal.signal(); 118 } 119} 120 121void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp, 122 sp<MemoryBase> captureBuffer) { 123 ATRACE_CALL(); 124 ALOGV("%s", __FUNCTION__); 125 Mutex::Autolock l(mInputMutex); 126 mCaptureTimestamp = timestamp; 127 mCaptureBuffer = captureBuffer; 128 if (!mNewCaptureReceived) { 129 mNewCaptureReceived = true; 130 mNewCaptureSignal.signal(); 131 } 132} 133 134 135void CaptureSequencer::dump(int fd, const Vector<String16>& /*args*/) { 136 String8 result; 137 if (mCaptureRequest.entryCount() != 0) { 138 result = " Capture request:\n"; 139 write(fd, result.string(), result.size()); 140 mCaptureRequest.dump(fd, 2, 6); 141 } else { 142 result = " Capture request: undefined\n"; 143 write(fd, result.string(), result.size()); 144 } 145 result = String8::format(" Current capture state: %s\n", 146 kStateNames[mCaptureState]); 147 result.append(" Latest captured frame:\n"); 148 write(fd, result.string(), result.size()); 149 mNewFrame.dump(fd, 2, 6); 150} 151 152/** Private members */ 153 154const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] = 155{ 156 "IDLE", 157 "START", 158 "ZSL_START", 159 "ZSL_WAITING", 160 "ZSL_REPROCESSING", 161 "STANDARD_START", 162 "STANDARD_PRECAPTURE_WAIT", 163 "STANDARD_CAPTURE", 164 "STANDARD_CAPTURE_WAIT", 165 "BURST_CAPTURE_START", 166 "BURST_CAPTURE_WAIT", 167 "DONE", 168 "ERROR", 169 "UNKNOWN" 170}; 171 172const CaptureSequencer::StateManager 173 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = { 174 &CaptureSequencer::manageIdle, 175 &CaptureSequencer::manageStart, 176 &CaptureSequencer::manageZslStart, 177 &CaptureSequencer::manageZslWaiting, 178 &CaptureSequencer::manageZslReprocessing, 179 &CaptureSequencer::manageStandardStart, 180 &CaptureSequencer::manageStandardPrecaptureWait, 181 &CaptureSequencer::manageStandardCapture, 182 &CaptureSequencer::manageStandardCaptureWait, 183 &CaptureSequencer::manageBurstCaptureStart, 184 &CaptureSequencer::manageBurstCaptureWait, 185 &CaptureSequencer::manageDone, 186}; 187 188bool CaptureSequencer::threadLoop() { 189 190 sp<Camera2Client> client = mClient.promote(); 191 if (client == 0) return false; 192 193 CaptureState currentState; 194 { 195 Mutex::Autolock l(mStateMutex); 196 currentState = mCaptureState; 197 } 198 199 currentState = (this->*kStateManagers[currentState])(client); 200 201 Mutex::Autolock l(mStateMutex); 202 if (currentState != mCaptureState) { 203 if (mCaptureState != IDLE) { 204 ATRACE_ASYNC_END(kStateNames[mCaptureState], mStateTransitionCount); 205 } 206 mCaptureState = currentState; 207 mStateTransitionCount++; 208 if (mCaptureState != IDLE) { 209 ATRACE_ASYNC_BEGIN(kStateNames[mCaptureState], mStateTransitionCount); 210 } 211 ALOGV("Camera %d: New capture state %s", 212 client->getCameraId(), kStateNames[mCaptureState]); 213 mStateChanged.signal(); 214 } 215 216 if (mCaptureState == ERROR) { 217 ALOGE("Camera %d: Stopping capture sequencer due to error", 218 client->getCameraId()); 219 return false; 220 } 221 222 return true; 223} 224 225CaptureSequencer::CaptureState CaptureSequencer::manageIdle( 226 sp<Camera2Client> &/*client*/) { 227 status_t res; 228 Mutex::Autolock l(mInputMutex); 229 while (!mStartCapture) { 230 res = mStartCaptureSignal.waitRelative(mInputMutex, 231 kWaitDuration); 232 if (res == TIMED_OUT) break; 233 } 234 if (mStartCapture) { 235 mStartCapture = false; 236 mBusy = true; 237 return START; 238 } 239 return IDLE; 240} 241 242CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) { 243 status_t res = OK; 244 ATRACE_CALL(); 245 mCaptureId++; 246 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) { 247 mCaptureId = Camera2Client::kCaptureRequestIdStart; 248 } 249 { 250 Mutex::Autolock l(mInputMutex); 251 mBusy = false; 252 } 253 254 int takePictureCounter = 0; 255 { 256 SharedParameters::Lock l(client->getParameters()); 257 switch (l.mParameters.state) { 258 case Parameters::DISCONNECTED: 259 ALOGW("%s: Camera %d: Discarding image data during shutdown ", 260 __FUNCTION__, client->getCameraId()); 261 res = INVALID_OPERATION; 262 break; 263 case Parameters::STILL_CAPTURE: 264 res = client->getCameraDevice()->waitUntilDrained(); 265 if (res != OK) { 266 ALOGE("%s: Camera %d: Can't idle after still capture: " 267 "%s (%d)", __FUNCTION__, client->getCameraId(), 268 strerror(-res), res); 269 } 270 l.mParameters.state = Parameters::STOPPED; 271 break; 272 case Parameters::VIDEO_SNAPSHOT: 273 l.mParameters.state = Parameters::RECORD; 274 break; 275 default: 276 ALOGE("%s: Camera %d: Still image produced unexpectedly " 277 "in state %s!", 278 __FUNCTION__, client->getCameraId(), 279 Parameters::getStateName(l.mParameters.state)); 280 res = INVALID_OPERATION; 281 } 282 takePictureCounter = l.mParameters.takePictureCounter; 283 } 284 sp<ZslProcessorInterface> processor = mZslProcessor.promote(); 285 if (processor != 0) { 286 ALOGV("%s: Memory optimization, clearing ZSL queue", 287 __FUNCTION__); 288 processor->clearZslQueue(); 289 } 290 291 /** 292 * Fire the jpegCallback in Camera#takePicture(..., jpegCallback) 293 */ 294 if (mCaptureBuffer != 0 && res == OK) { 295 ATRACE_ASYNC_END(Camera2Client::kTakepictureLabel, takePictureCounter); 296 297 Camera2Client::SharedCameraCallbacks::Lock 298 l(client->mSharedCameraCallbacks); 299 ALOGV("%s: Sending still image to client", __FUNCTION__); 300 if (l.mRemoteCallback != 0) { 301 l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, 302 mCaptureBuffer, NULL); 303 } else { 304 ALOGV("%s: No client!", __FUNCTION__); 305 } 306 } 307 mCaptureBuffer.clear(); 308 309 return IDLE; 310} 311 312CaptureSequencer::CaptureState CaptureSequencer::manageStart( 313 sp<Camera2Client> &client) { 314 ALOGV("%s", __FUNCTION__); 315 status_t res; 316 ATRACE_CALL(); 317 SharedParameters::Lock l(client->getParameters()); 318 CaptureState nextState = DONE; 319 320 res = updateCaptureRequest(l.mParameters, client); 321 if (res != OK ) { 322 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)", 323 __FUNCTION__, client->getCameraId(), strerror(-res), res); 324 return DONE; 325 } 326 327 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE && 328 l.mParameters.state == Parameters::STILL_CAPTURE) { 329 nextState = BURST_CAPTURE_START; 330 } 331 else if (l.mParameters.zslMode && 332 l.mParameters.state == Parameters::STILL_CAPTURE && 333 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) { 334 nextState = ZSL_START; 335 } else { 336 nextState = STANDARD_START; 337 } 338 mShutterNotified = false; 339 340 return nextState; 341} 342 343CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( 344 sp<Camera2Client> &client) { 345 ALOGV("%s", __FUNCTION__); 346 status_t res; 347 sp<ZslProcessorInterface> processor = mZslProcessor.promote(); 348 if (processor == 0) { 349 ALOGE("%s: No ZSL queue to use!", __FUNCTION__); 350 return DONE; 351 } 352 353 // We don't want to get partial results for ZSL capture. 354 client->registerFrameListener(mCaptureId, mCaptureId + 1, 355 this, 356 /*sendPartials*/false); 357 358 // TODO: Actually select the right thing here. 359 res = processor->pushToReprocess(mCaptureId); 360 if (res != OK) { 361 if (res == NOT_ENOUGH_DATA) { 362 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, " 363 "falling back to normal capture", __FUNCTION__, 364 client->getCameraId()); 365 } else { 366 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)", 367 __FUNCTION__, client->getCameraId(), strerror(-res), res); 368 } 369 return STANDARD_START; 370 } 371 372 SharedParameters::Lock l(client->getParameters()); 373 /* warning: this also locks a SharedCameraCallbacks */ 374 shutterNotifyLocked(l.mParameters, client, mMsgType); 375 mShutterNotified = true; 376 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 377 return STANDARD_CAPTURE_WAIT; 378} 379 380CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting( 381 sp<Camera2Client> &/*client*/) { 382 ALOGV("%s", __FUNCTION__); 383 return DONE; 384} 385 386CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing( 387 sp<Camera2Client> &/*client*/) { 388 ALOGV("%s", __FUNCTION__); 389 return START; 390} 391 392CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart( 393 sp<Camera2Client> &client) { 394 ATRACE_CALL(); 395 396 bool isAeConverged = false; 397 // Get the onFrameAvailable callback when the requestID == mCaptureId 398 // We don't want to get partial results for normal capture, as we need 399 // Get ANDROID_SENSOR_TIMESTAMP from the capture result, but partial 400 // result doesn't have to have this metadata available. 401 // TODO: Update to use the HALv3 shutter notification for remove the 402 // need for this listener and make it faster. see bug 12530628. 403 client->registerFrameListener(mCaptureId, mCaptureId + 1, 404 this, 405 /*sendPartials*/false); 406 407 { 408 Mutex::Autolock l(mInputMutex); 409 isAeConverged = (mAEState == ANDROID_CONTROL_AE_STATE_CONVERGED); 410 } 411 412 { 413 SharedParameters::Lock l(client->getParameters()); 414 // Skip AE precapture when it is already converged and not in force flash mode. 415 if (l.mParameters.flashMode != Parameters::FLASH_MODE_ON && isAeConverged) { 416 return STANDARD_CAPTURE; 417 } 418 419 mTriggerId = l.mParameters.precaptureTriggerCounter++; 420 } 421 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId); 422 423 mAeInPrecapture = false; 424 mTimeoutCount = kMaxTimeoutsForPrecaptureStart; 425 return STANDARD_PRECAPTURE_WAIT; 426} 427 428CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait( 429 sp<Camera2Client> &/*client*/) { 430 status_t res; 431 ATRACE_CALL(); 432 Mutex::Autolock l(mInputMutex); 433 while (!mNewAEState) { 434 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration); 435 if (res == TIMED_OUT) { 436 mTimeoutCount--; 437 break; 438 } 439 } 440 if (mTimeoutCount <= 0) { 441 ALOGW("Timed out waiting for precapture %s", 442 mAeInPrecapture ? "end" : "start"); 443 return STANDARD_CAPTURE; 444 } 445 if (mNewAEState) { 446 if (!mAeInPrecapture) { 447 // Waiting to see PRECAPTURE state 448 if (mAETriggerId == mTriggerId && 449 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 450 ALOGV("%s: Got precapture start", __FUNCTION__); 451 mAeInPrecapture = true; 452 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; 453 } 454 } else { 455 // Waiting to see PRECAPTURE state end 456 if (mAETriggerId == mTriggerId && 457 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 458 ALOGV("%s: Got precapture end", __FUNCTION__); 459 return STANDARD_CAPTURE; 460 } 461 } 462 mNewAEState = false; 463 } 464 return STANDARD_PRECAPTURE_WAIT; 465} 466 467CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( 468 sp<Camera2Client> &client) { 469 status_t res; 470 ATRACE_CALL(); 471 SharedParameters::Lock l(client->getParameters()); 472 Vector<int32_t> outputStreams; 473 uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE); 474 475 /** 476 * Set up output streams in the request 477 * - preview 478 * - capture/jpeg 479 * - callback (if preview callbacks enabled) 480 * - recording (if recording enabled) 481 */ 482 outputStreams.push(client->getPreviewStreamId()); 483 outputStreams.push(client->getCaptureStreamId()); 484 485 if (l.mParameters.previewCallbackFlags & 486 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 487 outputStreams.push(client->getCallbackStreamId()); 488 } 489 490 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) { 491 outputStreams.push(client->getRecordingStreamId()); 492 captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT); 493 } 494 495 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS, 496 outputStreams); 497 if (res == OK) { 498 res = mCaptureRequest.update(ANDROID_REQUEST_ID, 499 &mCaptureId, 1); 500 } 501 if (res == OK) { 502 res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT, 503 &captureIntent, 1); 504 } 505 if (res == OK) { 506 res = mCaptureRequest.sort(); 507 } 508 509 if (res != OK) { 510 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 511 __FUNCTION__, client->getCameraId(), strerror(-res), res); 512 return DONE; 513 } 514 515 // Create a capture copy since CameraDeviceBase#capture takes ownership 516 CameraMetadata captureCopy = mCaptureRequest; 517 if (captureCopy.entryCount() == 0) { 518 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 519 __FUNCTION__, client->getCameraId()); 520 return DONE; 521 } 522 523 /** 524 * Clear the streaming request for still-capture pictures 525 * (as opposed to i.e. video snapshots) 526 */ 527 if (l.mParameters.state == Parameters::STILL_CAPTURE) { 528 // API definition of takePicture() - stop preview before taking pic 529 res = client->stopStream(); 530 if (res != OK) { 531 ALOGE("%s: Camera %d: Unable to stop preview for still capture: " 532 "%s (%d)", 533 __FUNCTION__, client->getCameraId(), strerror(-res), res); 534 return DONE; 535 } 536 } 537 // TODO: Capture should be atomic with setStreamingRequest here 538 res = client->getCameraDevice()->capture(captureCopy); 539 if (res != OK) { 540 ALOGE("%s: Camera %d: Unable to submit still image capture request: " 541 "%s (%d)", 542 __FUNCTION__, client->getCameraId(), strerror(-res), res); 543 return DONE; 544 } 545 546 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 547 return STANDARD_CAPTURE_WAIT; 548} 549 550CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( 551 sp<Camera2Client> &client) { 552 status_t res; 553 ATRACE_CALL(); 554 Mutex::Autolock l(mInputMutex); 555 556 // Wait for new metadata result (mNewFrame) 557 while (!mNewFrameReceived) { 558 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration); 559 if (res == TIMED_OUT) { 560 mTimeoutCount--; 561 break; 562 } 563 } 564 565 // Approximation of the shutter being closed 566 // - TODO: use the hal3 exposure callback in Camera3Device instead 567 if (mNewFrameReceived && !mShutterNotified) { 568 SharedParameters::Lock l(client->getParameters()); 569 /* warning: this also locks a SharedCameraCallbacks */ 570 shutterNotifyLocked(l.mParameters, client, mMsgType); 571 mShutterNotified = true; 572 } 573 574 // Wait until jpeg was captured by JpegProcessor 575 while (mNewFrameReceived && !mNewCaptureReceived) { 576 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 577 if (res == TIMED_OUT) { 578 mTimeoutCount--; 579 break; 580 } 581 } 582 if (mTimeoutCount <= 0) { 583 ALOGW("Timed out waiting for capture to complete"); 584 return DONE; 585 } 586 if (mNewFrameReceived && mNewCaptureReceived) { 587 if (mNewFrameId != mCaptureId) { 588 ALOGW("Mismatched capture frame IDs: Expected %d, got %d", 589 mCaptureId, mNewFrameId); 590 } 591 camera_metadata_entry_t entry; 592 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP); 593 if (entry.count == 0) { 594 ALOGE("No timestamp field in capture frame!"); 595 } else if (entry.count == 1) { 596 if (entry.data.i64[0] != mCaptureTimestamp) { 597 ALOGW("Mismatched capture timestamps: Metadata frame %" PRId64 "," 598 " captured buffer %" PRId64, 599 entry.data.i64[0], 600 mCaptureTimestamp); 601 } 602 } else { 603 ALOGE("Timestamp metadata is malformed!"); 604 } 605 client->removeFrameListener(mCaptureId, mCaptureId + 1, this); 606 607 mNewFrameReceived = false; 608 mNewCaptureReceived = false; 609 return DONE; 610 } 611 return STANDARD_CAPTURE_WAIT; 612} 613 614CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart( 615 sp<Camera2Client> &client) { 616 ALOGV("%s", __FUNCTION__); 617 status_t res; 618 ATRACE_CALL(); 619 620 // check which burst mode is set, create respective burst object 621 { 622 SharedParameters::Lock l(client->getParameters()); 623 624 res = updateCaptureRequest(l.mParameters, client); 625 if(res != OK) { 626 return DONE; 627 } 628 629 // 630 // check for burst mode type in mParameters here 631 // 632 mBurstCapture = new BurstCapture(client, this); 633 } 634 635 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1); 636 if (res == OK) { 637 res = mCaptureRequest.sort(); 638 } 639 if (res != OK) { 640 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 641 __FUNCTION__, client->getCameraId(), strerror(-res), res); 642 return DONE; 643 } 644 645 CameraMetadata captureCopy = mCaptureRequest; 646 if (captureCopy.entryCount() == 0) { 647 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 648 __FUNCTION__, client->getCameraId()); 649 return DONE; 650 } 651 652 Vector<CameraMetadata> requests; 653 requests.push(mCaptureRequest); 654 res = mBurstCapture->start(requests, mCaptureId); 655 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10; 656 return BURST_CAPTURE_WAIT; 657} 658 659CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait( 660 sp<Camera2Client> &/*client*/) { 661 status_t res; 662 ATRACE_CALL(); 663 664 while (!mNewCaptureReceived) { 665 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 666 if (res == TIMED_OUT) { 667 mTimeoutCount--; 668 break; 669 } 670 } 671 672 if (mTimeoutCount <= 0) { 673 ALOGW("Timed out waiting for burst capture to complete"); 674 return DONE; 675 } 676 if (mNewCaptureReceived) { 677 mNewCaptureReceived = false; 678 // TODO: update mCaptureId to last burst's capture ID + 1? 679 return DONE; 680 } 681 682 return BURST_CAPTURE_WAIT; 683} 684 685status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms, 686 sp<Camera2Client> &client) { 687 ATRACE_CALL(); 688 status_t res; 689 if (mCaptureRequest.entryCount() == 0) { 690 res = client->getCameraDevice()->createDefaultRequest( 691 CAMERA2_TEMPLATE_STILL_CAPTURE, 692 &mCaptureRequest); 693 if (res != OK) { 694 ALOGE("%s: Camera %d: Unable to create default still image request:" 695 " %s (%d)", __FUNCTION__, client->getCameraId(), 696 strerror(-res), res); 697 return res; 698 } 699 } 700 701 res = params.updateRequest(&mCaptureRequest); 702 if (res != OK) { 703 ALOGE("%s: Camera %d: Unable to update common entries of capture " 704 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 705 strerror(-res), res); 706 return res; 707 } 708 709 res = params.updateRequestJpeg(&mCaptureRequest); 710 if (res != OK) { 711 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture " 712 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 713 strerror(-res), res); 714 return res; 715 } 716 717 return OK; 718} 719 720/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters ¶ms, 721 sp<Camera2Client> client, int msgType) { 722 ATRACE_CALL(); 723 724 if (params.state == Parameters::STILL_CAPTURE 725 && params.playShutterSound 726 && (msgType & CAMERA_MSG_SHUTTER)) { 727 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 728 } 729 730 { 731 Camera2Client::SharedCameraCallbacks::Lock 732 l(client->mSharedCameraCallbacks); 733 734 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__); 735 if (l.mRemoteCallback != 0) { 736 // ShutterCallback 737 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER, 738 /*ext1*/0, /*ext2*/0); 739 740 // RawCallback with null buffer 741 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY, 742 /*ext1*/0, /*ext2*/0); 743 } else { 744 ALOGV("%s: No client!", __FUNCTION__); 745 } 746 } 747} 748 749 750}; // namespace camera2 751}; // namespace android 752