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