CaptureSequencer.cpp revision da1c5c15c2483cd41035e1a492c5963ac86bbcf5
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 "Camera2Client::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 "CaptureSequencer.h" 26#include "BurstCapture.h" 27#include "../Camera2Device.h" 28#include "../Camera2Client.h" 29#include "Parameters.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 mClient(client), 44 mCaptureState(IDLE), 45 mTriggerId(0), 46 mTimeoutCount(0), 47 mCaptureId(Camera2Client::kFirstCaptureRequestId) { 48 ALOGV("%s", __FUNCTION__); 49} 50 51CaptureSequencer::~CaptureSequencer() { 52 ALOGV("%s: Exit", __FUNCTION__); 53} 54 55void CaptureSequencer::setZslProcessor(wp<ZslProcessor> processor) { 56 Mutex::Autolock l(mInputMutex); 57 mZslProcessor = processor; 58} 59 60status_t CaptureSequencer::startCapture() { 61 ALOGV("%s", __FUNCTION__); 62 ATRACE_CALL(); 63 Mutex::Autolock l(mInputMutex); 64 if (mBusy) { 65 ALOGE("%s: Already busy capturing!", __FUNCTION__); 66 return INVALID_OPERATION; 67 } 68 if (!mStartCapture) { 69 mStartCapture = true; 70 mStartCaptureSignal.signal(); 71 } 72 return OK; 73} 74 75void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) { 76 ATRACE_CALL(); 77 Mutex::Autolock l(mInputMutex); 78 mAEState = newState; 79 mAETriggerId = triggerId; 80 if (!mNewAEState) { 81 mNewAEState = true; 82 mNewNotifySignal.signal(); 83 } 84} 85 86void CaptureSequencer::onFrameAvailable(int32_t frameId, 87 CameraMetadata &frame) { 88 ALOGV("%s: Listener found new frame", __FUNCTION__); 89 ATRACE_CALL(); 90 Mutex::Autolock l(mInputMutex); 91 mNewFrameId = frameId; 92 mNewFrame.acquire(frame); 93 if (!mNewFrameReceived) { 94 mNewFrameReceived = true; 95 mNewFrameSignal.signal(); 96 } 97} 98 99void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp) { 100 ATRACE_CALL(); 101 ALOGV("%s", __FUNCTION__); 102 Mutex::Autolock l(mInputMutex); 103 mCaptureTimestamp = timestamp; 104 if (!mNewCaptureReceived) { 105 mNewCaptureReceived = true; 106 mNewCaptureSignal.signal(); 107 } 108} 109 110 111void CaptureSequencer::dump(int fd, const Vector<String16>& args) { 112 String8 result; 113 if (mCaptureRequest.entryCount() != 0) { 114 result = " Capture request:\n"; 115 write(fd, result.string(), result.size()); 116 mCaptureRequest.dump(fd, 2, 6); 117 } else { 118 result = " Capture request: undefined\n"; 119 write(fd, result.string(), result.size()); 120 } 121 result = String8::format(" Current capture state: %s\n", 122 kStateNames[mCaptureState]); 123 result.append(" Latest captured frame:\n"); 124 write(fd, result.string(), result.size()); 125 mNewFrame.dump(fd, 2, 6); 126} 127 128/** Private members */ 129 130const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] = 131{ 132 "IDLE", 133 "START", 134 "ZSL_START", 135 "ZSL_WAITING", 136 "ZSL_REPROCESSING", 137 "STANDARD_START", 138 "STANDARD_PRECAPTURE", 139 "STANDARD_CAPTURING", 140 "BURST_CAPTURE_START", 141 "BURST_CAPTURE_WAIT", 142 "DONE", 143 "ERROR", 144 "UNKNOWN" 145}; 146 147const CaptureSequencer::StateManager 148 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = { 149 &CaptureSequencer::manageIdle, 150 &CaptureSequencer::manageStart, 151 &CaptureSequencer::manageZslStart, 152 &CaptureSequencer::manageZslWaiting, 153 &CaptureSequencer::manageZslReprocessing, 154 &CaptureSequencer::manageStandardStart, 155 &CaptureSequencer::manageStandardPrecaptureWait, 156 &CaptureSequencer::manageStandardCapture, 157 &CaptureSequencer::manageStandardCaptureWait, 158 &CaptureSequencer::manageBurstCaptureStart, 159 &CaptureSequencer::manageBurstCaptureWait, 160 &CaptureSequencer::manageDone, 161}; 162 163bool CaptureSequencer::threadLoop() { 164 status_t res; 165 166 sp<Camera2Client> client = mClient.promote(); 167 if (client == 0) return false; 168 169 if (mCaptureState < ERROR) { 170 mCaptureState = (this->*kStateManagers[mCaptureState])(client); 171 } else { 172 ALOGE("%s: Bad capture state: %s", 173 __FUNCTION__, kStateNames[mCaptureState]); 174 return false; 175 } 176 177 return true; 178} 179 180CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) { 181 status_t res; 182 ATRACE_CALL(); 183 Mutex::Autolock l(mInputMutex); 184 while (!mStartCapture) { 185 res = mStartCaptureSignal.waitRelative(mInputMutex, 186 kWaitDuration); 187 if (res == TIMED_OUT) break; 188 } 189 if (mStartCapture) { 190 mStartCapture = false; 191 mBusy = true; 192 return START; 193 } 194 return IDLE; 195} 196 197CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) { 198 status_t res; 199 ATRACE_CALL(); 200 mCaptureId++; 201 202 { 203 Mutex::Autolock l(mInputMutex); 204 mBusy = false; 205 } 206 207 SharedParameters::Lock l(client->getParameters()); 208 switch (l.mParameters.state) { 209 case Parameters::STILL_CAPTURE: 210 l.mParameters.state = Parameters::STOPPED; 211 break; 212 case Parameters::VIDEO_SNAPSHOT: 213 l.mParameters.state = Parameters::RECORD; 214 break; 215 default: 216 ALOGE("%s: Camera %d: Still image produced unexpectedly " 217 "in state %s!", 218 __FUNCTION__, client->getCameraId(), 219 Parameters::getStateName(l.mParameters.state)); 220 } 221 222 return IDLE; 223} 224 225CaptureSequencer::CaptureState CaptureSequencer::manageStart( 226 sp<Camera2Client> &client) { 227 ALOGV("%s", __FUNCTION__); 228 status_t res; 229 ATRACE_CALL(); 230 SharedParameters::Lock l(client->getParameters()); 231 CaptureState nextState = DONE; 232 233 res = updateCaptureRequest(l.mParameters, client); 234 if (res != OK ) { 235 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)", 236 __FUNCTION__, client->getCameraId(), strerror(-res), res); 237 return DONE; 238 } 239 240 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE && 241 l.mParameters.state == Parameters::STILL_CAPTURE) { 242 nextState = BURST_CAPTURE_START; 243 } 244 else if (l.mParameters.zslMode && 245 l.mParameters.state == Parameters::STILL_CAPTURE) { 246 nextState = ZSL_START; 247 } else { 248 nextState = STANDARD_START; 249 } 250 251 return nextState; 252} 253 254CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( 255 sp<Camera2Client> &client) { 256 ALOGV("%s", __FUNCTION__); 257 status_t res; 258 sp<ZslProcessor> processor = mZslProcessor.promote(); 259 if (processor == 0) { 260 ALOGE("%s: No ZSL queue to use!", __FUNCTION__); 261 return DONE; 262 } 263 264 client->registerFrameListener(mCaptureId, 265 this); 266 267 res = client->getCameraDevice()->clearStreamingRequest(); 268 if (res != OK) { 269 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: " 270 "%s (%d)", 271 __FUNCTION__, client->getCameraId(), strerror(-res), res); 272 return DONE; 273 } 274 // TODO: Actually select the right thing here. 275 res = processor->pushToReprocess(mCaptureId); 276 if (res != OK) { 277 if (res == NOT_ENOUGH_DATA) { 278 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, " 279 "falling back to normal capture", __FUNCTION__, 280 client->getCameraId()); 281 } else { 282 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)", 283 __FUNCTION__, client->getCameraId(), strerror(-res), res); 284 } 285 return STANDARD_START; 286 } 287 288 SharedParameters::Lock l(client->getParameters()); 289 if (l.mParameters.playShutterSound) { 290 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 291 } 292 293 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 294 return STANDARD_CAPTURE_WAIT; 295} 296 297CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting( 298 sp<Camera2Client> &client) { 299 ALOGV("%s", __FUNCTION__); 300 return DONE; 301} 302 303CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing( 304 sp<Camera2Client> &client) { 305 ALOGV("%s", __FUNCTION__); 306 return START; 307} 308 309CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart( 310 sp<Camera2Client> &client) { 311 ATRACE_CALL(); 312 client->registerFrameListener(mCaptureId, 313 this); 314 { 315 SharedParameters::Lock l(client->getParameters()); 316 mTriggerId = l.mParameters.precaptureTriggerCounter++; 317 } 318 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId); 319 320 mAeInPrecapture = false; 321 mTimeoutCount = kMaxTimeoutsForPrecaptureStart; 322 return STANDARD_PRECAPTURE_WAIT; 323} 324 325CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait( 326 sp<Camera2Client> &client) { 327 status_t res; 328 ATRACE_CALL(); 329 Mutex::Autolock l(mInputMutex); 330 while (!mNewAEState) { 331 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration); 332 if (res == TIMED_OUT) { 333 mTimeoutCount--; 334 break; 335 } 336 } 337 if (mTimeoutCount <= 0) { 338 ALOGW("Timed out waiting for precapture %s", 339 mAeInPrecapture ? "end" : "start"); 340 return STANDARD_CAPTURE; 341 } 342 if (mNewAEState) { 343 if (!mAeInPrecapture) { 344 // Waiting to see PRECAPTURE state 345 if (mAETriggerId == mTriggerId && 346 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 347 ALOGV("%s: Got precapture start", __FUNCTION__); 348 mAeInPrecapture = true; 349 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; 350 } 351 } else { 352 // Waiting to see PRECAPTURE state end 353 if (mAETriggerId == mTriggerId && 354 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 355 ALOGV("%s: Got precapture end", __FUNCTION__); 356 return STANDARD_CAPTURE; 357 } 358 } 359 mNewAEState = false; 360 } 361 return STANDARD_PRECAPTURE_WAIT; 362} 363 364CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( 365 sp<Camera2Client> &client) { 366 status_t res; 367 ATRACE_CALL(); 368 SharedParameters::Lock l(client->getParameters()); 369 Vector<uint8_t> outputStreams; 370 371 outputStreams.push(client->getPreviewStreamId()); 372 outputStreams.push(client->getCaptureStreamId()); 373 374 if (l.mParameters.previewCallbackFlags & 375 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 376 outputStreams.push(client->getCallbackStreamId()); 377 } 378 379 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) { 380 outputStreams.push(client->getRecordingStreamId()); 381 } 382 383 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS, 384 outputStreams); 385 if (res == OK) { 386 res = mCaptureRequest.update(ANDROID_REQUEST_ID, 387 &mCaptureId, 1); 388 } 389 if (res == OK) { 390 res = mCaptureRequest.sort(); 391 } 392 393 if (res != OK) { 394 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 395 __FUNCTION__, client->getCameraId(), strerror(-res), res); 396 return DONE; 397 } 398 399 CameraMetadata captureCopy = mCaptureRequest; 400 if (captureCopy.entryCount() == 0) { 401 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 402 __FUNCTION__, client->getCameraId()); 403 return DONE; 404 } 405 406 if (l.mParameters.state == Parameters::STILL_CAPTURE) { 407 res = client->getCameraDevice()->clearStreamingRequest(); 408 if (res != OK) { 409 ALOGE("%s: Camera %d: Unable to stop preview for still capture: " 410 "%s (%d)", 411 __FUNCTION__, client->getCameraId(), strerror(-res), res); 412 return DONE; 413 } 414 } 415 // TODO: Capture should be atomic with setStreamingRequest here 416 res = client->getCameraDevice()->capture(captureCopy); 417 if (res != OK) { 418 ALOGE("%s: Camera %d: Unable to submit still image capture request: " 419 "%s (%d)", 420 __FUNCTION__, client->getCameraId(), strerror(-res), res); 421 return DONE; 422 } 423 424 if (l.mParameters.playShutterSound && 425 l.mParameters.state == Parameters::STILL_CAPTURE) { 426 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 427 } 428 429 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 430 return STANDARD_CAPTURE_WAIT; 431} 432 433CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( 434 sp<Camera2Client> &client) { 435 status_t res; 436 ATRACE_CALL(); 437 Mutex::Autolock l(mInputMutex); 438 while (!mNewFrameReceived) { 439 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration); 440 if (res == TIMED_OUT) { 441 mTimeoutCount--; 442 break; 443 } 444 } 445 while (!mNewCaptureReceived) { 446 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 447 if (res == TIMED_OUT) { 448 mTimeoutCount--; 449 break; 450 } 451 } 452 if (mTimeoutCount <= 0) { 453 ALOGW("Timed out waiting for capture to complete"); 454 return DONE; 455 } 456 if (mNewFrameReceived && mNewCaptureReceived) { 457 if (mNewFrameId != mCaptureId) { 458 ALOGW("Mismatched capture frame IDs: Expected %d, got %d", 459 mCaptureId, mNewFrameId); 460 } 461 camera_metadata_entry_t entry; 462 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP); 463 if (entry.count == 0) { 464 ALOGE("No timestamp field in capture frame!"); 465 } 466 if (entry.data.i64[0] != mCaptureTimestamp) { 467 ALOGW("Mismatched capture timestamps: Metadata frame %lld," 468 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp); 469 } 470 client->removeFrameListener(mCaptureId); 471 472 mNewFrameReceived = false; 473 mNewCaptureReceived = false; 474 return DONE; 475 } 476 return STANDARD_CAPTURE_WAIT; 477} 478 479CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart( 480 sp<Camera2Client> &client) { 481 ALOGV("%s", __FUNCTION__); 482 status_t res; 483 ATRACE_CALL(); 484 485 // check which burst mode is set, create respective burst object 486 { 487 SharedParameters::Lock l(client->getParameters()); 488 489 res = updateCaptureRequest(l.mParameters, client); 490 if(res != OK) { 491 return DONE; 492 } 493 494 // 495 // check for burst mode type in mParameters here 496 // 497 mBurstCapture = new BurstCapture(client, this); 498 } 499 500 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1); 501 if (res == OK) { 502 res = mCaptureRequest.sort(); 503 } 504 if (res != OK) { 505 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 506 __FUNCTION__, client->getCameraId(), strerror(-res), res); 507 return DONE; 508 } 509 510 CameraMetadata captureCopy = mCaptureRequest; 511 if (captureCopy.entryCount() == 0) { 512 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 513 __FUNCTION__, client->getCameraId()); 514 return DONE; 515 } 516 517 Vector<CameraMetadata> requests; 518 requests.push(mCaptureRequest); 519 res = mBurstCapture->start(requests, mCaptureId); 520 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10; 521 return BURST_CAPTURE_WAIT; 522} 523 524CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait( 525 sp<Camera2Client> &client) { 526 status_t res; 527 ATRACE_CALL(); 528 529 while (!mNewCaptureReceived) { 530 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 531 if (res == TIMED_OUT) { 532 mTimeoutCount--; 533 break; 534 } 535 } 536 537 if (mTimeoutCount <= 0) { 538 ALOGW("Timed out waiting for burst capture to complete"); 539 return DONE; 540 } 541 if (mNewCaptureReceived) { 542 mNewCaptureReceived = false; 543 // TODO: update mCaptureId to last burst's capture ID + 1? 544 return DONE; 545 } 546 547 return BURST_CAPTURE_WAIT; 548} 549 550status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms, 551 sp<Camera2Client> &client) { 552 ATRACE_CALL(); 553 status_t res; 554 if (mCaptureRequest.entryCount() == 0) { 555 res = client->getCameraDevice()->createDefaultRequest( 556 CAMERA2_TEMPLATE_STILL_CAPTURE, 557 &mCaptureRequest); 558 if (res != OK) { 559 ALOGE("%s: Camera %d: Unable to create default still image request:" 560 " %s (%d)", __FUNCTION__, client->getCameraId(), 561 strerror(-res), res); 562 return res; 563 } 564 } 565 566 res = params.updateRequest(&mCaptureRequest); 567 if (res != OK) { 568 ALOGE("%s: Camera %d: Unable to update common entries of capture " 569 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 570 strerror(-res), res); 571 return res; 572 } 573 574 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE, 575 params.jpegThumbSize, 2); 576 if (res != OK) return res; 577 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY, 578 ¶ms.jpegThumbQuality, 1); 579 if (res != OK) return res; 580 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY, 581 ¶ms.jpegQuality, 1); 582 if (res != OK) return res; 583 res = mCaptureRequest.update( 584 ANDROID_JPEG_ORIENTATION, 585 ¶ms.jpegRotation, 1); 586 if (res != OK) return res; 587 588 if (params.gpsEnabled) { 589 res = mCaptureRequest.update( 590 ANDROID_JPEG_GPS_COORDINATES, 591 params.gpsCoordinates, 3); 592 if (res != OK) return res; 593 res = mCaptureRequest.update( 594 ANDROID_JPEG_GPS_TIMESTAMP, 595 ¶ms.gpsTimestamp, 1); 596 if (res != OK) return res; 597 res = mCaptureRequest.update( 598 ANDROID_JPEG_GPS_PROCESSING_METHOD, 599 params.gpsProcessingMethod); 600 if (res != OK) return res; 601 } else { 602 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES); 603 if (res != OK) return res; 604 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP); 605 if (res != OK) return res; 606 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD); 607 if (res != OK) return res; 608 } 609 610 return OK; 611} 612 613 614}; // namespace camera2 615}; // namespace android 616