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