CaptureSequencer.cpp revision efb039e07c688c21122c938b008457bd4f555898
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 ALOGW("%s: Camera %d: Failed to use ZSL queue, falling back to standard capture", 278 __FUNCTION__, client->getCameraId()); 279 return STANDARD_START; 280 } 281 282 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 283 return STANDARD_CAPTURE_WAIT; 284} 285 286CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting( 287 sp<Camera2Client> &client) { 288 ALOGV("%s", __FUNCTION__); 289 return DONE; 290} 291 292CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing( 293 sp<Camera2Client> &client) { 294 ALOGV("%s", __FUNCTION__); 295 return START; 296} 297 298CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart( 299 sp<Camera2Client> &client) { 300 ATRACE_CALL(); 301 client->registerFrameListener(mCaptureId, 302 this); 303 { 304 SharedParameters::Lock l(client->getParameters()); 305 mTriggerId = l.mParameters.precaptureTriggerCounter++; 306 } 307 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId); 308 309 mAeInPrecapture = false; 310 mTimeoutCount = kMaxTimeoutsForPrecaptureStart; 311 return STANDARD_PRECAPTURE_WAIT; 312} 313 314CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait( 315 sp<Camera2Client> &client) { 316 status_t res; 317 ATRACE_CALL(); 318 Mutex::Autolock l(mInputMutex); 319 while (!mNewAEState) { 320 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration); 321 if (res == TIMED_OUT) { 322 mTimeoutCount--; 323 break; 324 } 325 } 326 if (mTimeoutCount <= 0) { 327 ALOGW("Timed out waiting for precapture %s", 328 mAeInPrecapture ? "end" : "start"); 329 return STANDARD_CAPTURE; 330 } 331 if (mNewAEState) { 332 if (!mAeInPrecapture) { 333 // Waiting to see PRECAPTURE state 334 if (mAETriggerId == mTriggerId && 335 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 336 ALOGV("%s: Got precapture start", __FUNCTION__); 337 mAeInPrecapture = true; 338 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; 339 } 340 } else { 341 // Waiting to see PRECAPTURE state end 342 if (mAETriggerId == mTriggerId && 343 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 344 ALOGV("%s: Got precapture end", __FUNCTION__); 345 return STANDARD_CAPTURE; 346 } 347 } 348 mNewAEState = false; 349 } 350 return STANDARD_PRECAPTURE_WAIT; 351} 352 353CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( 354 sp<Camera2Client> &client) { 355 status_t res; 356 ATRACE_CALL(); 357 SharedParameters::Lock l(client->getParameters()); 358 Vector<uint8_t> outputStreams; 359 360 outputStreams.push(client->getPreviewStreamId()); 361 outputStreams.push(client->getCaptureStreamId()); 362 363 if (l.mParameters.previewCallbackFlags & 364 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 365 outputStreams.push(client->getCallbackStreamId()); 366 } 367 368 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) { 369 outputStreams.push(client->getRecordingStreamId()); 370 } 371 372 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS, 373 outputStreams); 374 if (res == OK) { 375 res = mCaptureRequest.update(ANDROID_REQUEST_ID, 376 &mCaptureId, 1); 377 } 378 if (res == OK) { 379 res = mCaptureRequest.sort(); 380 } 381 382 if (res != OK) { 383 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 384 __FUNCTION__, client->getCameraId(), strerror(-res), res); 385 return DONE; 386 } 387 388 CameraMetadata captureCopy = mCaptureRequest; 389 if (captureCopy.entryCount() == 0) { 390 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 391 __FUNCTION__, client->getCameraId()); 392 return DONE; 393 } 394 395 if (l.mParameters.state == Parameters::STILL_CAPTURE) { 396 res = client->getCameraDevice()->clearStreamingRequest(); 397 if (res != OK) { 398 ALOGE("%s: Camera %d: Unable to stop preview for still capture: " 399 "%s (%d)", 400 __FUNCTION__, client->getCameraId(), strerror(-res), res); 401 return DONE; 402 } 403 } 404 // TODO: Capture should be atomic with setStreamingRequest here 405 res = client->getCameraDevice()->capture(captureCopy); 406 if (res != OK) { 407 ALOGE("%s: Camera %d: Unable to submit still image capture request: " 408 "%s (%d)", 409 __FUNCTION__, client->getCameraId(), strerror(-res), res); 410 return DONE; 411 } 412 413 if (l.mParameters.playShutterSound && 414 l.mParameters.state == Parameters::STILL_CAPTURE) { 415 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 416 } 417 418 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 419 return STANDARD_CAPTURE_WAIT; 420} 421 422CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( 423 sp<Camera2Client> &client) { 424 status_t res; 425 ATRACE_CALL(); 426 Mutex::Autolock l(mInputMutex); 427 while (!mNewFrameReceived) { 428 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration); 429 if (res == TIMED_OUT) { 430 mTimeoutCount--; 431 break; 432 } 433 } 434 while (!mNewCaptureReceived) { 435 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 436 if (res == TIMED_OUT) { 437 mTimeoutCount--; 438 break; 439 } 440 } 441 if (mTimeoutCount <= 0) { 442 ALOGW("Timed out waiting for capture to complete"); 443 return DONE; 444 } 445 if (mNewFrameReceived && mNewCaptureReceived) { 446 if (mNewFrameId != mCaptureId) { 447 ALOGW("Mismatched capture frame IDs: Expected %d, got %d", 448 mCaptureId, mNewFrameId); 449 } 450 camera_metadata_entry_t entry; 451 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP); 452 if (entry.count == 0) { 453 ALOGE("No timestamp field in capture frame!"); 454 } 455 if (entry.data.i64[0] != mCaptureTimestamp) { 456 ALOGW("Mismatched capture timestamps: Metadata frame %lld," 457 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp); 458 } 459 client->removeFrameListener(mCaptureId); 460 461 mNewFrameReceived = false; 462 mNewCaptureReceived = false; 463 return DONE; 464 } 465 return STANDARD_CAPTURE_WAIT; 466} 467 468CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart( 469 sp<Camera2Client> &client) { 470 ALOGV("%s", __FUNCTION__); 471 status_t res; 472 ATRACE_CALL(); 473 474 // check which burst mode is set, create respective burst object 475 { 476 SharedParameters::Lock l(client->getParameters()); 477 478 res = updateCaptureRequest(l.mParameters, client); 479 if(res != OK) { 480 return DONE; 481 } 482 483 // 484 // check for burst mode type in mParameters here 485 // 486 mBurstCapture = new BurstCapture(client, this); 487 } 488 489 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1); 490 if (res == OK) { 491 res = mCaptureRequest.sort(); 492 } 493 if (res != OK) { 494 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 495 __FUNCTION__, client->getCameraId(), strerror(-res), res); 496 return DONE; 497 } 498 499 CameraMetadata captureCopy = mCaptureRequest; 500 if (captureCopy.entryCount() == 0) { 501 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 502 __FUNCTION__, client->getCameraId()); 503 return DONE; 504 } 505 506 Vector<CameraMetadata> requests; 507 requests.push(mCaptureRequest); 508 res = mBurstCapture->start(requests, mCaptureId); 509 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10; 510 return BURST_CAPTURE_WAIT; 511} 512 513CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait( 514 sp<Camera2Client> &client) { 515 status_t res; 516 ATRACE_CALL(); 517 518 while (!mNewCaptureReceived) { 519 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 520 if (res == TIMED_OUT) { 521 mTimeoutCount--; 522 break; 523 } 524 } 525 526 if (mTimeoutCount <= 0) { 527 ALOGW("Timed out waiting for burst capture to complete"); 528 return DONE; 529 } 530 if (mNewCaptureReceived) { 531 mNewCaptureReceived = false; 532 // TODO: update mCaptureId to last burst's capture ID + 1? 533 return DONE; 534 } 535 536 return BURST_CAPTURE_WAIT; 537} 538 539status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms, 540 sp<Camera2Client> &client) { 541 ATRACE_CALL(); 542 status_t res; 543 if (mCaptureRequest.entryCount() == 0) { 544 res = client->getCameraDevice()->createDefaultRequest( 545 CAMERA2_TEMPLATE_STILL_CAPTURE, 546 &mCaptureRequest); 547 if (res != OK) { 548 ALOGE("%s: Camera %d: Unable to create default still image request:" 549 " %s (%d)", __FUNCTION__, client->getCameraId(), 550 strerror(-res), res); 551 return res; 552 } 553 } 554 555 res = params.updateRequest(&mCaptureRequest); 556 if (res != OK) { 557 ALOGE("%s: Camera %d: Unable to update common entries of capture " 558 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 559 strerror(-res), res); 560 return res; 561 } 562 563 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE, 564 params.jpegThumbSize, 2); 565 if (res != OK) return res; 566 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY, 567 ¶ms.jpegThumbQuality, 1); 568 if (res != OK) return res; 569 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY, 570 ¶ms.jpegQuality, 1); 571 if (res != OK) return res; 572 res = mCaptureRequest.update( 573 ANDROID_JPEG_ORIENTATION, 574 ¶ms.jpegRotation, 1); 575 if (res != OK) return res; 576 577 if (params.gpsEnabled) { 578 res = mCaptureRequest.update( 579 ANDROID_JPEG_GPS_COORDINATES, 580 params.gpsCoordinates, 3); 581 if (res != OK) return res; 582 res = mCaptureRequest.update( 583 ANDROID_JPEG_GPS_TIMESTAMP, 584 ¶ms.gpsTimestamp, 1); 585 if (res != OK) return res; 586 res = mCaptureRequest.update( 587 ANDROID_JPEG_GPS_PROCESSING_METHOD, 588 params.gpsProcessingMethod); 589 if (res != OK) return res; 590 } else { 591 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES); 592 if (res != OK) return res; 593 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP); 594 if (res != OK) return res; 595 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD); 596 if (res != OK) return res; 597 } 598 599 return OK; 600} 601 602 603}; // namespace camera2 604}; // namespace android 605