CaptureSequencer.cpp revision f1e98d857ec377f2c9b916073d40732e6ebb7ced
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 // Get the onFrameAvailable callback when the requestID == mCaptureId 383 client->registerFrameListener(mCaptureId, mCaptureId + 1, 384 this); 385 { 386 SharedParameters::Lock l(client->getParameters()); 387 mTriggerId = l.mParameters.precaptureTriggerCounter++; 388 } 389 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId); 390 391 mAeInPrecapture = false; 392 mTimeoutCount = kMaxTimeoutsForPrecaptureStart; 393 return STANDARD_PRECAPTURE_WAIT; 394} 395 396CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait( 397 sp<Camera2Client> &/*client*/) { 398 status_t res; 399 ATRACE_CALL(); 400 Mutex::Autolock l(mInputMutex); 401 while (!mNewAEState) { 402 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration); 403 if (res == TIMED_OUT) { 404 mTimeoutCount--; 405 break; 406 } 407 } 408 if (mTimeoutCount <= 0) { 409 ALOGW("Timed out waiting for precapture %s", 410 mAeInPrecapture ? "end" : "start"); 411 return STANDARD_CAPTURE; 412 } 413 if (mNewAEState) { 414 if (!mAeInPrecapture) { 415 // Waiting to see PRECAPTURE state 416 if (mAETriggerId == mTriggerId && 417 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 418 ALOGV("%s: Got precapture start", __FUNCTION__); 419 mAeInPrecapture = true; 420 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; 421 } 422 } else { 423 // Waiting to see PRECAPTURE state end 424 if (mAETriggerId == mTriggerId && 425 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 426 ALOGV("%s: Got precapture end", __FUNCTION__); 427 return STANDARD_CAPTURE; 428 } 429 } 430 mNewAEState = false; 431 } 432 return STANDARD_PRECAPTURE_WAIT; 433} 434 435CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( 436 sp<Camera2Client> &client) { 437 status_t res; 438 ATRACE_CALL(); 439 SharedParameters::Lock l(client->getParameters()); 440 Vector<int32_t> outputStreams; 441 uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE); 442 443 /** 444 * Set up output streams in the request 445 * - preview 446 * - capture/jpeg 447 * - callback (if preview callbacks enabled) 448 * - recording (if recording enabled) 449 */ 450 outputStreams.push(client->getPreviewStreamId()); 451 outputStreams.push(client->getCaptureStreamId()); 452 453 if (l.mParameters.previewCallbackFlags & 454 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 455 outputStreams.push(client->getCallbackStreamId()); 456 } 457 458 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) { 459 outputStreams.push(client->getRecordingStreamId()); 460 captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT); 461 } 462 463 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS, 464 outputStreams); 465 if (res == OK) { 466 res = mCaptureRequest.update(ANDROID_REQUEST_ID, 467 &mCaptureId, 1); 468 } 469 if (res == OK) { 470 res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT, 471 &captureIntent, 1); 472 } 473 if (res == OK) { 474 res = mCaptureRequest.sort(); 475 } 476 477 if (res != OK) { 478 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 479 __FUNCTION__, client->getCameraId(), strerror(-res), res); 480 return DONE; 481 } 482 483 // Create a capture copy since CameraDeviceBase#capture takes ownership 484 CameraMetadata captureCopy = mCaptureRequest; 485 if (captureCopy.entryCount() == 0) { 486 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 487 __FUNCTION__, client->getCameraId()); 488 return DONE; 489 } 490 491 /** 492 * Clear the streaming request for still-capture pictures 493 * (as opposed to i.e. video snapshots) 494 */ 495 if (l.mParameters.state == Parameters::STILL_CAPTURE) { 496 // API definition of takePicture() - stop preview before taking pic 497 res = client->stopStream(); 498 if (res != OK) { 499 ALOGE("%s: Camera %d: Unable to stop preview for still capture: " 500 "%s (%d)", 501 __FUNCTION__, client->getCameraId(), strerror(-res), res); 502 return DONE; 503 } 504 } 505 // TODO: Capture should be atomic with setStreamingRequest here 506 res = client->getCameraDevice()->capture(captureCopy); 507 if (res != OK) { 508 ALOGE("%s: Camera %d: Unable to submit still image capture request: " 509 "%s (%d)", 510 __FUNCTION__, client->getCameraId(), strerror(-res), res); 511 return DONE; 512 } 513 514 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 515 return STANDARD_CAPTURE_WAIT; 516} 517 518CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( 519 sp<Camera2Client> &client) { 520 status_t res; 521 ATRACE_CALL(); 522 Mutex::Autolock l(mInputMutex); 523 524 // Wait for new metadata result (mNewFrame) 525 while (!mNewFrameReceived) { 526 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration); 527 if (res == TIMED_OUT) { 528 mTimeoutCount--; 529 break; 530 } 531 } 532 533 // Approximation of the shutter being closed 534 // - TODO: use the hal3 exposure callback in Camera3Device instead 535 if (mNewFrameReceived && !mShutterNotified) { 536 SharedParameters::Lock l(client->getParameters()); 537 /* warning: this also locks a SharedCameraCallbacks */ 538 shutterNotifyLocked(l.mParameters, client, mMsgType); 539 mShutterNotified = true; 540 } 541 542 // Wait until jpeg was captured by JpegProcessor 543 while (mNewFrameReceived && !mNewCaptureReceived) { 544 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 545 if (res == TIMED_OUT) { 546 mTimeoutCount--; 547 break; 548 } 549 } 550 if (mTimeoutCount <= 0) { 551 ALOGW("Timed out waiting for capture to complete"); 552 return DONE; 553 } 554 if (mNewFrameReceived && mNewCaptureReceived) { 555 if (mNewFrameId != mCaptureId) { 556 ALOGW("Mismatched capture frame IDs: Expected %d, got %d", 557 mCaptureId, mNewFrameId); 558 } 559 camera_metadata_entry_t entry; 560 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP); 561 if (entry.count == 0) { 562 ALOGE("No timestamp field in capture frame!"); 563 } 564 if (entry.data.i64[0] != mCaptureTimestamp) { 565 ALOGW("Mismatched capture timestamps: Metadata frame %lld," 566 " captured buffer %lld", 567 entry.data.i64[0], 568 mCaptureTimestamp); 569 } 570 client->removeFrameListener(mCaptureId, mCaptureId + 1, this); 571 572 mNewFrameReceived = false; 573 mNewCaptureReceived = false; 574 return DONE; 575 } 576 return STANDARD_CAPTURE_WAIT; 577} 578 579CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart( 580 sp<Camera2Client> &client) { 581 ALOGV("%s", __FUNCTION__); 582 status_t res; 583 ATRACE_CALL(); 584 585 // check which burst mode is set, create respective burst object 586 { 587 SharedParameters::Lock l(client->getParameters()); 588 589 res = updateCaptureRequest(l.mParameters, client); 590 if(res != OK) { 591 return DONE; 592 } 593 594 // 595 // check for burst mode type in mParameters here 596 // 597 mBurstCapture = new BurstCapture(client, this); 598 } 599 600 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1); 601 if (res == OK) { 602 res = mCaptureRequest.sort(); 603 } 604 if (res != OK) { 605 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 606 __FUNCTION__, client->getCameraId(), strerror(-res), res); 607 return DONE; 608 } 609 610 CameraMetadata captureCopy = mCaptureRequest; 611 if (captureCopy.entryCount() == 0) { 612 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 613 __FUNCTION__, client->getCameraId()); 614 return DONE; 615 } 616 617 Vector<CameraMetadata> requests; 618 requests.push(mCaptureRequest); 619 res = mBurstCapture->start(requests, mCaptureId); 620 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10; 621 return BURST_CAPTURE_WAIT; 622} 623 624CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait( 625 sp<Camera2Client> &/*client*/) { 626 status_t res; 627 ATRACE_CALL(); 628 629 while (!mNewCaptureReceived) { 630 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 631 if (res == TIMED_OUT) { 632 mTimeoutCount--; 633 break; 634 } 635 } 636 637 if (mTimeoutCount <= 0) { 638 ALOGW("Timed out waiting for burst capture to complete"); 639 return DONE; 640 } 641 if (mNewCaptureReceived) { 642 mNewCaptureReceived = false; 643 // TODO: update mCaptureId to last burst's capture ID + 1? 644 return DONE; 645 } 646 647 return BURST_CAPTURE_WAIT; 648} 649 650status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms, 651 sp<Camera2Client> &client) { 652 ATRACE_CALL(); 653 status_t res; 654 if (mCaptureRequest.entryCount() == 0) { 655 res = client->getCameraDevice()->createDefaultRequest( 656 CAMERA2_TEMPLATE_STILL_CAPTURE, 657 &mCaptureRequest); 658 if (res != OK) { 659 ALOGE("%s: Camera %d: Unable to create default still image request:" 660 " %s (%d)", __FUNCTION__, client->getCameraId(), 661 strerror(-res), res); 662 return res; 663 } 664 } 665 666 res = params.updateRequest(&mCaptureRequest); 667 if (res != OK) { 668 ALOGE("%s: Camera %d: Unable to update common entries of capture " 669 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 670 strerror(-res), res); 671 return res; 672 } 673 674 res = params.updateRequestJpeg(&mCaptureRequest); 675 if (res != OK) { 676 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture " 677 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 678 strerror(-res), res); 679 return res; 680 } 681 682 return OK; 683} 684 685/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters ¶ms, 686 sp<Camera2Client> client, int msgType) { 687 ATRACE_CALL(); 688 689 if (params.state == Parameters::STILL_CAPTURE 690 && params.playShutterSound 691 && (msgType & CAMERA_MSG_SHUTTER)) { 692 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 693 } 694 695 { 696 Camera2Client::SharedCameraCallbacks::Lock 697 l(client->mSharedCameraCallbacks); 698 699 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__); 700 if (l.mRemoteCallback != 0) { 701 // ShutterCallback 702 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER, 703 /*ext1*/0, /*ext2*/0); 704 705 // RawCallback with null buffer 706 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY, 707 /*ext1*/0, /*ext2*/0); 708 } else { 709 ALOGV("%s: No client!", __FUNCTION__); 710 } 711 } 712} 713 714 715}; // namespace camera2 716}; // namespace android 717