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